Goal Reached Thanks to every supporter — we hit 100%!

Goal: 1000 CNY · Raised: 1000 CNY

100.0%

CVE-2019-5096 PoC — Embedthis Software GoAhead 资源管理错误漏洞

Source
Associated Vulnerability
Title:Embedthis Software GoAhead 资源管理错误漏洞 (CVE-2019-5096)
Description:An exploitable code execution vulnerability exists in the processing of multi-part/form-data requests within the base GoAhead web server application in versions v5.0.1, v.4.1.1 and v3.6.5. A specially crafted HTTP request can lead to a use-after-free condition during the processing of this request that can be used to corrupt heap structures that could lead to full code execution. The request can be unauthenticated in the form of GET or POST requests, and does not require the requested resource to exist on the server.
Description
CVE-2019-5096(UAF in upload handler) exploit cause Denial of Service
Readme
## CVE-2019-5096 Use After Free Dos Exploit
	python TriggerDOS.py ip	

![TriggerDoubleFree](./assets/TriggerDoubleFree.png)

### 漏洞分析
[https://github.com/embedthis/goahead.git] GoAhead githublink  



#### git diff the patch  

![GitDiff](./assets/git_diff.png)



#### 关键代码分析 

在代码中定位到upload.c:370,可以看到在
```c
	wp->currentFile=0
```

前执行了  
```c
typedef struct WebsUpload {
    char    *filename;              /**< Local (temp) name of the file */
    char    *clientFilename;        /**< Client side name of the file */
    char    *contentType;           /**< Content type */
    ssize   size;                   /**< Uploaded file size */
} WebsUpload;
...

typedef struct Webs {
...
    WebsUpload      *currentFile;
...
}Webs;
...
processContentData(Webs *wp){
...
	file = wp->currentFile;
	...
	hashEnter(wp->files, wp->uploadVar, valueSymbol(file), 0);
	defineUploadVars(wp);
	wp->currentFile=0;
	...
}
```

其中hashEnter函数是往hash表里添加一个元素,这里造成了 wp-currentFile 的多次引用。  wp->files(hash table)里的WebsUpload结构将在 http 会话结束( Webs 生命周期结束)调用 termWebs 时 free 掉  

```c
static void termWebs(Webs *wp, int reuse)
{
...
#if ME_GOAHEAD_UPLOAD
    if (wp->files >= 0) {
        websFreeUpload(wp);//遍历hashtable 取出WebsUpload结构体free掉。
    }
#endif
}

```

接下来看另外一个free 的点:  
```c
...
processUploadHeader(Webs *wp, char *line)
{
	while (key && stok(key, ";\r\n", &nextPair)) {// 这是以 ; 为分割符解析 upload 头部
		...
		else if (scaselesscmp(key, "filename") == 0) {
		...
		freeUploadFile(wp->currentFile);
		file = wp->currentFile = walloc(sizeof(WebsUpload));
		...		
        }
	}
}
```

发现如果  upload 头部有 filename 字段则 free 掉 wp->currentFile, 接着 walloc 一个 WebsUpload 。  
由于 sizeof(WebsUpload) 落在 global_max_fast 大小以内,堆快将按照先进后出分配,则刚刚 free 的
堆快马上又被分配,并且在之后的 processContentData 函数时又会加入 hash 表。此时 hash 表内已有该 chunk两次引用,
termWebs 时发生 double free 并 abort 。  



#### 触发漏洞

一次请求添加两个 upload 头部:    
在 processContentData 函数之后再次进入 processUploadHeader 函数。即如下顺序调用:  

websProcessUploadData (循环) #上传状态机,每次循环确定一个状态 
	->initUpload()  
 	->processContentBoundary()  
	->processUploadHeader()  
	->processContentData()  
	->processContentBoundary()  
	->processUploadHeader()  
	->processContentData()  
	->return;  

#### 代码执行可能性

...
File Snapshot

[4.0K] /data/pocs/38852e906682bd68681c50fad879435731110268 ├── [4.0K] assets │   ├── [ 22K] git_diff.png │   └── [265K] TriggerDoubleFree.png ├── [2.6K] README.md └── [ 781] TriggerDOS.py 1 directory, 4 files
Shenlong Bot has cached this for you
Remarks
    1. It is advised to access via the original source first.
    2. Local POC snapshots are reserved for subscribers — if the original source is unavailable, the local mirror is part of the paid plan.
    3. Mirroring, verifying, and maintaining this POC archive takes ongoing effort, so local snapshots are a paid feature. Your subscription keeps the archive online — thank you for the support. View subscription plans →