ν‹°μŠ€ν† λ¦¬ λ·°

CHALLENGE

XSS-Game Level 2

🌧: 2020. 11. 27.
μ„€λͺ…(λ²ˆμ—­)

μ›Ή μ‘μš© ν”„λ‘œκ·Έλž¨μ€ μ’…μ’… μ‚¬μš©μž 데이터λ₯Ό μ„œλ²„ 츑에 λ³΄κ΄€ν•˜κ³  점점 더 ν΄λΌμ΄μ–ΈνŠΈ μΈ‘ λ°μ΄ν„°λ² μ΄μŠ€μ— λ³΄κ΄€ν•˜κ³  λ‚˜μ€‘μ— μ‚¬μš©μžμ—κ²Œ ν‘œμ‹œν•©λ‹ˆλ‹€μ΄λŸ¬ν•œ μ‚¬μš©μž μ œμ–΄ λ°μ΄ν„°μ˜ μΆœμ²˜μ— 관계없이 μ‹ μ€‘ν•˜κ²Œ μ²˜λ¦¬ν•΄μ•Ό ν•©λ‹ˆλ‹€.

이 μˆ˜μ€€μ€ λ³΅μž‘ν•œ μ•±μ—μ„œ XSS 버그가 μ–Όλ§ˆλ‚˜ μ‰½κ²Œ λ„μž…λ  수 μžˆλŠ”μ§€ λ³΄μ—¬μ€λ‹ˆλ‹€.

 

μž„λ¬΄ λͺ©ν‘œ : alert() μ‘μš© ν”„λ‘œκ·Έλž¨ μ»¨ν…μŠ€νŠΈμ—μ„œ νŒμ—… 슀크립트λ₯Ό μ‚½μž…ν•©λ‹ˆλ‹€.

 

μ°Έκ³  : μ‘μš© ν”„λ‘œκ·Έλž¨μ€ κ²Œμ‹œλ¬Όμ„ μ €μž₯ν•˜λ―€λ‘œ κ²½κ³ λ₯Ό μ‹€ν–‰ν•˜κΈ° μœ„ν•΄ μ½”λ“œλ₯Ό 살짝 μž…λ ₯ν•˜λ©΄ λ‹€μ‹œ λ‘œλ“œν•  λ•Œλ§ˆλ‹€μ΄ μˆ˜μ€€μ΄ ν•΄κ²°λ©λ‹ˆλ‹€.

 

Level 2 μ—μ„œλŠ” " <script> " νƒœκ·Έλ₯Ό 막고 μžˆμŠ΅λ‹ˆλ‹€.

λ˜ν•œ 사진에 λ³΄μ΄λŠ” κ²ƒμ²˜λŸΌ HTML 폼에 μ•…μ˜μ μΈ 슀크립트 ꡬ문을 μ‚½μž…ν•˜μ—¬ ν•΄λ‹Ή νŽ˜μ΄μ§€μ— μ ‘κ·Όν•˜λŠ” λͺ¨λ“  μ‚¬μš©μž 듀을 νƒ€κΉƒμœΌλ‘œ ν•˜κ³  " Persistence " 지속성을 가진 곡격을 ν•˜λΌλŠ” 좜제자의 μ˜λ„κ°€ λ³΄μž…λ‹ˆλ‹€.

 

 --index.html--
 
 <!doctype html>
<html>
  <head>
    <!-- Internal game scripts/styles, mostly boring stuff -->
    <script src="/static/game-frame.js"></script>
    <link rel="stylesheet" href="/static/game-frame-styles.css" />
 
    <!-- This is our database of messages -->
    <script src="/static/post-store.js"></script>
   
    <script>
      var defaultMessage = "Welcome!<br><br>This is your <i>personal</i>"
        + " stream. You can post anything you want here, especially "
        + "<span style='color: #f00ba7'>madness</span>.";
 
      var DB = new PostDB(defaultMessage);
 
      function displayPosts() {
        var containerEl = document.getElementById("post-container");
        containerEl.innerHTML = "";
 
        var posts = DB.getPosts();
        for (var i=0; i<posts.length; i++) {
          var html = '<table class="message"> <tr> <td valign=top> '
            + '<img src="/static/level2_icon.png"> </td> <td valign=top '
            + ' class="message-container"> <div class="shim"></div>';
 
          html += '<b>You</b>';
          html += '<span class="date">' + new Date(posts[i].date) + '</span>';
          html += "<blockquote>" + posts[i].message + "</blockquote";
          html += "</td></tr></table>"
          containerEl.innerHTML += html; 
        }
      }
 
      window.onload = function() { 
        document.getElementById('clear-form').onsubmit = function() {
          DB.clear(function() { displayPosts() });
          return false;
        }
 
        document.getElementById('post-form').onsubmit = function() {
          var message = document.getElementById('post-content').value;
          DB.save(message, function() { displayPosts() } );
          document.getElementById('post-content').value = "";
          return false;
        }
 
        displayPosts();
      }
 
    </script>
 
  </head>
 
  <body id="level2">
    <div id="header">
      <img src="/static/logos/level2.png" /> 
      <div>Chatter from across the Web.</div>
      <form action="?" id="clear-form">
        <input class="clear" type="submit" value="Clear all posts">
      </form>
    </div>
 
    <div id="post-container"></div>
 
    <table class="message">
      <tr>
        <td valign="top">
          <img src="/static/level2_icon.png">
        </td>
        <td class="message-container">
          <div class="shim"></div>
          <form action="?" id="post-form">
            <textarea id="post-content" name="content" rows="2"
              cols="50"></textarea>
            <input class="share" type="submit" value="Share status!">
            <input type="hidden" name="action" value="sign">
          </form>
        </td>
      </tr>
    </table>
 
  </body>
</html>

 

ν•΄λ‹Ή λ ˆλ²¨μ—μ„œλŠ” <scirpt> νƒœκ·Έλ₯Ό 필터링 κ±Έμ–΄ μ•…μ˜μ μΈ μŠ€ν¬λ¦½νŠΈκ°€ μ‹€ν–‰λ˜μ§€ λͺ»ν•˜λ„둝 막고 μžˆλ‹€. 이럴 λ•ŒλŠ” λ‹€λ₯Έ νƒœκ·Έλ₯Ό μ‚¬μš©ν•˜μ—¬ μŠ€ν¬λ¦½νŠΈκ°€ μ‹€ν–‰λ˜λ„λ‘ μœ λ°œν•  수 μžˆλ‹€.

 

<img src> νƒœκ·Έμ™€ 이벀트 ν•Έλ“€λŸ¬λ₯Ό μ‘°ν•©ν•˜μ—¬ μ‹€ν–‰μ‹œν‚¬ 수 μžˆλ‹€.

 

html μ½”λ“œλ₯Ό 보면 <img src= λ₯Ό 톡해 /static/level 2μ΄λΌλŠ” 경둜λ₯Ό 톡해 이미지λ₯Ό 뢈러였고 μžˆλ‹€. λ§Œμ•½ 경둜λ₯Ό μ—†λŠ” 경둜둜 지정해주면 μ—λŸ¬κ°€ λ°œμƒν•˜λŠ”λ° μ΄λ•Œ μžλ°”μŠ€ν¬λ¦½νŠΈ 이벀트 ν•Έλ“€λŸ¬μΈ onerrorλ₯Ό μ—°κ³„ν•˜μ—¬ μ—λŸ¬κ°€ λ°œμƒ μ‹œ onerror ν•¨μˆ˜κ°€ λ°œμƒλ˜λ„λ‘ ν•  수 μžˆλ‹€.

 

λ§ˆμ§€λ§‰μœΌλ‘œ μ‚¬μš©μž 화면에 경고문ꡬλ₯Ό λ„μš°κΈ° μœ„ν•΄ alert, confirm, prompt λ“± μ‚¬μš©ν•˜λ©΄ λœλ‹€.

 

 

힌트

1. "ν™˜μ˜"κ²Œμ‹œλ¬Όμ—λŠ” ν…œν”Œλ¦Ώμ΄ μƒνƒœ λ©”μ‹œμ§€μ˜ λ‚΄μš©μ„ μ΄μŠ€μΌ€μ΄ν”„ ν•˜μ§€ μ•ŠμŒμ„ λ‚˜νƒ€λ‚΄λŠ” HTML이 ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

2. μ΄ μˆ˜μ€€μ—μ„œ <script> νƒœκ·Έλ₯Ό μž…λ ₯ν•˜λ©΄ μž‘λ™ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€λŒ€μ‹  JavaScript 속성이 μžˆλŠ” μš”μ†Œλ₯Ό μ‚¬μš©ν•΄λ³΄μ‹­μ‹œμ˜€.

3. μ΄ λ ˆλ²¨μ€ 문자 i , m , g λ° 속성에 μ˜ν•΄ ν›„μ›λ©λ‹ˆλ‹€ onerror

 

Exlpoit Code

<img src=onerror=prompt("xss")>
<img src=x onerror=prompt("xss")>

'CHALLENGE' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

XSS-Game Level 6  (0) 2020.12.01
XSS-Game Level 5  (0) 2020.11.30
XSS-Game Level 4  (0) 2020.11.29
XSS-Game Level 3  (0) 2020.11.28
XSS-Game Level 1  (2) 2020.11.26
κ³΅μœ ν•˜κΈ° 링크
Comment