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号