Bug #3475
closedSMB evasion against EICAR file detection
Description
Signature is
alert smb any any -> any any (msg:"EICAR file"; flow:established; file_data; content:"|58354f2150254041505b345c505a58353428505e2937434329377d2445494341522d5354414e444152442d414e544956495255532d544553542d46494c452124482b482a|"; sid:1; rev:1;)
Test pass with regular download : https://github.com/OISF/suricata-verify/pull/175
Signature is not triggered when overwriting file as in the attached pcap :
- a first dummy write of one byte at offset 0 is done
- the second full write of EICAR at offset 0 is then done and does not trigger detection
This issue seems generic for Rust parsers with files :
https://github.com/OISF/suricata/blob/master/rust/src/filetracker.rs#L147
I think that we should at least have one protocol event for this
Files
Updated by Philippe Antoine over 4 years ago
- Related to Task #3392: Tracking: protocol detection evasions added
Updated by Philippe Antoine over 4 years ago
Another evasion is to use dummy padding between SMB Parameter and SMB Data (and specify the right offset for data in the Parameter DataOffset field)
Simple patch could be
diff --git a/rust/src/smb/smb1_records.rs b/rust/src/smb/smb1_records.rs
index 35397e577..28e06dd7d 100644
--- a/rust/src/smb/smb1_records.rs
+++ b/rust/src/smb/smb1_records.rs
@@ -78,11 +78,12 @@ named!(pub parse_smb1_write_andx_request_record<Smb1WriteRequestRecord>,
>> _remaining: le_u16
>> data_len_high: le_u16
>> data_len_low: le_u16
- >> _data_offset: le_u16
+ >> data_offset: le_u16
>> high_offset: cond!(wct==14,le_u32)
>> bcc: le_u16
//>> padding: cond!(data_offset > 32, take!(data_offset - 32))
>> _padding: cond!(bcc > data_len_low, take!(bcc - data_len_low)) // TODO figure out how this works with data_len_high
+>> _padding_evasion: cond!(data_offset > 64, take!(data_offset - 64)) // TODO set an event
>> file_data: rest
>> (Smb1WriteRequestRecord {
offset: if high_offset != None { ((high_offset.unwrap() as u64) << 32)|(offset as u64) } else { 0 },
Updated by Philippe Antoine over 4 years ago
AndX is not parsed and subject to an evasion, cf attached pcap hiding the Write command
Updated by Philippe Antoine over 4 years ago
Sum up up so far :
Three different issues in Suricata code have been identified :
- writing file out of order
- Insertion of dummy padding against `parse_smb1_write_andx_request_record` (probably affects other commands such as Trans2)
- Use of AndX chains
How should we proceed for these ?
Here are my thoughts about the different possible
- writing file out of order :
This is a problem in other protocols (HTTP byte-range)
Should we set an event for this ?
- Insertion of dummy padding :
The fix is the one-liner mentioned above, so quite simple.
Should we set an event on detecting an evasion attempt ?
Should we fix the other commands using `data_offset` such as Trans2 ?
- Use of AndX chains :
This should be fixable, but will require some work
Should I ask the students to do this ?
There is also one issue for the signature writers
Cf https://doc.emergingthreats.net/bin/view/Main/2025719
This is subject to use of ascii (and not unicode)
If the rule is written with the specific smb keywords, there is no such evasion.
Should we do something about this ?
Updated by Philippe Antoine over 4 years ago
- Target version set to 5.0.3
- Affected Versions 5.0.2 added
- Label Needs backport to 4.1 added
Updated by Philippe Antoine over 4 years ago
- Status changed from New to In Review
Updated by Jeff Lucovsky over 4 years ago
- Copied to Bug #3670: SMB evasion against EICAR file detection added
Updated by Victor Julien over 4 years ago
- Target version changed from 5.0.3 to 5.0.4
Updated by Philippe Antoine over 4 years ago
- File myandx.pcapng myandx.pcapng added
Here is a new pcap with andx and padding combined
(anti padding does not work ie Windows does not accept the file)
Produced with :
client does
smbclient -p 4445 //192.168.1.12/catena/ -U" "%" " -m NT1
(yes with spaces in quotes)
Quick and dirty proxy is
import sys
import binascii
from threading import Thread
import time
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("192.168.1.12", 4445))
s.listen(1)
conn, addr = s.accept()
s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2.connect(("192.168.1.51", 445))
ok = True
while ok:
data = conn.recv(1024)
print("received", len(data))
if len(data) == 0:
break
data = bytearray(data)
changed = 0
if data[8] == 0x2f:
changed = 1
#update netbios size
data[3] = (data[3] + 19 + 9) % 256
#change opcode to locking
data[8] = 0x24
#change data offset to after locking andx and close
data[59] = (data[59] + 19 + 9) % 256
#get fid for locking
fid = "%02x%02x" % (data[41], data[42])
#offset for write andX after its data and locking
andxoff = "%02x" % (0x20 + 19)
locking = binascii.unhexlify("082f00"+andxoff+"00" + fid +"000000000000000000000000")
close = binascii.unhexlify("03"+fid+"ffffffff0000")
# close is next andx command
data[37] = 4
# offset for close
data[39] = (0x20 + 19)+len(data[36:-68])
data = data[:36] + locking +data[36:-68]+close+data[-68:]
print("modified", binascii.hexlify(data))
s2.send(data)
resp = s2.recv(1024)
print("response", len(resp))
resp = bytearray(resp)
#if changed == 1:
#resp[8] = 0x2f
#resp = resp[:36] + resp[43:]
conn.send(resp)
conn.close()
s.close()
And server is a Windows10 with public shared folder without password catena
Updated by Philippe Antoine about 4 years ago
- Label Needs backport to 5.0 added
Updated by Victor Julien about 4 years ago
- Status changed from In Review to Closed
Updated by Philippe Antoine about 4 years ago
There is still the AndX case to fix.
Do you want a separate ticket ?
Updated by Philippe Antoine almost 4 years ago
- Status changed from Closed to Assigned
- Assignee set to Philippe Antoine
- Target version changed from 5.0.4 to 7.0.0-beta1
- Affected Versions 6.0.0 added
- Affected Versions deleted (
5.0.2)
Still AndX to do
Updated by Philippe Antoine almost 4 years ago
- Target version changed from 7.0.0-beta1 to 6.0.1
Updated by Victor Julien almost 4 years ago
- Target version changed from 6.0.1 to 6.0.2
Updated by Philippe Antoine almost 4 years ago
Updated by Victor Julien over 3 years ago
- Target version changed from 6.0.2 to 7.0.0-beta1
Updated by Philippe Antoine over 3 years ago
- Label Needs backport to 6.0 added
- Label deleted (
Needs backport to 4.1)
Updated by Philippe Antoine over 3 years ago
- Status changed from In Review to Closed
Updated by Shivani Bhardwaj about 3 years ago
- Label deleted (
Needs backport to 5.0, Needs backport to 6.0)
Philippe:
I would lean toward the feature only for 7
AndX is not supported by every SMB command
Updated by Philippe Antoine about 3 years ago
I agree AndX support is more a feature added than a bug fix.