Dreamhack - csrf-1 (csrf 공격)

·2025년 7월 8일

Dreamhack-Writeups

목록 보기
16/52

csrf-1

문제 링크

https://dreamhack.io/wargame/challenges/26

문제 설명

여러 기능과 입력받은 URL을 확인하는 봇이 구현된 서비스입니다.
CSRF 취약점을 이용해 플래그를 획득하는 문제입니다.

CSRF 취약점 : 사용자가 로그인된 상태를 악용하여, 공격자가 의도한 요청을 사용자 모르게 실행하게 하는 공격입니다.

드림핵의 xss-1 문제와 유사합니다.
xss-1 문제 풀이 : https://velog.io/@yunaa/Dreamhack-xss-1-XSS공격

풀이과정

  1. 주어진 서비스에 접속을 해 보았습니다.

    flag에 들어가면 http://127.0.0.1:8000/vuln?param=( ) 에 무언갈 입력할 수 있습니다. 이 입력을 통해 CSRF 공격을 하는 문제임을 알 수 있습니다.
  2. app.py를 보면,
    @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 에 접속한 사용자의 ip가 127.0.0.1이고, userid 가 admin 인 경우에만 memo에 플래그가 입력됨을 알 수 있습니다.
  3. http://127.0.0.1:8000/vuln?param=( )
    <script>
    fetch("/admin/notice_flag?userid=admin");
    </script>
    를 입력해 보았지만, 플래그가 출력되지 않았습니다.
    이는
        @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가 포함된 키워드는 "*"로 대체됩니다. 즉, 공격을 위해서는 다른 우회법이 필요합니다.
  4. <img src="/admin/notice_flag?userid=admin"> 를 입력하였습니다.

태그는 HTML 문서 안에서 이미지를 삽입할 때 사용합니다. 브라우저는 이 태그를 만나면 src 속성에 있는 URL에 자동으로 GET 요청을 보냅니다.
하지만 특별한 방어가 없는 이상, 브라우저는 URL이 src가 이미지가 아니더라도 무조건 GET 요청을 보냅니다.
이를 이용해서 /admin/notice_flaguserid=admin 으로 접속해 GET할 수 있는 요청을 보낼 수 있습니다.
7. memo에 접속하여 정상적으로 플래그를 획득하였습니다.


배운점

  • CSRF 공격을 실습을 통해 배워볼 수 있었습니다.
  • script 로 접속이 불가능한 상황에 우회할 수 있는 방법인 <img> 태그에 대해 알 수 있었습니다.
  • 필터링된 키워드(script, on, frame)가 있다고 하더라도, HTML의 다양한 태그와 속성을 이용해 우회가 가능하다는 점을 배웠습니다. 실제 공격에서는 단순한 필터링보다 더 정교한 방어가 필요하다는 걸 느꼈습니다.

Summary (English)

  • The service allows a bot to visit user-supplied URLs.
  • CSRF is exploited to make the bot (logged in as admin, IP: 127.0.0.1) access /admin/notice_flag?userid=admin.
  • Direct <script> tags are filtered (script, on, frame*).
  • Used <img src="/admin/notice_flag?userid=admin"> to bypass the filter and trigger the request.
  • After the bot visited the crafted URL, the flag was written into the memo.
  • Successfully accessed the memo page to retrieve the flag.
profile
CTF 풀이 및 실습 중심 학습을 기록합니다.

0개의 댓글