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大牛说的。。。好简单。不知道他是咋自动交互的。。。。
你猜我之前咋做的。。。没错,按钮全点一遍,然后再获取静态页面的链接和表单。 = =|,这样做有一个很严重错误,假设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
你大四出去实习没呢
@东吃:我毕业去工作了 --
在腾讯吗?好牛逼
@chu:在蘑菇街 0 0 chu牛 不装 还是朋友
很赞 本来想学习scrapy爬虫的 看了你的文章 还是学习phantomjs吧 估计能少走好多坑
@whynot:都可以了解一下~
好牛逼,膜拜渗透师傅...
有一年了吧,师傅大人自己爽完了,终于发出来了....哈哈
@D_M:赢家莫嘲笑 :cool:
博主,python的selenium或者其他库可以实现onResourceRequested方法么。
@r0:selenium,我了解的比较少。你得多查查资料了
不知道你有没有遇到过一个点,例如访问
http://www.xx.com/admin/index.php
返回内容
302 to login pageadmin/index.php 完整内容HTTP Header
这样通过类似这种渲染的引擎,如果不先通过解析页面再渲染,会漏掉。 而普通的爬虫却能获取到,admin/index.php页面里的超级链接.
@he1renyagao:admin/index.php跳转了? 那admin/index.php可以被hook到,但是admin/index.php页面里的超级链接确实拿不到。phantomjs拿的到302跳转前的html内容么?而且既然是302跳转,那这页面的链接是不是应该比较少?