BUGTRAQ ID: 37454
CoreHTTP是一款小型的Web服务器。
CoreHTTP服务器的http.c文件没有正确的过滤用户输入便调用了popen(),这允许攻击者使用标准的Web浏览器执行任意命令:
/* escape the url for " and \ since we use it in popen */
for (i = 0; i < PATHSIZE; i++) {
if (url[i] == '\0') break;
else if (url[i] == '\\' || url[i] == '\"' || url[i] == '\'') {
find = url + i;
strcpy(temp, find);
*find = '\\';
*(find+1) = '\0';
strcat(url, temp);
i++;
}
}
上面的代码仅转义了“"”和“\”,用户可以指定“|”、“`”、“&”等特殊格式字符。之后URL拆分为了两部分:
- url
- args
这里有些限制:
if (c == 0) { /* TODO our dirlist perl script takes the path
of the dir as the arg. the way we do cgi
right now is scipt.pl?arg turns into
commandprompt> ./script.pl arg. obviously
when urlencode is implemented correctly this
must be changed. */
strcpy(args, url);
strcpy(url, DIRLIST);
break;
}
可见DIRLIST覆盖了url的值,url覆盖了args的值,因此简单的目录列表操作就会导致很难利用这个漏洞。
最终是对popen的调用:
} else if (cmd[0] != '\0') { /* if its dynamic content */
pipe(pipefd); /* make pipe then fork */
c = fork();
if (c > 0) { /* original, keep going */
close(pipefd[1]); /* no need to write */
sprocket->fd = pipefd[0];
SetNonBlock(sprocket->fd);
} else if (c == 0) { /* child, popen */
close(pipefd[0]); /* no need to read */
pipetoprog = popen(cmd, "r");
/* fread should be non-blocking for this to exit fast
when parent proc closes pipe */
while ((i = fread(temp, 1, BUFSIZE, pipetoprog)) != 0
&& write(pipefd[1], temp, i) > 0);
pclose(pipetoprog);
close(pipefd[1]);
exit(EXIT_SUCCESS); /* exit after done */
} else { /* failed */
RemoveSprock(sprocket, &FIRSTSPROCK);
return NULL;
}
对于启用了CGI的coreHTTP服务器,请求/foo.pl%60command%26%60就会将url设置为/foo.pl,将args设置为command&然后调用popen。
CoreHTTP 0.5.3.1
厂商补丁:
CoreHTTP
--------
目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:
http://corehttp.sourceforge.net/
暂无评论