Return Oriented Programming(ROP) _x86
NX bit와 ASLR 보호기법, 코드 서명과 같은 보호기법을 우회할 수 있는 기술
프로그램의 흐름 변경을 위해 Stack Overflow와 같은 취약점을 이용해 콜 스택 통제
→ 주로 스택 기반연산을 하는 코드 가젯(gadgets) 사용
>> RTL + Gadgets
(32bit: 함수의 인자를 스택에 저장)
gadgets
해당 프로그램이 사용하는 메모리에 이미 있는 기계 명령어
일반적으로 "ret"(반환명령어)이 끝으로, 기존 프로그램 또는 공유 라이브러리 코드 내의 서브루틴에 존재
gadgets은 여러 개의 함수를 호출하기 위해 사용한다.
-호출하는 함수의 인자가 3개일 때: "pop; pop; pop; ret"
-호출하는 함수의 인자가 2개일 때: "pop; pop; ret"
-호출하는 함수의 인자가 1개일 때: "pop; ret"
-호출하는 함수의 인자가 없을 경우: "ret"
이 gadgets의 역할을 ESP 레지스터의 값을 증가시키는 것; RTL에 의해 호출되는 함수에 전달되는 인자 값이 저장된 영역을 지나 다음 함수가 호출될 수 있도록 한다.
(*x86 binary에서는 pop 명령어의 피연산자 값은 중요하지 않다)
여러 개의 함수를 연속 실행하는 방법
-RTL에서 호출할 함수(주소 값이 저장된)의 다음 영역은 해당 함수가 종료된 후 이동할 Return Address 영역
-return address 영역에 gadgets의 주소를 저장함 >> 다음 함수 호출
PLT & GOT
PLT (Procedure linkage table)
= 동적 링커가 공유 라이브러리 함수를 호출하기 위한 코드 저장 >> ".plt" 섹션에 저장
GOT (Global offset table)
= 동적 링커에 의해 공유 라이브러리에서 호출할 함수의 주소를 저장 >> ".got.plt"섹션에 저장
--> 공격자들의 공격 대상이 된다. 주로 힙 ".bss" exploit에 의해 포인터 값을 변조한다.
Example
$ gcc -m32 -fno-stack-protector -o rop rop.c //x86 binary로 컴파일
esp(0xffffcffc)에 저장된 주소: 0x08048484 (main+42)
esp(0xffffcfa0)에 저장된 값: 0x00000000, 0xffffcfbe, 0x100
buf의 시작주소 (0xffffcffc) - Return Address (0xffffcfbe) = 62 bytes
=> 62개 이상의 문자를 입력함으로써 Return address 영역을 덮어 쓸 수 있음
Exploit Method
1. read 함수를 이용해 "/bin/sh"명령을 쓰기 가능한 메모리 영역에 저장: read(0, writableArea, len(str(binsh)))
2. write 함수를 이용해 read 함수의 .got 영역에 저장된 값 출력: write(1, read_got, len(str(read_got)))
3. read 함수를 이용해 read 함수의 .got 영역에 system 함수의 주소로 덮어씀: read(0, read_got, len(str(read_got)))
4. read 함수를 호출; read.got 영역에 system 함수 주소 저장되어 있어 system 함수가 이어서 호출됨: system(writableArea)
확인할 정보 목록
- "/bin/sh" 명령을 저장할 수 있는 쓰기 가능한 메모리 공간 (writableArea)
- read(), write()함수의 plt, got
- system()함수의 주소
- pop, pop, pop, ret 가젯의 위치
쓰기 가능한 메모리 공간 찾기
0x0804a000~0x0804b000: 쓰기권한이 있음
23(.got.plt), 24(.data) 25(.bss)의 memory address와 size를 확인할 수 있다.
23 .got.plt // 주소: 0x0804a000 // size: 0x18
24 .data // 주소: 0x0804a018 // size: 0x8
25 .bss // 주소: 0x080fa020 // size: 0x4
gadget 찾기 (rp++)
gadget 찾기 (ropsearch)
plt, got address 찾기
(cf. elfsymbol 명령어: peda에서 사용하는 명령어로, elf 파일의 심볼 정보 출력 >> plt 주소를 탐색할 때 좋다)
(다만 pwndbg에는 elfsymbol명령어가 없음 >> pwntools에서 elf.symbols[]로 주소불러올 수 있음)
참고: https://devanix.tistory.com/186
system() address 찾기
read()함수의 주소: 0xf7ed9b00
system()함수의 주소: 0xf7e3eda0
Exploit
'System > System Hacking' 카테고리의 다른 글
SROP x64 (0) | 2020.07.24 |
---|---|
SROP x86 (0) | 2020.07.23 |
SROP (0) | 2020.07.23 |
64bit ROP (0) | 2020.06.14 |
RTL (Return to libc) (0) | 2020.05.24 |