 Hi, I'm Ben Feinstein. I'm with the SecureWorks Counter Threat Unit. I'm going to be giving you a talk today about snort plug-in development. And just to start off a little basics. So what am I going to talk about today? I'm going to go over the V2 snort architecture at a higher level and cover some of the internals. And I'm going to go over the process of snort plug-in development and cover two areas of that. One area is dynamic rules. The other area is dynamic preprocessors. I'm going to go over some of the relevant snort APIs, give you some code examples, point out a few areas that can be confusing and that can hold you up in development, give you a few tips on how to succeed. And I'm also going to be discussing two new plug-ins or two new dynamic preprocessors that are GPL-ed. They're available on the SecureWorks website. There'll be a URL later in the presentation. The first preprocessor deals with ActiveX controls, essentially a virtual kill bit. And the other preprocessor deals with SSH, Diffie-Hellman key exchange that is affected by the Debian OpenSSL random number generator bug. So some basics. I don't need a review for some of the guys in the front row here from Sourcefire, but snort is the... Snort's an open source IDS and IPS that was originally created by Marty Rosh. And he released it back in... He released it back in 1998. And it was commercialized later by Sourcefire Inc. There's an inline mode that's available. The inline mode is essentially IPS. Typically it's going to use a Linux bridge plus a net filter. And you have IPQ and NFQ interfaces to queue the packets in and out of kernel space and user space through snort and let snort make verdicts on how to take action on those packets and streams. Some of you that follow snort are aware that v3 is now making its way through beta. This is a long time in coming and we're real excited to see that co-base getting released. I'm not going to be discussing v3 today. I'm not going to be talking about the v3 architecture. Marty will do much more justice to that and you can catch a talk from Marty at some other conferences and he will talk all about the v3 architecture. It's some really cool stuff they've done there. So the v2 architecture here. It's quite modularized. It's built to be extended. You have the snort rules and the rules matching engine. So the SF engine is a dynamic plugin. So actually the core rule matching engine is pluggable. You also have dynamic detection plugins that can implement or extend the rules language. So you can add new keywords and new constructs to the syntax of the rules language by building shared objects and dynamic plugins that will add to the detection capabilities of snort. They also have output plugins. So output plugin example is the unified or the unified two outputs. That's a highly efficient binary alert and log stream. You have your classic syslog output and there's some other output plugins as well that are less commonly used. You've got your classic two types of preprocessors here. You've got detection preprocessors. What those essentially do is they look at traffic and they will generate alerts. And in an inline scenario, they will drop traffic or send resets. Then you have normalization preprocessors. What these are there for is to decode and normalize traffic before it's presented to other plugins and to other end of the snort rules matching language or engine rather. So for instance, HTTP inspect is a preprocessor that does some normalization of HTTP requests and then other rules and preprocessors can then inspect the decoded traffic there. So continue on talking about the architecture. A dynamic preprocessor is basically a shared object. You can define a packet processing callback, a C function that snort is going to send packets through. You have the ability to do preprocessor local storage and you also have the ability using the stream API to do stream local storage. You define callbacks to deallocate your stream local storage when snort decides to free that session object. It'll call your cleanup method and you can gracefully free your memory that you've allocated. Now dynamic rules are relatively new in the snort code base. You could think of a dynamic rule as essentially writing a snort rule in C. I may be wrong, but I think around 2.8.01 there was an ability to register a C callback added to the dynamic rules in CIs. So before that C callback was defined, it seemed to me like the only reason to do dynamic rules was to obfuscate what your rule's doing. To kind of hide maybe the exploit or the vulnerability that could be determined from the rule. 2.6.1.5 was the version. I'm hearing from SourceFire. So basically some commercial snort rule sets out there use these dynamic rules for some of their rules. However, it's relatively straightforward to reverse engineer these files in something like Ida Pro. So it does raise the bar in terms of obfuscating the content of your rules but it's not going to prevent a more skilled adversary from figuring out what's in there. So a few other internals to cover is the alerting versus logging. It's pretty simple. Logs are going to contain the packet capture data in addition to the alert summary. Alerts are just simply the summaries. And Unified 2 is an interesting addition in that it's an extensible output format or it's designed to be extensible. My understanding of it is that you can encode additional data for instance from your preprocessor using link value encodings into that Unified 2 stream. And so it's great if your preprocessor wants to log some additional data. You ought to use Unified 2. And so examples I believe the sourcefire code base is moving to try to use this Unified 2 to gather the preprocessor statistics and performance statistics and also things like port scan alerts. So what do you need to get started developing Snort plugins? Or to step back a moment why do you want to develop Snort plugins? Well Snort is quite mature. It's a common part of IT security environments all over the world. So instead of chasing around the new hotness of the day, the new security technology, sometimes it makes sense to extend the capabilities of your existing controls that you've already got widely deployed. So Snort is going to give you some great features. It's going to reassemble the streams for you. It's going to put stuff back in order. It gives you a nice mature alerting and logging framework. So it's really a nice environment to start developing this kind of technology instead of just creating a whole new separate program or module to do all these things. So one great resource is the Snort developers mailing list. The source file developers are great. They're on there all the time. They're typically very responsive. And just my advice would be do your homework before you mail the list. You're going to get a much better experience and you're going to save everybody time and aggravation. So there is some issues with documentation around building dynamic preprocessors. There's some example code in the Snort code base. There's a few older materials online from around the 2.6 time frame. But the APIs have changed some. Some things have changed. So the documentation is a little bit out of date. And I'm hoping that from this talk and from the source code that we're publishing other plugin developers can kind of get a better sense of how to build these things. So like I said there's some basic examples in there in Snort code base of the dynamic rules and the dynamic preprocessors. So how are you going to get started developing? Use the source. It's there. Start looking at existing plugins. How do they work? How do they do what they do? The DNS plugin is a good start. It's relatively small. The HTTP inspect plugin is much more full featured. There's a lot more code in it. And there's some other interesting plugins that you can look at how they're doing things and kind of figure out how you should use the APIs. I personally approach development by writing small blocks of code and unit testing them and doing incremental development like that. So I think that's a great way to approach it. And also when you get stuck, if you're really stuck and you can't get past it, go to the Snort developers list, you know, post the problem you're having. And typically someone out there will have encountered this problem and have an answer for you. So my Snort development environment basically is the Snort 2.8.x source tar ball, whatever the latest stable release is, running CentOS 5 box with GCC4.1 and G-Lib C25. Now, CentOS or Red Hat Enterprise 5 packages slightly older versions of AutoConf and Automate. So to get your environment working in sync with the source development environment, you're going to have to build AutoConf 261 and Automate 1.10 from scratch. Put that in your path and use those tools unless you want to screw around with AutoMake and AutoConf yourself and deal with that mess. So to jump into the dynamic rules, these are probably the simplest ways you can extend Snort using the C language. There's one key header file that you ought to look at. It's the SF Snort plugin API header. And what it does is it defines C structure equivalents to all the rule syntax structures. We're talking flow, content, PCRE, those kind of structures. So basically in C code I can create a struct that defines the same properties as I would in the rules language. Inside your dynamic rule file, or a C file that contains multiple rules, you have this array of pointers to rules called rules. And the framework pretty much handles the rest. You point Snort to the dynamic rule shared object you've built and you have dummy rules that have to be present, it will load them into the engine. The Snort make file pretty much takes care of most of it for you. It creates the shared objects using libto and they'll be dynamically loaded at Snort in runtime. So how do you get Snort to load your shared objects? Well, there's a few command line and configuration options you should be aware of. In the Snort config command line you've got dynamic detection live and dynamic detection live dir. The first one of these is you just point it to your shared object file, it's going to load it up. The second, you're going to give it a directory to any number of shared objects that are dynamic rules and it will load those up. Snort has this new command line option called dump dynamic rules. All these dynamic rules require stubbed or dummy rules to be in the rules files, meta rules. So this will actually dump all that information out for you in a nice format. You can throw it into a rules file. So below I've got an example of just real basic hello world rule. It's using this new keyword called metadata, colon, engine shared. You link it up with your SID, which in this case is 2 million one, and you've got a generator ID of three. Three is the generator ID that's assigned to dynamic rules. So that's just a very basic stubbed out meta rule that's actually spit out by Snort. As I said, you've got different C-structs for all the rule options. So a rule option is simply a union of all the different types of structures there. And a rule structure itself is simply a null terminated array of rule options. You also have a pointer to a rule header struct and you have some rule references which would be pointers to a CVE, pointers to some web reference, for instance. The API also exposes functions to match on these different rule constructs for content, flow, flow bits and such. So you can actually create a rule option for a content match, call the content match function in the API and get back rule match or rule no match. It also offers some basic functions to register and to dump the dummy rules out. So what I got up here is just a very simple content info structure. This comes from the example dynamic rules that's in Snort source tar ball. All this is is looking for the content of net bus. You tell it what buffers to look in. Typically you're going to use the normalized buffers but you could use raw buffers. And these two null objects and the zero counters down there. When you register the rule with Snort it goes and creates the Boyer-Mor structures, sets those pointers. Aircorsic fast pattern matcher. Basically it will initialize that structure for you. You need to do that before you can call the content match with this structure. And then here you just wrap that. If you want to create a rule option you simply wrap the content info in this option type content macro. And there you go. You can pass that rule option in and do that null terminated array of rule options in your rule structure. And then below is just the API call you're going to make to attempt a content match using a pointer to your content structure. That void pointer that's just a casted to void star. It's a SF Snort packet which is the standard structure that you're going to get passed in your callback function. PCRE matching same thing here. You give it some PCRE flags. You know what buffers you want to match against. And then you wrap it in a pound to find option type PCRE object. And there's your PCRE match function. You initialize your PCRE structure. You have a packet pointer. You can go call that. It's going to return rule match or rule no match. And you would know whether your PCRE is matching in that content or not. Same thing with flow. Establish to client to server. Wrap it in an object. You've got a function call to check if the flow is matched. So here's like how you create this rule structure for a dynamic rule file. You have two other C files that are going to find this rule struct. You have a null terminated array of pointers to rules. And then basically the engine itself is going to call register rules on that array. Which will then internally fix up the a horocorsic, the pointers, all that stuff and add it to the engine. So onto the C processing callback that we mentioned. This is really the most powerful part of dynamic rules. You're going to be able to just define a C function and say to the engine that when you've matched all these elements of my rule, also I want you to call this C function, pass the packet to it and the C function will return a rule match or a rule no match. So you can do this to create much more sophisticated matching algorithms than you could ever do in a rule. This is just a very simple MyDynamicRule.C. Include a couple header files define my callback function in my rule structure I have a pointer to it and the stored engine is going to take care of the rest. Here's a little code snippet from an example rule detection function. Now I failed to say at the beginning of this talk I've got two of these lovely DC404 t-shirts available here. I'm going to give one of these t-shirts to whoever can answer this question on here and one of the t-shirts to the best question at the end of the presentation. So what is this little I don't know if I'll let the sourcefire guys answer this question but what does this little C snippet do, this callback you get a packet structure I cast it to an SF sort packet and I have this if statement and I'm going to match on the if. So who out there for a lovely DC404 t-shirt can tell me what this does? This is going to match if the IPID is odd. I'm simply taking it at mod 2. Very simple stuff. But this is an example of something you couldn't do in the snort rules language. There's no operator to say take IPID and take it modular something and compare it. But you can define a four or five line C function that will do the exact same thing. So maybe the two best questions will get t-shirts. Another key header file dynamicpreprocessor.h The key structure to be aware of is this dynamic preprocessor data. Almost everything you're doing with the APIs is going to be off of pointers to this DPD object. It's typically named underscore DPD. You got a callback for initialization, exit, restart of your preprocessor. You got callbacks to or you got function pointers to internal logging functions. You've got ability to interact with the stream APIs, the search APIs. You have alerting functions, and also you have the ability to do snort inline functions like packet drop. All this is available through that dynamic preprocessor data structure that is available to your preprocessor. Right here, here's a little code snippet from my ActiveX preprocessor. All you do is you define the setup function and I'm registering a preprocessor called ActiveX. I'm pointing it to my initialization function. Initialization function takes the command line of the preprocessor named ActiveX. It's going to call the addPreproc function on the dynamic preprocessor data structure and it's going to basically say what priority do I want? You have a transport application and a few others. And also, pp ActiveX is going to be a unique number that I've defined in another header file that uniquely identifies the ID of that preprocessor. And then you've got process ActiveX which is where the real work of the module is. You get a context pointer to SF Snort packet, you get a context pointer and then after you've done all your work you see that alert add call. That's basically calling the Snort alert mechanism to say hey my preprocessor wants a generator alert in another header file I've defined a signature ID and a string that goes along with that signature ActiveX event, Kilbit's STR and I basically call that alert add and it shoves that out. So when you're in a preprocessor you can also use some of the dynamic rules functionality. And using the rule match function register one rule is a curious callback and it was a little confusing for me. You register one rule, you give it a pointer to your rule and then there's this flag called don't register rule. So at first I said okay register one rule but don't register rule. All the don't register rule does is it doesn't add it into the tree of nodes there. You still have to call this function to initialize all the pointers in your structures there. So it sets up the Hocorosik and the internal pointers. But this was a confusing point to me. So when you're using rule structures inside your preprocessor you need to register them but not register them. So these plugins I'm talking about you can download them from secureworks.com slash research slash tools there's a link to the SNORT plugins there. I'm releasing them, released this Wednesday morning under the GPL. We can't support these, we can't give any warranty for these plugins. Use them at your own risk, your mileage may vary but we do appreciate feedback so we can help improve these things and bug reports and such. And also if you want to extend these plugins we you have no obligation to but we'd love to feed the code back to us upstream so we can get those fixes in there. So the first plugin that we're releasing is just a simple ActiveX Detection dynamic preprocessor. So what it does is it inspects web traffic for some JavaScript or scripting that's going to instantiate a vulnerable ActiveX control. When I say vulnerable it's basically based on public vulnerability disclosures about ActiveX controls. So in the preprocessor configuration I point the preprocessor to a local database file of ActiveX controls listed by class ID and optionally method and property. The database is in XML format, I'm sorry but it it seemed easy at the time to parse. And it basically just looks at the traffic, the response is coming off the web servers, looks for ActiveX and looks for the class ID and the PCRE and basically if you've defined methods and properties in the database it'll also look for is that scripting using those vulnerable methods or properties. So it can be evaded like most things in security. JavaScript is a great way to office get attacks. I'm not going to un-X or your JavaScript and determine that there's ActiveX control in there. But however today a lot of attackers that are attacking ActiveX controls, they're just using plain class IDs. They're not really being that sophisticated. Also you could probably evade this with some HTTP encodings using GZIP or deflate rather. In the future I want to add some snort inline support to this so that when it detects the plugin getting instantiated it could actually drop the packet or potentially send a reset back. And also I want to extend this a little bit more to leverage all the work that's HTTP inspectors doing there. And another idea is to use leverage the unified two output plugin to write out some more details about the ActiveX control that we've triggered on. So I took a shortcut implementing this and I used the match rule function. It was very convenient. It's probably not the most efficient way to do this in terms of space and time. But it was most efficient for me to implement. And it's basically the code right now that's transforming a naive linear search of class IDs. And basically my plan is to take the high performance, I think it's tri-based data structures that HTTP inspectors using and leverage those. It's using Snort's flow match to make sure that it's a response coming back from the server and it does some content matching and some PCRE matching behind the scenes to detect that. So I'm going to give you a quick live demo here of the ActiveX detection preprocessor function. So I've got a shell here. I've got a VM running its ids.example.com. So right here you can see I'm pointing Snort at my shared object files. It's in my working directory where I've been building the code, building the source. So dynamic preprocessor file point it to the ActiveX, point it to the SSH plugin we'll see later. And you see down below I'm including a little configuration for this ActiveX control. So here's basically the configuration for that ActiveX preprocessor. You just tell it what ports you want to look on. You point it to a local XML database file on initialization. It reads in the file, allocates pattern matching structures and starts looking at HTTP responses coming back in. So let's start up Snort. So up here you can see where my ActiveX plugin is echoing back parts of its configuration on startup. It tells you what kill bits, this is pretty verbose right here but it's telling you what kill bits it's looking for, what properties it's looking for, and what ports it's going to look at. So Snort's running, it's got that ActiveX plugin loaded. I'm going to start up a real basic HTTP server here. So here's a normal web server, it's doing nice red blinking text, hello DC-404. And you can see back here we got a get request, we sent a 200 back. And then if we go over here we'll do the request again just to show that there's no alerts being generated. So Snort's not generating alerts, back here we're tailing the Snort alert file and we're getting this nice blinking text back. So let's stop this web server. Let's run the evil web server. Now let's go make a request there. And in the background you'll see we're going to be tailing the log. You've been pwned. There's your alert. Bad ActiveX control detected. If we look at this source code on this page you'll see we're instantiating ActiveX object by class ID. And we're calling the IE start method which is bad juju and you know overflowing it with 4K's vase. And that's what it alerted on. And you see the alert in the background there. So it worked. Alright. So the next plug in is a little more interesting. Basically I'm going to do a quick background on the Debian OpenSSL random number generator. Please go see Luciano Bello and Maximiliano Berticini's talk tomorrow afternoon. Luciano and his colleague discovered this vulnerability in the Debian OpenSSL random number generator. I personally think it's one of the coolest phones of 08 and I believe the Pony Awards agreed. So the effect is that keys generated that were using this bad code since around 2006 rather September 2006 can be predicted. There's no real entropy in this random number generator other than your process ID. So that bad code eventually made its way from unstable Debian to testing Debian to stable Debian and it made its way into Debian Edge to Ubuntu. So kind of that code never got caught until recently and leaked its way all into these other branches of Debian. And these are a couple of humorous cartoons that HD Moore threw up on his site when this phone came out. So you got your Dilbert talking about a random number generator here and you've got XKCD doing a similar kind of thing. Guaranteed. Nice roll, right? Four. So I'm going to probably breeze through this so I don't steal the thunder from Luciano but this is bad. The Debian Vuln was bad. HD Moore jumped on this thing so quick within hours or a day or something he had brute forced the weak keys, generated them, posted them to his Metaspoit page. So he hit this really quick and I was impressed. So you've been mitigating this vulnerability, right? You scan your assets for bad SSH and SSL servers using the back listed keys, right? Nessus can do this for you. You scan all your home durs for the bad keys, right? There's a new tool called SSH Phone Key that'll do this for you. You look through all your home durs, you look through all your windows protected storage, browser profiles for blacklisted SSL certs, right? And what about connections to external servers you don't control that are still using an unpatched Debian OpenSSL? Okay. It's still going to impact your security. So our preprocessor, it's basically a detection preprocessor at this point. What it does is it looks at the Diffie-Helman key exchange between the two SSH peers and it attempts to brute force the random values that are generated. If one or both of the parties was using this bad Debian OpenSSL random number generator. So it's got a detective capability right now. In the near future, I hope to release code that's going to take this the next step and be a normalization preprocessor that's going to decode the whole stream. But it's not ready yet at this time. So this will be able to detect users connecting to external servers that are using the bad SSL and connections coming in from the outside that have a bad unpatched Debian SSL. So like I said, the goal in the near future is to have this actually decode both sides of the session. Right now, I calculate the shared secret, the Diff-Helman shared secret, I scroll away some other data about the session into the session object or session storage and then I generate alerts saying the client's vulnerable the server is vulnerable. The cool thing about normalizing it is then all the other snort preprocessors and rules could then inspect on the unencrypted content. And unencrypted sessions could be logged out to PCAP or Unified. I'm not a lawyer, I don't know the crypto export laws, but this may be crypto analytic software which may have some more controls on it. So I got to give props to the people that really came up with this stuff. I mentioned Bello and Berticini and they're speaking tomorrow afternoon. This fellow, Alexander Klink who's at Synops H over in Germany, he had posted a proof of concept Perl script to full disclosure and I have a link to the actual script right there. And basically it's a Perl proof of concept that's using GNU multiple precision libraries to attempt to brute force the SSH Diff-Helman key exchange. So these other two gentlemen here, Luciano just pointed me to their work today I haven't had a chance to review it, but I believe they're doing some work on a cell phone in SSH but potentially related to the host keys and identity keys, not necessarily the Diffie-Helman key exchange. And Luciano and his colleague have posted some patches to Wireshark that's going to break the perfect forward secrecy of TLS and SSL and there's a link to a post on the Wireshark bugzilla I think you can find their code up there and they'll probably cover this in their talk tomorrow. So I'm going to give some background on the how Diffie-Helman key exchange really works. It's a really elegant algorithm and it's a way for two parties to agree on a shared secret without ever having to have pre-knowledge or do a pre-key exchange. So the server is going to generate two numbers, a generator G and P which is the modulus. And that's wrong actually, it's not 1024, it's just a really long prime number. The client is going to generate a random number, let's say X. It's going to take that number take G to the X power modulo P I guess it's a number E. So it's a function of G, X and P. The server likewise generates a random number Y. It'll take this random number Y raise G to the Y power and take it modulo P and get another value F. So the server exchanges F with the client and the client exchanges E with the server. So all the security of this relies on the fact that it's too computationally expensive or it's computationally infeasible to brute force the discrete logarithm and solve for X and Y. Now K the shared secret K is defined as a function of F, X and P and E, Y and P. So in that sense both parties can calculate their shared secret K but no E's dropper unless you knew the X and Y value they could never figure out what K is. The weakness here is that the X and Y random numbers if you're using this bad Debian open SSL they're not random. There's about 32,768 possibilities that you're going to get and it's all dependent on the process ID. So I want to emphasize this is not about SSH host keys, it's not about SSH identity keys. This is all about the Diffie-Helman key exchange where they generate their shared secret which builds all the initialization vectors for the triple desk or AES encryption that follows. So down below this is how they do it for a triple desk encryption on an SSH session. You got K, both parties no K. No one else does. You take a hash and typically it's Shaw one and you concatenate V sub C which is the initial version string the client sends, V sub S which is the initial version string the server sends I sub C, I sub S which is their hello strings which is the public key signature of the server E, F, and the shared secret K concatenate all that together, take a Shaw one hash of it that gives you a hash H. H is the initial session ID or excuse me H is the session ID for the duration. If you have H and you have K you can calculate the initialization vector from client to server you can calculate the initialization vector for triple desk from server to client and also you can calculate the keys. These are the triple desk keys and actually those are literal A, B, C, and D if you read the RFC that's how they define those functions. Given K and everything else is in clear text over the wire I can calculate the IVs, the keys, the hashes, everything I need to decrypt this SSH session. So when does this occur? When do you have a problem here? Well, if you have an open SSH client or server that is linked or have been statically compiled against the vulnerable Debian open SSL I believe open SSH actually calls the ran bytes function that was found to be the problem. The X or Y values that are generated by the server and client are completely predictable based on the PID of the open SSH process. This is bad. I can quickly brute force through actually 32,000 possibilities if I needed to search the entire key space and solve that discrete log and then I have the shared secret K. With X or Y, like I said, you got the shared secret K all bets are off. I can do your triple desk decryption. I can look inside that supposedly secure SSH session. So some interesting implications here. Tunnel clear text passwords. Remember how people say tunnel clear text passwords are bad? Well, this shows why they're bad. If I can break the triple desk encryption I've got your username and password in the clear. If you're using RSA or DSA public key off I can't do that, right? Even if I crack the diff helmet key exchange I still can't break your authentication when you're using the public key stuff. But, yeah, I can harvest clear text passwords all day long if you're using this bad Debian open SSL. You can grab files or any other data in the session that's being transferred. And observers can relatively easily tell if one or both of the servers is vulnerable and then proceed to decrypt the stream. So let's do a little live demo here of this stuff. So right at start I took let's look at the Hello World peak habit sample in Wireshark here. So this is a basic SSH session that the client is using the bad open SSL random number generator. You can see the key exchange. Let me scroll this over here. You see the cleats change init where it's in the packet capture it's saying all the algorithms and such it uses server key exchange init. We have to grab these strings in clear text for the wire because they go into those hash functions. Here's the gexinit here's the key exchange reply and these two messages are key here. The init and the reply. The init, the client sending its e-value to the server and the reply the server sending its f-value back to the client. Then you see this new keys message. They send the new keys message and that means everything afterwards goes into encryption and you see this stuff is all encrypted afterwards. So let's run an extended version of Alexander Klink's check that weak SSH keys script. So initialization is a little bit slow. It's got a load 32,768 multiple precision integers into memory, which it's doing right now. And it's not really a private key, it's probably a misnomer but these are the random values that would be generated by the OpenSSL PRNG when OpenSSH is calling it. So it's loading up all these things. There's a local file that's got all these hex value multiple precision ints and it's reading from that local file and by the way it's not cracking now it's simply loading the keys. Okay now it's cracking, now it's brute forcing done. It just told me that the client is vulnerable the server is not. If you go back through my verbose output I got g, the generator g I've got the prime number those are all in clear text, nothing special about that I got g to the x and g to the y and this should read g to the y but it's one function that just prints it out. And the cool stuff here is that k. I brute forced the discrete log, I calculated the shared secret k with k I calculated the hash h which is the initial session id, k sub s is the public key fingerprint of the server I v c is the initialization vector from client to server, I v s initialization vector the other way and then e c and e s are actually the triple desk encryption keys for that session so let's do this in snort now I'm just going to load that hello world pcap file we just processed through there before we hit that off, let's start tailing the snort log here no alerts in there let's load up snort you see s s h k e x d h we'll come back to that in the log so it's now about to load the pcap file and start processing the pcap file through the preprocessor and boom, it's done you go up, okay generated one alert log one packet and here you can see the s s h key exchange group key exchange config that's just the configuration stuff and it points it to a local file that has all those random numbers in it and let's go flip back over to our alert file, boom my preprocessor just generated an alert it brute forced the defelman key exchange just told you that that client is vulnerable that client is using a bad debbie and open s s l alright and we're back alright so I have a few minutes left some snort futures stuff and v3 is very exciting development I haven't really played with it yet but I've definitely been reading the release notes and the change logs and seeing what's going on with that looks to be a major major enhancement to snort it's all basically got Lua scripting language hardware optimized packet acquisition that can be put in hardware and the snort 2.8 plugin content matching engine is simply a plugin into v3 2.8.3 I think it's a release candidate now it's no longer a beta some cool stuff was added to htp and spec they're breaking up parts of the request and the response into new buffers that you can match on very web 2.0 of them and so to wrap it all up you know I chose snort because it's such a powerful framework it gives me stream reassembly it puts the packets back in order it gives me a stream api where I can do stream local storage it gives me a high efficiency logging and alerting output plugins so why reinvent the wheel I just write some snort plugins and let the big brains at Sourcefire handle the rest so hopefully with this talk you can take away and start writing your own plugins if you've got a little bit of background in the C language look at the source code for existing plugins ask questions on the developers list ask me questions email me and snort v2 I'm not sure how much more it's evolving I'm not sure where the resources are going into v3 or v2 but I'm still seeing release after release they're adding new things into the apis so if it doesn't support something you're trying to do they might do it for you so to wrap up I want to thank Dark Tangent all the folks that made DEF CON happen again this year and the goons and also I want to give a shout out to my local Atlanta DEF CON group DC-404 we've got a lot of speakers out here this year Dr. Chaos, Karek, Dave Maynard Scott Moulton, Adam Bregner and our own goon decode is somewhere around here so if you have any questions you can email me I'm going to be heading over to the Q&A room in a few minutes after this wraps up and this code is available on the SecureWorks website, SecureWorks.com slash research slash tools there should be a link towards the bottom of the page and we appreciate any feedback thank you