Tuesday, November 4, 2008

RIT Honeynet Project

Good news. The proposal sent in for the RIT Honeynet Project was accepted today. A small group of students, including myself, have been planning out the project for about a month now, and the NSSA Department has agreed to supply us with the materials we requested. We will post more information regarding our project on this blog, as well as post a link to our RIT Honeynet webpage once it is created.

Wednesday, October 22, 2008

Nmap tarpits

There are two main types of Nmap scans: those which simply check whether ports are open (TCP SYN / RST scanning), and those which try to do fingerprint analysis of each service (connect completely, wait for response, check response against known responses). The following is a technique which makes both of these attacks much more difficult.

Typically, an Nmap scan will scan the low-numbered privileged ports such as ports 1-1023, since these are where most services will listen for connections. Common services an attacker might hope to find include FTP (21), SSH (22), SMTP (25), and HTTP (80), all within this range. Because of this, our tarpit script will focus on this range.

The approach is simple - open all otherwise unused ports and do nothing with them. This has two consequences: a simple scan will identify all ports as open and render no useful information, while a fingerprinting scan will wait for each port in the range to respond until max timeout (since our listening program will never reply). This means that scans will either return unless information or the scan will be slowed dramatically (those configured with a low timeout per port), which can also sometimes cause inaccurate results. While this will not stop serious attackers, it will stave off any wide-area scans of your network or anyone with only an elementary knowledge of network security.

Here is a simple implementation in Perl:
#!/usr/bin/perl -w
use strict;

use IO::Socket;

my @port = ();

for (1..1023) {
  $port[$_] = IO::Socket::INET->new(
    Proto => 'tcp',
    LocalPort => $_,
    Listen => SOMAXCONN,
    Reuse => 1);
  next if $! =~ /already in use/i;
}

sleep 10 while 1;

This script must be run as root to access the privileged ports. It should also be noted that while this script is active, no new services can be started in the privileged port range. This tends not to be an issue with already-configured servers as services aren't usually changed, but stopping the script while a new service is added is trivial.

A more advanced script could also detect when a single IP connects several times on different ports (this is safe because no legitimate user will connect to any of the ports listened to by the script) and add that IP to a systemwide blacklist or software firewall deny list.

If an attacker decides to DDoS the script, it will begin using memory to store the unread messages. If this is a concern, you could have the script occasionally read from the sockets and discard the data or simply restart the script occasionally.

Tuesday, October 21, 2008

Unpacking UPX

This was a presentation I gave at a SPARSA meeting. It's just a basic overview of how packers work and how one might go about unpacking a packed executable.

A packer is a compression tool (in this example used for PE files) for binary files. Other types of compression could be: Zip, rar, tar, bzip, gzip, etc. When UPX compresses the PE file, it has to know how to decompress it once the program is run. This version of UPX (http://upx.sourceforge.net/#download) uses a decompression loop that is inserted during compression. Once the binary executes the decompression loop, it is unpacked in to memory. If we wish to obtain the original unpacked binary, we just have to dump the process from memory..sounds easy enough. Why would we want to obtain the unpacked executable? If we weren't sure of the packer, or it wasn't UPX (which you can decompress using the command "upx -d") we would be unable to understand the disassembled code in your favorite disassembler.

To start, I'll show the PEiD (http://www.peid.info/) output of winmine.exe to show it isn't packed. PEiD works much like antivirus products do. It uses a signature database to find byte-matching patterns within the file.


To pack the executable, we simply run the UPX command on the command line.


We can still run the new executable, winmine_packed.exe, from the command line because it simply decompresses the binary file in to memory. To show that the file was successfully packed, we can throw the new executable back in to PEiD.

Ok, now for the fun part. We have to open the packed executable in a debugger. For this presentation I used OllyDBG (http://www.ollydbg.de/download.htm). OllyDBG will complain that the file is compressed but we already know this. Once we get in to OllyDBG, the first comamnd we see is PUSHAD. This command pushes all the registers on to the stack. This way they can be decompressed in to memory. The call we are looking for is POPAD, which would make sense because it pops the registers back off the stack after the decompression loop.


If you scroll down in Olly, you should find POPAD near the bottom of the loop.


You can see at the end of the loop the program compares the ESP (stack pointer) with the EAX register. If it is not decompressed, it jumps back to the the PUSH 0 call. If however, the decompression loop is complete, it uses a JMP command. This is exactly what we're looking for. If we follow this jump, we will find our original entry point in the program (OEP). The original entry point is where the unpacked binary starts. We will start by placing a breakpoint on the final JMP call. This way, once we start the program, it will hault on that call. You can set a breakpoint in OllyDBG by pressing F2 on the JMP call.

You then would start the program execution either by clicking the Play button in Olly, or by pressing F9. It should hit the breakpoint you set and hault execution. Now, the JMP should lead us back to the OEP. To move one step in Olly, rather than execution the remaining code, you can press F7 (step into). You should now be at the oep and olly should display something like this:


Now that we have gone through the decompression loop, our binary is unpacked in memory. The next step is to dump the process from memory. To do this, I used a tool called LordPE (http://www.woodmann.net/collaborative/tools/index.php/LordPE). Open up LordPE and select the winmine_packed.exe process that is running through OllyDBG. Right click the process, and select "Dump Full".


I would suggest naming it something that you will remember such as winmine_dumped.exe. Now that the program has been dumped from memory, lets try to run it.


As you may have thought, the fun is not over yet. Once the dumped program is executed, you are confronted with an error saying it was unable to initialize properly. When a process is dumped from memory, this can mess up the import table. A PE file's import table is used to know which files it needs to dynamically link to when mapping in to memory (DLLs). So how do we fix this? We use another program I used in this presentation called ImportREC (http://vault.reversers.org/ImpRECDef). Again, select winmine_packed.exe from the process list. The program should finish loading the process, and give you an Image Base. Lets go back to our Olly window that's still open, and get the address of our OEP.


As seen earlier, our address of the OEP is 01003E21. Back in ImportREC, we need to set the OEP in the IAT Info section. If our image base is already 01000000, then our OEP would be at 0003E21 (Image base plus + OEP = relative location in memory). We then click the IAT AutoSearch button in ImportRec:


You should see a good looking message stating that it found an address which may be in the original IAT. If we follow the instructions in the dialog box, we would click Get Imports at the bottom of ImportREC.


ImportREC should look something like the screenshot above. It has successfully found imports for winmine_packed.exe. We then click Fix Dump, and select our previously dumped winmine file (winmine_dumped.exe). ImportREC will then save the file as winmine_dumped_.exe. Let's throw that file back in to PEiD to see if it's still packed:

We are back to where we started, and the dumped binary is able to run successfully.

Monday, October 20, 2008

New Blog

Welcome to the new SPARSA blog. The site is under a lot of construction still and we're gathering blog authors from the organization. For those of you who don't know, SPARSA is a security club at Rochester Institute of Technology. We thought it would be a good idea to create a blog talking about research group members have been doing, and presentations given during meetings. Our website is at:
http://www.sparsa.org