¿me echais una mano? es un programa en assembler muy fácil.

Iniciado por black_flowers, 9 Febrero 2011, 01:06 AM

0 Miembros y 3 Visitantes están viendo este tema.

black_flowers

a ver si alguien me puede echar una mano con este programa en assembler (pensado para generar una shellcode).
Más simple no puede ser, quiero llamar a winexec para que ejecute la calculadora: (no hace nada). Cuando lo depuro con olly, por pasos, al llegar a la llamada a la dirección de winexec me dá un error de modo que esa dirección no puede ser leída.
La dirección de winexec la obtengo con el típico programa que utiliza la función getprocadress, y en principio debería ser correcta.

.386
.model flat, stdcall
option casemap:none

.data
.code
start:
sub esp, 9h
mov byte ptr [ebp-11h],63h 
mov byte ptr [ebp-10h],61h   
mov byte ptr [ebp-0fh],6Ch
mov byte ptr [ebp-0eh],63h
mov byte ptr [ebp-0dh],2Eh
mov byte ptr [ebp-0ch],65h
mov byte ptr [ebp-0bh],78h
mov byte ptr [ebp-0ah],65h
mov byte ptr [ebp-09h],00h
push 5
lea eax, [ebp-11h]   ;cargamos la direccion que apunta a nuestra cadena
push eax     
mov eax,71c326d3h   ;winexec
call eax
push 1     
mov eax,772e2aefh   ;exit process
call eax
end start


no hace nada, lo intento depurar con ollydbg pero no entiendo muy bien si hace lo correcto o no.

lo primero que hago es reservar espacio en la pila para 9 bytes. Luego inserto la cadena pero me salto unos bytes que había antes en la pila, por eso empieza en ebp-11h.

una vez insertada la cadena en la pila, "calc.exe/0", meto el parametro 5 (que equivale a SW_SHOW, y que es otro parámetro de winexec).

y finalmente llamo a winexec.

black_flowers

lo he probado en visual studio y el problema parece estar en la dirección de winexec. Sin embargo el método para obtener dicha dirección es el de usar getprocadress  (en otro programa) y no me había fallado con otras funciones hasta ahora.

¿pasa algo raro con la dirección de winexec en kernel32.dll en windows7?

black_flowers

he probado con CreateProcessA en lugar de winexec y el resultado es igual. La dirección que devuelve getprocadress no es correcta. No lo entiendo.

SirPallic

Primero comproba que la direccion que apunta a winexec es la correcta, porque las direcciones virtuales varían en otras máquinas y sistemas operativos. Ahora te digo donde está el error. Luego de meter los bytes que forman calc.exe debes de corregir la pila, agrega add esp,9h antes de push 5. Con eso se arregla tu problema.

black_flowers

así lo he hecho pero sigue sin hacer nada. Como bien dices, he comprobado la dirección y a mí me parece que el problema es justamente ese, la dirección de la función winexec. Es cierto que varían de un sistema a otro, e incluso te puedo decir que en el caso del w7 varía cada vez que el sistema se reinicia. pero ese no es el problema ya que la modifico cada vez que la utilizo (como puedes imaginarte esta no es para una verdadera shellcode sino más bien para una introducción a como funcionan). Y la dirección la obtengo con un programa que llama a getprocadress y me imprime la dirección en la consola. Luego yo la modifico en mi programa. Pero lo he depurado con ollydbg y parece que la dirección de winexec no es correcta. No pasa lo mismo con ExitProcess que sí que lo es.

SirPallic

comment %
Este codigo lo modifique para tu caso en especial, luego tu veras como lo adaptas a tu antojo.
Simplemente obtenemos el kernel base y buscamos el nombre de la libreria en particular. Luego buscamos su desplazamiento y por ultimo se llama al mismo para ejecutar la calculadora. Si con este codigo no logras hacer nada no se que pueda pasar en tu computadora. Este codigo funciona correctamente en xp.
%
.486
.model flat,stdcall      ;ensamblado con masm32
option casemap:none


.code       
start:

jmp empieza
kernel_base dd 0         ;para que esto contenga luego el offset al kernel
milibreia db "WinExec",0   ;debes de linkarlo con /section:.text,RWE
calculator db "calc.exe",0   ;pero tu lo adaptas como hiciste antes

empieza:
assume fs:nothing         ;esto debes de colocarlo si o si
mov esi,dword ptr[fs:30h]
mov esi,dword ptr[esi+0ch]
mov esi,dword ptr[esi+1ch]
busca:
mov edx,dword ptr[esi+8h]
mov edi,dword ptr[esi+20h]
mov esi,dword ptr[esi]
cmp dword ptr[edi+0ch],320033h
jnz busca
mov kernel_base, edx      ;si no obtienes el kernel, hay otro codigo que puedes usar.

lea esi,milibreia
mov ecx,7
call proceso
push 5
push offset calculator
call eax
ret
nop
nop
nop

proceso:
mov edx,kernel_base
add edx,[edx+3ch]
mov edx,[edx+78h]
add edx,kernel_base
mov edi,[edx+32]
add edi,kernel_base
mov edi,[edi]
add edi,kernel_base
mov eax,[edx+24]
xor ebx,ebx
empieza_buscar:           
push ecx
inc ebx         
push esi
push edi
repz cmpsb
pop edi
pop esi
jnz no_encontrado
pop ecx
mov ecx, [edx+36]
add ecx,kernel_base
dec ebx
movzx eax, word ptr [ecx+ebx*2]                       
mov ebx, [edx+28]
add ebx,kernel_base
mov eax, [ebx+eax*4]               
add eax,kernel_base
ret
no_encontrado: 
dec edi           
busca_fin:
inc edi
cmp byte ptr [edi],0
jnz busca_fin
inc edi           
dec eax
jz salimos           
pop ecx
jmp empieza_buscar
salimos:
ret
end start

black_flowers

Cita de: SirPallic en 15 Febrero 2011, 06:34 AM
milibreia db "WinExec",0   ;debes de linkarlo con /section:.text,RWE
calculator db "calc.exe",0   ;pero tu lo adaptas como hiciste antes

no entiendo muy bien qué es /section:.text,RWE y cómo debo linkarlo etc.
La verdad es que lo de hacer la shellcode de esta forma es todavía muy avanzado para mí. Necesito hacerlo primero con las direcciones hardcodeadas y luego pasar a este método.

un saludo.

SirPallic

No se si ya has arreglado tu problema, pero te traigo una posible solución. Si el problema era la dirección a WinExec, proba con ShellExecuteA. Te pongo el codigo. $ mov dword ptr[ebp],636c6163h $ mov dword ptr[ebp+4],6578652eh $ mov dword ptr[ebp+9],0 $ push 5 $ push 0 $ push 0 $ push ebp $ push 0 $ push 0 $ call ShellExecuteA $ ret . El simbolo "$" lo pongo para hacer el salto de línea porque estoy desde el celular.

black_flowers

Cita de: SirPallic en 19 Febrero 2011, 05:07 AM
No se si ya has arreglado tu problema, pero te traigo una posible solución. Si el problema era la dirección a WinExec, proba con ShellExecuteA. Te pongo el codigo. $ mov dword ptr[ebp],636c6163h $ mov dword ptr[ebp+4],6578652eh $ mov dword ptr[ebp+9],0 $ push 5 $ push 0 $ push 0 $ push ebp $ push 0 $ push 0 $ call ShellExecuteA $ ret . El simbolo "$" lo pongo para hacer el salto de línea porque estoy desde el celular.

lo he arreglado pero todavía no tengo claro por qué falla la dirección de winexec y de CreateProcess:

Para empezar en el código había errores:

primero yo estaba restando 9h y en realidad había que restar 10h en la pila(no entiendo el porqué pues no manejo bien lo de la pila):
sub esp, 10h
Luego la dirección que le daba a la cadena también estaba mal, tenía que ser 0fh y no 11h cómo venía poniendo yo (tampoco entiendo el porqué).

tambien sumaba despues de la cadena la longitud de esta pero en realidad no hay que hacerlo.
add esp, 9h

y finalmente, y esto sí que es extraño... la dirección de winexec no era correcta. como había dicho la obtenía con Getprocadress en un programita creado en visual Studio. El Offset de la función winexec dentro de kernel32 me dá correcto pero la dirección base que obtiene un programa hecho en visual studio no coincide con la dirección base que utiliza mi programa ejecutable.

al final he averiguado la dirección, haciendo primero un invoke winexec y mirando a qué dirección saltaba mediante el ollydbg, y luego utilizando dicha dirección en mi programa, al fin ha funcionado pero no he entendido muy bien los fallos.

de todas formas probaré el código que tú me pones a ver si me funciona también, muchas gracias!!

ah,,  se me olvidaba, el código que me funciona es este:

.386
.model flat, stdcall
option casemap:none

.data
.code
start:

push ebp
mov ebp, esp
xor dl, dl    ;con esto hacemos que dl valga 0

sub esp, 10h
mov byte ptr [ebp-0fh],63h 
mov byte ptr [ebp-0eh],61h   
mov byte ptr [ebp-0dh],6Ch
mov byte ptr [ebp-0ch],63h
mov byte ptr [ebp-0bh],2Eh
mov byte ptr [ebp-0ah],65h
mov byte ptr [ebp-09h],78h
mov byte ptr [ebp-08h],65h
mov byte ptr [ebp-07h],dl
push 5
lea eax, [ebp-0fh]   ;cargamos la direccion que apunta a nuestra cadena
push eax     
mov eax,7732e76dh   ;winexec
call eax
push 1     
mov eax,772f2aefh   ;exit process
call eax

end start