第一步:对页面进行分析

通过抓包看到页面

没有其他的敏感内容

尝试输入【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上获取到了该题目的源代码

  • \(sql = "select ".\)post['query']."||flag from Flag";

    这就是执行的sql语句

我们对源码分析发现这里有【||】表示或,传入的参数经过拼接后就成了(如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

后端显示的结果

这道题严格意义上来说难度不大,在于考察的是对注入的掌握程度

本题中核心的知识点有:

  1. 堆叠注入
  2. 利用Sql_mode中的PIPES_AS_CONCAT 将 || 的作用转换连接
  3. 非预期注入

标签: BuuCTF

添加新评论