Project

General

Profile

Actions

Bug #3475

closed

SMB evasion against EICAR file detection

Added by Philippe Antoine over 1 year ago. Updated 7 months ago.

Status:
Closed
Priority:
Normal
Target version:
Affected Versions:
Effort:
Difficulty:
Label:
Needs backport to 5.0, Needs backport to 6.0

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

input.pcap (4.14 KB) input.pcap Philippe Antoine, 02/12/2020 03:01 PM
smb1_eicar_andx_write_padding.pcap (7.69 KB) smb1_eicar_andx_write_padding.pcap Philippe Antoine, 02/26/2020 01:35 PM
smb1_eicar_andx_locking_write.pcap (3.28 KB) smb1_eicar_andx_locking_write.pcap Philippe Antoine, 04/01/2020 11:54 AM
myandx.pcapng (5.73 KB) myandx.pcapng Philippe Antoine, 05/29/2020 01:57 PM

Related issues

Related to Task #3392: Tracking: protocol detection evasionsNewActions
Copied to Bug #3670: SMB evasion against EICAR file detectionClosedShivani BhardwajActions
Actions #1

Updated by Philippe Antoine over 1 year ago

  • Related to Task #3392: Tracking: protocol detection evasions added
Actions #2

Updated by Philippe Antoine over 1 year 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 },

Actions #3

Updated by Philippe Antoine over 1 year ago

AndX is not parsed and subject to an evasion, cf attached pcap hiding the Write command

Actions #4

Updated by Philippe Antoine over 1 year 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 ?

Actions #5

Updated by Philippe Antoine over 1 year ago

  • Target version set to 5.0.3
  • Affected Versions 5.0.2 added
  • Label Needs backport to 4.1 added
Actions #6

Updated by Philippe Antoine over 1 year ago

  • Status changed from New to In Review
Actions #7

Updated by Jeff Lucovsky over 1 year ago

  • Copied to Bug #3670: SMB evasion against EICAR file detection added
Actions #8

Updated by Victor Julien over 1 year ago

  • Target version changed from 5.0.3 to 5.0.4
Actions #9

Updated by Philippe Antoine over 1 year ago

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

Actions #10

Updated by Philippe Antoine 12 months ago

  • Label Needs backport to 5.0 added
Actions #11

Updated by Victor Julien 12 months ago

  • Status changed from In Review to Closed
Actions #12

Updated by Philippe Antoine 12 months ago

There is still the AndX case to fix.
Do you want a separate ticket ?

Actions #13

Updated by Philippe Antoine 11 months ago

  • Status changed from Closed to Assigned
  • Assignee set to Philippe Antoine
  • Target version changed from 5.0.4 to 7.0rc1
  • Affected Versions 6.0.0 added
  • Affected Versions deleted (5.0.2)

Still AndX to do

Actions #14

Updated by Philippe Antoine 10 months ago

  • Target version changed from 7.0rc1 to 6.0.1
Actions #15

Updated by Victor Julien 10 months ago

  • Target version changed from 6.0.1 to 6.0.2
Actions #16

Updated by Philippe Antoine 10 months ago

  • Status changed from Assigned to In Review

Gitlab MR

Actions #17

Updated by Philippe Antoine 8 months ago

  • Private changed from Yes to No
Actions #19

Updated by Victor Julien 7 months ago

  • Target version changed from 6.0.2 to 7.0rc1
Actions #20

Updated by Philippe Antoine 7 months ago

  • Label Needs backport to 6.0 added
  • Label deleted (Needs backport to 4.1)
Actions #21

Updated by Philippe Antoine 7 months ago

  • Status changed from In Review to Closed
Actions

Also available in: Atom PDF