HNCTF_PyJail练习
通过HNCTF的题目学习PyJail
分析过程和wp主要参考:
https://zhuanlan.zhihu.com/p/578966149
calc_jail_beginner
下载附件
|
|
payload
|
|
calc_jail_beginner_level1
|
|
过滤了
|
|
payload1
|
|
payload2
从显示带有元组的子类入手
|
|
其中的b会被ban,使用getattr()函数
|
|
但其中的单引号会被ban,使用ascii2chr的拼接
|
|
得到
|
|
对__subclasses__
同样的方式绕过
|
|
倒数第四个子类<class 'os._wrap_close'>
,则payload
|
|
使用以上方法绕过,得到
|
|
calc_jail_beginner_level2
|
|
限制传入字符不大于13
参数逃逸
|
|
calc_jail_beginner_level2.5
|
|
payload
|
|
就会进到Pdb里面,随后pj直接一句话RCE
calc_jail_beginner_level3
|
|
限制传入字符不大于7
可以通过help
函数来进行RCE
开始输入help()
,进入到help界面,然后随便找个模块,例如os
输入,此时就会显示os
模块的帮助页面,输入!sh
就能进到shell里面去。
payload
|
|
python2 input
|
|
- 在python 2中,
input
函数从标准输入接收输入,并且自动eval
求值,返回求出来的值;- 在python 2中,
raw_input
函数从标准输入接收输入,返回输入字符串;- 在python 3中,
input
函数从标准输入接收输入,返回输入字符串;- 可以认为,python 2
input()
= python 2eval(raw_input())
= python 3eval(input())
如果碰到python 2中间用了input
函数,那么我们就可以直接一句话RCE:
|
|
lake lake lake
|
|
这个key变量是全局变量,可以用globals()
来泄露所有全局变量的值
|
|
|
|
l@ke l@ke l@ke
|
|
calc_jail_beginner_level3的方法不能完全生效
|
|
laKe laKe laKe
|
|
这道题涉及到对python random库中函数的分析
分析过程参考
|
|
payload
|
|
4 byte command
题目无附件,有回显
|
|
payload
|
|
另外,读取server.py发现
|
|
直接将输入的内容作为os.system()
参数
其他短字符串绕过姿势可以参考
https://xiaolong22333.top/archives/201/
lak3 lak3 lak3
|
|
tyPe Ch@nnEl
|
|
侧信道注入….没打通
calc_jail_beginner_level4
|
|
Show subclasses with tuple:
|
|
但’被ban了 **方法1:**利用bytes的ASCII list初始化方式
|
|
**方法2:**利用__doc__
魔术方法
可以从__doc__
里面去找,用索引的方式得到想要的字符,并拼接在一起,得到我们想要的字符串。
|
|
找到对应的偏移量
|
|
得到19,然后在payload里面直接使用().__doc__[19]
,就得到了字符's'
payload
|
|
**方法3:**直接读flag
|
|
calc_jail_beginner_level4.0.5
没有源码
|
|
calc_jail_beginner_level4的两种方法仍然可以用
calc_jail_beginner_level4.1
|
|
把bytes删掉了
Show subclasses with tuple:
|
|
发现byte类在索引6
|
|
#转换为
|
|
calc_jail_beginner_level4.2
|
|
Show subclasses with tuple:
索引byte的方法仍然可以用
|
|
题目将+
也ban了,__doc__
魔法函数的方法无法直接用
可以改变字符串的拼接方法
|
|
payload
|
|
calc_jail_beginner_level4.3
|
|
calc_jail_beginner_level4.2的payload仍然可以用
|
|
calc_jail_beginner_level5
没有附件,只有回显
|
|
按题目hint输入dir()
得到
|
|
随后尝试一句话RCE
|
|
calc_jail_beginner_level5.1
|
|
尝试dir()
,随后一句话RCE,发现__import__
可能被删了
|
|
尝试Show subclasses with tuple
|
|
calc_jail_beginner_level6
|
|
几乎把所有的hook给ban了
参考https://ctftime.org/writeup/31883
利用_posixsubprocess.fork_exec
来RCE
但如果我们直接import _posixsubprocess
,会触发audit hook:
|
|
可以通过如下方法绕过:
|
|
或者
|
|
因为是多次exec
,所以我们可以输入多行代码:
|
|
calc_jail_beginner_level6.1
|
|
使用海象运算符
|
|
但是起来shell会立刻断掉
|
|
手段也是越来越离谱
s@Fe safeeval
|
|
基于代码字节码的操作码来拦截
无法直接用__import__
。类似地,也没法用__builtins__
这些变量。
用lambda表达式包裹起一句话RCE:
|
|
顺便查看一波源代码
|
|
在github连接中,查看test_expr的定义
|
|
我们的payload被解析出来的操作码:
|
|
都在题目所给的Black List
里面
calc_jail_beginner_level7
|
|
根据python抽象语法树(AST)来拦截输入的
知识盲区了,目前只能照抄:
我们试着输入
1+1
:
1 2 3 4 5 6
E Pls input your code: (last line must contain only --HNCTF) 1+1 --HNCTF ERROR: Banned statement <ast.Expr object at 0x7f6c147ff6d0> Press any key to continue
发现的确ban了Expr,也就是展示的确实是Black List。
不能
import
,不能定义函数,也不能用lambda表达式,但是可以执行多行代码。这个时候,我想到了类的定义。经过一段时间的搜索,我找到了如下writeup:
1 2
https://gynvael.coldwind.pl/n/python_sandbox_escape # [organizers] Robin_Jadoul solution
(不得不说Robin真的太强了,organizers太强了,是我难以企及的偶像……)
1 2 3
@exec @input class X: pass
这份代码里面只有两个函数装饰器和一个类定义,应该不包含拦截的东西。果然,输入进去之后,程序得到了结果:
1 2 3 4 5 6 7 8
E Pls input your code: (last line must contain only --HNCTF) @exec @input class X: pass --HNCTF check is passed!now the result is: <class '__main__.X'>
此时再输入一句话RCE的payload:
1
__import__('os').system('sh')
就可以拿到shell。