Feature #783
openLuaJIT be able to return various messages for a single script.
Description
Using the following example script we do the following detections and more inside of JAR files
https://github.com/EmergingThreats/et-luajit-scripts/blob/master/suri-suspicious-jar2.lua
Which we call using the following rules
alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"ET LUAJIT CURRENT_EVENTS Suspicious Jar"; flowbits:isset,ET.http.javaclient; file_data; content:"PK"; depth:2; luajit:suri-suspicious-jar2.lua; filestore:response; classtype:trojan-activity; sid:379000002; rev:2;) alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"ET LUAJIT CURRENT_EVENTS Suspicious Jar via vulnerable client"; flowbits:isset,ET.http.javaclient.vulnerable; file_data; content:"PK"; depth:2; luajit:suri-suspicious-jar2.lua; filestore:response; classtype:trojan-activity; sid:379000003; rev:2;)
From a performance perspective it doesn't make sense to decompress the jar multiple times to perform an inspection for specific string. It would make more sense if we could return an optional rule message to use instead and attempt to perform multiple matches with a single call to the script. So perhaps 1 and 0 are match and no match and any other number is a sid. Perhaps we could have special rules whose only purpose it is, is to hold a rule msg and are not otherwise inspected via some special keyword i.e....
alert ip any any -> any any (msg:"Blackhole Zelix obfuscator string inside of JAR"; luajitmsg; sid:555555;)
Then if we match this string in the Jar we can return 555555.
-- {strings to match, number of matching strings needed, simple strings, description} susp_class = { {"EpgKF3twh",1,true,"Blackhole URL obfuscation string",0}, {"ZKM5.4.3",1,true,"Blackhole Zelix obfuscator string",0}, {"/.:_-?&=%#;",1,true,"g01pack obfuscation string",0}, {"%zI.........................................................................\1%zI.........................................................................\12",1,false,"possible g01pack obfuscation strings",0}, {"DEvuYp",1,true,"Nuclear obfuscation string",0}, {"ic?e3s",1,true,"RedKit obfuscation string",0}, {"yv66v",1,true,"Base-64-encoded class file",0}, {"/upload/install_flash_player.",1,true,"Unknown EK Payload Download",0}, {"glassfish/gmbal",1,true,"glassfish/gmbal CVE-2012-5076 exploit class file",0}, {"jmx/mbeanserver",1,true,"jmx/mbeanserver Java 7u9 exploit class file",0}, {"mbeanserver/Introspector",1,true,"mbeanserver/Introspector Java 7u11 exploit class file",0}, {'glassfish/external/statistics/impl',1,true,"CVE-2012-5076 2 exploit class file",0}, {"management/MBeanServer",1,true,"management/MBeanServer Java 7 exploit class file",0}, {'sun.org.mozilla.javascript.internal.Context','sun.org.mozilla.javascript.internal.GeneratedClassLoader',2,true,"Mozilla JS Class Creation Used in Various Exploits",0}, {"SunToolkit", "getField","forName","setSecurityManager","execute",5,true,"CVE-2012-4681 Metasploit and others",0}, {"AtomicReferenceArray","ProtectionDomain","AllPermission","defineClass","newInstance",5,true,"BH CVE-2012-0507 Metasploit and Others",0}, {'java/awt/color/ColorSpace','BufferedImage','StackTrace',3,true,"CVE-2013-1493 exploit",0}, {"f428e4e8",1,true,"Blackhole obfuscated class file",0}, {"CAFEBABE",1,true,"Hex-encoded class file",0}, {"[Cc].?.?.?[Aa].?.?.?[Ff].?.?.?[Ee].?.?.?[Bb].?.?.?[Aa].?.?.?[Bb].?.?.?[Ee]",1,false,"Hex-encoded class file (possibly obfuscated)",0}, {"F-Abr-rb",1,true,"Cool EK/SofosFO encoded class file",0}, {'fuck','Payload','java.security.AllPermission','AtomicReferenceArray',4,true,"Blackhole Atomic Reference Array exploit",0}, {'invokeWithArguments','invoke/MethodHandle','invoke/MethodType','forName',4,true,"CVE-2012-5088 exploit class file",0}, {'wnin.frphevgl',1,true,"rot13-encoded class name",0} }
Updated by Victor Julien over 11 years ago
It sounds like that what you'd really want is a way to create a buffer that can then be inspected by normal rules. In this case the luajit script wouldn't be a detection plugin, but more a data normalizer, creating a normalized buffer. I think such a model could be very interesting, but extremely non-trivial. So something like you suggest could work, although I'm not yet convinced we have a sane rule integration proposal.
The main idea is to run the script once, store the output somehow and then evaluate this output from different rules. The easiest way would probably be a numeric return by the script. That leaves storage in the engine simple and low. It would put a burden on the script writer to keep track of unique return codes though.
What about something like:
luajit:<script>[,<retval>];
Where the retval part is optional, so maintain backwards compatibility.
So:
alert http any any -> any any (msg:"JAR condition 1"; luajit:jar.lua,1; sid:1;) alert http any any -> any any (msg:"JAR condition 2"; luajit:jar.lua,2; sid:2;) alert http any any -> any any (msg:"JAR condition N"; luajit:jar.lua,N; sid:N;) alert http any any -> any any (msg:"Independent script"; luajit:somescript.lua; sid:X;)
This would make things quite simple on the engine side I think.
Updated by Victor Julien over 11 years ago
- Status changed from New to Assigned
- Target version set to TBD
Updated by Victor Julien over 7 years ago
- Status changed from Assigned to New
- Assignee changed from Victor Julien to OISF Dev