Suricata之CVE-2024-21773 Tomcat请求走私检测


通常情况下,大多数漏洞利用suricata提供的content、pcre等关键字进行特征匹配即可完成告警。

但是CVE-2024-21773这个漏洞,唯一的特征就是content-length的值大于request_body的长度,此时再仅仅用content等关键字来完成特征匹配则会力不从心。

CVE-2024-21773的利用价值虽然不高,但是该漏洞规则的编写和优化过程记录下来,作为depth、bsize、byte_extract、byte_math、isdataat关键字的实际应用案例,还是很不错的。


初期 – 检测特定PoC

在初期,实现对网上主要流通的PoC的检测

POST / HTTP/1.1Host: hostnameSec-Ch-Ua: "Chromium";v="119", "Not?A_Brand";v="24"Sec-Ch-Ua-Mobile: ?0Sec-Ch-Ua-Platform: "Linux"Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.6045.159 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7Sec-Fetch-Site: noneSec-Fetch-Mode: navigateSec-Fetch-User: ?1Sec-Fetch-Dest: documentAccept-Encoding: gzip, deflate, brAccept-Language: en-US,en;q=0.9Priority: u=0, iConnection: keep-aliveContent-Length: 6Content-Type: application/x-www-form-urlencoded
X

可以提取出主要特征:content-length:6request_body:X,然后形成如下规则:

alert http any any -> any any (msg:"Tomcat CVE_2024_21773";flow:established,to_server;http.method;content:"POST";http.content_len;content:"6";fast_pattern;http.request_body;content:"X";)

虽然把content-length:6request_body:X作为固定特征,可以针对特定的PoC进行检测了。但是上面的这条规则还是太粗了,因为content是部分匹配的。也就是只要有流量的content-length的值中包含6,并且request_body中包含大写字母X,上面的规则同样会产生告警,极易产生误报。
那就需要借助其他关键字进一步来限制content的匹配范围了。
因为该PoC里的两个特征字符都只占用了1个字节的长度。这里可以采用bsize来限制sticky buffer缓冲区的大小,或采用depth来限制content匹配的深度。
alert http any any -> any any (msg:"Tomcat CVE_2024_21773 - bsize";flow:established,to_server;http.method;content:"POST";http.content_len;content:"6";bsize:1;http.request_body;content:"X";bsize:1;)
alert http any any -> any any (msg:"Tomcat CVE_2024_21773 - depth";flow:established,to_server;http.method;content:"POST";http.content_len;content:"6";depth:1;http.request_body;content:"X";depth:1;)

Suricata之CVE-2024-21773 Tomcat请求走私检测

中期 – 通用检测

isdataat
上面针对特定PoC的检测只是初期的一种应急措施,但是只要其中字符串特征稍有变动,就会导致漏报,因此需要编写更通用的检测规则。
通过isdataat关键字可以判断在特定位置是否存在数据,而在PoC中,只要request_body部分长度小于6个字节,都会触发漏洞,所以我们只需要判断第六个字节的位置不存在数据即可。这样即使request_body的数据是长度为1-5字节的任意内容,都不会产生漏报。
alert http any any -> any any (msg:"Tomcat CVE_2024_21773 - isdata :!6";flow:established,to_server;http.method;content:"POST";http.content_len;content:"6";bsize:1;http.request_body;isdataat:!6;)

Suricata之CVE-2024-21773 Tomcat请求走私检测

byte_extract
只检测content-length长度为6的特殊情况,还不够通用,下一步自然就会想到suricata是否支持将content-length的值提取出来,并作为isdataat的判断依据。
suricata通过byte_extract提供了数据提取,并存储到变量中的能力。通过byte_extract可以从指定的偏移开始提取指定字节数的数据进行存储,并且该数据可以按照指定的方式进行进制转换后再存储。
例如:http.content_len;byte_extract:1,0,clength,string,dec;,表示在http.content_len这个buffer中进行数据提取,从buffer中偏移0的位置开始提取1个字节的数据,转换为dec(十进制)后存储在名为clength的变量中。
遗憾的是suricata目前不具备提取完整buffer来进行进制转换和变量存储的能力,byte_extract必须指定需要提取的字节数,且长度不能够大于后续数据的长度,即如果是5个字节的buffer,从偏移1开始提取,最多只能让byte_extract提取4个字节,如果指定的长度大于4个字节,则规则不告警。
因此为了让byte_extract提取的数据准确,还需要使用bsize来判断content-length的长度,需要针对content-length长度不同的情况,编写多条规则。
content-length长度为1个字节:http.content_len;bsize:1;byte_extract:1,0,clength,string,dec;content-length长度为2个字节:http.content_len;bsize:2;byte_extract:2,0,clength,string,dec;

最后可以编写如下规则(仅考虑检测content-length长度为1个字节的情况):

alert http any any -> any any (msg:"Tomcat CVE_2024_21773 - byte_extract 1 byte to isdataat:!clength";flow:established,to_server;http.method;content:"POST";http.content_len;bsize:1;byte_extract:1,0,clength,string,dec;http.request_body;isdataat:!clength;)

Suricata之CVE-2024-21773 Tomcat请求走私检测

后期 – 通用检测优化

上面的规则实现了对所有content-length大于实际request_body的情况的检测。但是在规则的实际运营过程中,产生了误报。

POST / HTTP/1.1Host: hostnameSec-Ch-Ua: "Chromium";v="119", "Not?A_Brand";v="24"Sec-Ch-Ua-Mobile: ?0Sec-Ch-Ua-Platform: "Linux"Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.6045.159 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7Sec-Fetch-Site: noneSec-Fetch-Mode: navigateSec-Fetch-User: ?1Sec-Fetch-Dest: documentAccept-Encoding: gzip, deflate, brAccept-Language: en-US,en;q=0.9Priority: u=0, iConnection: keep-aliveContent-Length: 3Content-Type: application/x-www-form-urlencoded
abc
对于正常的请求,依然产生告警。这主要是因为suricata官方文档对于isdataat的说明不够清晰给规则编写人员带来了误解。
在官方文档中(https://docs.suricata.io/en/suricata-7.0.7/rules/payload-keywords.html#isdataat),重点对于使用isdataat:x, relative;进行的举例和说明。

Suricata之CVE-2024-21773 Tomcat请求走私检测

可以看出,文档的文字说明和图片示例都表明isdataat中的数字代表了位置,即1代表第一个字节,2代表第2个字节……512就代表第512个字节,位置从1开始算。
但是通过实际测试发现使用relative和不使用relative是两回事,如果使用relative,则数字如同官方文档所说代表位置,位置从1开始计算。
而如果不使用relative,则数字应代表偏移,偏移从0开始计算。
因此实际上我们之前编写的通用规则就会对所有的POST流量告警:content-length为3,request_body共3个字节,但是isdataat:!3;判断偏移3,即第4个字节不存在数据,该判断为真,产生误报。
因此通过byte_extract提取的content-length的值还应减去1,才是我们真正需要判断的偏移位。byte_math刚好就提供了提取数据并进行运算的能力。
http.content_len;bsize:1;byte_math:bytes 1,offset 0,oper -,rvalue 1,result off,string dec;

在http.content_len这个buffer中进行数据提取,从buffer中偏移0的位置开始提取1个字节的数据,执行减运算,减去数值1,转换为dec(十进制)后存储在名为off的变量中。

alert http any any -> any any (msg:"Tomcat CVE_2024_21773 - byte_math 1 byte ";flow:established,to_server;http.method;content:"POST";http.content_len;bsize:1;byte_math:bytes 1,offset 0,oper -,rvalue 1,result off,string dec;http.request_body;isdataat:!off;)

未来 – 新特性?

其实我们关于这个Tomcat请求走私的漏洞,主要思路还是在于检测request_body的长度,小于content-length的值。理论上来说使用byte_extract + bsize就可以实现。通过byte_extract将content-length的值提取到变量clength中,再通过http.request_body;bsize:<clength;进行判断。这样就不再需要麻烦byte_math和isdataat了。

alert http any any -> any any (msg:"Tomcat CVE_2024_21773 - bsize < byte_extract";flow:established,to_server;http.method;content:"POST";http.content_len;bsize:1;byte_extract:1,0,clength,string,dec;http.request_body;bsize:<clength;)
但可惜的是这么写,引擎会提示语法错误。
回到官方文档来看:https://docs.suricata.io/en/suricata-7.0.7/rules/payload-keywords.html#bsize

Suricata之CVE-2024-21773 Tomcat请求走私检测

目前bsize只支持与数值进行比较,还不支持于变量进行比较。
在今年3月份社区中已经有人提出了相同的需求,希望可以支持bsize与变量的比较。但目前还未对这个需求做出任何的响应。
https://redmine.openinfosecfoundation.org/issues/6853

Suricata之CVE-2024-21773 Tomcat请求走私检测

最后,之前的两篇文章,有大佬看了之后,反馈对规则方面挺感兴趣,并提议创建个群,方面后续交流互助。群已建,欢迎各位大佬加入指导。

Suricata之CVE-2024-21773 Tomcat请求走私检测


原文始发于微信公众号(菜鸡瞎扯):Suricata之CVE-2024-21773 Tomcat请求走私检测

版权声明:admin 发表于 2024年10月25日 下午7:24。
转载请注明:Suricata之CVE-2024-21773 Tomcat请求走私检测 | CTF导航

相关文章