when HTTP_REQUEST { # Version 2.2 - 2021-12-13 19:00 Eastern # - Added PUT method payload check # Version 2.1 - 2021-12-13 17:00 Eastern # - Revision to header & body regexp for new evasions # - Made default URI regexp less aggressive to avoid false positives - same as header & body now # - Added while loop limit # Version 2.0 - 2021-12-11 23:40 Eastern # - Handling nested URI encoding # - Improved matching # Version 1.0 - 2021-12-11 06:10 Eastern # - Initial release # # Very aggressive regexp "\$\{.+" (remove quotes and replace regexps below "\$\{\s*(j|\$?\{.+?\})") # URI blocking # Be sure you're patched for CVE-2021-22991 or remove -normalized set tmpUri [HTTP::uri -normalized] set uri [URI::decode $tmpUri] set loopLimit 5 set loopCount 1 while { $uri ne $tmpUri } { if {$loopCount >= $loopLimit} { log local0. "log4j_rce_detection drop on URI loop limit: $loopCount $uri" drop event disable all return } else { set tmpUri $uri set uri [URI::decode $tmpUri] incr loopCount } }
if {[string tolower $uri] matches_regex {\$\{\s*(j|\$?\{.+?\})}} { log local0. "log4j_rce_detection drop on URI: $uri" drop event disable all return }
# Header blocking (sysin) set tmpReq [HTTP::request] set req [URI::decode $tmpReq] set loopLimit 5 set loopCount 1 while { $req ne $tmpReq } { if {$loopCount >= $loopLimit} { log local0. "log4j_rce_detection drop on header loop limit: $loopCount $req" drop event disable all return } else { set tmpReq $req set req [URI::decode $tmpReq] incr loopCount } }
if {[string tolower $req] matches_regex {\$\{\s*(j|\$?\{.+?\})}} { log local0. "log4j_rce_detection drop on header: $req" drop event disable all return }
# POST & PUT Payload blocking # NOTE: This only collects the first 1MB by default - edit 'collectSize' to change set collectSize 1048576 if {([HTTP::method] eq "POST") || ([HTTP::method] eq "PUT")} { # Trigger collection for up to 1MB of data (sysin) if {[HTTP::header "Content-Length"] ne "" && [HTTP::header "Content-Length"] <= $collectSize}{ set content_length [HTTP::header "Content-Length"] } else { set content_length $collectSize } # Check if $content_length is not set to 0 if { $content_length > 0} { HTTP::collect $content_length } } }
when HTTP_REQUEST_DATA { set tmpPayload [HTTP::payload] set payload [URI::decode $tmpPayload] set loopLimit 5 set loopCount 1 while { $payload ne $tmpPayload } { if {$loopCount >= $loopLimit} { log local0. "log4j_rce_detection drop on payload loop limit: $loopCount" drop event disable all return } else { set tmpPayload $payload set payload [URI::decode $tmpPayload] incr loopCount } }
if {[string tolower $payload] matches_regex {\$\{\s*(j|\$?\{.+?\})}} { log local0. "log4j_rce_detection drop on payload" drop event disable all } }