• 如果您想对本站表示支持,请随手点击一下广告即可~
  • 本站致力于提供原创、优秀的技术文章~
  • 有任何疑问或建议 均可以在站点右侧栏处 通过各种方式联系站长哦~
  • CTF – Prompt(1)解题报告 [Level H1 – Hoisting]

    渗透测试 EXP 385阅读 0评论

    指引

    题目(隐藏关卡)

    分析

    从代码可以知道,注入点在 if 内部,很自然有三种思路:

    • 使得 history.length > 1337 条件成立
    • 闭合 if
    • 闭合 <script>

    但是由于 }< 被过滤了,因此不论闭合 if 还是 <script> 都是不可能的,剩下的方法就是想办法令到 history.length > 1337 条件成立。

    前置知识

    解题思路

    这三个知识点是这题的解题关键。

    关于 history 对象,需要知道的是它不可被直接读写,目前唯一保留的 API 只有 4 个:lengthback()forward()go()

    而在本题中用到的 length ,它会在首次打开浏览器窗口的时候置 0 ,每访问一个新得页面自动 +1 。但是这个特性并不能被利用来解题,原因是 length 得上限值是 50,而条件中的目标值是 1337 ,即使我们预先访问了 1337 个页面, length 的值还是 50 ,仍然无法绕过条件。


    但这并不意味着毫无办法了:因为 history 说到底就是一个全局对象,我们可以构造一个同名的 history 对象(必定是局部对象)实现对全局对象的覆盖。同时只要所构造的这个 history 局部对象同样具备 length 属性,且可以被我们自由控制,那么就能实现 if 条件绕过了。

    既然可以使用局部对象覆盖,那么就有两个选择:

    • 局部变量(如数组):可以初始化数组的元素个数控制 length 属性
    • 局部函数 :可以通过声明入参的个数控制 length 属性

    但是不要忘了,我们的注入点是在 if 里面的,亦即不管我们声明 history 局部函数、还是声明 history 局部变量,都是在 history.length 条件后面的位置,亦即会出现 先使用后声明 的语法错误。


    而为了解决这个问题,可以利用 Javascript 中的 Hoisting (提升)机制:在早期的 Javascript 编译器中,会把所有出现在代码中的 变量声明 或 函数声明,全部移到代码的开头。

    不过 变量提升 和 函数提升 之间还是存在区别的:

    • 变量提升:仅仅是把 声明变量的语句 提升到代码的开头,但是初始化语句还是保留在原有位置不变的,如果在初始化语句之前就使用了该变量,依然会出现语法错误(变量未定义)
    • 函数提升:函数不存在初始化的说法,从而因为提升机制,使得函数只要在任意地方声明过一次,就可以在任何位置调用。

    回到这题,由于注入点在 if 里面,所有我们应该选择函数提升,而不是变量提升。

    Javascript 的 Hoisting 机制仅在早期的编译器支持,现在 9102 年绝大部分浏览器都不会这样做了,经测试只有 IE10 还支持这种机制,换言之要用 Hoisting 机制解题,只能使用 IE10 浏览器。

    构造 payload

    根据前面的思路,我们构造 payload 的方法为:在注入点声明一个 history 局部函数,函数入参数量至少为 1338 ,就能使得 if 条件成立,从而执行我们注入的代码。

    例如 payload 为:

    不过这个 payload 有个问题:就是我们要构造 history 函数,就需要使用到花括号 { } ,但是 } 已经被题目过滤了 !换言之我们不能直接输入 }

    不能直接输入,但是可以间接输入。

    绕过的方法需要利用到题目 JS 的 replace('{{injection}}', input) 函数的语法,第二个由我们控制的参数 input 是可以插入特殊变量名以达到某些效果的(详见 这里 ):

    而我们要使用的特殊变量名,就是

    就这题而言,因为 replace('{{injection}}', input) 被匹配的子串必定是 {{injection}},利用 $& 将其插入到我们的 payload ,就能获得两对花括号 {{ }} 了,而里面的一对花括号会被编译器认为是局部代码块,因此并不会影响语法。

    所以我们应该构造的 payload 为 :

    当这个 payload 经过题目的 replace('{{injection}}', input) 函数处理,就会得到我们想要的效果:

    完成挑战

    最后,输入这个 payload 到 IE10 即可完成挑战:

    转载请注明:EXP 技术分享博客 » CTF – Prompt(1)解题报告 [Level H1 – Hoisting]

    喜欢 (0) 分享 (0)
    发表我的评论
    取消评论

    表情

    Hi,您需要填写昵称和邮箱!

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址