前言
实际上goahead是个漏洞高发区,学习一下有很多好处
只搞到了D-Link DIR-823G v1.02 B03
没有搞到D-Link DIR-823G v1.02 B05的固件,不过大差不差
漏洞详情
固件解包
惯例binwalk
可以看到有个Squashfs文件系统,漏洞存在于web文件夹内:
开放服务情况
查看/etc/init.d/rcS
watchdog应该是一种进程的监控程序,启动1000秒
紧接着,启动了goahead,是一种嵌入式设备使用的web服务器
使用find等方法,找到squashfs-root/bin/下的goahead文件,这就是负责网络服务的文件,已经被编译为bin文件了
固件分析
main
首先看main部分
重点关注方法423F90,
(下次可以关注一下if 方法<0 则return -1 的方法,这其实一般是比较关键的部分)
sub_423F90
以上其实并不是很重要,仅仅是一些用户管理的操作,在没有用户的时候会添加一个账户密码为admin:1234的账户,可以看出这其实也是没有什么安全意识的做法
实际上,41BC40也是通往system函数的,后面可以看看,但存在漏洞的其实是:
这里有对不同的请求类别(Handler,cgi等)进行处理的函数
在此之前先了解一下goahead的开发文档https://www.embedthis.com/goahead/doc/users/routing.html
HNAP实际上是代表这个
实际上,跟类似的goahead项目是类似的,sub_40B1F4其实是websUrlHandlerDefine这个东西,
那么,可以参考一下websUrlHandlerDefine的源代码,看看是怎么对web的url的句柄进行define的
//暂且看前四个参数,就能明白了,第一个是urlPrefix,第二个是webDir,第三个是arg,第四个是一个int格式的handler指针,也就是指向某个执行的函数
int websUrlHandlerDefine(char_t *urlPrefix, char_t *webDir, int arg,
int (*handler)(webs_t wp, char_t *urlPrefix, char_t *webdir, int arg,
char_t *url, char_t *path, char_t *query), int flags)
{
websUrlHandlerType *sp;
int len;
a_assert(urlPrefix);
a_assert(handler);
/*
* Grow the URL handler array to create a new slot
*/
len = (websUrlHandlerMax + 1) * sizeof(websUrlHandlerType);
if ((websUrlHandler = brealloc(B_L, websUrlHandler, len)) == NULL) {
return -1;
}
sp = &websUrlHandler[websUrlHandlerMax++];
memset(sp, 0, sizeof(websUrlHandlerType));
sp->urlPrefix = bstrdup(B_L, urlPrefix);
sp->len = gstrlen(sp->urlPrefix);
if (webDir) {
sp->webDir = bstrdup(B_L, webDir);
} else {
sp->webDir = bstrdup(B_L, T(""));
}
sp->handler = handler;
sp->arg = arg;
sp->flags = flags;
/*
* Sort in decreasing URL length order observing the flags for first and last
*/
qsort(websUrlHandler, websUrlHandlerMax, sizeof(websUrlHandlerType),
websUrlHandlerSort);
return 0;
}
事实上,直接从IDA读sub_40B1F4源代码,我不是很能看懂,但这样对比着看,就明白了
OK!搞清楚以后,跟进sub_42383C
sub_42383C
这部分估计是作者自己实现的?
其实还是很好看懂的,首先是定义了一个包含header头的字符串,暂且称呼其为web_request
当然,这并么有什么问题
但是这里:
使用snprintf格式化字符串的%s,把a7赋值给 web_request的27位置 ,但是,这个赋值是没有任何过滤的
那么,如果使用单引号闭合,然后使用“把我们需要执行的东西括起来,就等于命令注入了,这就是这个漏洞的原理
rce复现
payload构造
对于echo ‘%s’ >/var/hnaplog
可以构造
command = “‘`echo 114514>/web_mtn/abc.txt`'”
但是
使用这个payload,以及burp进行手工的命令注入,并没有打通?
我是用attify3os来仿真的,然后再在仿真的机器上执行,结果试了很久,都没有能从网站访问到abc.txt
本来想从fofa里选一些来练手的,结果搜索不到。。。还是得想想这类资产怎么发现比较高效率
拓展
搜索了一下goahead造成的惨案,实在太多了