phantomjs爬虫小记

phantomjs爬虫小记

1.前言

爬虫能力是web扫描器发现能力第一要素,如果爬虫能力一般会大大限制web扫描器的发现漏洞能力,因此写好爬虫是web扫描器的第一步。

tsrc上有一篇好文章写得爬虫的大家可以先看看:https://security.tencent.com/index.php/blog/msg/34 ,他们的爬虫是pyqt来写的,但是我自己感觉pyqt太重,所以我选择了phantomjs来做。

http://phantomjs.org/这是他的官网,安装还有函数什么的说的太清楚了,大家自己慢慢看。

2.爬虫分析页面的五大功能

根据tsrc上的文章,我们知道:

- 1.javascript动态解析 
- 2.hook所有的网络请求 
- 3.静态页面链接分析 
- 4.自动分析表单 
- 5.自动交互是爬虫的5个大功能。

除了自动交互,其它四个功能phantomjs完成都是轻轻松松的。下面简单说下如何轻松实现这四个功能:

- 1.javascript动态解析,phantomjs在打开这个url时候就会自动使用自己的webkit内核去执行javascript。
- 2.hook所有的网络请求,phantomjs有page.onResourceRequested方法来hook所有的网络请求,我们在这个函数里面获取url。
- 3.静态页面链接分析和自动分析表单。phantomjs提供page.evaluate,这个方法会创建一个“沙盒”来解析javascript,这里面的变量和phantomjs脚本的变量是不一样的,两个环境就不同。我们可以使用这个沙盒执行javascript,以此获得静态页面链接分析和表单。

3.头疼的自动交互

自动交互是最头疼的,不过到目前为止我也能达到一个比较符合我自己要求的结果了。
看看tsrc大牛说的。。。好简单。不知道他是咋自动交互的。。。。
tsrc大牛图
你猜我之前咋做的。。。没错,按钮全点一遍,然后再获取静态页面的链接和表单。 = =|,这样做有一个很严重错误,假设html是这样的:

<div id=abc>-</div>
<input type=button id=1 onclick="abc.innerHTML ='<a href=click_link.php'+'?id=2>click_link.php?id=2</a>'" value=""/>
</div>
<input type=button id=1 onclick="abc.innerHTML ='<a href=click_link2.php'+'?id=2>click_link2.php?id=2</a>'" value=""/>

知道了吧,要是你点了两个,那么你只能获取到click_link2.php?id=2,而click_link.php?id=2你是获取不到的。可以知道全点按钮的结果就是有可能会导致覆盖前一个dom。
我的解决思路是这样的,定义两个数组,一个存放分析到的链接(urls=[]),一个存放页面中的自动交互事件(onevents=[]),再定义两个函数,一个获取页面全部链接( function getallurl()),一个获取页面全部自动交互事件 function getonevents())。
遍历onevents,每执行一个自动交互事件,再获取一次页面全部链接和自动交互事件(即使执行getallurl(), getonevents(),当然这两个函数都有做是否重复的检查)
这里要注意一个非常重要的东西,每执行一个自动交互事件,再获取页面全部链接和自动交互事件之前,需要我们等待几秒!这是因为如果该交互事件为ajax的请求,它需要等得到服务器返回数据以后,才继续渲染页面。(http://testphp.vulnweb.com/AJAX/index.php 这个页面就是这种情况)

4.更头疼的javascirpt等待问题

现在,我们需要等待。但是javascirpt并没有sleep函数。。
然后测试时候看到又发现这个问题:如果使用for循环直接会卡死浏览器,如果使用setTimeout下面的程序会继续运行,所以有什么好的办法能够实现类似sleep的功能(https://segmentfault.com/q/1010000002498592)。
后来我才知道,根本没有这种方法,你只能老老实实用setTimeout来做,咋做用?答案是:递归!

function doloop(i) {
      getallurl();//获取页面全部链接
      getonevents();//获取页面全部自动交互事件
      if (onevents.length ==0) {
           return;
      }
      if (i == (onevents.length - 1)) {
     //触发onevent事件的伪代码
          setTimeout(function () {
                getallurl();
                getonevents();
               }, 1000);
      }
      else {
     //触发onevent事件的伪代码
i = i + 1; //1
          setTimeout(function () {
               doloop(i);
             }, 1000);
         }
}

你想到是这样做了么?反正我是想了好久。。。

5.代码时间

正所谓。no code,you say a jb。。 代码同步git,方便维护:https://github.com/wilson9x1/crawler_phantomjs

6.效果

http://testphp.vulnweb.com(这个站太卡。。测试时候建议延长超时时间)
效果
http://demo.aisec.cn/demo/aisec/
效果

7.问题

再说说的这个爬虫的问题。。。。

  • 1.phantomjs自身可能crash的问题,我是不断更新phantomjs最新版,phantomjs现在已经是2.1.1,相信他会越做越好。
  • 2.自动交互事件,我之获取了onclick事件和href的伪协议,还有好多on事件,我没写。。
  • 3.这个onevents的数组是不是还有问题?假设我触发了一个交互事件,这个交互事件把前面的交换事件(allElements[i])修改了或者消除了,那怎么办?
  • 4.等待超时时间设置为1秒,脚本运行超时时间设置10秒,仍可能因为网络问题,导致爬虫不准确,这个大家可以自己设置爬虫超时时间。

更多问题欢迎留言,或者直接联系我(wilson9x1@foxmail.com)

8.资料来源

https://security.tencent.com/index.php/blog/msg/34

http://phantomjs.org/

https://segmentfault.com/q/1010000002498592

http://epy.iteye.com/blog/1950135

标签: none

已有 11 条评论

  1. 东吃

    你大四出去实习没呢

    1. wilson

      @东吃:我毕业去工作了 --

  2. chu

    在腾讯吗?好牛逼

    1. wilson

      @chu:在蘑菇街 0 0 chu牛 不装 还是朋友

  3. whynot

    很赞 本来想学习scrapy爬虫的 看了你的文章 还是学习phantomjs吧 估计能少走好多坑

    1. wilson

      @whynot:都可以了解一下~

  4. D_M

    好牛逼,膜拜渗透师傅...
    有一年了吧,师傅大人自己爽完了,终于发出来了....哈哈

    1. wilson

      @D_M:赢家莫嘲笑 :cool:

  5. r0

    博主,python的selenium或者其他库可以实现onResourceRequested方法么。

    1. wilson

      @r0:selenium,我了解的比较少。你得多查查资料了

  6. he1renyagao

    不知道你有没有遇到过一个点,例如访问
    http://www.xx.com/admin/index.php

    返回内容
    HTTP Header

    302 to login pageadmin/index.php 完整内容

    这样通过类似这种渲染的引擎,如果不先通过解析页面再渲染,会漏掉。 而普通的爬虫却能获取到,admin/index.php页面里的超级链接.

    1. wilson

      @he1renyagao:admin/index.php跳转了? 那admin/index.php可以被hook到,但是admin/index.php页面里的超级链接确实拿不到。phantomjs拿的到302跳转前的html内容么?而且既然是302跳转,那这页面的链接是不是应该比较少?

添加新评论