XSS Challenges

Stage #1

http://xss-quiz.int21h.jp/?sid=e03ee5801343796c467d726953fb2a6b49f58006

  • 观察变量

    • 在search框中输入一个普通变量观察周围变量环境

      image-20210115101332788
    • 由上图可见当我们任意输入aaa之后,审核元素可以发现输入的值写入到标签中

  • 构造payload

    • 由于是直接写入到b标签的内容里面,所以可以看出并没有对输入做任何过滤限制,于是可以直接构造js语句对其进行攻击

      1
      <b>"<script>alert(document.domain)</script>"</b>
    • 我们这样做的目的只有一个,我们所提交的js参数要与周围环境和谐,浏览器才会对整个页面从新渲染,从而执行我们所提交的JS代码

Stage #2

http://xss-quiz.int21h.jp/stage2.php?sid=5068ea10a358df7653be0f031b52e6f43b6207cf

  • 观察变量

    • 在search同样输入普通变量aaa观察周围环境变量

    • 可以看见这次我们输入的值,被传入了value值中,于是可以思考我们的js代码在input标签中,那么是否可以提前将input标签闭合,闭合后再传值作为内容部分,从而执行我们的JS代码

      1
      <input type="text" name="p1" size="50" value="<script>alert(document.domain)</script>">
  • 构造payload

    • 经过上面的分析我们可以构造js语句了(其核心思路就为根据提交和返回的值得关系,从而判断出提交规则,绕过)

      1
      "><script>alert(document.domain)</script>

Stage #3

http://xss-quiz.int21h.jp/stage-3.php?sid=ee0a5108164b4daae0a2afaeef662c7adf1c59e4

  • 观察变量

    • 这次当我们输入变量aaa之后,观察发现与stage #1类似,但事情估计不会那么简单

    • 还是尝试着构造了一个payload试了一下,果然不行

      1
      <script>alert(1)</script>

      失败原因:字符输入时被转义,可以看下关于PHP htmlspecialchars()的介绍

    • 继续审核元素,发现后面有一个country也在b标签内,但在页面无法修改,改用抓包查看

​ 发现请求的参数中有p2,从前面的审核元素中可以看见是属于country的,于是可以试着从p2入手

  • 构造payload

    • 将p2中的值修改为放包

      成功执行

Stage #4

http://xss-quiz.int21h.jp/stage_4.php?sid=f5ecdd2b1ac189b0313a0395bba13c15ec23df4c

  • 观察变量

    • 同样输入一个普通常量aaa观察一下

      发现这不就是上一关吗,于是按照正常逻辑,就不在此页面演示了,直接抓包改值

      还是一样的直接修改p2的值,但是这次发现不行

      想一想也是,毕竟是上升了一关了,于是发现在请求处符出现了一个p3,但这个p3=hackme,这个值并未在页面中出现,接着尝试修改了p3,发现还是不行,但此处通过抓包信息无法得出什么了,于是继续回到输入处,审核元素

      发现修改p3的值,在页面处返回的信息中看见,我的js脚本是在input标签中,做到这里感觉不是跟stage #2一样吗,于是构造payload

  • 构造payload

​ 成功实现

3

Stage #5

http://xss-quiz.int21h.jp/stage--5.php?sid=3b204b3e8efd497a0a085f531ed716e828372d27

  • 观察变量

    • 同样输入一个普通观察元素

    发现是在input标签中,跟第二关一样吗?,试一试

    发现报错,点开查看,发现在value值后面输入的语句不完整,被自动裁掉了一半,发现前面有一个maxlength元素限制了长度

  • 构造payload

    修改maxlength的值,然后再构造闭合input标签的js语句

    成功执行

Stage #6

http://xss-quiz.int21h.jp/stage-no6.php?sid=95f8ced6ca36ff11e4df12eec643be78224705fa

  • 观察元素

    • 还是一样的审核下元素,发现又是一样的,事情想也想得到不会这么简单,还是执行以下js语句看下怎么回事

    • 插入js语句后发现字符转义了,<>被HTML特殊内容所代替

<img src="https://cdn.jsdelivr.net/gh/hang-thresh/imgbed/images/20210119142356.png" alt="image-20210115161703461" style="zoom:200%;" />

​ 看到这,看了下提示event handler attributes(事件处理程序属性 ),提示我们要用事件属性来处理了

  • 构造payload

    根据提示,构造了如下js语句,具体可以看下onmouseover事件的用法,onclick等还有许多类似的用法

    1
    " onmouseover="alert(document.domain)
    image-20210115162957456

Stage #7

http://xss-quiz.int21h.jp/stage07.php?sid=0a0cc8b0b0c12ee8cd0590ce19865f165b628ad9

  • 观察元素

    • 输入一个普通元素看下elements,发现跟stage #2一样的情况,但有了stage #6前车之鉴,还是输入一下js语句,给他一个面子

      执行语句之后,发现并未如同之前一样做什么转义,但发现我们输入的内容颜色(“ < >)好像不跟周围环境颜色相同,那么就只有可能我们传入的值成为了内容的一部分,也就是我们的”并未对value元素闭合,从而导致input标签也未被闭合,(“)发生了转义,我们传入的值未执行。

  • 构造payload

    • 有了上面的分析,基本可以有了一个方向,那就是让“不被转义,要让他执行,于是用对“进行utf编码一下,在放进去执行看看,发现还是没用

      “还是被转义了,又尝试了下url编码绕过还是不行,最后百度了一下,发现可以通过可通过双引号后面加空格分隔属性,浏览器会自动补齐“,从而执行后面的语句,但在空格之前得输入一个值,然后空格输入,不然还是被当做是value中的传入,后面又发现同样对<>和/做了转义,于是还是参考stage #6的思路(不知道描述是否正确这一题)

      1
      1 onclick=alert(document.domain)

      成功执行

Stage #8

http://xss-quiz.int21h.jp/stage008.php?sid=8e5137095794b899dbc36606cebfc1abc73498b2

​ 成功执行

Stage #9

http://xss-quiz.int21h.jp/stage_09.php?sid=b96b4ca3bcd27679e5ab65d3a8200edf3f212d4e

  • 观察变量

    • 同样输入随机变量,观察下周围的环境变量

      发现还是和之前一样,构造一个js语句试下,发现不行,语句没有闭合执行

      于是用stage 7之前用到的payload试下

      1
      1 onclick=alert(document.domain)

      发现没能通过,可直接看HTML的信息,发现和stage #7一样,一度怀疑自己前面错了,但后面想了下,对于xss双引号绕过,有很多不同的绕过放式,于是又试了下url编码、Unicode编码、HTML编码还是不对,于是又转到审核元素处,发现在input p1输入框下还有一个输入框,但页面没有显示,于是抓包看了下,发现是charset属性,又查了下euc-jp,是一种日文编码,于是应该是该文档的字符编码为euc-jp

  • payload构造

    上面查看出了编码类型,但还是没找到太多关于euc-jp的利用,本想着构造一个反编码,奈何太菜,没实现

    于是放弃了此题,后面查看了提示是utf-7,于是可能是跟utf-7有关,但还是没能实现。看了文章,一些大佬的笔记,大致如下

    思路:

    1.将payload构造成UTF-7编码

    然后抓包改为如下

    1
    p1=1%2bACI- οnmοuseοver=%2bACI-alert(document.domain)%2bADsAIg- x=%2bACI-&charset=UTF-7

    2.浏览器适应UTF-7,这里可以尝试一下,IEtester、ie7浏览器

    具体做法就没尝试了,后面有时间在更新一下

Stage #10

http://xss-quiz.int21h.jp/stage00010.php?sid=9cead88514d9b964cca7ade5a16b96b883f9de9b

  • 观察变量

    • 还是同样的套路,输入一个普通常量,观察下周围的变量

      不出意外还是自我感觉良好,和之前一样一步一步来吧

      发现内容溢出了,而且还找不到domain不见了,于是双写domain尝试了下

      1
      "><script>alert(document.domaindomain)</script>

      发现还是不行,那估计domain关键字被过滤了,试了下重写

      1
      "><script>alert(document.dodomainmain)</script>

      成功执行

Stage #11

  • 网址已无法打开

Stage #12

http://xss-quiz.int21h.jp/stage_no012.php?sid=491f61be10e2e4f1f9dc913f1bef5102ee7dd635

  • 观察

    • 还是老套路,先观察一番再说,看看周围环境变量

    还是老惯例,基本不能闭合value来闭合表签绕过

    但没办法,还是得输入进去,再看看具体情况

    1
    "><script>alert(document.domain)</script>

    发现过滤了我们输入的”、<>

    那么既然这样我们在stage #7中有一个类似的题,那么就用上面的playload去试一下

    1
    1 onclick=alert(document.domain)

    发现并没有类似于之前的Stage #7,利用空格分隔了属性

  • 构造payload

    • 那么我们这个地方就只有一个目标将value属性闭合,但是又无法直接利用”,”是被直接过滤的,也就是应该无法利用编码之类的,想起了之前看xss绕过的一篇文章时,说道了可利用``代替”,去进行闭合,但是这是ie浏览器特性

      成功

Stage #13

http://xss-quiz.int21h.jp/stage13_0.php?sid=39d578dbf7595d696ce798c5cab005b9fd12bf12

  • 观察

    • 还没开始输入就直接有个backgroud-color元素在里面

      还是一样的就闭合value呗,老欺骗了

      当执行常规js语句后,发现并没有起作用,可以看见颜色并没有发生变换,估计也是被过滤了,但上面有做过一个类似的题stage #7也是“被过滤,没起作用,构造了试了一下。还是没起作用

      1
      background-color:salmon onclick=alert(document.domain)

      做到这其实也有点类似于上一题了,直接在ie浏览器上代替,但是估计还是不行

      这不是没啥变换吗,题都升级了,总不可能绕过放式一样撒

      果不其然,不得行,``失效了,估计在后端对此做了防御,有点无从下手了,看了下提示“style attribute”样式属性,百度了一下style xss,好像是带样式属性的xss攻击(并不是很清楚css特性),发现是利用css特性设置backgroud:url和javascript伪协议来做,难怪不得一进入13关就有background元素,对于这方面并不是很清楚吗,就直接利用payload了,但是值得注意的是必须要在低版本的ie浏览器下,才能执行,ie10以下,测试了ietester(需要安装f2插件)通过

      1
      background:url(javascript:alert('xss'))

Stage #14

http://xss-quiz.int21h.jp/stage-_-14.php?sid=452eceb5376523131d1711cb7b21e5db0de6130d

  • 观察

    • 还是如同13关一样一进去就是backgroud·····,那么就直接用13关的,先去IEtester,用了下13关的方法

      可以发现url/script/eval/expression都被替换成xxx了,可以采用注释符打断

  • 构造payload

    1
    xss:expres/**/sion(if(!window.x){alert(document.domain);window.x=1;})

    有关于css expression的介绍可以看些这篇文章

Stage #15

http://xss-quiz.int21h.jp/stage__15.php?sid=1812d76c0cb38953e97626afc6cfca6bea4f9215

  • 观察

    • 还是一样提交普通变量看下外围环境

    • 提交普通变量看下外围环境

      发现第一处和第三处地方没变,第二处的地方发生了转义,HTML编码

      那么试下以下js语句,看下第一处和第三处

      1
      "><script>alert(document.domain)</script>

      这次得到的信息要多一点发现”也被转义了,除此外在另外两处中,”也被实体化了

      也就是我们不能提交”、<>,那么用16进制提交试一下呢

      1
      2
      3
      <   3c    
      > 3e
      \x3cscript\3ealert(document.domain)\x3c/script\x3e

      发现\被过滤了,再添加一个试一试

      1
      \\x3cscript\\3ealert(document.domain)\\x3c/script\\x3e

      成功

      这里主要利用了浏览器的特性,会自动转换16进制

后续

​ 由于后续几关都涉及到浏览器的版本问题就没在继续闯关了

总结

一、主要思路:

1.看外围环境

2.提交普通变量观察周围环境 aaa

3.提交普通JS探测

1
<script>alert(document.domain)</script>

4.观察周围环境变量,看下返回参数

5.思考是否有转义字符,过滤,字符长度等

6.测试

7.构造payload

二、1-15关主要绕过放式

1.1-5关都是很基础的,只需要闭合标签就行或者寻找其他攻击点,基本没过滤,转义等,直接构造语句实现

2.第6关<>被转义利用事件属性完成 onmouseover、onclick等

3.第七关大体跟第6关一样,只不过”被实体化了,最后利用了双引号后面加空格分隔属性,浏览器自动补齐双引号完成绕过

4.第8关主要利用了JavaScript伪协议完成了绕过

5.第10关主要利用了重写绕过

6.第12关利用ie浏览器的特性``代替”绕过

7.第13关利用了css特性和javascript伪协议绕过,行内样式属性xss攻击

1
background:url(javascript:alert('xss'))

8.第14关主要利用了css expression加注释符打断绕过

1
xss:expres/**/sion(if(!window.x){alert(document.domain);window.x=1;})

9.第15关主要利用了浏览器特性-自动解码16进制绕过

1
\x3cscript\3ealert(document.domain)\x3c/script\x3e

三、知识点

1.JS三种弹窗

  1. alert()方法/警告框alert()

    1
    <script>alert(document.domain)</script>
  2. confirm()方法/确认框confirm()

    1
    <script>confirm(document.domain)</script>
  3. prompt()方法/提示框prompt()

    1
    <script>prompt("文本","默认值")</script>
  4. SVG与XSS

1
<svg/onload=alert(document.domain)>

3.鼠标事件

​ 因为上面有几关用到了鼠标事件,于是罗列了几个出来

   onclick: 鼠标按下后松开才会触发

   ondblclick:双击

   onmousedown:按下   鼠标按下即可触发

   onmouseenter:指针移动到元素上时触发

   onmouseleave:指针移出元素时触发

   onmousemove:指针进入后,在元素范围内,只要移动就会一直触发

   onmouseover:移进去触发

   onmouseout:移出时触发

   onmouseup:鼠标进去后,按键松开时,触发一次

4.JavaScript伪协议

将JavaScript代码放在伪协议说明符javascript:后的url中,这样当加载这个url时,就会执行这个url中包含的JavaScript代码

1
javascript:alert(document.domain)