1. 보호기법 확인
$ checksec simplerop
NX 걸려있다. Stack에 읽기만 가능하고 쉘코드 등을 올려서 실행할 수 없다.
따라서 쓰기 권한의 영역을 찾아서 그 섹션에 쉘코드를 넣고, mprotect 함수로
mprotect(writableArea, len(shellcode), 7)로 실행권한을 주면 쉘코드가 실행될 수 있다.
2. IDA – pseudo code 확인
V4 변수 크기는 20 바이트인데 100 바이트를 입력받아서 overflow 취약점 존재
3. v4 에서 return address 까지 거리
Bp 1 : main 함수 첫 번째 명령어 -> return address
Bp 2 : read 함수 호출 전 -> v4 시작 주소
Read 함수 호출 전 eax를 넣으므로 eax 값을 확인해보면 v4의 시작주소 알 수 있다.
Return address – v4 시작주소 = 32 -> v4(20) + dummy(4) + SFP(4) + return address(4)
4. ROP 과정
1. read(0, bss, len(shellcode)) : bss 영역에 shellcode 넣음
2. mprotect(bss, 0x1000, 7) : shellcode가 들어가있는 bss 영역에 0x1000 바이트만큼 rwx 권한 부여
3. bss : shellcode가 있는 bss 섹션 실행해서 쉘코드 실행
*“pop;pop;pop;ret” 가젯의 사용 :
POP 명령어의 역할은 ESP 레지스터 값을 증가시켜서 함수를 연속으로 호출하고,
호출할 함수에 전달될 인자 값을 레지스터에 저장한다.
RET은 다음으로 사용할 함수를 호출하기 위해 필요
5. 구해야 하는 것
1. read, mprotect 주소
2. "pop;pop;pop;ret" 주소 => read와 mprotect 함수 인자가 3개이므로 gadget은 “pop;pop;pop;ret”
호출하는 read, mprotect 함수의 인자 값을 저장하기 위해 필요
3. bss 주소 => mprotect 함수가 호출 프로세스의 메모리 페이지들에 대한 접근 보호를 변경하는데, 이때 첫 번째 인자인 주소는 페이지 경계에 맞게 정렬되어야 한다고 한다.
따라서 하위 3bit를 “000”으로 맞춘다.
6. read, mprotect, “pop;pop;pop;ret” 주소
read 함수 주소 : 0x806cd50
mprotect 함수 주소 : 0x806d870
0x80e9000-0x80eb000 영역이 writable한 공간이다.
$ objdump -h ./simplerop
그리고 “.bss” 섹션은 0xeaf80부터 크기가 136c이다.
1000 단위로 “.bss” 섹션 주소는 0x80ec000으로 선택한다.
$ ./rp-lin-x86 -f ./simplerop -r 4 | grep "pop" "pop"
“pop;pop;pop;ret” gadgets 주소는 위의 주소 중 아무거나 선택한다.
7. exploit code
$ vi exploit.py
ELF(“./simplerop”)가 있어야 exploit이 되고 EOF를 안 받았다.
Address나 symbols 구하려고 필요할 때만 쓰는 건줄 알았는데 불러와야 하는 것이었다.
$ vi ex.py
Pwntools의 ROP를 이용해서 간단한 ex 코드도 됐다.
이때도 mprotect 함수의 성질(?)때문에 그냥 e.bss()로 주소를 불러오면 안 되는 것 같고 뒤의 세자리를 000으로 지정해서 주소를 줘야 exploit이 됐다.
8. exploit
$ python exploit.py
$ python ex.py
[Defcon 2015] r0pbaby (0) | 2019.08.16 |
---|---|
[PlaidCTF 2013] ropasaurusrex (0) | 2019.08.15 |
[TAMU 2019] pwn2 (0) | 2019.08.14 |
[TAMU 2019] pwn1 (0) | 2019.08.14 |
[TAMU 2018] pwn4 (0) | 2019.08.10 |