일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- React
- 웹개발
- 선우예권
- 프리코스
- jsx
- 네트워크 계층
- 예술의 전당
- 백엔드
- 커밋메시지
- Upstream
- 자바
- 프랑스어 #프랑스어배우기 #프랑스어독학 #델프인강 #시원스쿨프랑스어 #delf독학 #델프 #프랑스어기초 #프랑스어공부
- 위상 정렬
- 우테코
- 깃헙
- 비동기 처리
- 진입차수
- 코리안챔버오케스트라
- 우아한테크코스
- 깃
- 서울청년문화패스
- c
- 애플리케이션 계층
- 알고리즘
- Dreamhack
- 트랜스포트 계층
- webhacking
- linux
- 동적 프로그래밍
- 다이나믹 프로그래밍
- Today
- Total
yon11b
[DH] csrf-2 본문
코드 분석 전
script 문자열 자체를 *로 바꾼다.
on도 *로 바꾼다
코드 분석
@app.route("/vuln")
def vuln():
param = request.args.get("param", "").lower()
xss_filter = ["frame", "script", "on"]
for _ in xss_filter:
param = param.replace(_, "*")
return param
[필터링 되는 것들] (못 쓰는 거)
- script
- ScriPT
- img src=z onerror
이런 건 안 되지만 잘 우회하면 js도 실행이 될 것 같다.
이걸 제외하고 쓸 수 있는 우회 기법은 아래와 같다. csrf-1에서 썼던 방법이다.
<img src="/admin/notice_flag?userid=admin">
이제 어디에서 무엇을 알아내야 할지를 보자.
users 정보이다. 계정은 guest, admin 두 가지가 있고, guest는 pw까지 나와 있다.
users = {
'guest': 'guest',
'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', text='please login')
return render_template('index.html', text=f'Hello {username}, {"flag is " + FLAG if username == "admin" else "you are not an admin"}')
session에 저장된 값이 admin 이면 flag가 출력된다.
그렇다면 어떻게 session에 admin값이 들어오게 할 수 있을까?
로그인을 admin으로 하면 될 것이다.
지금 우리는 admin 의 pw를 모른다.
그러므로 우리가 지금 구해야 하는 것은 admin의 pw가 될 것이다.
@app.route("/change_password")
def change_password():
pw = request.args.get("pw", "")
session_id = request.cookies.get('sessionid', None)
try:
username = session_storage[session_id]
except KeyError:
return render_template('index.html', text='please login')
users[username] = pw
return 'Done'
물론 다른 방법도 있지만 /change_password가 있는 것으로 봐서 pw를 바꿔야 하는 것 같다.
pw를 파라미터로 받고 session을 요청한다.
그리고 username을 session에서 가져오고 session이 없다면 keyerror를 발생하고 종료하고
session이 있으면 users[username]에 pw를 집어넣는다.
가져올 session이 있어야 오류가 안 난다.
그렇다면 admin의 session이 생성되는 곳이 분명히 있을 것이다.
@app.route("/flag", methods=["GET", "POST"])
def flag():
if request.method == "GET":
return render_template("flag.html")
elif request.method == "POST":
param = request.form.get("param", "")
session_id = os.urandom(16).hex() # 세션 생성
session_storage[session_id] = 'admin'
if not check_csrf(param, {"name":"sessionid", "value": session_id}):
return '<script>alert("wrong??");history.go(-1);</script>'
return '<script>alert("good");history.go(-1);</script>'
/flag에서 post로 param를 받으면 admin의 session_id가 생성된다.
check_csrf 함수에서는 param과 cookie를 read_url로 전달한다.
url은 /vuln으로 보낸다.
def check_csrf(param, cookie={"name": "name", "value": "value"}):
url = f"<http://127.0.0.1:8000/vuln?param={urllib.parse.quote(param)}>"
return read_url(url, cookie)
정리
- /flag에서 post로 전달하면 admin의 session이 생김
- /change_password에서 pw를 파라미터로 전달하면 session을 요청하고 응답받은 session값의 pw를 바꾼 pw로 변경한다.
- 응답받은 session값이 admin이면, admin의 pw를 지정할 수 있는 것이다.
- session 값이 admin이면 (admin으로 로그인하면) flag가 뜬다
해야할 일
- /flag에서 post로 /change_password?pw=test로 하고
- /login 페이지에서 admin, test로 로그인한다.
핵심
http://127.0.0.1:8000/vuln?param=<img src="/change_password?pw=test">
'보안 > WRITE_UP' 카테고리의 다른 글
[DH] simple-ssti (0) | 2022.07.28 |
---|---|
[DH] Mango (0) | 2022.07.28 |
[webhacking.kr] old-25 (0) | 2022.05.19 |
[webhacking.kr] g00gle2 (1) | 2022.05.19 |
[webhacking.kr] g00gle1 (1) | 2022.05.19 |