https://dreamhack.io/wargame/challenges/1114
랜덤한 2개의 숫자를 더한 결과가 입력 값과 일치하는지 확인하는 과정을 50번 반복하는 프로그램입니다. 모두 일치하면 flag 파일에 있는 플래그를 출력합니다. 알맞은 값을 입력하여 플래그를 획득하세요.
플래그 형식은 DH{...} 입니다.
Hint : pwntools

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;
}
1초동안 50번, 연산을 해야 결과가 출력됩니다. 인간의 힘으로는 풀 수 없는 문제입니다.
스템 해킹 문제를 빠르고 효율적으로 풀기 위해 설계된 파이썬(Python) 라이브러리이자 프레임워크입니다.
해킹 스크립트를 작성하기 위한 강력한 도구 모음이라고 생각하면 됩니다.
pwntools 툴을 활용해 1초에 50번 계산하는 코드를 짜고, 문제를 풀어야 함을 유추해볼 수 있었습니다.
우분투에서는 현재 사용자가 임의로 파이썬 환경에 라이브러리를 설치하는걸 막고 있습니다. 따라서 바로 명령어를 입력하였을 땐 설치가 되지 않습니다. 따라서 우분투 내에서 가상환경인 venv를 활용하여 pwntools 을 설치해야 합니다.
python3 -m venv venv # 가상 환경 생성
source venv/bin/activate # 가상 환경 활성화
pip install pwntools # pwntools 설치
위의 명령어를 차례로 입력하여 venv 와 pwntools 을 설치합니다.

우분투 내의 텍스트 편집기를 열고, 저장을 파일명.py 로 하면 파이썬 코드를 저장,활용할 수 있습니다.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from pwn import * # pwntools를 쓰기 위해 호출해야 함
import re
# 연결 설정 (로컬 파일 또는 원격 서버)
# ------------------------------------
HOST = 'host8.dreamhack.games' # 실제 서버 주소로 변경하세요
PORT = 24238 # 실제 포트 번호로 변경하세요
# ------------------------------------
def solve_math_challenge():
# 서버에 연결을 시도합니다.
try:
p = remote(HOST, PORT)
print(f"[*] 연결 성공! {HOST}:{PORT}")
except Exception as e:
print(f"[ERROR] 서버 연결 실패: {e}")
return
print("[*] 50개의 덧셈 문제를 시작합니다.")
# 1. 첫 번째 문제 수신 (루프 진입 전에 한 번만 수행)
# 서버가 시작하면 바로 첫 번째 문제를 보냅니다.
try:
line = p.recvline().decode('utf-8').strip()
except EOFError:
print("[-] 초기 문제 수신 실패 또는 연결 종료.")
p.close()
return
# 50번 반복 (문제는 총 50개)
for i in range(50):
try:
# 2. 현재 라인 파싱
match = re.search(r'(\d+)\+(\d+)=\?', line)
if not match:
# 파싱에 실패하면, 서버가 이상한 메시지(TIME OUT 등)를 보낸 것입니다.
print(f"[-] 문제 파싱 실패: {line}")
p.close()
return
num1 = int(match.group(1))
num2 = int(match.group(2))
answer = num1 + num2
# 3. 정답 전송
p.sendline(str(answer).encode())
print(f"[+] {i+1}/50: {num1}+{num2}={answer} -> 전송 성공")
# 4. 서버 응답 확인 및 다음 문제 수신
# 서버는 답을 받으면 '아무 응답 없이' 바로 다음 문제("X+Y=?")를 보냅니다.
# recvline()을 사용하여 다음 문제 프롬프트를 한 줄 읽습니다.
line = p.recvline(timeout=1.5).decode('utf-8').strip()
# 응답에 "Wrong"이나 "TIME OUT"이 포함되어 있는지 확인합니다.
if "Wrong" in line or "TIME OUT" in line:
print(f"[-] 서버 응답 (오답/시간 초과): {line}")
p.close()
return
# line 변수에는 이제 다음 문제("numX+numY=?")가 들어 있습니다.
except EOFError:
print("[-] 50문제 해결 전에 연결이 끊어졌습니다 (EOF).")
p.close()
return
except PwnlibException as e:
# 50문제를 모두 풀고 나면, 서버가 더 이상 출력을 보내지 않아 이 예외로 빠집니다.
print("[*] 모든 문제를 풀었거나, 통신 오류 발생.")
break
# 50문제를 모두 풀었다면, 최종 플래그를 받아야 합니다.
print("[*] 최종 응답을 기다립니다...")
# 서버가 플래그 출력 전에 보낼 수 있는 "Nice!"를 포함한 모든 잔여 출력을 읽습니다.
# .recvall()로 연결이 끊길 때까지 모든 데이터를 읽습니다.
final_output = p.recvall(timeout=2).decode('utf-8', errors='ignore').strip()
p.close()
# 출력에서 플래그 패턴을 찾습니다.
if "Nice!" in final_output:
flag_lines = [line for line in final_output.split('\n') if line and "Nice!" not in line]
if flag_lines:
flag = flag_lines[0].strip()
print("\n" + "="*50)
print(f"[SUCCESS] 플래그를 찾았습니다: {flag}")
print("="*50 + "\n")
return
print("\n" + "="*50)
print("[-] 플래그를 찾지 못했습니다. 최종 응답:")
print(final_output)
print("="*50 + "\n")
if __name__ == "__main__":
solve_math_challenge()
python3 dreamhack.py # dreamhack.py : 내가 설정한 파이썬 코드 파일 이름.
실행하면, 성공적으로 플래그를 획득할 수 있었습니다.

+) 플래그를 찾았는데 왜 찾지 못했다고 뜨는지는 잘 모르겠습니다….. 아마 코드 문제인 것 같은데, 플래그 자체는 획득 완료했습니다!
num1 + num2 = ?) sent by the service; each iteration sets alarm(1), giving only 1 second per question. pwn.remote() to connect, recvline() + regex (\d+)\+(\d+)=\? to parse each problem, compute the sum, and sendline() the answer immediately. Nice! and the flag (format DH{...}).