当时做的时候完全不会,现在学了一点iot,又看了看其他师傅的wp,发现这个题其实很简单
题目分析

一上来首先是一个切换目录,由于我是本地环境,所以把这里patch掉,不然程序运行不起来
接着就是接受请求头,根据后面的代码分析可知格式为 GET /xxx HTTP/1.0

第二行要填Host: xxx.xxx.xxx.xxx

第三行填Content-Length: xxxxx(不超过5位)

这里要做一个目录穿越的检查,不能回退到上级目录,只能用绝对路径或者当期路径。不过这个也不担心,前面告诉你了是/home/ctf/html

接着这里执行了popen,而haystack经过调试发现就是get的请求头,因此这里有一个任意命令执行(不懂的话去查一下popen函数),然而ls,cat flag等命令在这里是不会显示的,原因有两个,在执行popen前程序把标准输出重定向到了/dev/null,所以不会有输出,第二个原因是仅仅fp=popen(“ls”,”r”)是不回会显的,要后面再次调用输出函数输出fp才行,所以一开始我patch掉了两个freopen,发现还是没有用,这就是因为后面压根没有输出stream的地方,所以在patch之前,输入ls>./1是没有反应的,因为stdout被关了,在patch之后,ls>./1就把输出输入到“1”这个文件里了

测试完毕后其实这个题就很简单了,远端环境我们patch不了,但还是可以执行任意命令,所以我们可以先把/flag复制到当前文件夹底下,然后再读出来

后面的程序中有一段是这样的,简单来说就是如果你的get后面跟的是一个正常的文件,那么最终就会把文件里的内容输出出来
解题方法
所以最终我们的输入应该是
第一次
GET /cp%20%/flag%20/home/ctf/html HTTP/1.0
Host: 192.168.0.1
Content-Length: 0
注意这里要用%20代替空格,因为在程序中


这个函数经过AI分析,就是把get后面跟的东西里面的%xx转化成ASCII码(%20就是空格),如果不这样的话在匹配字符串的时候会有问题
第二次
GET /flag HTTP/1.0
Host: 192.168.0.1
Content-Length: 0
这样的话最终就能出flag了