GoAhead 是一个开源、简单、轻巧、功能强大、可以在多个平台运行的嵌入式Web Server。很多厂商的产品使用过GoAhead,比如IBM、HP、Oracle、波音、D-link。
GoAhead 版本 4.X 到 5.0存在一个内存信息泄漏漏洞。
wget https://github.com/embedthis/goahead/archive/v5.0.0.zip
unzip v5.0.0
cd goahead-5.0.0
#编译GoAhead
make
#运行GoAhead Web服务器
sudo ./build/linux-x64-default/bin/goahead -v ./ 0.0.0.0:8888
访问goahead服务器
漏洞发生在文件http.c的websRedirect函数,websRedirect顾名思义,处理跳转的请求。
在route.txt中配置一条可以跳转的路由,比如: 强制跳转到login.html页面
route uri=/ auth=form handler=continue redirect=401@/login.html
此时访问根目录,当http头host字段太长时,导致内存信息泄漏。
在websRedirect函数,会将http head中的host信息拷贝到hostbuf中,后期会拼接http字符串返回给用户,显示页面的跳转信息。
1625 PUBLIC void websRedirect(Webs *wp, cchar *uri)
1 {
2 .....
3 char hostbuf[ME_GOAHEAD_LIMIT_STRING];
.....
.....
13 if ((host = (wp->host ? wp->host : websHostUrl)) != 0) {
14 scopy(hostbuf, sizeof(hostbuf), host);
....
...
ME_GOAHEAD_LIMIT_STRING的值为256,当host长度大于256时。scopy为防止发生溢出,不进行复制,返回-1。
scopy函数
14151 PUBLIC ssize scopy(char *dest, ssize destMax, cchar *src)
1 {
2 ssize len;
3
4 assert(src);
5 assert(dest);
6 assert(0 < dest && destMax < MAXINT);
7
8 len = slen(src);
9 if (destMax <= len) {
10 return -1;
11 }
12 strcpy(dest, src);
13 return len;
14 }
scopy没有进行拷贝,hostbuf也没有初始化,此时hostbuf内存的信息为内存中的随机的信息,并且将这些信息返回给客户端,导致了内存信息泄漏。这就是为什么上面burp suite response会出现乱码的原因。
1625 PUBLIC void websRedirect(Webs *wp, cchar *uri)
1 {
.....
.....
.....
22 if (smatch(uri, "http://") || smatch(uri, "https://")) {
23 /* Protocol switch with existing Uri */
24 scheme = sncmp(uri, "https", 5) == 0 ? "https" : "http";
25 uri = location = makeUri(scheme, hostbuf, 0, wp->url);
26 }
27 secure = strstr(uri, "https://") != 0;
28 fullyQualified = strstr(uri, "http://") || strstr(uri, "https://");
29 if (!fullyQualified) {
30 port = originalPort;
31 if (wp->flags & WEBS_SECURE) {
32 secure = 1;
33 }
34 }
35 scheme = secure ? "https" : "http";
36 if (port <= 0) {
37 port = secure ? defaultSslPort : defaultHttpPort;
38 }
39 if (strstr(uri, "https:///")) {
40 /* Short-hand for redirect to https */
41 uri = location = makeUri(scheme, hostbuf, port, &uri[8]);
42
43 } else if (strstr(uri, "http:///")) {
44 uri = location = makeUri(scheme, hostbuf, port, &uri[7]);
45 } else if (!fullyQualified) {
46 uri = location = makeUri(scheme, hostbuf, port, uri);
47 }
48 message = sfmt("<html><head></head><body>\r\n\
49 This document has moved to a new <a href=\"%s\">location</a>.\r\n\
50 Please update your documents to reflect the new location.\r\n\
51 </body></html>\r\n", uri);
52 len = slen(message);
53 websSetStatus(wp, HTTP_CODE_MOVED_TEMPORARILY);
54 websWriteHeaders(wp, len + 2, uri);
55 websWriteEndHeaders(wp);
56 websWriteBlock(wp, message, len);
57 websWriteBlock(wp, "\r\n", 2);
58 websDone(wp);
59 wfree(message);
60 wfree(location);
61 }
漏洞产生的原因是因为没有初始化内存,可能我见识比较少,感觉这种漏洞比较不常见,挖到这个漏洞的Dbappsecurity老哥是代码审计到的?