sabeis como se calculan los espacios que hay que restar a esp para introducir una cadena en la pila? En el siguiente código yo meto 8 cacacteres pero en cambio necesito restar 0bh es decir 11 espacios para que el programa funcione. Ademas ni siquiera necesito empezar la cadena en la parte superior, es decir en el espacio 11 sino que empezando en el espacio 8 funciona. No entiendo el porqué de esto.
sub esp, 0bh ; dejamos espacio en la pila para meter nuestra cadena
mov byte ptr [ebp-08h], 57h ; 'W'
mov byte ptr [ebp-07h], 69h ; 'i'
mov byte ptr [ebp-06h], 6eh ; 'n'
mov byte ptr [ebp-05h], 45h ; 'E'
mov byte ptr [ebp-04h], 78h ; 'x'
mov byte ptr [ebp-03h], 65h ; 'e'
mov byte ptr [ebp-02h], 63h ; 'c'
mov byte ptr [ebp-01h], dl ; 0x00
lea ecx, [ebp-08h] ; cargamos la direccion que apunta a nuestra cadena
push ecx
push esi ;dirección base de kernel32
call eax ; llamamos a getprocadress
Vaya complicación!
Yo hago:
xor eax, eax
push eax
push 0x41424344 ; DDCCBBAA
push 0x41424344 ; DDCCBBAA
mov eax, esp
Y en EAX tienes tu cadenita (o la dirección, que es lo que necesitas)
vaya, pues si que es más fácil tu método. Lo voy a probar.
Cita de: Sagrini en 26 Marzo 2011, 11:14 AM
Vaya complicación!
Yo hago:
xor eax, eax
push eax
push 0x41424344 ; DDCCBBAA
push 0x41424344 ; DDCCBBAA
mov eax, esp
Y en EAX tienes tu cadenita (o la dirección, que es lo que necesitas)
tienes razón queda mucho más sencillo. El único problema es que no se como evitar caracteres nulos, sin ir mas lejos el que hay que poner al final de la cadena.
Cita de: black_flowers en 26 Marzo 2011, 15:59 PM
tienes razón queda mucho más sencillo. El único problema es que no se como evitar caracteres nulos, sin ir mas lejos el que hay que poner al final de la cadena.
El push eax mete el caracter nulo, concretamente mete 4 xD.
Saludos
Edito: Otra forma de hacerlo:
call str_1
_String1 db "Soy un String",0
str_1:
pop ecx
;ecx apunta a la cadena
Cita de: [Zero] en 27 Marzo 2011, 00:13 AM
El push eax mete el caracter nulo, concretamente mete 4 xD.
pero cuando hago por ejemplo esto, para meter la cadena enla pila:
push 636578h ;incluye un 00 al inicio automaticamente (que es el nulo del final de la cadena)
push 456e6957h ;caracteres de winexec en sentido contrario
mov ecx,esp
push ecx
push esi ;dirección base de kernel32
mov ebx,eax
call eax ; llamamos a getprocaddress
el primer push pasado a opcodes es: 68 78 65 63 00, lo cual implica un nulo. A eso me refiero. ¿como evitas eso?
00401000 > 33DB XOR EBX, EBX
00401002 53 PUSH EBX
00401003 68 44434241 PUSH 41424344
00401008 68 44434241 PUSH 41424344
0040100D 8BDC MOV EBX, ESP
pues no veo ningun opcode null
(http://i56.tinypic.com/2n0207l.jpg)
Cita de: black_flowers en 27 Marzo 2011, 13:59 PM
pero cuando hago por ejemplo esto, para meter la cadena enla pila:
push 636578h ;incluye un 00 al inicio automaticamente (que es el nulo del final de la cadena)
push 456e6957h ;caracteres de winexec en sentido contrario
mov ecx,esp
push ecx
push esi ;dirección base de kernel32
mov ebx,eax
call eax ; llamamos a getprocaddress
el primer push pasado a opcodes es: 68 78 65 63 00, lo cual implica un nulo. A eso me refiero. ¿como evitas eso?
el opcode nulo está en mi cadena, en la que quiero utilizar yo. ;D
Una cadena ASCII no puede tener un byte nulo por el medio... ya que la cadena ASCII se mida hasta la aparicion de un byte nulo... Y si tu "cadena" tiene bytes nulos sencillamente xorea todo el numero y lo vuelves a xorear una vez en la pila... seria algo asi:
push 0xAABBCCDD ;Caracteres xoreados con nMagic para quitar 00s
xor [esp], nMagic ;Vuelves a xorear para dejar como estaba
Cita de: Karcrack en 28 Marzo 2011, 16:17 PM
Una cadena ASCII no puede tener un byte nulo por el medio... ya que la cadena ASCII se mida hasta la aparicion de un byte nulo... Y si tu "cadena" tiene bytes nulos sencillamente xorea todo el numero y lo vuelves a xorear una vez en la pila... seria algo asi:
push 0xAABBCCDD ;Caracteres xoreados con nMagic para quitar 00s
xor [esp], nMagic ;Vuelves a xorear para dejar como estaba
me parece que el se refiere a otra cosa....
00401002 53 PUSH EBX
esto reemplaza el opcode null osea el zero terminator a eso te refieres?
osea
lstrCadena db "Hola",0
te refieres a ese 0 el zero terminator?.... si es así con lo que te dice sagrini se hace el push ebx pone el zero terminator en la pila.... si no es asi.. pon como es tu cadena! y nosotros te podremos ayudar( que no sea en hex si no en ascii).
Salu2!
Cita de: Иōҳ en 28 Marzo 2011, 19:40 PM
me parece que el se refiere a otra cosa....
00401002 53 PUSH EBX
esto reemplaza el opcode null osea el zero terminator a eso te refieres?
osea
lstrCadena db "Hola",0
te refieres a ese 0 el zero terminator?.... si es así con lo que te dice sagrini se hace el push ebx pone el zero terminator en la pila.... si no es asi.. pon como es tu cadena! y nosotros te podremos ayudar( que no sea en hex si no en ascii).
Salu2!
claro, es el cero terminador. Pero no entiendo cómo lo sustituyes por push ebx, ya que push ebx envía 4 nulos ¿me equivoco?
Y yo necesito un nulo justo al final de mi cadena.
push 636578h ;incluye un 00 al inicio automaticamente (que es el nulo del final de la cadena)
push 456e6957h ;caracteres de winexec en sentido contrario
lo que mando a la pila son los caracteres de WinExec en orden inverso. Pero al final tengo que poner un nulo, es decir despues del 63 va un 00. En mi caso he enviado el 636578h en lugar de 00636578h aunque a fin de cuentas son equivalentes.
La pregunta era que cómo me deshago de ese 00 terminador.
lo sustituyo porque ebx vale 0 y lo que estas pasando es un valor nullo a la pila para que sea el zero terminator, el push ebx envia a la 00000000 a la 'pila', luego le pasas las cadena, al final solo te queda debuggear si al final de esta subrutina queda desbalanceada la pila... para balancearlo. no sabria decirte con exactitud si desbalancea la pila. =/
Dato: TODA cadena tiene que tener un zero terminator que indica el final.
Salu2!
es que hay algún sitio en donde nonos estamos entendiendo. Para clarificarlo voy a preguntar esto que no tiene más vuelta de hoja: ¿cómo introducirías en la pila winexec sabiendo que estos son sus caracteres asci?
57h 'W'
69h 'i'
6eh 'n'
45h 'E'
78h 'x'
65h 'e'
63h 'c'
disculpa por no entenderte, pero creo que debistes resaltar la cadena a pasar en primera instancia.. en ascii o talvez fue un despiste mio de no prestar atencion a tu cadena en hex sea cual sea, esto me funciono, chequelo. :xD
00401000 > 33DB XOR EBX, EBX
00401002 53 PUSH EBX
00401003 68 45786563 PUSH 63657845
00401008 C74424 FD 57696E45 MOV DWORD PTR SS:[ESP-3], 456E6957
00401010 8D5C24 FD LEA EBX, DWORD PTR SS:[ESP-3]
pd: Me esta pareciendo interesante codear una shellcode eh! jeje (como nunca lo he hecho X)
pd2: el code creo que esta un poco ortodoxo, fijate si necesitas reservar espacio en la pila.. ya que estoy moviendo valores directamente, se puede mejorar, pero ya tienes la idea :).
Salu2!
Cita de: Иōҳ en 29 Marzo 2011, 17:54 PM
disculpa por no entenderte,pero creo que debistes resaltar la cadena a pasar en primera instancia.. en ascii o talvez fue un despiste mio de no prestar atencion a tu cadena en hex sea cual sea, esto me funciono, chequelo. :xD
00401000 > 33DB XOR EBX, EBX
00401002 53 PUSH EBX
00401003 68 45786563 PUSH 63657845
00401008 C74424 FD 57696E45 MOV DWORD PTR SS:[ESP-3], 456E6957
00401010 8D5C24 FD LEA EBX, DWORD PTR SS:[ESP-3]
pd: Me esta pareciendo interesante codear una shellcode eh! jeje (como nunca lo he hecho X)
pd2: el code creo que esta un poco ortodoxo, fijate si necesitas reservar espacio en la pila.. ya que estoy moviendo valores directamente, se puede mejorar, pero ya tienes la idea :).
Salu2!
lo que pasa es que estaba tratando de hacerlo tal y como indicó sagrini en un post anterior, él utilizaba sólo push, y no mov, de esa manera la pila queda siempre balanceada, eso es lo que intento principalmente.
Por lo tanto para meter la cadena con push hago esto:
En este primer caso no hay problemas con los opcodes nulos puesto que la cadena ocupa ocho caracteres y no necesito mandar ningún valor nulo.
xor ecx,ecx ;necesitamos mandar el nulo (en este caso mandamos 4 ya que mandamos el ecx entero)
push ecx
push 6578652Eh ;caracteres de calc.exe
push 636C6163h
mov ecx,esp
pero en este caso: la cadena ocupa siete caracteres con lo cual hay que mandar un 00 al final.
push 00737365h ;caracteres de exitprocess
push 636f7250h
push 74697845h
mov ecx,esp
y ese es el problema ese caracter nulo. Sospecho que en linux igual no hay ese problema, pero tampoco estoy muy seguro.
ah! y Nox gracias por tu ayuda! por cierto vaya N más rara jeje.
el code que te pase funciona como te dije fijate si queda desbalanceada la pila o antes de eso le podes reservar espacio en la pila luego la balanceas.. con lo que te doy ya tenes una idea si no quieres hacer mov puedes hacer que esp apunte 3 posiciones antes con un lea, y luego haces el push te evitas de hacer mov, y luego restauras a esp, en fin miles de ideas, te recomiendo que usaes algun debugger asi practica practica hasta que te salga!
Salu2!
ok, Nox. Ya había conseguido antes hacerlo funcionar pero introducía la cadena en la pila de otra manera y quedaba la pila desbalanceada (aunque funcionaba igual sin problemas). no obstante de esta manera es más sencillo.
Un saludo!
bien bien pero parece que no resolvimos ese problema de tu code el del principio mira yo use este code para loadlibrary, y me funciona perfectamente checa como le reservo la pila... si solo cambias los caracteres debe funcionar
;00402044 4C 6F 61 64 4C 69 62 72 LoadLibr
;0040204C 61 72 79 41 00 aryA.
mov ebp,esp; ebp puntero al stack
sub esp, 0Dh; reservamos espacio
xor ecx,ecx
mov byte ptr [ebp - 0Dh], 4Ch
mov byte ptr [ebp - 0Ch], 6Fh
mov byte ptr [ebp - 0Bh], 61h
mov byte ptr [ebp - 0Ah], 64h
mov byte ptr [ebp - 09h], 4Ch
mov byte ptr [ebp - 08h], 69h
mov byte ptr [ebp - 07h], 62h
mov byte ptr [ebp - 06h], 72h
mov byte ptr [ebp - 05h], 61h
mov byte ptr [ebp - 04h], 72h
mov byte ptr [ebp - 03h], 79h
mov byte ptr [ebp - 02h], 41h
mov byte ptr [ebp - 01h], cl
lea ecx, dword ptr [ebp - 0Dh]
push ecx
push edx; BaseKernel
call ebx; GPA
add esp, 0Dh; Balanceamos la pila
pd: la pila se balancea para poder evitar errores, puede que haya un tipo de seguridad que mire la pila, y si a la hora de volver por ejemplo al programa la pila no esta como antes crash! y aunque no te de ese problema cuando lo haces una aplicacion autonoma, es por buena costumbre que lo harias :).
Salu2!
Os habéis ido del tema, no lo habéis entendido...
xor eax, eax
push eax
push byte 0x63; 'c'
push byte 0x65; 'e'
push byte 0x78; 'x'
push byte 0x45; 'E'
push byte 0x6e; 'n'
push byte 0x69; 'i'
push byte 0x57; 'W'
mov eax, esp
Al introducir "push eax" lo que hacemos es meter el byte nulo, lo que es equivalente a poner "string BLAHBLAH, 0", que es lo que queréis.
Si no lo entendéis, PM.
Un saludo. Sagrini
PS1: He puesto lo de byte para que no haya nulos entre medias, por si acaso...
PS2: Aparte, los pongo uno a uno porque son 7 bytes. Se podrían poner divididos en un WORD y tres bytes, pero no tengo ganas ;)...
Cita de: Sagrini en 2 Abril 2011, 20:56 PM
Os habéis ido del tema, no lo habéis entendido...
xor eax, eax
push eax
push byte 0x63; 'c'
push byte 0x65; 'e'
push byte 0x78; 'x'
push byte 0x45; 'E'
push byte 0x6e; 'n'
push byte 0x69; 'i'
push byte 0x57; 'W'
mov eax, esp
Al introducir "push eax" lo que hacemos es meter el byte nulo, lo que es equivalente a poner "string BLAHBLAH, 0", que es lo que queréis.
Si no lo entendéis, PM.
Un saludo. Sagrini
PS1: He puesto lo de byte para que no haya nulos entre medias, por si acaso...
PS2: Aparte, los pongo uno a uno porque son 7 bytes. Se podrían poner divididos en un WORD y tres bytes, pero no tengo ganas ;)...
Pero si el lío se lo metiste tú pusheando dos dword's al principio, y el quiso hacer lo mismo con una cadena de 7 bytes :xD. Para pushear con bytes, no hay problema, para pushear con dwords puedes hacer lo que te dijo Karcrack de hacer un xor con el 'xoreado' o hacer lo que hizo Nox con un mov. O hacer lo que te dije yo, que ocupa menos con cadenas de más de 7 bytes, pero que deja nulos.
Saludos
Cita de: [Zero] en 3 Abril 2011, 01:08 AM
Pero si el lío se lo metiste tú pusheando dos dword's al principio, y el quiso hacer lo mismo con una cadena de 7 bytes :xD. Para pushear con bytes, no hay problema, para pushear con dwords puedes hacer lo que te dijo Karcrack de hacer un xor con el 'xoreado' o hacer lo que hizo Nox con un mov. O hacer lo que te dije yo, que ocupa menos con cadenas de más de 7 bytes, pero que deja nulos.
Saludos
creo que lo que quiere hacer el es una shellcode, por eso tanto lio de los bytes nullos, si es asi no podria usar el metodo de karcrack ni el tuyo, ya que karcrack usa una direccion creada en la sección .data, y especificamente para ella si el la querra usar G_G, bueno si usa la tuya ya sabemos bytes nullos D:.
Creo que ya sabe que hacer
Salu2!
Cita de: Sagrini en 2 Abril 2011, 20:56 PM
Os habéis ido del tema, no lo habéis entendido...
xor eax, eax
push eax
push byte 0x63; 'c'
push byte 0x65; 'e'
push byte 0x78; 'x'
push byte 0x45; 'E'
push byte 0x6e; 'n'
push byte 0x69; 'i'
push byte 0x57; 'W'
mov eax, esp
Al introducir "push eax" lo que hacemos es meter el byte nulo, lo que es equivalente a poner "string BLAHBLAH, 0", que es lo que queréis.
Si no lo entendéis, PM.
Un saludo. Sagrini
PS1: He puesto lo de byte para que no haya nulos entre medias, por si acaso...
PS2: Aparte, los pongo uno a uno porque son 7 bytes. Se podrían poner divididos en un WORD y tres bytes, pero no tengo ganas ;)...
push byte 57h ; esta instruccion no esta permitida en masm. hay que mandar 4 bytes en cada push.
Cita de: Иōҳ en 30 Marzo 2011, 01:05 AM
bien bien pero parece que no resolvimos ese problema de tu code el del principio mira yo use este code para loadlibrary, y me funciona perfectamente checa como le reservo la pila... si solo cambias los caracteres debe funcionar
;00402044 4C 6F 61 64 4C 69 62 72 LoadLibr
;0040204C 61 72 79 41 00 aryA.
mov ebp,esp; ebp puntero al stack
sub esp, 0Dh; reservamos espacio
xor ecx,ecx
mov byte ptr [ebp - 0Dh], 4Ch
mov byte ptr [ebp - 0Ch], 6Fh
mov byte ptr [ebp - 0Bh], 61h
mov byte ptr [ebp - 0Ah], 64h
mov byte ptr [ebp - 09h], 4Ch
mov byte ptr [ebp - 08h], 69h
mov byte ptr [ebp - 07h], 62h
mov byte ptr [ebp - 06h], 72h
mov byte ptr [ebp - 05h], 61h
mov byte ptr [ebp - 04h], 72h
mov byte ptr [ebp - 03h], 79h
mov byte ptr [ebp - 02h], 41h
mov byte ptr [ebp - 01h], cl
lea ecx, dword ptr [ebp - 0Dh]
push ecx
push edx; BaseKernel
call ebx; GPA
add esp, 0Dh; Balanceamos la pila
pd: la pila se balancea para poder evitar errores, puede que haya un tipo de seguridad que mire la pila, y si a la hora de volver por ejemplo al programa la pila no esta como antes crash! y aunque no te de ese problema cuando lo haces una aplicacion autonoma, es por buena costumbre que lo harias :).
Salu2!
este metodo es el que utilizo yo, solo que cuando balanceo la pila incomprensiblemente no me funciona. En cambio cuando no la balanceo si funciona. Algo debe de andar mal en la pila, aquí pongo los codigos:
este funciona (y eso que no balanceo la pila):
.386
.model flat, stdcall ;32 bit memory model
option casemap :none ;case sensitive
assume fs:nothing
.code
start:
; ******************************************
; 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
; ******************************************************************************************************************************************
; programa principal
; ******************************************************************************************************************************************
mov esi, [esp];************************************************************obtener dirección de winexec**********************************
xor dl, dl
sub esp, 0bh ; dejamos espacio en la pila para meter nuestra cadena
mov byte ptr [ebp-08h], 57h ; 'W'
mov byte ptr [ebp-07h], 69h ; 'i'
mov byte ptr [ebp-06h], 6eh ; 'n'
mov byte ptr [ebp-05h], 45h ; 'E'
mov byte ptr [ebp-04h], 78h ; 'x'
mov byte ptr [ebp-03h], 65h ; 'e'
mov byte ptr [ebp-02h], 63h ; 'c'
mov byte ptr [ebp-01h], dl ; 0x00
lea ecx, [ebp-08h] ; cargamos la direccion que apunta a nuestra cadena
push ecx
push esi ;dirección base de kernel32
mov ebx,eax
call eax ; llamamos a getprocadress
xor dl, dl;******************************************************************ejecutar winexec(calc.exe)*********************************
sub esp, 11h ; dejamos espacio en la pila para meter nuestra cadena
mov byte ptr [ebp-09h], 63h ; 'c'
mov byte ptr [ebp-08h], 61h ; 'a'
mov byte ptr [ebp-07h], 6Ch ; 'l'
mov byte ptr [ebp-06h], 63h ; 'c'
mov byte ptr [ebp-05h], 2Eh ; '.'
mov byte ptr [ebp-04h], 65h ; 'e'
mov byte ptr [ebp-03h], 78h ; 'x'
mov byte ptr [ebp-02h], 65h ; 'e'
mov byte ptr [ebp-01h], dl ; 0x00
lea ecx, [ebp-09h] ; cargamos la direccion que apunta a nuestra cadena
push 5 ;parametro de winexec (show)
push ecx
call eax ;llamamos a winexec
xor dl, dl;******************************************************************salir del programa con exitprocess*************************
sub esp, 20h ; dejamos espacio en la pila para meter nuestra cadena
mov byte ptr [ebp-12h], 45h ; 'E'
mov byte ptr [ebp-11h], 78h ; 'x'
mov byte ptr [ebp-10h], 69h ; 'i'
mov byte ptr [ebp-0fh], 74h ; 't'
mov byte ptr [ebp-0eh], 50h ; 'P'
mov byte ptr [ebp-0dh], 72h ; 'r'
mov byte ptr [ebp-0ch], 6fh ; 'o'
mov byte ptr [ebp-0bh], 63h ; 'c'
mov byte ptr [ebp-0ah], 65h ; 'e'
mov byte ptr [ebp-09h], 73h ; 's'
mov byte ptr [ebp-08h], 73h ; 's'
mov byte ptr [ebp-07h], dl ; '0'
lea ecx, [ebp-12h] ; cargamos la direccion que apunta a nuestra cadena
push ecx
push esi ;dirección base de kernel32
call ebx ; llamamos a getprocadress
;obtenemos direccion de exitprocess
xor ecx, ecx
push ecx
call eax ;llamamos a exitprocess
end start
;ml -c -coff -Cp c:\shellcodes\shellcode.asm
;link /SUBSYSTEM:WINDOWS shellcode.obj
y este encambio no funciona y eso que sí, balanceo la pila y guardo el espacio justo para cada cadena:
.386
.model flat, stdcall ;32 bit memory model
option casemap :none ;case sensitive
assume fs:nothing
.code
start:
; ******************************************
; 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
; ******************************************************************************************************************************************
; programa principal
; ******************************************************************************************************************************************
mov esi, [esp];************************************************************obtener dirección de winexec**********************************
push ebp
mov ebp, esp
xor ecx,ecx
xor dl, dl
sub esp, 08h ; dejamos espacio en la pila para meter nuestra cadena
mov byte ptr [ebp-08h], 57h ; 'W'
mov byte ptr [ebp-07h], 69h ; 'i'
mov byte ptr [ebp-06h], 6eh ; 'n'
mov byte ptr [ebp-05h], 45h ; 'E'
mov byte ptr [ebp-04h], 78h ; 'x'
mov byte ptr [ebp-03h], 65h ; 'e'
mov byte ptr [ebp-02h], 63h ; 'c'
mov byte ptr [ebp-01h], dl ; 0x00
lea ecx, dword ptr [ebp-08h] ; cargamos la direccion que apunta a nuestra cadena
mov ebx,eax ;movemos getprocadress a ebx porque al volver del call se sobreescribe eax
push ecx
push esi ;dirección base de kernel32
call eax ; llamamos a getprocadress
add esp, 08h
pop ebp
push ebp;******************************************************************ejecutar winexec(calc.exe)*********************************
mov ebp, esp
xor ecx,ecx
xor dl, dl
sub esp, 09h ; dejamos espacio en la pila para meter nuestra cadena
mov byte ptr [ebp-09h], 63h ; 'c'
mov byte ptr [ebp-08h], 61h ; 'a'
mov byte ptr [ebp-07h], 6Ch ; 'l'
mov byte ptr [ebp-06h], 63h ; 'c'
mov byte ptr [ebp-05h], 2Eh ; '.'
mov byte ptr [ebp-04h], 65h ; 'e'
mov byte ptr [ebp-03h], 78h ; 'x'
mov byte ptr [ebp-02h], 65h ; 'e'
mov byte ptr [ebp-01h], dl ; 0x00
lea ecx, dword ptr [ebp-09h] ; cargamos la direccion que apunta a nuestra cadena
push 5 ;parametro de winexec (show)
push ecx
call eax ;llamamos a winexec
add esp, 09h
pop ebp
push ebp;******************************************************************salir del programa con exitprocess*************************
mov ebp, esp
xor ecx,ecx
xor dl, dl
sub esp, 0ch ; dejamos espacio en la pila para meter nuestra cadena
mov byte ptr [ebp-0ch], 45h ; 'E'
mov byte ptr [ebp-0bh], 78h ; 'x'
mov byte ptr [ebp-0ah], 69h ; 'i'
mov byte ptr [ebp-09h], 74h ; 't'
mov byte ptr [ebp-08h], 50h ; 'P'
mov byte ptr [ebp-07h], 72h ; 'r'
mov byte ptr [ebp-06h], 6fh ; 'o'
mov byte ptr [ebp-05h], 63h ; 'c'
mov byte ptr [ebp-04h], 65h ; 'e'
mov byte ptr [ebp-03h], 73h ; 's'
mov byte ptr [ebp-02h], 73h ; 's'
mov byte ptr [ebp-01h], dl ; '0'
lea ecx, dword ptr [ebp-0ch] ; cargamos la direccion que apunta a nuestra cadena
push ecx
push esi ;dirección base de kernel32
call ebx ; llamamos a getprocadress
;obtenemos direccion de exitprocess
xor ecx, ecx
push ecx
call eax ;llamamos a exitprocess
add esp, 0ch
pop ebp
end start
;ml -c -coff -Cp c:\shellcodes\shellcode_pila_balanceada.asm
;link /SUBSYSTEM:WINDOWS shellcode_pila_balanceada.obj
Cita de: Иōҳ en 3 Abril 2011, 06:38 AM
creo que lo que quiere hacer el es una shellcode, por eso tanto lio de los bytes nullos, si es asi no podria usar el metodo de karcrack ni el tuyo, ya que karcrack usa una direccion creada en la sección .data, y especificamente para ella si el la querra usar G_G, bueno si usa la tuya ya sabemos bytes nullos D:.
Creo que ya sabe que hacer
Salu2!
No, Karcrack no usa nada de la sección .data :S. Y bueno, si la shellcode no es para hacer malware, debería de ir en Bugs y Exploits, no aquí, así que bueno, para la próxima ya sabes.
Saludos
Cita de: [Zero] en 3 Abril 2011, 16:25 PM
No, Karcrack no usa nada de la sección .data :S. Y bueno, si la shellcode no es para hacer malware, debería de ir en Bugs y Exploits, no aquí, así que bueno, para la próxima ya sabes.
Saludos
y nMagic donde lo declara? D:.. no se tal vez entendi mal :-\, esta usando una direccion de memoria de su propia aplicacion pero para una shellcode creo que no sirviria no se corrijeme nunca he codeado una D:.
@black_flowers creo que le llevas dedica muxo tiempo, y esto amerita que te deje este code.. miralo y espero que resuelvas tus problemas :xD.
Inyeccion PROC
cdq; EDX=0
mov EDX, fs:[edx+30h]; EDX = &PEB
mov eax, [edx+0Ch]; EAX = PEB->PPEB_LDR_DATA
mov esi, [eax+1Ch]; ESI = &PEB->PPEB_LDR_DATA->InInitializationOrderModuleList[0]
SiguienteModulo:
mov eax, [esi+08h]; EAX = PEB->PPEB_LDR_DATA->InInitializationOrderModuleList[i].BaseAddress
mov edi, [esi+20h]; EDI = PEB->PPEB_LDR_DATA->InInitializationOrderModuleList[i]. NameModule
mov esi, [esi]; ESI = PEB->PPEB_LDR_DATA->InInitializationOrderModuleList[i].flink (NextModule)
cmp byte ptr[edi+6*2], '3' ;// NameModule[6] == '3' ¿?
jne SiguienteModulo
mov ebp,eax ; EBP = base kernel32
assume eax: ptr IMAGE_DOS_HEADER
add eax,[eax].e_lfanew; BaseKernel32 + 3Ch = PEHeader, Como es RVA + BaseKernel32
assume eax:ptr IMAGE_NT_HEADERS
mov edi,[eax].OptionalHeader.DataDirectory[0].VirtualAddress; PEHeader + 78h = .edata
add edi,ebp ;Como es RVA
assume edi:ptr IMAGE_EXPORT_DIRECTORY
mov esi,[edi].AddressOfNames; .edata + 20h = AddressOfNames
add esi,ebp ; Como es RVA
xor edx,edx
assume eax:nothing ; Para Evitar Errores
Busqueda:
mov eax,[esi]
add eax,ebp
cmp word ptr [eax+0Ch],"ss"
jne Siguiente
cmp dword ptr [eax+04h], "Acor"
jne Siguiente
cmp dword ptr [eax+00h], "PteG"
jne Siguiente
cmp dword ptr [eax+08h], "erdd"
jne Siguiente
mov eax,[edi].AddressOfNameOrdinals; .edata + 24h = AofNamesOrdinal
add eax,ebp ; Como es RVA
movzx ebx,word ptr [edx*2+eax]; Como es una entrada de WORDS multiplico * 2 al contador
; EBX = Asi obtendremos el puntero al ordinal de la funcion GetProcAddress
mov eax,[edi].AddressOfFunctions; .edata + 1Ch = AddressOfFunction
add eax,ebp ; RVA ._.
;EAX = AddressOfFunction
;EBX Puntero al ordinal
;Multiplicamos *4 el puntero al ordinal de GPA porque la tabla es de dwords.
mov ebx,[ebx*4+eax]; EBX = RVA de GetProcAddress
add ebx,ebp ; EBX = GetProcAddress
jmp Listo ; Salimos :)
Siguiente:
add esi,4
inc edx; EDX = CONTADOR
cmp edx,[edi].NumberOfNames
jne Busqueda
Listo:
assume edi:nothing ; Evitamos Errores D=
mov edx, ebp
;00402044 4C 6F 61 64 4C 69 62 72 LoadLibr
;0040204C 61 72 79 41 00 aryA.
mov ebp, esp
sub ebp, 10h
mov byte ptr [ebp - 0Dh], 4Ch
mov byte ptr [ebp - 0Ch], 6Fh
mov byte ptr [ebp - 0Bh], 61h
mov byte ptr [ebp - 0Ah], 64h
mov byte ptr [ebp - 09h], 4Ch
mov byte ptr [ebp - 08h], 69h
mov byte ptr [ebp - 07h], 62h
mov byte ptr [ebp - 06h], 72h
mov byte ptr [ebp - 05h], 61h
mov byte ptr [ebp - 04h], 72h
mov byte ptr [ebp - 03h], 79h
mov byte ptr [ebp - 02h], 41h
mov byte ptr [ebp - 01h], 00h
lea ecx, dword ptr [ebp - 0Dh]
push ecx
push ebp
call ebx;
nop
nop
ret
Inyeccion endp
pd: agradezco la portabilidad ha... YSK... me ayudo sobre el peb :)
pd2: cuando hagas una shellcode si no me equivoco tiene que ser lo menos pesado posible (perdon por el horro de terminos =B), asi que como veras pasarle de manara la string no es muy buena que digamos asi que podes usar el no se el mov que te dije al principio.
Salu2! Nox
gracias por el codigo nox, me viene de perlas para lo proximo que quiero hacer en donde voy a necesitar loadlibrary.
Por cierto ya he encontrado donde estaba el fallo con mi codigo anterior. Aunque no entiendo muy bienel porqué sé que era la pila que quedaba desbalanceada y petaba al llamar a la segunda funcion: winexec(calc.exe)
entonces esto era lo que estaba mal:
push ebp
mov ebp, esp
xor ecx,ecx
xor dl, dl
sub esp, 08h ; dejamos espacio en la pila para meter nuestra cadena
mov byte ptr [ebp-08h], 57h ; 'W'
mov byte ptr [ebp-07h], 69h ; 'i'
mov byte ptr [ebp-06h], 6eh ; 'n'
mov byte ptr [ebp-05h], 45h ; 'E'
mov byte ptr [ebp-04h], 78h ; 'x'
mov byte ptr [ebp-03h], 65h ; 'e'
mov byte ptr [ebp-02h], 63h ; 'c'
mov byte ptr [ebp-01h], dl ; 0x00
lea ecx, dword ptr [ebp-08h] ; cargamos la direccion que apunta a nuestra cadena
mov ebx,eax ;movemos getprocadress a ebx porque al volver del call se sobreescribe eax
push ecx
push esi ;dirección base de kernel32
call eax ; llamamos a getprocadress
add esp, 08h
pop ebp
y así está bien:
mov esi, [esp]
push ebp
mov ebp, esp
xor ecx,ecx
xor dl, dl
sub esp, 07h ; dejamos espacio en la pila para meter nuestra cadena
mov byte ptr [ebp-07h], 57h ; 'W'
mov byte ptr [ebp-06h], 69h ; 'i'
mov byte ptr [ebp-05h], 6eh ; 'n'
mov byte ptr [ebp-04h], 45h ; 'E'
mov byte ptr [ebp-03h], 78h ; 'x'
mov byte ptr [ebp-02h], 65h ; 'e'
mov byte ptr [ebp-01h], 63h ; 'c'
mov byte ptr [ebp-00h], dl ; 0x00
lea ecx, dword ptr [ebp-07h]
mov ebx,eax
push ecx
push esi ;dirección base de kernel32
call eax ; llamamos a getprocadress
add esp, 07h
pop ebp
había alguna clase de problema en el ajuste de las cadenas en la pila,
gracias x todo, y un saludo!