문제 사이트에 들어가면 다음과 같이 문제 파일과 간단한 로그인 서비스가 구현된 웹사이트를 하나 볼 수 있었다.
본격적으로 문제 해결에 앞서, 문제에서 주어진 코드를 살펴보자.
이 부분은 guest와 user의 아이디, 비밀번호가 나와있고 admin은 FLAG값임을 알 수 있었다.
users = {
'guest': 'guest',
'user': 'user1234',
'admin': FLAG
}
다음은 메인 페이지와 관련된 코드이다.
@app.route('/')
def index():
session_id = request.cookies.get('sessionid', None)
try:
username = session_storage[session_id]
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"}')
코드 마지막 줄을 통해 username이 admin이면 FLAG 값을 출력해준다는 것을 확인할 수 있었다.
다음은 로그인 페이지 코드이다.
@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("not found user");history.go(-1);</script>'
if pw == password:
resp = make_response(redirect(url_for('index')) )
session_id = os.urandom(4).hex()
session_storage[session_id] = username
resp.set_cookie('sessionid', session_id)
return resp
return '<script>alert("wrong password");history.go(-1);</script>'
아래 부분에 있는 if 문을 확인해보면 session_id가 session_storage에 저장하였고 이 값은 username임을 확인할 수 있었다.
마지막으로 admin 페이지 관련된 코드이다.
if __name__ == '__main__':
import os
session_storage[os.urandom(1).hex()] = 'admin'
print(session_storage)
app.run(host='0.0.0.0', port=8000)
이 부분을 통해 hex 값을 랜덤으로 뽑아서 세션값에 저장하여 사용하는 것으로 확인할 수 있었다. 따라서 부루트포스 공격 즉, 무차별대입 공격을 사용해야한다고 한다.
이제 웹사이트를 접속해보자.
사이트 우측 상단에 로그인 버튼에서 username과 password를 모두 guest로 입력하고 로그인했더니 admin이 아니므로 'Hello guest, your are not admin' 라는 문구가 출력된 것을 볼 수 있었다.
admin과 관련된 부분을 해결하기 위해 Burp Suite 프로그램을 사용하여 문제를 해결해보았다.
먼저, 프로그램을 열고 프록시의 인터셉트 off를 on으로 변경하고 Open browser 버튼을 눌러 나오는 페이지에 문제 사이트 주소를 넣어주었더니 아래 이미지와 같이 쭉 관련 내용이 나왔고, 여기서 Intruder 부분으로 보내주었다.
다시 홈페이지로 돌아가서 sessionid의 쿠키값을 확인해보니 내 쿠키값은 다음과 같은 값이 나왔다.
위에서 찾은 쿠키값을 버프스위트 인터루더 부분 중 Positions에 sessionid의 쿠키값을 추가해주었다.
그리고 인터루더의 Payloads 부분에 Character set, 최대, 최소 길이를 설정해 주고 Start attack 버튼을 눌러주었다.
그러면 총 256개의 공격 결과값이 나오는데 이때, 다른 값의 길이는 모두 1417이지만, 한가지 값의 길이만 1505으로 길이가 다른 것을 확인할 수 있었다.
해당 부분을 Response 부분으로 가서 플래그 값의 형식인 dh를 검색하니 플래그 값을 찾을 수 있었다.
문제 해결 완료!!
[참고자료]
'CTF' 카테고리의 다른 글
[Dreamhack] session-basic (0) | 2023.05.02 |
---|---|
[Dreamhack] mongoboard (0) | 2023.04.12 |
[Dreamhack] image-storage (0) | 2023.04.12 |
[Dreamhack] command-injection-1 (0) | 2023.04.12 |
[Dreamhack] devtools-sources (0) | 2023.04.01 |