若有错误,还请斧正。
攻击者可在正常的SQL语句中注入自己的语句,使得原SQL语句改变并执行则为SQL注入.
注入点数据类型为整型则为整型注入,如下
输入的id不同,会从数据库中取出不同的结果。我们输入的id被直接拼接进sql语句中执行,这就使得我们可以直接接管sql。通过在id处注入sql语句来获取各种信息.
在这里我们可以构造联合查询payload来获取信息,首先需要判断查询语句的字段数
,当查询字段数大于等于这个数字时页面会给出正确执行的结果。
当查询字段数小于这个数字时页面会给出错误的执行结果
轮番操作后就可以确定在此处的查询字段数为3.而后便可以通过联合查询来确定结果显示位。
对了。此时mysql执行的sql语句为,在id部分我们需要一个数据库中没有的数据(比如0),
确定了结果显示位为联合查询的数字3处,由此可借由mysql系统库(information_schema)来获取表,如下
获取表的列信息如下
mysql的group_concat函数可以将查询结果合并为一个结果
在获取了表与列的信息和即可查询该表的具体数据
字符型注入与整型注入差别不大,两者最主要的差别在于字符型注入需要闭合引号.当我们注入一个引号时,mysql在执行时引号不成对,则会出错。
通过各种手段处理引号后则可以正常构造与整型注入类似的payload来获取各种信息.对于sql语句后面自带的引号可以采取注释、闭合等手段。
后面与整型相同,则不再赘述
引号处理
在程序不输出查询结果,但会输出mysql错误信息时则可通过报错注入来获取信息.报错注入不需要像联合注入一样获取显示位,因为错误信息所在即是显示位.
报错注入通常使用以下函数
报错用法
报错用法
报错用法,概率报错
或
rand函数可在0-1之间生成一个随机数,而floor则是获得小于等于传入值的整数
当我们使用rand()*2时则可以获得一个0-2之间的随机数,倘若这时使用floor则可以获得一个0或者1
mysql可以使用group by 对结果进行分组,将结果相同的划为一组,count(*)可以统计结果数量
注入结果无任何回显即是盲注
根据注入执行结果的布尔值(true,或false),页面显示不同,由此作为判断注入结果的依据即是布尔盲注
我们可以通过构造sql语句来逐步判断后端的结果,如下
当页面显示wow时,就说明database之一个字符为s,由此,进一步注入判断出当前数据库全名为sqli.
为提高注入效率,可编写脚本如下(已注释掉highlight_file(__FILE__))
该脚本相比于手工注入,效率有了很大的提升,但是该脚本的缺点还是很明显 --- 因为每一个字符都要进行判断,从而导致运行速度不够快
故我们可以使用二分法编写一个脚本,如下
在注入结果不会被输出,并且不管注入成功还是失败页面始终只有一个反应时,则可进行延时盲注,通过mysql执行需要一定时间的函数来作为注入正确与否的判断标准.
我的环境出了些问题,故这里用的CTFHUB->技能树->时间盲注
正常发起请求时响应时间如下,51ms
sleep配合if函数,延时payload
延时后的响应时间如下(依照不同环境,响应时间不同),1047ms=1.047s
故可以在if的之一个参数处构造sql语句,再通过响应时间来判断结果是否正确
猜解表名payload
猜解列名payload``1 and if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='表名'),{第几个字符},1)<{字符ascii码},sleep(1),1)`
获取值 payload``1 and if(ascii(substr((select 列名 from 表名),{第几个字符},1)<{字符ascii码},sleep(1),1)`
为提高注入效率,编写脚本如下
延时盲注流程大抵如此,再罗列一些延时注入的函数如下
参考文章离怀秋
通过分号(;)来结束一条语句并同时执行其他sql语句即是堆叠注入.
可以通过mysql预编译语句来执行查询语句
下面给一实例
构造堆叠注入payload
查询数据库信息
查询数据库表信息
也可
大小写绕过限制
1';Set @a=0x73656c6563742067726f75705f636f6e636174287461626c655f6e616d65292066726f6d20696e666f726d6174696f6e5f736368656d612e7461626c6573207768657265207461626c655f736368656d613d64617461626173652829;Prepare b from @a;execute b;
再构造
也可
1';Set @a=0x73656c6563742067726f75705f636f6e63617428636f6c756d6e5f6e616d65292066726f6d20696e666f726d6174696f6e5f736368656d612e636f6c756d6e73207768657265207461626c655f6e616d653d273139313938313039333131313435313427;Prepare b from @a;execute b;
最后构造
1';Set @a=0x73656c65637420666c61672066726f6d20603139313938313039333131313435313460;Prepare b from @a;execute b;
参考文章backlion
在一个输入点将用户输入的含有特殊字符的字符串存入数据库,在某一个输出点将存入的字符串取出时未进行转义便拼接进另一处sql语句,所导致的sql注入即是二次注入.如下
网鼎杯2018 Unfinish
只有一个登录、注册功能,成功登录后便进入主页!
尝试注册稀奇古怪的用户名
注册没有成功,尝试闭合单引号
注册成功,登录查看.确定是sql注入
在本地测试后发现我们注入在insert中的语句可构成布尔型结果,故可进行布尔盲注
fuzz一下哪些字符被过滤,哪怕bp设置1线程,也会被buuctf的限制请求干扰到,所以写脚本
information被过滤了我们无法获取到表名等信息(sys数据库不一定存在),这里猜表名为flag,直接因为并不能确定列名(先测试了select flag from flag ,会出错)
先来确定我们的布尔盲注
没问题,写脚本
2017-赛客夏令营-Web injection
整型注入
判断列数,
获取回显位
表名
字段名
爆值
WUSTCTF2020 颜值成绩查询
经过一番测试发现,stunum为数字布尔注入.
经fuzz,发现select被过滤,但可大写select绕过
故编写脚本如下
BJDCTF 2nd 简单注入
访问robots.txt发现提示文件hint.txt
fuzz过后发现过滤了以下关键字
单、双引号皆被过滤。要想注入语句首先需要逃逸单引号,这里很简单提交即可将sql语句自带的一个单引号转义,进而逃逸出一个引号.而后在password处构造语句来注入数据
and被过滤,但是or可用,通过or + 异或操作使执行结果出现不同布尔值,发现页面响应信息不同.
测试payload与
故编写脚本如下
SUCTF 2018 MultiSQL
正常注册后登录
编辑头像处,可以上传图片
用户信息与注册处存在sql注入.前者为堆叠注入、后者为二次注入。这里使用堆叠注入写入webshell
payload
CISCN2019 day2 easyweb
在robots.txt中发现备份文件.下载
首先需要思考单引号的闭合问题。
因为addslashes的存在无法直接使用引号闭合,也无法使用来逃逸单引号。但是代码11-12行对传入数据的替空处理可做利用。
构造一个即可逃逸单引号。(经过addslashes处理变成,再经过str_replace的处理,将替换为空,则得到一个)
故,可构造payload,根据页面响应内容进行布尔判断.
二分脚本
登录
上传常规shell,后缀不能为php,使用phtml绕过
查看该文件,是用户的上传记录,记录了上传的文件名
考虑修改文件名为shell,因为文件名会检测关键字php,所以使用php短标签
再访问日志文件
RCTF2015 EasySQL
程序只有几个功能:注册、登录、修改密码、查看文章
在注册时发现有过滤一些敏感词,fuzz如下
测试后发现注册点username处存在二次注入
过滤了and(忽略大小写)但没过滤,尝试进行报错注入
admin4"&&updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema=database()))),1)#
admin4"&&updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name='flag'))),1)#
admin4"&&updatexml(1,concat(0x7e,(select(flag)from(flag))),1)#, flag not here
老折磨怪了
admin4"%26%26updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name='users'))),1)#
通过这几次的结果可以看出,输出结果有长度限制,但是这不妨碍我们猜到字段为real_flag_1s_here
常用的字符截取函数都被过滤了
长度690,真flag藏在里面,可以
先尝试将所有结果翻转,可以看到是flag的一部分
admin4"&&updatexml(1,concat(0x7e,(select(reverse(group_concat(real_flag_1s_here)))from(users))),1)#
需要想办法取剩下的一部分.这里尝试通过正则获取结果,rlike被过滤了,但是可以使用rlike的同名函数regexp
admin4"&&updatexml(1,concat(0x7e,(select(real_flag_1s_here)from(users)where(real_flag_1s_here)regexp('^flag'))),1)#
两者组合
给个半自动脚本
NCTF2019 SQLi
给了sql语句
hint
拿到密码即可getflag,ban了很多字符,截取字符的函数substr不能用,需要()的函数也都不能用
但是这里可以使用正则匹配来曲线救国
首先,使来逃逸引号,而后构造payload使得结果为true和false查看页面不同
,这里的%00并非真实的%00而是ascii码为0的字符,用该字符截断sql语句后面的引号(注释符被过滤)
当查询语句为真时,页面会进行重定向
可以将状态码作为判断正确与否的标准
故编写脚本如下
读取源码
还发现提示文件hint.php
经过一番审计后,在search.php中发现一个注入点
过滤了一些注入关键词,无法深入注入,再找其他地方
在change.php中发现二次注入
参数未经正则检验,只使用了addslashes转义字符
在代码第21行,可以看到在更新地址时它不但修改了当前地址,还保存了旧地址。由此二次注入产生
构造payload验证
编写脚本如下
结果只会显示31位
测试发现存在flag.txt,读取该文件
fuzz可用字符
结果如下
substring被过滤,但是substr可以用
构造payload进行测试
布尔型结果,故可编写脚本了。
因为information_schema被过滤了,所以我们使用sys数据库来获取表信息
脚本如下
flag
书写新时代全面依法治国新篇章 全面依法治国是坚持和发展中国特色社会主义的本质要求和重要保障,事关我们党执政兴国,事关人民幸福安康,事关党和国家事业发展。在协调推进“四个全面”战略布局中,全面...
之前清水健绿汁的文章,详见:日本男优清水健与致命绿汁,重口慎入 原题目:xxxx男优天天从事什么事情?著名男优清水健忙碌的一天。。 原文链接(日文) 由中国网友翻译润色,投递于煎蛋。煎蛋链接...
入住酒店记录查询app(如何查询酒店住房记录) 专业盗取微信密码,开房查询,通话记录查询,查询微信聊天记录,非常靠谱!微信官方账户"微信110"宣布,从现在起,将启动为期100天的"清风计划"内容生...
P8来临时,有三个组员分别是P8青春版、P8、P8 Max,那样的产品形态,好像Mate 8上还要效仿,终究能够立即遮盖大、中、小三个显示屏尺寸。 官方消息称,华为公司Mate 8会出现三个版本号,...
steam在连接至steam服务器时遇到问题(如何解决steam服务器问题呢?) 用户在登录steam的时候遇见了“ steam在连接至steam服务器时遇到问题”的错误,没有具体提示、不知道怎么解...
“私人伴游小姐自述-【陈姚】” 伴游范围:全国微博地址:2809为了真实、安全、靠谱,天津高端伴游看图预约,但联系方式:微信号、qq群、电话、电话手机号码只对会员提供!注册时间:2019-8-3注册时...