Skip to main content

A auto pyjail (python sandbox) solver

Project description

Typhon: Lets solve pyjail without brain

PyPI Downloads License Python_version PyPI Version Tests codecov

听着,我已经受够那些愚蠢的CTF pyjail题目了——每次我都要浪费时间在又臭又长的黑名单和各种pyjail总结之间找哪个链子没被过滤,或者在命名空间里一个一个运行dir()去找能用的东西。这简直就是一种折磨。

所以这就是Typhon(提丰),一个致力于让你不需要脑子也能做pyjail的一把梭工具。

image

文档: https://typhon.lamentxu.top/
博客: https://www.cnblogs.com/LAMENTXU/articles/19101758

请务必看完本readme后再使用Typhon工具,尤其是Q&A部分。

Highlights

  • 完全开源,免费的一把梭工具
  • 不需要大脑就能完成pyjail题目,爱护您的脑细胞和眼球
  • 拥有数百条gadgets和几乎所有主流的bypass方法
  • 支持多种函数以达成不同功能,如RCE用bypassRCE(), 读文件用bypassRead()等等
  • 不依赖第三方库(包含 CLI/WebUI,均为标准库实现)

How to Use

Install

你可以使用pip进行安装:

pip install TyphonBreaker

命令行(typhonbreaker)与 WebUI(typhonbreaker webui)无需额外依赖(均为标准库实现)。

WebUI

启动 WebUI:

typhonbreaker webui

浏览器打开:http://127.0.0.1:6240

注:当前 WebUI 会监听 0.0.0.0:6240,如果运行在服务器上请注意访问控制/防火墙配置。

Docker WebUI

本仓库包含用于构建 WebUI 镜像的 Dockerfile,并提供 GitHub Actions 自动发布到 GHCR。

  1. 拉取并运行:
docker run --rm -p 6240:6240 ghcr.io/lamentxu123/typhonbreaker-webui:latest
  1. 或使用 compose:
docker compose up --build

自定义宿主机端口(容器内仍是 6240):

TYPHONBREAKER_PORT=7000 docker compose up --build

Interface

提供 bypass* 系列接口。主要见 API 文档

Step by Step Tutorial

你可以通过示例文档中的例题来学习 Typhon 的实战用法。以下仅仅提供一个示例。

假设有如下题目:

import re
def safe_run(cmd):
    if len(cmd) > 160:
        return "Command too long"
    if any([i for i in ['import', '__builtins__', '{}'] if i in cmd]):
        return "WAF!"
    if re.match(r'.*import.*', cmd):
        return "WAF!"
    exec(cmd, {'__builtins__': {}})

safe_run(input("Enter command: "))

Step1. 分析waf

首先,我们需要分析一下pyjail waf的功能(这可能是唯一需要大脑的地方)。

可以看出,上述题目的waf如下:

  • 限制长度最大值为160
  • 在exec的命名空间里没有__builtins__
  • 禁止使用builtins, import, {}字符
  • 设置了正则表达式'.*import.*'限制条件

Step2. 将waf导入Typhon

首先我们将exec行删除:

import re
def safe_run(cmd):
    if len(cmd) > 160:
        return "Command too long"
    if any([i for i in ['import', '__builtins__', '{}'] if i in cmd]):
        return "WAF!"
    if re.match(r'.*import.*', cmd):
        return "WAF!"

safe_run(input("Enter command: "))

然后,我们以Typhon对应的bypass函数替代exec行,在对应位置导入WAF, 并在该行上方import Typhon

import re
def safe_run(cmd):
    import Typhon
    Typhon.bypassRCE(cmd,
    banned_chr=['__builtins__', 'import', '{}'],
    banned_re='.*import.*',
    local_scope={'__builtins__': {}},
    max_length=160)

safe_run(input("Enter command: "))

Step3. 运行

运行你的题目程序,等待Jail broken的信息出现即可。

image

Q&A

  • 何时import Typhon

一定要将行import Typhon放在Typhon内置绕过函数的上一行(即使你患有PEP-8强迫症)。否则,Typhon将无法通过栈帧获取当前的全局变量空间。

Do:

def safe_run(cmd):
    import Typhon
    Typhon.bypassRCE(cmd,
    banned_chr=['builtins', 'os', 'exec', 'import'])

safe_run('cat /f*')

Don't:

import Typhon

def safe_run(cmd):
    Typhon.bypassRCE(cmd,
    banned_chr=['builtins', 'os', 'exec', 'import'])

safe_run('cat /f*')
  • 为什么需要使用与题目相同的python版本?

Pyjail中存在一些通过索引寻找对应object的gadgets(如继承链)。继承链的利用随着索引变化很大。因此,请务必确保Typhon的运行环境与题目相同。

无法保证?

是的,大多数题目都不会给出对应的python版本。因此,Typhon会在使用涉及版本的gadgets时做出提示

image

这种情况下往往需要CTF选手自己去找题目环境中该gadgets需要的索引值。

  • 如果题目的execeval没有限制命名空间怎么办?

假设题目没有限制命名空间,则不必填写local_scope参数。Typhon会自动使用import Typhon时的当前命名空间进行绕过

  • 这个payload我用不了能不能换一个?

你可以在参数中加上print_all_payload=True,Typhon就会打印其生成的所有payload。

  • 这个WEB题好像没开放stdin,我exec(input())没用怎么办?

你可以在参数中加上interactive=False,Typhon就会禁止使用所有涉及stdin的payload。

  • 最后输出的payload没回显怎么办?

对于bypassRCE,我们认为:只要命令得到了执行,就是RCE成功。 至于回显问题,你可以选择反弹shell,时间盲注,或者:添加print_all_payload=True参数,查看所有payload,其中可能含有能够成功回显的payload。

Proof of Concept

Typhon的工作原理如下:

bypass by path & technique

我们定义两种bypass方式:

  • path: 通过不同的载荷进行绕过(例如os.system('calc')subprocess.Popen('calc')
  • technique: 使用不同技术对相同的有效载荷进行处理从而绕过(例如,os.system('c'+'a'+'l'+'c')os.system('clac'[::-1]))

Typhon内置了上百种path。每次我们要绕过获取某个东西时,我们先通过local_scope找到所有可以用的path,接下来,通过bypasser.py中的technique生成每个path对应的不同变体,并尝试绕过黑名单。

gadgets chain

本思路受到pyjailbreaker工具的启发。

pyjailbreaker不直接通过gadgets一步到位实现RCE,而是一步一步寻找RCE链条中需要的项。如假设存在下列黑名单:

  • 本地命名空间无__builtins__
  • 禁止使用builtins字符

对于这个WAF,Typhon是这样处理的:

  • 首先,我们通过'J'.__class__.__class__获取type
  • 随后,我们找到获取type后可能可以获取builtins的RCE链子TYPE.__subclasses__(TYPE)[0].register.__globals__['__builtins__']
  • 已知题目黑名单过滤了__builtins__字符,则我们将此path投入bypasser产生数十种变体。选择其中最短的变体:TYPE.__subclasses__(TYPE)[0].register.__globals__['__snitliub__'[::-1]]
  • 随后,我们找到获取__builtins__后的RCE链子BUILTINS_SET['breakpoint']()
  • 最后,我们将代表builtins字典的占位符BUILTINS_SET替换为上步中获取的__builtins__路径,以此类推,将TYPE占位符替换为真实的路径,就得到了最终的payload。
'J'.__class__.__class__.__subclasses__('J'.__class__.__class__)[0].register.__globals__['__snitliub__'[::-1]]['breakpoint']()

Step by Step

Typhon的workflow顺序如下:

  • 每一个终点函数(bypassRCE, bypassREAD,etc.)都会调用主函数bypassMAIN,主函数会尽可能搜集所有的可用gadgets(如上例中的type)并将收集到的内容传递给对应的下级函数。
  • bypassMAIN函数在简单分析完当前的变量空间后,会:
    • 尝试直接RCE(如help(), breakporint()
    • 尝试获取生成器
    • 尝试获取type
    • 尝试获取object
    • 尝试获取bytes
    • 如当前空间中的__builtins__未被删除,但被修改,尝试恢复(如id.__self__
    • 如当前空间中的__builtins__被删除,尝试从其他命名空间恢复
    • 承上,尝试继承链绕过
    • 尝试获取import包的能力
    • 尝试直接通过可能恢复的__builtins__ RCE
    • 将结果传递给下级函数
  • 下级函数拿到bypassMAIN的结果后,会根据该函数所实现的需求,选择对应的gadgets进行处理(如bypassRCE专注于RCE,bypassREAD专注于文件读取,bypassENV专注于读取环境变量)。其过程与上述相似。

Limitations

  • 目前Typhon只支持python 3.9及以上版本。

  • 目前Typhon只支持linux沙箱。

  • 目前Typhon尚无法绕过audithook沙箱。

  • 由于Typhon采用局部最优的递归策略,对于一些简单的题目,反而需要耗时更久(约1min)。

  • 目前已知的不支持的bypass方法:

    • Typhon不支持以list.pop(0)代替list[0],这是因为Typhon所生成的payload都需要经过本地执行验证才能成立,而pop方法在验证时会将元素从列表中删除,从而破坏后续环境。

Milestones

v1.0 (已发布)

  • 实现基本框架

v1.1

  • 实现更多绕过器
    • 使用魔术方法替换二元运算符 (a.__add__(b)替换a+b)
    • list.pop(0)替换list[0]
    • list(dict(a=1))[0]替换'a'
    • str()替换空字符串
  • 实现内置的bash bypasser
  • 更好的bypassREAD函数
  • 实现白名单功能
  • 自动寻找bytes

v1.2

  • 实现audithook沙箱的绕过
  • 在没有长度限制的情况下,不使用局部长度最优的递归算法
  • 实现bypassENV函数,用于环境变量的读取

Contributing

提供Typhon无法解出的题目

我们将长期收集Typhon无法解出的题目。这对提升工具性能及其重要!如果你碰到无法一把梭的题目,请于本仓库打开issue,并写明题目来源(最好有对应的题解),我们会尽可能实现对该题目的自动求解。

作为回报,我们会在下一个release版本中囊括您的github ID。

Credits

Author & Maintainer

@ LamentXU (Weilin Du)

Contributors

感谢所有对此项目做过贡献的人:

Copyright

针对bash绕过的内置绕过器,感谢bashFuck项目的作者@ ProbiusOfficial,其License于此。

Copyright (c) 2024 ProbiusOfficial.

下游项目(若有)请务必涵盖此。

另:当前版本中尚未添加此功能。此copyright信息为预先保留。

Speical Thanks

@ 黄豆安全实验室给予我必须的鼓励
@ pyjailbreaker项目给予我启发

License

这个项目在Apache 2.0协议下发布。

Copyright (c) 2025 Weilin Du.

404星链计划

Typhon 现已加入 404星链计划

Star History Chart

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

typhonbreaker-1.0.13.5.tar.gz (3.9 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

typhonbreaker-1.0.13.5-py3-none-any.whl (3.9 MB view details)

Uploaded Python 3

File details

Details for the file typhonbreaker-1.0.13.5.tar.gz.

File metadata

  • Download URL: typhonbreaker-1.0.13.5.tar.gz
  • Upload date:
  • Size: 3.9 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.9.0

File hashes

Hashes for typhonbreaker-1.0.13.5.tar.gz
Algorithm Hash digest
SHA256 69332c8944affca81f41547dfc0dda26e6a0cb0f559675192f6fdca791b301a8
MD5 8f229c10a21967e5e6f7aeeb98e8d225
BLAKE2b-256 ea5d1a20b7afc09147f3ff5ec2ebde1e4109342cf8b23219f90eb83555a68742

See more details on using hashes here.

File details

Details for the file typhonbreaker-1.0.13.5-py3-none-any.whl.

File metadata

File hashes

Hashes for typhonbreaker-1.0.13.5-py3-none-any.whl
Algorithm Hash digest
SHA256 66699bd5d97d1db3b83a63afeb5e9555345b3ab5208b090c48d1c7e9c5e01786
MD5 ffec45f284a1991aa2c81b83682c7bac
BLAKE2b-256 fe22d9684dd22e2304765b98b25ea5da693cb44a6de5cbcb46d2fdab34adf318

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page