우선 CSRF가 무엇인지 알아야 이를 연습할 수 있겠지? CSRF는 Cross Site Referer Forgery의 약어이다. 크로스 사이트 리퍼러 위조.. 블로그 몇 군데를 찾아보니 다향히도 막 어려운 개념은 아니었다. 개인적으로 보자마자 와닿았던 예시가 있는데, 피싱 사이트에 "페이스북 피드에 불법 광고를 게시하도록 하는 스크립트 구문"을 삽입해놓고 피해자가 해당 사이트에 접속하면 스크립트 문이 실행되어 피해자의 브라우저에 로그인되어 있던 피해자의 페이스북 계정을 이용해 피해자의 담벼락에 불법 광고가 게시되는 예시. 너무 이해가 잘 된다. 실제 요청을 보내는건 피해자의 브라우저이지만, 실제로 해당 요청을 유도하는건 전혀 다른 웹사이트(referer)에 탑재된 공격자의 코드이기 때문에 referer fergery가 되는 것이다.
다시 말해 XSS가 피해자의 브라우저에 스크립트를 주입해 사용자 권한을 탈취하는 것이 목적이라면, CSRF는 피해자의 브라우저로 하여금 공격자가 원하는 요청을 피해자로 하여금 (인지하지 못 하고) 실행하도록 만드는 것이 주 목적인 셈이다.
이제 개념에 대해 이해했으니 웹페이지에 접속해보자.
코드도 그렇고 사이트도 그렇고 저번 XSS-1과 상당히 유사하다. memo에 최종 flag를 출력해서 확인하면 되고, flag를 통해 vuln을 타겟으로 공격을 수행하면 된다. 다만 이번 문제에서는 각 페이지에 공격 수행을 어렵게 만드는 방해 요소들이 들어가 있다. vuln 페이지부터 살펴보자
해당 페이지에서는 브라우저와 코드 내용에서 볼 수 있는 것처럼 'script', 'frame', 'on' 문자열을 검열 필터링하여 *로 바꾸고 있다. 다시 말해 이번에는 JS를 사용할 수 없다는 뜻이다. 웹 초보는 이러한 상황이 막막하지만 frame 이랑 on... 어디서 본 적이 있다. 브라우징하면서 HTML 코드를 뜯어보면 iframe, a href 같은 단편을 자주 본 기억이 있는데, 이거 뭔가 힌트가 될 수도 있을 것 같다. 어쨌든 우리의 목표는 해당 사이트로 하여금 우리가 원하는 페이지로 localhost에서 요청을 보내게 만드는 것이므로 특정 URL에 요청을 보내는 형태의 코드를 작성하면 된다. 대표적으로 <img src = [[이미지가 저장된 주소]]>를 이용하면 해당 URL에 존재하는 이미지를 가져오게 만들 수 있는데, 해당 URL에 GET 메소드로 접근하는 것일테니 이를 사용하면 될 것 같다.
<img src=/admin/notice_flag?userid=admin>
위 HTML 태그는 userid 변수에 "admin"을 대입하여, 로컬호스트의 /admin/notice_flag/path에 대해 이미지를 요청하는 코드이다. 실제로 해당 경로에 이미지가 존재하지는 않지만, userid = admin인 요청이 해당 path에 전달되는 것 만으로도 아래의 코드가 트리거되어 memo에 flag 값이 출력되어 있을 것이다. 자세한 코드 흐름은 아래에서 코드를 보면서 설명하겠다.
@app.route("/memo")
def memo():
global memo_text
text = request.args.get("memo", None)
if text:
memo_text += text
return render_template("memo.html", memo=memo_text)
@app.route("/admin/notice_flag")
def admin_notice_flag():
global memo_text
if request.remote_addr != "127.0.0.1":
return "Access Denied"
if request.args.get("userid", "") != "admin":
return "Access Denied 2"
memo_text += f"[Notice] flag is {FLAG}\n"
return "Ok"
" /admin/notice_flag " path가 호출될 때 두 가지를 검사한다. remote_addr가 로컬호스트인지와 userid가 ' admin '인지 여부.
우리는 "/vuln"에 HTML 태그를 주입하여 localhost로 하여금 " /admin/notice_flag "에 요청을 보내도록 조작하였기에 첫 번째 조건은 통과하였다. 또한, " ?userid=admin "이라는 쿼리문을 통해 두 번째 조건 역시 충족하였으므로 두 개의 if 문을 모두 통과할 수 있게 된다.
flag 값은 global로 선언된 전역 변수 memo_text에 저장되었으니, "/memo" 경로로 이동하면 이가 텍스트 필드에 출력되어 다음과 같이 표출될 것이다.
[Notice] flag is DH{YAYAYAYY!! I GOT THE FLAG}
memo
설레는 마음을 부여잡고 확인해보자
DH{11a230801ad0b80d52b996cbe203e83d}
참고자료
CSRF 공격이란? 그리고 CSRF 방어 방법
CSRF 공격(Cross Site Request Forgery)은 웹 어플리케이션 취약점 중 하나로 인터넷 사용자(희생자)가 자신의 의지와는 무관하게 공격자가 의도한 행위(수정, 삭제, 등록 등)를 특정 웹사이트에 요청하게
itstory.tk
[dreamhack] csrf-1 문제풀이
[WEB] csrf-1 문제풀이 CSRF(Cross-site request forgery) 취약점은 웹사이트 취약점 공격방법중 하나로, 사용자가 자신의 의지와는 상관없이 공격자가 의도한 수정, 삭제, 등록 행위 등 특정 웹사이트에 요
mokpo.tistory.com
'War Game > dreamhack.io' 카테고리의 다른 글
[pwn] shell_basic -상- (orw 쉘코드를 작성해보려고 노력해보자) (0) | 2023.04.26 |
---|---|
[Web] File-Download-1 (0) | 2023.04.19 |
[Web] XSS-1 (0) | 2023.04.15 |
[pwn] Return Address Overwrite (0) | 2023.04.14 |
[pwn] basic_exploitation_001 (BOF) (0) | 2023.04.12 |