用户
搜索
  • TA的每日心情

    2016-8-11 21:08
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    安全团队

    Rank: 7Rank: 7Rank: 7

    11

    主题

    38

    帖子

    629

    魔法币
    收听
    0
    粉丝
    9
    注册时间
    2016-8-11

    i春秋认证

    发表于 2016-9-28 14:07:10 98679
    1.SQL注入
    1.1 普通注入
    普通注入分为int型和string型,在string型注入中需要使用单或双引号闭合。

    1.1.1 整型注入
    测试代码:
    [PHP] 纯文本查看 复制代码
    [mw_shl_code=applescript,true]<?php
    header("Content-type:text/html;charset=utf-8");
    $uid = $_GET['id'];
    $sql = "select * from test where id=".$uid;
    $conn = mysql_connect('localhost', 'root', '123456');
    mysql_select_db("sw1t0", $conn);
    $result = mysql_query($sql, $conn);
    print_r ('执行SQL语句:'.$sql.'<br />结果:');
    print_r (mysql_fetch_row($result));
    ?>
    [/mw_shl_code]
    测试代码中GET id参数中存在SQL注入漏洞(整型注入),测试如下
    图片1.png

    原本的SQL注入语句已通过查询出错的方式结合union联合查询到了当前数据库的相关信息。需要注意的是查询出错和语法出错是两回事,加单引号和双引号是用来闭合语句重新构造的,像这个例子如果是通过加引号的方式,那样得到的报错是语法错误,数据库根本不会解析执行,同样后半句的联合查询也不会执行。在此一定要把sql注入的原理理解清楚。
    数据库操作存在一些关键字,php代码审计的时候可以通过查找这些关键字来定向挖掘SQL注入漏洞:select from、mysql_connect、mysql_query、mysql_fetch_row等。

    1.2 编码注入
    编码处理的函数也是存在问题的,通过输入转码函数不兼容的特殊字符,可以导致输出的字符变成有害数据。SQL注入里最常见的编码注入是MYSQL宽字节以及urldecode/rawurldecode函数导致的。

    1.2.1 宽字节注入
    当设置“set character_set_client=gbk”时会导致一个编码转换的注入问题,这就是宽字节注入:注入参数里带入%df%27,即可把程序中过滤出的\(%5c)吃掉。
    假设
    [AppleScript] 纯文本查看 复制代码
    /1.php?id=1

    里面的id参数存在宽字节注入漏洞,当按照普通字符型注入提交
    [AppleScript] 纯文本查看 复制代码
    /1.php?id=-1' and  1=1%23

    时,MYSQL实际运行的SQL语句是
    [AppleScript] 纯文本查看 复制代码
    select * from user where id='-1\' and 1=1#'

    这是由于单引号被自动转义成\'后,前面的%df和转义字符\反斜杠(%5c)组合成了%df%5c,也就是“運”字,这时候后面的单引号还在,成功闭合了前面的单引号。
      出现这个漏洞的原因是在PHP连接MySQL的时候执行了“set character_set_client=gbk”的设置,告诉MySQL服务器:客户端来源数据编码是GBK,然后MySQL服务器对查询语句进行GBK转码导致反斜杠\被%df吃掉,而一般都不直接这么设置。通常的设置方法是 SET NAMES 'gbk' ,等同于如下代码:
    [PHP] 纯文本查看 复制代码
    [mw_shl_code=applescript,true]SET
    character_set_connection = 'gbk',
    character_set_results='gbk',
    character_set_client=gbk
    [/mw_shl_code]
      这同样也是存在漏洞的,官方建议使用mysql_set_charset方式来设置编码,然而它也只是调用了SET NAMES,所以效果也是一样的。不过mysql_set_charset调用SET NAMES之后还记录了当前的编码,留着给后面mysql_real_escape_string处理字符串时使用,所以在后面使用mysql_real_escape_string()函数来参数过滤可以解决这个漏洞。

    测试代码:
    [PHP] 纯文本查看 复制代码
    [mw_shl_code=applescript,true]<?php
    //header("Content-type:text/html;charset=utf-8");
    $conn = mysql_connect('localhost', 'root', '123456');
    mysql_select_db('sw1t0', $conn);
    mysql_query("SET NAMES 'gbk'", $conn);
    $uid = addslashes($_GET['id']);
    $sql = "select * from test where id='".$uid."'";
    $result = mysql_query($sql, $conn);
    print_r ('执行SQL语句:'.$sql.'<br/>结果:');
    print_r (mysql_fetch_row($result));
    mysql_close();
    ?>
    [/mw_shl_code]

    测试效果:
    图片2.png

    因为编码问题所以存在汉字显示乱码的问题,但是可以看到SQL语句是正常执行了的,注入成功。
      对宽字符注入的挖掘只需搜索如下几个关键字即可:SET NAMES、character_set_client=gbk、mysql_set_charset('gbk')

    1.2.2 二次urldecode注入
    现在的web程序大多都会进行参数过滤,通常使用addslashes()、mysql_real_escape_string()、mysql_escape_string()函数或者开启GPC的方式来防止注入,也就是给单引号(')、(")、反斜杠(\)和NULL加上反斜杠转义。如果某次使用了urldecode或者rawurldecode函数,则会导致二次解码生成单引号而引发注入。
      原理是当提交参数到WebSever时,WebSever会自动解码一次,假设目标开启了GPC,提交
    [AppleScript] 纯文本查看 复制代码
    /test.php?id=1%2527

    因为提交的参数里没有单引号,所以第一次解码后的结果是id=1%27,%25的解码结果是%,如果程序里使用了urldecode或者rawurldecode函数来解码id参数,则解码后的结果是id=1',单引号成功拼接近字符串,可能引发注入。

    测试代码:
    [PHP] 纯文本查看 复制代码
    [mw_shl_code=applescript,true]<?php
    header("Content-type:text/html;charset=utf-8");
    $conn = mysql_connect('localhost', 'root', '123456');
    mysql_select_db('sw1t0', $conn);
    $uid = addslashes($_GET['id']);
    $uid = urldecode($uid);
    $sql = "select * from test where id='".$uid."'";
    $result = mysql_query($sql, $conn);
    print_r ('执行SQL语句:'.$sql.'<br/>结果:');
    print_r (mysql_fetch_row($result));
    mysql_close();
    ?>
    [/mw_shl_code]

    测试效果:
    图片3.png
    这种注入漏洞主要是由于urldecode使用不当导致的,因此可以通过搜索urldecode和rawurldecode函数来挖掘二次urldecode注入漏洞。

    注:
    此笔记为代码审计一书的学习笔记,将我认为必须要了解和掌握的原理性的知识记录下来便于复习和巩固。同时本书中出现的错误着实不少,不论是文字叙述还是代码段都有,因此我建议大家去自己手动把这些例子都挨着敲一遍,根据报错就可以发现同时也加深对这些漏洞出现的原理的理解。这样以后自己做代码审计的时候举一反三,自己独立挖掘分析,而不是照葫芦画瓢。

    本帖被以下淘专辑推荐:

    发表于 2016-9-28 14:36:37
    很溜嗷
    使用道具 举报 回复
    发表于 2016-9-28 20:38:44
    看看看看
    使用道具 举报 回复
    ro1e表哥在学习代码审计啊
    我们在攻与防的路上你追我逐
                                                                                            我们在黑与白的边界徘徊不定
    使用道具 举报 回复
    代码审计才是一门艺术啊
    使用道具 举报 回复
    发表于 2016-11-7 21:38:46
    使用道具 举报 回复
    发表于 2016-12-21 14:17:01
    现在大部分php版本都不支持mysql_connect这种方式连接了,建议可以用pdo方式做例子,可能会更好一些,个人建议。
    使用道具 举报 回复
    好东西啊,超喜欢啊
    使用道具 举报 回复
    恩恩,好厉害啊,很喜欢,不不错啊,厉害了我的哥哥
    使用道具 举报 回复
    好牛逼的样子啊,我看好你哦,谢谢啦,嗯嗯呢
    使用道具 举报 回复
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册