๐๏ธ Access
๋๋คํ 2๊ฐ์ ์ซ์๋ฅผ ๋ํ ๊ฒฐ๊ณผ๊ฐ ์ ๋ ฅ ๊ฐ๊ณผ ์ผ์นํ๋์ง ํ์ธํ๋ ๊ณผ์ ์ 50๋ฒ ๋ฐ๋ณตํ๋ ํ๋ก๊ทธ๋จ์ ๋๋ค. ๋ชจ๋ ์ผ์นํ๋ฉด flag ํ์ผ์ ์๋ ํ๋๊ทธ๋ฅผ ์ถ๋ ฅํฉ๋๋ค. ์๋ง์ ๊ฐ์ ์ ๋ ฅํ์ฌ ํ๋๊ทธ๋ฅผ ํ๋ํ์ธ์.
ํ๋๊ทธ ํ์์ DH{…} ์ ๋๋ค.
Hint) pwntools
๐พ Exploit Algorithm & Payload
> chall.c
// Name: chall.c
// Compile Option: gcc chall.c -o chall -fno-stack-protector
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#define FLAG_SIZE 0x45
void alarm_handler() {
puts("TIME OUT");
exit(1);
}
void initialize() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
signal(SIGALRM, alarm_handler);
}
int main(void) {
int fd;
char *flag;
initialize();
srand(time(NULL));
flag = (char *)malloc(FLAG_SIZE);
fd = open("./flag", O_RDONLY);
read(fd, flag, FLAG_SIZE);
close(fd);
int num1 = 0;
int num2 = 0;
int inpt = 0;
for (int i = 0; i < 50; i++){
alarm(1);
num1 = rand() % 10000;
num2 = rand() % 10000;
printf("%d+%d=?\n", num1, num2);
scanf("%d", &inpt);
if(inpt != num1 + num2){
printf("Wrong...\n");
return 0;
}
}
puts("Nice!");
puts(flag);
return 0;
}
> chall
> flag
#1
: ๋ฌธ์ ๋ฅผ ๋ค์ด๋ฐ์์ ํ์ด๋๋๋ ์ด๋ฏธ ์ปดํ์ผ ํ์ผ์ด ์์๊ธฐ ๋๋ฌธ์ ๋ฐ๋ก ์ฝ๋ ์ด์
๋ถ์์ด ๊ฐ๋ฅํ๋ค.
(๋ง์ฝ ์์๋ค๋ฉด gcc chall.c -o chall -fno-stack-protector)
: ์ด๋ฅผ ํ์ฉํ์ฌ ๋ช ๋ น์ด์ ์คํ๋ง๋ค ๋ ์ง์คํฐ, ์คํ, ์คํ ์ค์ธ ์ฝ๋์ ์ ๋ณด...๋ฅผ ๋ค์ํ๊ฒ ํ์ธํ๋ค.
readelf -h chall
: ์ง์ ์ ๊ฐ์ ํ์ธํ๊ณ ๋ถ์์ ์์ํ๋ค.
#2
: ์ฝ๋๋ฅผ ๋ถ์ํ์ ๋, alarm_handler()์ด ์ฌ์ฉ์์ ์ ํ ์๊ฐ์ ๋ถ์ฌํ๊ณ , ๋ฌด์์ ์์ฑ๋ ๋ ์ซ์๋ฅผ ๋ํ ๊ฐ์ ์ฌ์ฉ์์๊ฒ ์ ๋ ฅ๋ฐ๋ ํ๋ก๊ทธ๋จ์ด๋ค.
: ์ฒ์์๋ ๋ฐ๋ณต๋ฌธ์ ๊ฑฐ์น์ง ์๊ณ jumpํ๋ค๋ฉด ๋ฐ๋ก flag๋ฅผ ์ป์ ์ ์์ง ์์๊น ์ถ์์ง๋ง ์ป์ง ๋ชปํ๋ค.
: ๊ทธ๋ฐ๋ฐ ์ฌ์ฉ์๊ฐ 50๋ฒ์ ๋ง์ ๋ฌธ์ ๋ฅผ ๋ชจ๋ ์ฌ๋ฐ๋ฅด๊ฒ ํ๋ฉด ํ๋๊ทธ๋ฅผ ์ถ๋ ฅํ๋ ๊ทธ๋ ์ง ์์ผ๋ฉด ์ถ๋ ฅํ์ง ์์์ ์ ์ ์๋ค.
* issue) ์ฒ์ ๋ฐ๋ณต๋ฌธ ๊ฑฐ์น์ง ์๊ณ flag๋ฅผ ํ์ธํ๊ธฐ ์ํด ๋ฐ๋ณต๋ฌธ ์์์ ๊ณผ ๋๋๋ ์ง์ ์ ์ค๋จ์ ์ผ๋ก ์ก์ ํ, exploit code๋ฅผ ์์ฑํ์ผ๋ ์ณ์ง ์์์ ๊นจ๋ฌ์์.
๐Analysis and results for obtaining the Flag DH{…}
# ์๊ฒฉ ์๋ฒ์ ์ฐ๊ฒฐ
conn = remote(['address'], [port number])
for _ in range(50):
question = conn.revline().decode().strip()
num_str, _ = quetion.split("=")
num1, num2 = map(int, num_str.split('+'))
conn.sendline(str(num1 + num2))
print(conn.revall().decode())
1) from pwn import *: pwn ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ํฌํธ. ๋ฐ์ด๋๋ฆฌ ์ต์คํ๋ก์ดํ ์ด์ ๊ณผ ๋ฆฌ๋ฒ์ค ์์ง๋์ด๋ง์ ์ํ ๋๊ตฌ ์ ๊ณต.
2) conn = remote(['address'], [port number]): ์๊ฒฉ ์๋ฒ์ ์ฐ๊ฒฐ. 'address'์ 'port number'๋ ์ค์ ์๋ฒ์ ์ฃผ์์ ํฌํธ ๋ฒํธ.
3) question = conn.revline().decode().strip(): ์๋ฒ๋ก๋ถํฐ ํ ์ค ์์ ํ๊ณ , ์ด๋ฅผ ๋์ฝ๋ํ์ฌ ๋ฌธ์์ด๋ก ๋ณํ, ์ ๋์ ๊ณต๋ฐฑ์ ์ ๊ฑฐ.
4) num_str, _ = question.split("="): ์์ ํ ๋ฌธ์์ด์ '=' ๊ธฐํธ๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ถ๋ฆฌ, ๋ถ๋ฆฌํ ์ฒซ ๋ฒ์งธ ๋ถ๋ถ์ num_str์ ์ ์ฅ.
5) num1, num2 = map(int, num_str.split('+')): num_str์ '+' ๊ธฐํธ๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ถ๋ฆฌ, ๋ถ๋ฆฌํ ๊ฐ ๋ถ๋ถ์ ์ ์๋ก ๋ณํ, ์ด๋ฅผ num1๊ณผ num2์ ์ ์ฅ.
6) conn.sendline(str(num1 + num2)): num1๊ณผ num2๋ฅผ ๋ํ ๊ฒฐ๊ณผ๋ฅผ ๋ฌธ์์ด๋ก ๋ณํ, ์ด๋ฅผ ์๋ฒ์ ์ ์ก.
7) print(conn.revall().decode()): ์๋ฒ๋ก๋ถํฐ ์์ ํ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ๋์ฝ๋ํ์ฌ ์ถ๋ ฅ.