目录
一、注点判断
已知目标网站127.0.0.1/new_list.php?id=1,我们可以首先通过字符型和数字型注入点进行判断是否为字符型或数字型
1.1数字型
添加?id=1 and 1=1和?id=1 and 1=2 查看内容是否正常显示
添加?id=1 and 1=2,根据sql语句语法在and后面的1=2很明显是不符合条件的,所以我们可以预料内容应该出现错误
然而实际却并没有出现错误,原因是可能属于字符型。
如果为字符型:那么我们输入的1 and 1=2 会因为是字符型被添加单引号,这样进入php脚本执行的sql语句是这样的:select xx from xx where id='1 and 1=2',也就是说他变成了一个单纯的字符串了故没有1=2的判断内容,因此我们还需要进行字符类型注入判断
1.2字符型
添加?id=1' and 1=1 --+,这里解释一下这段话,添加这句话后实际sql执行内容其实是select xx from xx where id='1' and 1=1 --+‘ ,这么写是为了将id后面的和前面的单引号闭合形成字符串,并且让and语句的'通过--+进行注释,因此按照sql语句语法,返回内容应是正常的
为了确定它是字符型注入我们再次添加内容?id=1' and 1=2 --+,实际添加内容就是select xx from xx where id='1' and 1=2 --+‘,根据sql语句语法返回内容应是错误的
然而实际结果依然是正常的,那么这是什么原因呢,我们是否可以直接判断他不是字符型注入而是其他没有学过的方式呢?
关于字符型和数字型注入判断详细可以参考:【干货】如何判断 Sql 注入点_判断是否存在sql注入-CSDN博客
1.3宽字节
在进行宽字节注入前,我们首先引入一个概念:
宽字节注入发生的位置就是PHP发送请求到MYSQL时字符集使用character_set_client设置值进行了一次编码。在使用PHP连接MySQL的时候,当设置“character_set_client = gbk”时会导致一个编码转换的问题,也就是我们熟悉的宽字节注入,两个以上的字节就是宽字节
宽字节注入原理即是利用编码转换,将服务器端强制添加的本来用于转义的\符号吃掉,从而能使攻击者输入的引号起到闭合作用,以至于可以进行SQL注入
这里的宽字节注入是利用mysql的一个特性,mysql在使用GBK编码(GBK就是常说的宽字节之一,实际上只有两字节)的时候,会认为两个字符是一个汉字(前一个ascii码要大于128,才到汉字的范围),而当我们输入有单引号时会自动加入\进行转义而变为\’(在PHP配置文件中magic_quotes_gpc=On的情况下或者使用addslashes函数,icov函数,mysql_real_escape_string函数、mysql_escape_string函数等,提交的参数中如果带有单引号’,就会被自动转义\’,使得多数注入攻击无效),由于宽字节带来的安全问题主要是吃ASCII字符(一字节)的现象,将后面的一个字节与前一个大于128的ascii码进行组合成为一个完整的字符(mysql判断一个字符是不是汉字,首先两个字符时一个汉字,另外根据gbk编码,第一个字节ascii码大于128,基本上就可以了),此时’前的\就被吃了,我们就可以使用’了,利用这个特性从而可实施SQL注入的利用
最常使用的宽字节注入是利用%df,其实我们只要第一个ascii码大于128就可以了,比如ascii码为129的就可以,但是我们怎么将他转换为URL编码呢,其实很简单,我们先将129(十进制)转换为十六进制,为0x81,然后在十六进制前面加%即可,即为%81。另外可以直接记住GBK首字节对应0×81-0xFE,尾字节对应0×40-0xFE(除0×7F),则尾字节会被吃掉,如转义符号\对应的编码0×5C!另外简单提一下,GB2312是被GBK兼容的,它的高位范围是0xA1-0xF7,低位范围是0xA1-0xFE(0x5C不在该范围内),因此不能使用编码吃掉%5c
具体该内容学习,可以进行参考WEB渗透学习笔记5——宽字节、Cookie、base64注入_web渗透 cookie-CSDN博客
总结的来说其实就是1'时,由于magic和addslashes函数会导致'前加上\是的'被转义为无效字符,我们加上1%df\'后%df和\会由于gbk编码会将两者看作一个中文字符(双字节为一个中文字符),因此效果来看就是\被“吞掉了”
我们添加?id=1%df'查看效果
果然报错了,报错原因是因为单引号没有闭合,最后sql执行的语句实际是select xx from xx where id =' 1%df\'',%df与\构成了一个中文字符
剩下操作具体流程可以参考上期的内容,操作方式基本一致
二、sqlmap宽字节注入
本次实验是基于kali系统来进行的,详细sqlmap安装可以参考其他博客或者github上寻找
首先我们使用sqlmap -u指令对其直接进行注入点判断
可以发现它根本没有发现注入点,由于我们通过手工注入已经知道是因为这是一个宽字节漏洞,因此我们可以使用在sqlmap的tamper目录下的脚本unmagicquotes.py
运行结果如下图所示:可以看到已经成功获取了信息。
然后使用python3 sqlmap.py -u "http://124.70.71.251:41606/new_list.php?id=1" --tamper=unmagicquotes.py --current-db 可以查看当前的数据库是哪个
根据当前数据库我们再去查找表名python3 sqlmap.py -u "http://124.70.71.251:41606/new_list.php?id=1" --tamper=unmagicquotes.py -D ‘mozhe_discuz_stormgroup ’--tables
随后再根据选取的表名我们去找字段名以及它的值python3 sqlmap.py -u "http://124.70.71.251:41606/new_list.php?id=1" --tamper=unmagicquotes.py -D ‘mozhe_discuz_stormgroup ’ -T 'stormgroup_member' --dump
至此找到了账号和密码,通过md5解密就可以得到正确密码
三、实战总结
总的来说使用sqlmap的前提是需要知道当前漏洞注入是属于宽字节的注入才行,所以也间接证明了手动注入学习的重要性,只有知道了注入的原理,才能正确的使用脚本,同时sql内容的学习也极其关键,如果不能明白其中的原理,在实战中也不发现不了其中的问题。