[Dreamhack] Audio Steganography

파일을 다운로드 받아서 압축을 풀면 Hi라는 wav 파일이 나온다.
예전에 비슷한 CTF문제를 오디오 소프트웨어를 사용해서 파형을 다른 형식으로 바꿔줬을 때 플래그를 획득한 경험이 있어서 소프트웨어를 먼저 다운로드 받아줌.

파일을 소프트웨어에 넣어주면 이런 화면이 나옴

왼쪽 네모박스 오른쪽 위에 있는 ... 버튼을 눌러주면 아래와 같은 화면이 나오는데, 스펙트로그램으로 변경해주고 세로로 길게 늘려주면 플래그를 획득할 수 있었음.


[Dreamhack] Hefty Image

파일을 다운로드 받아 압축을 풀면 아래와 같은 사진이 나옴.


용량이 크고 단순한 사진이 아닌 것 같다고 하는 힌트로 보아 내부에 다른 파일이 숨겨져 있을 것 같아 HextEdit으로 열어주었다.

그리고 내부에 헤더와 푸터 시그니처가 다르다면 분리할 수 있게 하려고 했는데, 아래로 쭉 내려보다 보니 플래그와 플래그 파일이 같이 있는 걸 확인할 수 있었다.

[Dreamhack] PEPERO
https://dreamhack.io/wargame/challenges/2425
로그인 | Dreamhack
dreamhack.io

같이 준 파일은 쓸데없는 파일이었다.
서버에 접속해서 우선 힌트를 구매해보자.




입력 창에 음수를 입력하면
값은 0 이상이어야 합니다
라는 클라이언트 측 검증 메시지가 나오고 폼이 제출되지는 않는다.
아마 HTML <input type="number" min="0"> 속성과 자바스크립트의 클라이언트 유효성 검사? 때문일 것이다.
하지만 이 검증은 프론트엔드(브라우저)에서만 동작한다.

그렇기 때문에
document.querySelector('input[name="amount"]').removeAttribute('min');
같은 코드를 콘솔창에 입력하고 엔터누르면 빼빼로를 음수만큼 살 수 있게 된다.
즉, 빼빼로가 음수가 되는 만큼 돈을 벌 수 있게 된다.






[Dreamhack] ex-reg-ex

서버 접속한 화면

문제 파일 다운받아서 코드 확인
#!/usr/bin/python3
from flask import Flask, request, render_template
import re
app = Flask(__name__)
try:
FLAG = open("./flag.txt", "r").read() # flag is here!
except:
FLAG = "[**FLAG**]"
@app.route("/", methods = ["GET", "POST"])
def index():
input_val = ""
if request.method == "POST":
input_val = request.form.get("input_val", "")
m = re.match(r'dr\w{5,7}e\d+am@[a-z]{3,7}\.\w+', input_val)
if m:
return render_template("index.html", pre_txt=input_val, flag=FLAG)
return render_template("index.html", pre_txt=input_val, flag='?')
app.run(host="0.0.0.0", port=8000)
정규식 조건을 만족하는 문자열을 입력하면 flag.txt 내용을 그대로 보여주는 구조이다
정규식(Regular Expression, Regex)은 특정한 패턴을 가진 문자열을 찾거나 검사하기 위해 만든 ‘문자열 패턴 언어’
주어진 정규식을 분석해보자
m = re.match(r'dr\w{5,7}e\d+am@[a-z]{3,7}\.\w+', input_val)
| 패턴 | 의미 |
| dr | 문자열은 반드시 dr로 시작해야 함 |
| \w{5,7} | 알파벳/숫자/밑줄로 이루어진 5~7글자 |
| e | 그 다음 문자: e |
| \d+ | 숫자 1개 이상 |
| am | 그다음: am |
| @ | @ 문자가 그대로 |
| [a-z]{3,7} | 소문자 알파벳 3~7글자 |
| \. | '.' 문자 |
| \w+ | 알파벳/숫자/밑줄 1개 이상 |
즉, 전체 패턴은 이런 구조여야 한다
dr + (5~7글자) + e + (숫자들) + am + @ + (소문자 3~7) + . + (영숫자 여러개)
위의 구조를 만족하는 drabcdefe123am@test.com 를 입력해보면 플래그가 출력된다

[Dreamhack] login filtering

<?php
if (isset($_GET['view-source'])) {
show_source(__FILE__);
exit();
}
/*
create table user(
idx int auto_increment primary key,
id char(32),
ps char(32)
);
*/
if(isset($_POST['id']) && isset($_POST['ps'])){
include("./lib.php"); # include for $FLAG, $DB_username, $DB_password.
$conn = mysqli_connect("localhost", $DB_username, $DB_password, "login_filtering");
mysqli_query($conn, "set names utf8");
$id = mysqli_real_escape_string($conn, trim($_POST['id']));
$ps = mysqli_real_escape_string($conn, trim($_POST['ps']));
$row=mysqli_fetch_array(mysqli_query($conn, "select * from user where id='$id' and ps=md5('$ps')"));
if(isset($row['id'])){
if($id=='guest' || $id=='blueh4g'){
echo "your account is blocked";
}else{
echo "login ok"."<br />";
echo "FLAG : ".$FLAG;
}
}else{
echo "wrong..";
}
}
?>
<!DOCTYPE html>
<style>
* {margin:0; padding:0;}
body {background-color:#ddd;}
#mdiv {width:200px; text-align:center; margin:50px auto;}
input[type=text],input[type=[password] {width:100px;}
td {text-align:center;}
</style>
<body>
<form method="post" action="./">
<div id="mdiv">
<table>
<tr><td>ID</td><td><input type="text" name="id" /></td></tr>
<tr><td>PW</td><td><input type="password" name="ps" /></td></tr>
<tr><td colspan="2"><input type="submit" value="login" /></td></tr>
</table>
<div><a href='?view-source'>get source</a></div>
</form>
</div>
</body>
<!--
you have blocked accounts.
guest / guest
blueh4g / blueh4g1234ps
-->
get source로 들어가면 코드가 나온다. 쿼리문에 해당하는 코드가 php로 보이고 사용자의 입력값의 select로 문으로 들어가 실행된 my_sql이 코드에 나와있으니까 sql injection을 생각해 본다. guest로 제시된 로그인 방법으로 하면 Your account is blocked로 나온다. sql은 대소문자 구분을 하지 않으니 Guest guest로 로그인하면 플래그 값이 나온다.

'4-1. 2025-2 심화 스터디 > 워게임 도장 깨기' 카테고리의 다른 글
| [2주차] 25.10.04 워게임 도장 깨기 (0) | 2025.11.15 |
|---|---|
| [4주차] 25.11.15 워게임 도장 깨기 (0) | 2025.11.15 |
| [3주차] 25.11.8 워게임 도장 깨기 (0) | 2025.11.14 |
| [1주차] 25.09.27 워게임 도장 깨기 (0) | 2025.09.27 |