sql注入题目合集
一.[极客大挑战 2019]BabySQL 基础的注入题目
一开始先使用万能密码1‘ or 1=1查看登录成功后的回显位置

这里报错可判断出or被过滤了,再尝试双写绕过过滤

这里登录成功了,说明可用双写绕过,再查看列数和回显

这里报错判断select或union或都被过滤了,再使用双写绕过过滤

查看出列数为3列,注点为2和3。这道题会显示报错,先出尝试使用报错注入。注入途中发现substr,from,information,where也被过滤,使用双写绕过。

最后注入成功,查看出表名,然后依次查找出列名,列里的flag


最后使用substr函数提取出完整的flag

二.[极客大挑战 2019]LoveSQL 基础的注入题目
原理与babysql一样,不过没有函数过滤,不需要双写绕过,直接报错注入即可拿到flag
三.[CISCN2019 华北赛区 Day2 Web1]Hack World
开局先用1‘ or 1=1万能账号查看,发现有sql语句过滤机制

用sql字典爆破查看被过滤的sql语句,发现空格,/**/,or,and,–+,#,union,还有一些报错注入的函数都被过滤了,无法使用联合注入和报错注入,优先考虑盲注

因or和and被过滤,所以可使用异或符^来判断页面两种不同的状态


因为真为1,假为0,且1^1=0,1^0=1,所以括号中条件为真时,页面输出Error Occured When Fetch Result.当括号中条件为假时,页面输出Hello, glzjin wants a girlfriend.可根据这两种输出盲注
写出盲注脚本
1 | import requests |
注意
1. 脚本中使用了time.sleep(0.1),是为了避免请求频率过高,导致服务器繁忙请求失败,从而使得到的flag残缺
2. 脚本中使用了session.Session()是为了保持会话状态,避免每次请求都重新登录,导致注入失败
执行脚本,获取flag

四.[b01lers2020]Life on Mars
进入题目后无法直接获取get或post参数的变量名,抓包查看信息

发现get参数search,且只要地址正确,就会返回以下页面
、
用order by注入查看字段数,发现字段为2时,页面正常显示


再使用union联合注入查看回显位置

发现回显位置在最末尾,再查看所有库名

选择一个库,依次查看表名,列名和列内容



这里刚好得到了flag,如果没有就换一个库或列继续查找
五.October 2019 Twice SQL Injection
考察知识
二次注入
先随便注册一个账号,进行登录,输入sql语句查看过滤情况,发现没有过滤,但是单引号用\转义了,初步判断为二次注入

尝试注册用户名为:1’ union select database()# 的账号,登录后发现回显数据库名

进一步注入,注册用户名为:1’ union select group_concat(table_name) from information_schema.tables where table_schema=database()# 的账号,登录后回显表名

把sql注入语句注册为用户名,依次查找列名和列内容,最终获取flag


六.[CISCN2019 华北赛区 Day1 Web5]CyberPunk
考察知识
二次注入,php伪协议
先查看源码,发现页面源代码末尾有提示file传参

使用php伪协议读取php文件源码的base64编码,再解码

依次拿到提交订单,修改订单,查看订单,删除订单的php源码,发现修改订单的代码中存在注入漏洞

1 | $sql = "update `user` set `address`='".$address."', `old_address`='".$row['address']."' where `user_id`=".$row['user_id']; |
查看库名
在地址中输入:’,’address’=(select group_concat(schema_name) from information_schema.schemata)#
再修改地址使sql语句生效,最后查看订单回显sql执行结果

查看ctftraining库的表名
在地址中输入:’,’address’=(select group_concat(table_name) from information_schema.tables where table_schema=’ctftraining’)#
再修改地址使sql语句生效,最后查看订单回显sql执行结果

查看列名
在地址中输入:’,’address’=(select group_concat(column_name) from information_schema.columns where table_schema=’ctftraining’ and table_name=’FLAG_TABLE’)#
再修改地址使sql语句生效,最后查看订单回显sql执行结果

查看列内容
在地址中输入:’,’address’=(select * from FLAG_COLUMN)#
再修改地址使sql语句生效,最后查看订单回显sql执行结果
发现值为空,没有flag,被骗了,再尝试查看文件目录是否有flag文件
在地址中输入:’,’address’=(select(load_file(‘/flag.txt’)))#
再修改地址使sql语句生效,最后查看订单回显sql执行结果

最终获取flag
七.[GYCTF2020]Ezsqli 无列名注入
考察知识
布尔盲注,无列名注入
思路
1. 先输入1‘,1“,只返回了bool(false),并没有具体的报错信息,所以报错应该不回显,排除报错注入
2. 依次输入id=1,id=2,id=3,id=0.发现id=1时返回NULL,id=2时返回V&N,id>=3或<=0时返回Error Occured When Fetch Result.可用布尔盲注
3. 用sql字典爆破出被过滤的字符,发现if,union,or,and,information等字符被过滤了,还可以用^异或来进行布尔盲注
4. information_schema无法使用,可以用sys.schema_table_statistics_with_buffer库和sys.x$schema_flattened_keys库代替来查找表名,效果与imformation_schema.tables库相同
5. 但是无法查找列名,所以用无列名注入法,查找列的内容,这里用到了ascii位偏移

给定两个字符串,会各取两个字符串的首字符ascii码来比较,不等式成立返回1,不等式不成立返回0,且两个比较的列数和非比较列要相同(比如select 1,”b”中,1是非比较列,b是比较列),如果两个首字符的ascii码都相等则比较第二个字符,以此类推;如果前面的字符都相等,一个后面有字符,另一个没有字符,则有字符的大。



6. 根据以上规律,写出盲注脚本
1 | import requests |
7. 先用sys.schema_table_statistics_with_buffer代替information_schema.tables库,查找到表名f1ag_1s_h3r3_hhhhh,再无列名注入查找flag

八.[SUCTF 2019]EasySQL 堆叠注入
1. 先输入1或>=1的数返回Array ( [0] => 1 ),输入0或字符无回显,返回为空,推断可能有||结构
||运算规则:首先0和字符为假,非0数字为真,如果第一个为真直接返回真,如果第一个为假则判断后一个,如果后一个为假则返回假,如果后一个为真则返回真
2. 根据前面的返回,则判断后一个为假内容及[输入的数据] || 假,所以结构应该为 ‘select [输入的数据] || 假 from Flag’
3. 所以可以用*,1绕过||运算,返回所有字段的内容
输入*,1后,结构变为 ‘select ,1 || 假 from Flag’ 因为 ‘1||假‘=1,所以返回所有字段的内容(包括flag)
为什么是,1,而不是*,0/字符?
因为0和字符为假,0 || 假返回空无回显,无法查看flag

4. 最终获取flag
另一种方法是通过 set sql_mode 将 || 的语义强制转换为字符串连接符。执行以下两个步骤的 payload:
- 首先执行 1;set sql_mode=PIPES_AS_CONCAT;
- 然后执行 select 1。
这样做能将 || 从逻辑”或”运算符转换为与 Oracle 数据库兼容的字符串连接符,从而拼接并输出完整的 flag 内容。

