Apache Httpd AJP请求走私 CVE-2022-26377 漏洞分析

渗透技巧 2年前 (2022) admin
1,872 0 0

Smi1e@卫兵实验室

漏洞分析

0x00 影响版本

Apache Httpd < 2.4.54

0x01 AJP协议介绍

Tomcat最主要的功能是提供Servlet/JSP容器,尽管它也可以作为独立的Java Web服务器,它在对静态资源(如HTML文件或图像文件)的处理速度,以及提供的Web服务器管理功能方面都不如其他专业的HTTP服务器,如IIS和Apache服务器。因此在实际应用中,常常把Tomcat与其他HTTP服务器集成。

AJP13 是一个二进制的TCP传输协议相比HTTP这种纯文本的协议来说,效率和性能更高,也做了很多优化。显然,浏览器并不能直接支持AJP13协议,只支持HTTP协议。所以实际情况是,通过Apache的 proxy_ajp 模块进行反向代理,暴露成 HTTP 协议给客户端访问。而Apache此时的作用就是将HTTP协议解析成AJP协议反代给Tomcat AJP协议端口。
Apache Httpd AJP请求走私 CVE-2022-26377 漏洞分析
(https://tomcat.apache.org/connectors-doc/ajp/ajpv13a.html 中介绍了AJP协议的格式。)
Apache Httpd AJP请求走私 CVE-2022-26377 漏洞分析

AJP协议中包含4种基本数据类型: Byte、Boolean、Integer、String

其中 ByteBoolean 为1个字节,Integer 为两个字节,无符号整数,高位字节在前,String 类型为可变长字符串,最大长度为2的16次方。编码时首先将长度打包成两个字节,然后是字符串(包括终止符 ),长度不包括结尾的

从server发送到container的数据包以 0x1234 两字节魔术头开头,随后两字节代表数据包长度(不包括前4个字节)。

然后是数据部分,除了POST包发送的请求体外,其他包的数据部分的首字节为其消息类型(code)。这里只需要关注 Forward RequestData

Apache Httpd AJP请求走私 CVE-2022-26377 漏洞分析

Forward Request 数据包消息格式如下:

AJP13_FORWARD_REQUEST :=    prefix_code      (byte) 0x02 = JK_AJP13_FORWARD_REQUEST    method           (byte)    protocol         (string)    req_uri          (string)    remote_addr      (string)    remote_host      (string)    server_name      (string)    server_port      (integer)    is_ssl           (boolean)    num_headers      (integer)    request_headers *(req_header_name req_header_value)    attributes      *(attribut_name attribute_value)    request_terminator (byte) OxFF

其中 prefix_code0x02 表示这是一个 Forward Request 类型的数据包。method 字段表示HTTP请求的方法类型。其余部分可以在文档中找到对应说明,这里不是重点。

Apache Httpd AJP请求走私 CVE-2022-26377 漏洞分析

Data  类型的数据包文档中没有特别的说明,只说了当 Content-Length 存在且不为0时,则 container 会认为请求有body,例如POST请求,并且立即从输入流中读取单独的数据包以获得该 body 。可以看到对于POST请求,AJP协议会发送两个数据包,一个是 Forward Request 一个是 DATA 。而DATA数据包的格式比较简单,依然是 0x1234 做为两个字节的魔术头,然后紧跟的是两个字节的数据包长度,第五位第六位为body数据的长度,最后跟着的是body。
Apache Httpd AJP请求走私 CVE-2022-26377 漏洞分析
0x02 Apache Httpd mod_proxy_ajp 请求走私
Apache 解析AJP协议的部分在 mod_proxy_ajp 模块 。在发送 DATA 类型的数据包时,会在前两位填充数据,分别是魔术头 0x1234 、数据包长度、body 长度。其中数据包长度为 body 长度加2字节,而 body 长度即是 Forward Request 数据包中 Content-Length 的长度。

Apache Httpd AJP请求走私 CVE-2022-26377 漏洞分析

通过对比 DATA 数据包和 Forward Request 数据包,可以发现由于发送的 DATA 数据包前面填充了六位,因此六位后的数据是我们完全可控的,而前六位中两者只有第五第六位是有差别的。在 Forward Request 数据包中分别对应 prefix_codemethod ,在 DATA 数据包中对应的是body的长度,因此我们可以通过控制DATA 数据包中 body 的长度令其等于正常Forward Request 数据包的prefix_codemethod
比如正常的GET Forward Request  数据包prefix_codemethod 分别为 0x02 0x020x0202=514,即需要填充够514个长度的body。body的具体内容为正常的 Forward Request 数据包6位之后的数据即可。
发送之后会发现数据包内容和正常的 Forward Request  数据包内容一样,但是wireshark并没有识别出来,依然把他当成了 REQ:Body
Apache Httpd AJP请求走私 CVE-2022-26377 漏洞分析
这是因为tomcat  AjpProcessor 在接收到 Content-Length 大于0的请求头时,会调用 AjpProcessor.receive() 读取后续的body数据,我们的第二个请求包依然被当作了一个body而没有被当作一个新的 Forward Request 请求。因此我们需要让其获取到的 Content-Length 不大于0或者不发送这个请求头。

Apache Httpd AJP请求走私 CVE-2022-26377 漏洞分析

Apache Httpd AJP请求走私 CVE-2022-26377 漏洞分析

除了 Content-Length 外,还有一种指定HTTP消息实体采用何种编码形式的请求头 Transfer-Encoding
Transfer-Encoding 的可选值如下:

Apache Httpd AJP请求走私 CVE-2022-26377 漏洞分析

由于tomcat AjpProcessor 没有对 Transfer-Encoding 做特殊处理,我们可以不使用 Content-Length 而使用 Transfer-Encoding 进行分块传输,或者两者一起使用,Apache会忽略 Content-Length
不过在 mod_proxy_ajp 模块中禁止 Transfer-Encodingchunked 开头,但是 Transfer-Encoding 支持使用逗号分割多个值,可以在前面插任意字符,例如 a,chunked 等。

Apache Httpd AJP请求走私 CVE-2022-26377 漏洞分析

当使用分块传输时,wireshark把第二个走私的body数据包解析成了GET方式的 Forward Request 数据包。不过在Apache httpd低版本,并不支持 Transfer-Encoding 使用逗号分割多个值,会直接返回501错误, Transfer-Encoding 只能是 chunked

Apache Httpd AJP请求走私 CVE-2022-26377 漏洞分析

POST  Forward Request 数据包走私

由于AJP协议对于POST类型的HTTP请求会分成 headerbody 两个数据包发送,而我们正常走私的请求只有一个header数据包,body数据会无法走私过去。

不过前面提到了当 Content-Length 大于0时,会调用 AjpProcessor.receive() 读取后续的body数据。我们可以在走私的body数据包发过去之后立即发送一个带有POST参数的正常POST数据包,此时该正常数据包的 headerbody 都会被当做我们走私的POST数据包的body部分。因此我们只需要让走私的POST数据包的Content-Length 小于等于正常数据包headerbody 的总长度即可,此时可以将我们要发送的参数插在两个 & 之间用来分割前后的垃圾数据。为了提高成功率,可以在发送走私请求后,多线程发送多个包含POST参数的正常POST数据包。

修复建议

不允许出现 Transfer-Encoding 请求头

Apache Httpd AJP请求走私 CVE-2022-26377 漏洞分析

详见下方链接:
https://github.com/apache/httpd/commit/156ddf6fb575a643007a335237899d9d738a7dc0#diff-f11bfc66b2dfc07a2f0a428b0ca9bd13fba8cec48e8404e5b570eb6c42eb2079R248

关于我们

Apache Httpd AJP请求走私 CVE-2022-26377 漏洞分析

人才招聘

二进制安全研究员

(Windows内核方向)

岗位职责:

– 负责研究Window内核相关漏洞利用技术;

– 负责分析Window内核漏洞的原理及缓解措施;


任职要求:

– 2年以上windows逆向工作经验。

– 熟悉windows底层架构、运行机制,熟悉汇编语言 C/C++语言,熟悉win32/64开发,并有相关开发经验;

– 熟悉windows驱动开发、熟悉windows平台内核架构;能熟练运用Windows平台下的软件调试方法。

– 熟练使用ida、windbg等调试软件工具调试分析漏洞。

– 有CVE编号、内核研究成果者优先;

– 具备良好的团队沟通、协作能力、良好的职业道德。

二进制安全研究员

(Linux内核方向)

岗位职责:

– 负责研究Linux内核相关漏洞利用技术;

– 负责分析Linux内核漏洞的原理及缓解措施;


任职要求:

– 2年以上Linux逆向工作经验。

– 熟悉Linux底层架构、运行机制,熟悉汇编语言 C/C++语言,熟悉x86/64开发,并有相关开发经验;

– 熟悉Linux驱动开发、熟悉Linux平台内核架构;能熟练运用Linux平台下的软件调试方法。

– 熟练使用ida、gdb、lldb等调试软件工具调试分析漏洞。

– 有CVE编号、内核研究成果者优先;

– 具备良好的团队沟通、协作能力、良好的职业道德。

二进制安全研究员

(系统应用方向)

岗位职责:

– 负责安全技术研究,跟踪国内外最新的安全技术以及安全漏洞的追踪;

– 负责进行二进制漏洞挖掘,包括不限于浏览器、chakara引擎、js引擎、office、pdf等等各种二进制类应用;


任职要求:

– 能主动关注国内外最新安全攻防技术,并在自己擅长和兴趣的领域能够进行深入的学习、研究;

– 熟练掌握windbg、ida、gdb等调试工具;

– 熟悉各类二进制安全漏洞原理(堆溢出、栈溢出、整数溢出、类型混淆等等)以及各种利用技术;

– 能够无障碍阅读英文技术文档;

– 具备良好的团队沟通、协作能力、良好的职业道德。

Web安全研究员

岗位职责:

– 跟踪最新安全技术动态,对高危安全漏洞进行快速分析和响应;

– 负责安全产品的线下、线上功能及流程的验收测试,保证项目进度和品质;

– 从事影响比较大的国内外大型的cms、中间件、框架漏洞挖掘工作


任职要求:

– 深入了解漏洞原理,能够独立挖掘/分析包括但不限于PHP/JAVA/.NET/ASP等大中型应用漏洞,并编写exp;

– 具备优秀的JAVA开发能力,能熟练挖掘 JAVA WEB 方面的漏洞,深入了解tomcat,weblogic,jboss,resin等中间件内部构造;

– 熟练使用至少一门开发语言,如:PHP、python、java;

– 有比较强的开发能力,熟悉java web的常见漏洞原理,有能力挖掘和分析java web方面的漏洞;

– 有重大漏洞发掘或高质量的CVE、0day挖掘能力的优先考虑;

Web安全研究员

(安全测试方向) 


岗位职责:

– 安全攻防技术研究,最新web应用及中间件漏洞挖掘研究;

– 跟踪分析国内外的安全动态,对重大安全事件进行快速响应;

– 针对相关产品,进行全面详细的安全测试评估;


任职要求:

– 了解常见的网络协议(TCP/IP,HTTP,FTP等);

– 熟练使用Wireshark等抓包工具,熟悉正则表达式;

– 掌握常见漏洞原理,有一定的漏洞分析能力;

– 具备php、python、java或其他相关语言编码能力;

– 对常见waf绕过有一定的基础经验;

– 具备一定的文档编写能力,具备良好的团队共同能力;

– 对安全有浓厚的兴趣,工作细致耐心。

原文始发于微信公众号(网络安全研究宅基地):Apache Httpd AJP请求走私 CVE-2022-26377 漏洞分析

版权声明:admin 发表于 2022年6月11日 上午8:01。
转载请注明:Apache Httpd AJP请求走私 CVE-2022-26377 漏洞分析 | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...