第一步:对页面进行分析
通过抓包看到页面
没有其他的敏感内容
尝试输入【1】
输入【or】后发现被过滤了
然后尝试fuzz一下
发现以下内容均被过滤
prepare|flag|unhex|xml|drop|create|insert|like|regexp|outfile|readfile|where|from|union|update|delete|if|sleep|extractvalue|updatexml|or|and|&|"
尝试使用堆叠注入
- 所谓堆叠注入就是将多条sql语句放在一起执行并且以【;】分开
获取到当前数据库
获取到当前数据库中到表单
由于 【from】被禁用,我们这里没有办法从flag中拿取数据
这里尝试许多办法最后在GitHub上获取到了该题目的源代码
我们对源码分析发现这里有【||】表示或,传入的参数经过拼接后就成了(如query=1)
select 1 || flag from Flag
在数据库中查询就变成了
正如我们获取到的数据
现在要做的就是如何绕过【||】,并且让其执行后面的代码【flag from Flag】
方法一:使用Sql_mode 中的PIPES_AS_CONCAT函数
- PIPES_AS_CONCAT:将【||】原本的“或”转换为“连接字符”,就是将||前后进行拼接
使用方法:PayLoad1【1;set sql_mode=PIPES_AS_CONCAT;select 1】
拼接过后的结果就是【select 1;set sql_mode=PIPES_AS_CONCAT;select 1||flag from Flag】
数据库就会识别为【select 1||flag from Flag;】注意:这里的||以及不是或的意思,是管道符的意思,就是将1查询完后,会继续查询flag的内容,然后将结果合并返回,如图
1后面的就是我们的flag
同时还有别的sql_mode
ANSI_QUOTES
启用 ANSI_QUOTES 后,不能用双引号来引用字符串,因为它被解释为识别符,作用与 一样。设置它以后,
update t set f1="" ...`,会报 Unknown column '' in 'field list 这样的语法错误。
NO_TABLE_OPTIONS
使用 SHOW CREATE TABLE
时不会输出MySQL特有的语法部分,如 ENGINE
,这个在使用 mysqldump 跨DB种类迁移的时候需要考虑。
NO_AUTO_CREATE_USER
字面意思不自动创建用户。在给MySQL用户授权时,我们习惯使用 GRANT ... ON ... TO dbuser
顺道一起创建用户。设置该选项后就与oracle操作类似,授权之前必须先建立用户。5.7.7开始也默认了。
方法二:利用非预期注入方式获取Flag
我们传递过去的内容会被解析为\(sql = "select ".\)post['query']."||flag from Flag";
因此我们可以在传递值这边做文章,让数据库进行错误的判断
我们可以尝试传入1,1
返回回来的结果
在数据库中的操作
我们可以发现,这里的内容查询不是对【1,1】||【flag】而是对【1】,【1||flag】
这就是数据库对符号的判断不严谨,导致的非预期漏洞
我们就可以将","前的内容改为“ * ”, 从而构建PayLoad【 *,1 】
成功拿到flag
后端显示的结果
这道题严格意义上来说难度不大,在于考察的是对注入的掌握程度
本题中核心的知识点有:
- 堆叠注入
- 利用Sql_mode中的PIPES_AS_CONCAT 将 || 的作用转换连接
- 非预期注入