However, there is a more simple way to accomplish this job. We can use the linux system call.
In linux, when you want to use a system call in assembly, just use the int $0x80.
The system call number is store in the %eax, and the parameter of the system call is store in the %ebx and so on.
Ok, it's time to use these information and write them into shell code.
First write a normal program and use inline assembly in the program.
exit.c
int main(){ __asm__("movw $1, %eax;\ movw $0, %ebx;\ int $0x80;"); return 0; }
and now compile it with the following command.
gcc -static -g -o exit.out exit.c
objdump -d exit.out >> dump.txt
dump.txt main function
080482c0 <main>: 80482c0: 55 push %ebp 80482c1: 89 e5 mov %esp,%ebp 80482c3: b8 01 00 00 00 mov $0x1,%eax 80482c8: bb 00 00 00 00 mov $0x0,%ebx 80482cd: cd 80 int $0x80 80482cf: b8 00 00 00 00 mov $0x0,%eax 80482d4: 5d pop %ebp 80482d5: c3 retthe machine code part is what we need.
Let's change them into shell code.
exit_shell.c
char shellcode[]= "\xb8\x01\x00\x00\x00" "\xbb\x00\x00\x00\x00" "\xcd\x80"; int main(){ int *ptr; int i; for(i=0;i<10;i++){ ptr = (int*)&ptr+i; *(ptr) = (int)shellcode; } return 0; }
P.S The for loop is to overflow the return address and transfer the execution flow to the shellcode.
compile it with the following and remember to use the execstack to enable the executable stack.gcc -static -g -o exit_shell.out exit_shell.c
execstack -s exit_shell.out
Result:
now use gdb to verify our thoughts.
(gdb) disassem main Dump of assembler code for function main: 0x080482c0 <+0>: push %ebp 0x080482c1 <+1>: mov %esp,%ebp 0x080482c3 <+3>: sub $0x10,%esp 0x080482c6 <+6>: movl $0x0,-0x8(%ebp) 0x080482cd <+13>: jmp 0x80482eb <main+43> 0x080482cf <+15>: lea -0x4(%ebp),%eax 0x080482d2 <+18>: mov -0x8(%ebp),%edx 0x080482d5 <+21>: shl $0x2,%edx 0x080482d8 <+24>: add %edx,%eax 0x080482da <+26>: mov %eax,-0x4(%ebp) 0x080482dd <+29>: mov -0x4(%ebp),%eax 0x080482e0 <+32>: mov $0x80ce028,%edx 0x080482e5 <+37>: mov %edx,(%eax) 0x080482e7 <+39>: addl $0x1,-0x8(%ebp) 0x080482eb <+43>: cmpl $0x9,-0x8(%ebp) 0x080482ef <+47>: jle 0x80482cf <main+15> 0x080482f1 <+49>: mov $0x0,%eax 0x080482f6 <+54>: leave 0x080482f7 <+55>: ret End of assembler dump. (gdb) b *(main+55) Breakpoint 1 at 0x80482f7: file exit_shell.c, line 12. (gdb) r Breakpoint 1, 0x080482f7 in main () at exit_shell.c:12 12 } (gdb) ni 0x080ce028 in shellcode () (gdb) x/4i $eip => 0x80ce028 <shellcode>: mov $0x1,%eax 0x80ce02d <shellcode+5>: mov $0x0,%ebx 0x80ce032 <shellcode+10>: int $0x80 0x80ce034 <shellcode+12>: add %al,(%eax) (gdb) ni 0x080ce02d in shellcode () (gdb) ni 0x080ce032 in shellcode () (gdb) ni Program exited normally.The result is just what we expected. When main function returned, it will start execute the shellcode.
And exited normally.
video demo is right here (using full screen is better):
http://www.youtube.com/watch?v=I6iYFQl-3kk&feature=player_embedded#at=14
No comments:
Post a Comment