Monday, June 2, 2008

CISCO response on IOS rootkits

'Rootkits on Cisco IOS Devices' is a document published by CISCO in response to my presentation on IOS rootkits.
It talks about several security measures to take to detect binary image modification but I think that there are some things that are worth mentioning:
1) System Administrators don't read logs very often.
2) Implementing AAA is not easy task for every company (specially small-med sized corps).
3) Using the 'verify' or any other CLI command can easily be hooked by DIK and return whatever it wants instead of the real values.

Ohh come on! You cannot rely on any information given by IOS because this is equivalent than diagnosing an infected Windows machine from within the infected OS.

Let's analyze the case of the verify command.
If you execute that command on any IOS you get an output like:
router#verify /md5 disk0:c7301-jk9s-mz.124-10.bin 0c5be63c4e339707efb7881fde7d5324

%Error verifying disk0:c7301-jk9s-mz.124-10.bin
Computed signature = ad9f9c902fa34b90de8365c3a5039a5b
Submitted signature = 0c5be63c4e339707efb7881fde7d5324


So, now we know the strings used by this command, and if we go to IDA and take a look at the strings list (View->Open Subwindows->Strings) we could find any of those strings like '%Error verifying ' (which is obviously located next to the previously seen strings 'Computed signature = ' and 'Submitted signature = ') which will take us directly to the function that displays the verify command output.
Now that the function is located, we can do the known procedure of intercepting it's call and check if the filename to verify is the router image and just display the output we want (previously obtained printf() memory address, right?).
A different approach could be to intercept open_file() to check if the IOS filename is opened and set a flag inside the rootkit so that any call to read_file() with the FD (File descriptor) of the previous call to open_file() must be monitored to return the original bytes of the image at it's corresponding locations. But this is more difficult and some other things have to be taken into consideration.
So this sounds difficult? How about intercepting the function that received a char* with the calculated MD5 and overwrite it with the correct value previously stored inside the rootkit? That sounds way too easy, right? Well, it is! ;)

Now what do you think about verify /md5 command? Useful? Yeah right...

No comments: