Apache HTTP Server mod_lua�?榛撼迩缏堵斫欧治觯–VE-2021-44790)
颁布功夫 2022-01-20缝隙概述
2021年12月20日,Apache 团队颁布了Apache HTTP Server 2.4.52版本,建复了Apache HTTP Server中的一个缓冲区溢露马脚(CVE-2021-44790),该缝隙存在于mod_lua解析器中,当服务器解析恶意要求时触发缓冲区溢出,可导致回绝服务或执行肆意代码。
影响领域
影响版本:Apache HTTP Server <= 2.4.51
有关介绍
Mod_lua�?�
Mod_lua�?槭茿pache上的一个扩大�?�,合用于2.3以上版本。该�?樵市硎褂胠ua剧本扩大服务器,还蕴含很多其他�?榭捎玫墓匙雍�。例如将要求 Map 到文件,天生动态响应,接见节造,身份验证和授权等。若是开启该�?�,可能会造成一些安全隐患。
在/etc/httpd/httpd.cnf配置文件中取缔下面这行注解,即可开启该�?榈闹澳�。

当收到.lua文件要求时,mod_lua�?榕灿胠ua-script的handle函数进行处置。下图为handle函数事俘。

apr内存池
为了削减系统内存分配的功夫,提高法式运行效能,Apache的开发者创建了一套基于池概想的内存治理规划。这套步骤移到apr中成为通用的内存治理规划,也就是apr内存池。
apr的内存池结构其实是一种树状的档次结构,parent指向当前内存池的父内存池,child指向当前内存池的子内存池,sibling则指向当前内存池的兄弟内存池。用户使用的内存空间,则是active治理的一个节点链表。用户要申请内存空间的时辰就会在active治理的内存节点中寻找。
结构体如下所示:

用户申请内存过程:
(1)首先取最靠近不幼于8字节倍数大幼的空间(8字节对齐),而后凭据申请大幼判断active节点可用空间是否足够。若内存足够,移动first_avail指针,返回其地址;若空间不及,则持续进行2之后的步骤。
(2)判断下一个内存节点的渣滓空间是否足够,若足够则使用之,并将之脱离当前链表;若不及,则通过度配子分配新的内存节点。
(3)将第2步中得到的节点插入active节点之前,并成为新的active节点。
(4)推算旧的active节点的渣滓空间大幼,并且与其链表后的所有节点的渣滓空间大幼比力,并插入链表中正确的地位。

补丁分析
该缝隙在Apache HTTP Server 2.4.52中进行了建复,在内存申请之前,增长了对长度的合法性校验。当end-crlf幼于蹬宗8,法式会直接退出,预防整数溢出。

缝隙分析
凭据缝隙布告,可知缝隙存在于mod_lua�?橹�,lua剧本挪用了r:parsebody()函数产生了缓冲区溢出。结合patch信息,直接定位到req_parsebody函数。
本文使用Apache HTTP Server 2.4.49版本进行分析,代码中红色方框标识出来的部门即缝隙代码地位,图片中对关键部门进行了相应的注解。

下面结合post数据包来分析法式处置逻辑。机关如下post数据包:

首先,start变量指向post数据包起头的地位,也就是对应上面第一个标识符--VILC2R2IHFHLZZ的地位,crlf指向两个空行(\r\n\r\n)起头的地位,end指向下一个标识符VILC2R2IHFHLZZ起头的地位,那么在crlf和end之间的数据就有下面这些内容,总长度为8(特殊字符长度)+len(数据参数长度)个字节。
‘\r\n\r\ntest\r\n--’
凭据上面参数内容,我们就能够理解下面这行代码的意思了。vlen蹬宗总长度减去有余的8个特殊字符,就能够推算出参数的长度。
vlen=end-crlf-8;
而后,法式挪用apr_pcalloc分配内存。
![]()
法式没有对vlen值的合法性进行查抄,若是上面参数中的特殊字符缺失,推算的vlen值就可能变为负数,造成整数溢出。当申请空间的时辰,会出现安全问题。
动态调试
凭据分歧畸形包的机关,思考以下两种情况,结合动态调试进行分析。
申请超大的空间
如果缺失'/r/n--'这4个特殊字符,且数据部门为2字节,vlen=(2+4-8)=-2。挪用apr_pcalloc(r->pool, vlen+1)申请内存时,vlen+1=0xffffffffffffffff。
使用gdb附加过程,进行动态调试。在缝隙函数处设置断点,而后发送特殊的post要求。

apr内存池无法提供这么大的内存,这时apr的分配子就会向系统申请内存空间,但是申请的巨大内存空间是系统无法提供的,所以系统会直接将过程kill掉(0x75是过程号),造成回绝服务。

溢出超长的字节
如果缺失'/r/n--'这4个特殊字符,且数据部门为3字节,vlen=(3+4-8)=-1,挪用apr_pcalloc(r->pool, vlen+1)申请内存时,长度vlen+1=0,凭据apr内存池内存分配机造,apr内存池会分配最幼的内存块8字节,最后使用函数memcpy的时辰:
memcpy(buffer, crlf + 4, vlen)
vlen又为FFFFFFFF.......(-1),就会产生缓冲区溢出。
动态调试时能够看到挪用apr_palloc时,长度参数是0,现实上会分配8字节的空间。


参考链接:
[1]https://mp.weixin.qq.com/s/XLzXHZYvpPIqNrDz3OHaMA
[2]https://nakedsecurity.sophos.com/2021/12/21/apaches-other-product-critical-bugs-in-httpd-web-server-patch-now/
[3]https://httpd.apache.org/security/vulnerabilities_24.html
[4]https://ubuntu.com/security/CVE-2021-44790
[5]https://github.com/apache/httpd/commit/07b9768cef6a224d256358c404c6ed5622d8acce


京公网安备11010802024551号