Smi1e@卫兵实验室
漏洞分析
Apache Httpd < 2.4.54
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协议端口。AJP协议中包含4种基本数据类型: Byte、Boolean、Integer、String
。
其中 Byte
和 Boolean
为1个字节,Integer
为两个字节,无符号整数,高位字节在前,String
类型为可变长字符串,最大长度为2的16次方。编码时首先将长度打包成两个字节,然后是字符串(包括终止符 ),长度不包括结尾的
。
从server发送到container的数据包以 0x1234
两字节魔术头开头,随后两字节代表数据包长度(不包括前4个字节)。
然后是数据部分,除了POST包发送的请求体外,其他包的数据部分的首字节为其消息类型(code)。这里只需要关注 Forward Request
和 Data
。
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_code
为 0x02
表示这是一个 Forward Request
类型的数据包。method
字段表示HTTP请求的方法类型。其余部分可以在文档中找到对应说明,这里不是重点。
Data
类型的数据包文档中没有特别的说明,只说了当 Content-Length
存在且不为0时,则 container
会认为请求有body,例如POST请求,并且立即从输入流中读取单独的数据包以获得该 body
。可以看到对于POST请求,AJP协议会发送两个数据包,一个是 Forward Request
一个是 DATA
。而DATA数据包的格式比较简单,依然是 0x1234
做为两个字节的魔术头,然后紧跟的是两个字节的数据包长度,第五位第六位为body数据的长度,最后跟着的是body。mod_proxy_ajp
模块 。在发送 DATA
类型的数据包时,会在前两位填充数据,分别是魔术头 0x1234
、数据包长度、body
长度。其中数据包长度为 body
长度加2字节,而 body
长度即是 Forward Request
数据包中 Content-Length
的长度。DATA
数据包和 Forward Request
数据包,可以发现由于发送的 DATA
数据包前面填充了六位,因此六位后的数据是我们完全可控的,而前六位中两者只有第五第六位是有差别的。在 Forward Request
数据包中分别对应 prefix_code
和 method
,在 DATA
数据包中对应的是body的长度,因此我们可以通过控制DATA
数据包中 body
的长度令其等于正常Forward Request
数据包的prefix_code
和 method
。Forward Request
数据包prefix_code
和 method
分别为 0x02 0x02
,0x0202=514
,即需要填充够514个长度的body。body的具体内容为正常的 Forward Request
数据包6位之后的数据即可。Forward Request
数据包内容一样,但是wireshark并没有识别出来,依然把他当成了 REQ:Body
。AjpProcessor
在接收到 Content-Length
大于0的请求头时,会调用 AjpProcessor.receive()
读取后续的body数据,我们的第二个请求包依然被当作了一个body而没有被当作一个新的 Forward Request
请求。因此我们需要让其获取到的 Content-Length
不大于0或者不发送这个请求头。Content-Length
外,还有一种指定HTTP消息实体采用何种编码形式的请求头 Transfer-Encoding
。Transfer-Encoding
的可选值如下:AjpProcessor
没有对 Transfer-Encoding
做特殊处理,我们可以不使用 Content-Length
而使用 Transfer-Encoding
进行分块传输,或者两者一起使用,Apache会忽略 Content-Length
。mod_proxy_ajp
模块中禁止 Transfer-Encoding
以 chunked
开头,但是 Transfer-Encoding
支持使用逗号分割多个值,可以在前面插任意字符,例如 a,chunked
等。当使用分块传输时,wireshark把第二个走私的body数据包解析成了GET方式的 Forward Request
数据包。不过在Apache httpd低版本,并不支持 Transfer-Encoding
使用逗号分割多个值,会直接返回501错误, Transfer-Encoding
只能是 chunked
。
POST Forward Request 数据包走私
header
和 body
两个数据包发送,而我们正常走私的请求只有一个header数据包,body数据会无法走私过去。不过前面提到了当 Content-Length
大于0时,会调用 AjpProcessor.receive()
读取后续的body数据。我们可以在走私的body数据包发过去之后立即发送一个带有POST参数的正常POST数据包,此时该正常数据包的 header
和 body
都会被当做我们走私的POST数据包的body部分。因此我们只需要让走私的POST数据包的Content-Length
小于等于正常数据包header
和 body
的总长度即可,此时可以将我们要发送的参数插在两个 &
之间用来分割前后的垃圾数据。为了提高成功率,可以在发送走私请求后,多线程发送多个包含POST参数的正常POST数据包。
修复建议
Transfer-Encoding
请求头关于我们
人才招聘
岗位职责:
- 负责研究Window内核相关漏洞利用技术;
- 负责分析Window内核漏洞的原理及缓解措施;
任职要求:
- 2年以上windows逆向工作经验。
- 熟悉windows底层架构、运行机制,熟悉汇编语言 C/C++语言,熟悉win32/64开发,并有相关开发经验;
- 熟悉windows驱动开发、熟悉windows平台内核架构;能熟练运用Windows平台下的软件调试方法。
- 熟练使用ida、windbg等调试软件工具调试分析漏洞。
- 有CVE编号、内核研究成果者优先;
- 具备良好的团队沟通、协作能力、良好的职业道德。
岗位职责:
- 负责研究Linux内核相关漏洞利用技术;
- 负责分析Linux内核漏洞的原理及缓解措施;
任职要求:
- 2年以上Linux逆向工作经验。
- 熟悉Linux底层架构、运行机制,熟悉汇编语言 C/C++语言,熟悉x86/64开发,并有相关开发经验;
- 熟悉Linux驱动开发、熟悉Linux平台内核架构;能熟练运用Linux平台下的软件调试方法。
- 熟练使用ida、gdb、lldb等调试软件工具调试分析漏洞。
- 有CVE编号、内核研究成果者优先;
- 具备良好的团队沟通、协作能力、良好的职业道德。
岗位职责:
- 负责安全技术研究,跟踪国内外最新的安全技术以及安全漏洞的追踪;
- 负责进行二进制漏洞挖掘,包括不限于浏览器、chakara引擎、js引擎、office、pdf等等各种二进制类应用;
任职要求:
- 能主动关注国内外最新安全攻防技术,并在自己擅长和兴趣的领域能够进行深入的学习、研究;
- 熟练掌握windbg、ida、gdb等调试工具;
- 熟悉各类二进制安全漏洞原理(堆溢出、栈溢出、整数溢出、类型混淆等等)以及各种利用技术;
- 能够无障碍阅读英文技术文档;
- 具备良好的团队沟通、协作能力、良好的职业道德。
岗位职责:
- 跟踪最新安全技术动态,对高危安全漏洞进行快速分析和响应;
- 负责安全产品的线下、线上功能及流程的验收测试,保证项目进度和品质;
- 从事影响比较大的国内外大型的cms、中间件、框架漏洞挖掘工作
任职要求:
- 深入了解漏洞原理,能够独立挖掘/分析包括但不限于PHP/JAVA/.NET/ASP等大中型应用漏洞,并编写exp;
- 具备优秀的JAVA开发能力,能熟练挖掘 JAVA WEB 方面的漏洞,深入了解tomcat,weblogic,jboss,resin等中间件内部构造;
- 熟练使用至少一门开发语言,如:PHP、python、java;
- 有比较强的开发能力,熟悉java web的常见漏洞原理,有能力挖掘和分析java web方面的漏洞;
- 有重大漏洞发掘或高质量的CVE、0day挖掘能力的优先考虑;
岗位职责:
- 安全攻防技术研究,最新web应用及中间件漏洞挖掘研究;
- 跟踪分析国内外的安全动态,对重大安全事件进行快速响应;
- 针对相关产品,进行全面详细的安全测试评估;
任职要求:
- 了解常见的网络协议(TCP/IP,HTTP,FTP等);
- 熟练使用Wireshark等抓包工具,熟悉正则表达式;
- 掌握常见漏洞原理,有一定的漏洞分析能力;
- 具备php、python、java或其他相关语言编码能力;
- 对常见waf绕过有一定的基础经验;
- 具备一定的文档编写能力,具备良好的团队共同能力;
- 对安全有浓厚的兴趣,工作细致耐心。
原文始发于微信公众号(网络安全研究宅基地):Apache Httpd AJP请求走私 CVE-2022-26377 漏洞分析
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论