Dailydave mailing list archives

Re: The Hydrogen hundred dollar challenge


From: Jason <security () brvenik com>
Date: Tue, 12 Apr 2005 22:56:23 -0400



Neil wrote:
I don't think that is possible to find Hydrogen with snort.

I think it is doable in a number of ways. Here are my initial thoughts.

The header will be

4 byte packet type
4 byte size
4 byte error code

followed by a body up to char[20000]

The payload is supposed to be fully encrypted so who really cares about that. I did see a point where it looked like a custom responder might be able to force hydrogen to stop performing encryption but that is a different pursuit.

Focusing on the 12 byte header where the first byte will be a value greater than 0 and less than 60 followed by 4 bytes for size and then followed by an error code which should always be 0 for everything but a sessionkey you can create a set of rules as follows.

alert tcp any any -> any any (msg:"hydrogen.command"; content:"|01|"; depth:1; content:"|00|"; distance:3, within:1; flow:established; flowbits:toggle,hydrogen.command; flowbits:noalert; sid:1000000; rev:1)

alert tcp any any -> any any (msg:"hydrogen.sessionkey"; content:"|1E|"; depth:1; content:"|00|"; distance:3, within:1; flow:established; flowbits:toggle,hydrogen.sessionkey; flowbits:noalert; sid:1000001; rev:1)

alert tcp any any -> any any (msg:"hydrogen.putstart"; content:"|15|"; depth:1; content:"|00|"; distance:3, within:1; flow:established; flowbits:toggle,hydrogen.putstart; flowbits:noalert; sid:1000002; rev:1)

continued...

wash rinse repeat as desired.

create rules for each command that will cause a return record with a result set checking flowbits. These returns will have a similar 12 byte header but may have error values associated. Those values can be tested as between 0 and 4 at the moment. ( Would it be worth looking for return results that are ultimately errors? It may but that only means more typing for anyone that wants to do it. )

alert tcp any any -> any any (msg:"hydrogen.command.response"; content:"|01|"; depth:1; content:"|00|"; distance:3, within:1; flow:established; flowbits:isset,hydrogen.command; flowbits:toggle,hydrogen.command; sid:1000100; rev:1)

alert tcp any any -> any any (msg:"hydrogen.sessionkey.response"; content:"|1E|"; depth:1; content:"|00|"; distance:3, within:1; flow:established; flowbits:toggle,hydrogen.sessionkey; flowbits:noalert; sid:1000101; rev:1)

continued...

wash rinse repeat for udp

A more interesting thing to do would be to handle it in a preprocessor and if you suspect hydrogen to return a sessionkey packet with error 3 on a request to the sender or client and observe the results. A safer approach is injecting your own commands and waiting for the appropriate resulting error.

There is also the opportunity to watch the 0 -> 1 flushing behavior on each connect to the server to know more definitively that it is hydrogen. There were a few other areas I thought possible to look into but that is for another time. There are certainly edge cases and ways to change the protocol but that is outside the scope of my 30 minutes of drinking and typing.


1. Since the packets that we need to trigger off of are less than or equal
to 4 bytes snort does not look at them. See you email thread with Marty for
more info:
http://archives.neohapsis.com/archives/sf/ids/2005-q1/0074.html. Even though
this is not MSRPC fragmentation I think that the guidelines still apply.

Not applicable at all and I submitted a patch to make this behavior configurable within a randomized boundary so that would make it totally unpredictable moving forward. Even with the default behavior of stream4 the 12-byte headers are too small and confined to the start of the packets to take advantage of stream4's flushing behavior.


2. Since Hydrogen does not use a static port we can't add it to the stream4
preprocessor without a severe impact to performance in a production
environment. Currently only the most use ports ("default" will turn
on reassembly for ports 21, 23, 25, 53, 80, 143, 110, 111 and 513) are
handled by stream4. If you used a static port then you could add it to
stream4 and have your way with it.

12 byte headers pretty much means that you would have to use an mss at <12 for this to be an issue. When you get down to that size pkt you should be setting off all kinds of strangeness alerts in any well tuned snort environment. As I understand it the new stream5 code will be dynamically identifying session to reassemble so even this consideration goes away in the future. Stream5 is currently in testing.


Just for kicks why don't you use a random size in the initital packets and
have the valuable info somewhere in there. It would make just a bit harder
to detect.

Only if you encrypt the entire payload. Providing random data still requires some format to decipher the intent. Rules can model that format too.
_______________________________________________
Dailydave mailing list
Dailydave () lists immunitysec com
https://lists.immunitysec.com/mailman/listinfo/dailydave


Current thread: