Flask内存马的检测与清除

Demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from flask import Flask, request, render_template_string,current_app

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()

Flask 内存马生成

1
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']})

Flask内存马检测

情景1 代码自带内存马

image-20221016005717629

类似于这种直接执行命令的,再复杂一点的base64编码之类的,看到之后直接清除掉即可。

情景2 通过ssti种植内存马

1
2
url_for.__globals__['current_app'].url_map
打印当前所有路由,可用来结合流量观察是否有内存马

rule的意思是通过URL访问的地址,如/shell,后面->跟的是entrypoint,可以理解为处理到达该请求的函数是什么,比如rule ‘/‘的entrypoint是hello_world,那么当访问首页的时候就会转到函数hello_world去进行处理。

image-20221016001751973

flask内存马清除

修改源代码,新建一个同名路由(如/shell),即可抵消新写入路由的影响,并且修复ssti,只需要过滤花括号就可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from flask import Flask, request, render_template_string,current_app

app = Flask(__name__)


@app.route('/')
def hello_world(): # put application's code here
person = 'knave'
blacklist='{'#彻底杜绝ssti
if request.args.get('name'):
person = request.args.get('name')
if blacklist in person:#关键字检测
return "fxxk hacker"
template = '<h1>Hi, %s.</h1>' % person
return render_template_string(template)
@app.route('/shell')
def test():
return "123"

if __name__ == '__main__':
app.run()

再次使用payload打一下,情况如下

image-20221016005113292

参考

https://xz.aliyun.com/t/10933#toc-4

https://www.anquanke.com/post/id/279160#h3-11