注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

碳基体

http://weibo.com/tanjiti

 
 
 
 
 

日志

 
 

Web应用指纹识别  

2014-10-31 14:18:34|  分类: WAF |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
web应用指纹识别,是web渗透信息收集最关键的一步,这方面开源的工具也非常多,像BlindElephantwhatweb 以及在非安全圈都很火的wappalyzer。本文主要描述如何使用wappalyzer的perl与php接口进行指纹识别。

wappalyzer的功能是识别单个uri的指纹,其原理就是给指定URI发送HTTP请求,获取响应头与响应体并按指纹规则进行匹配。这也是web应用指纹识别最基础的部分,除此之外,还有指纹置信度计算(如何去处伪造指纹,多种指纹特征如何综合判断,隐藏指纹信息如何提取),整个站点的指纹识别还涉及到有效爬虫抓取,分布式计算等问题,这些都不在本文内容中。


一、perl版本
原理:
给指定uri发送HTTP请求,通过分析HTTP相应的以下部分来判断指纹
(1)  headers特征 
响应头key:value对,多个key:value用逗号隔开,例如

"headers": { "X-AMP-Version": "([\\d.]+)\\;version:\\1", "Set-Cookie": "^AMP=" },

(2)   html特征 
响应体内容,多个规则用逗号隔开,例如

"html": [ "<div class=\"[^\"]*parbase", "_jcr_content", "/etc/designs/", "/etc/clientlibs/" ]

特别注意:html全文匹配的规则一定要谨慎编写
(3)  url特征
url内容,例如

"url": "/cgi-bin/UCEditor\\?(?:.*&)?merchantid=."

(4)  meta特征
响应html 页面中诸如<meta name="version" content="neblog-1.0"/>中的名字name:内容content对,多个规则用逗号隔开,例如

"meta": { "generator": "webEdition", "DC.title": "webEdition" }

(5)  script特征
响应html页面中诸如<script type="text/javascript" src="http://b1.bst.126.net/newpage/r/j/ec.js?v=1413881655525"></script> src中中url内容,多个规则用逗号隔开,例如

"script": [ "angular(?:\\-|\\.)([\\d.]*\\d)[^/]*\\.js\\;version:\\1", "/([\\d.]+(\\-?rc[.\\d]*)*)/angular(\\.min)?\\.js\\;version:\\1", "angular.*\\.js" ]


局限性
不支持规则文件中APP版本号与置信度的获取
对非utf8的中文编码可能会存在问题

优点:
较之PHP版本,使用qr正则预编译处理,可以提前发现正则的问题,这是我选择该语言版本的主要原因。
(接下来的php版本就能让你知道正则不预编译处理有多坑了!)

脚本的功能:
(1)指纹识别结果按JSON格式返回,以便后续指纹信息入库等处理
(2)支持批量uri查询
(3)支持指定自定义JSON格式的指纹规则文件 
(默认的指纹文件放置在/usr/lib/perl5/WWW/apps.json ,具体的路径会因cpan模块的安装路径有区别
可以使用perl -V 察看@INC变量来确定路径,或者更暴力的find吧)


安装

cpan -i  WWW::Wappalyzer  

clone https://github.com/tanjiti/FingerPrint.git


运行
(1)获取单个uri的指纹

perl FingerPrint.pl www.xxx.com<uri 必选> tanjiti.json[指纹规则文件,可选]

返回结果 

{
"www.xxx.com": {
"blogs": [
"WordPress"
],
"web-servers": [
"Nginx"
],
"cdn": [
"CloudFlare"
],
"cms": [
"WordPress"
],
"font-scripts": [
"Google Font API"
],
"javascript-frameworks": [
"jQuery"
],
"javascript-graphics": [
"Javascript Infovis Toolkit"
]
}
}

(2) 从文件读取url列表进行批量指纹识别,并将结果输出到文件中

perl FingerPrint.pl url.txt<uri 文件路径 必选> tanjiti.json[指纹规则文件,可选]

结果输出到 url.txt__fingerprint 文件里

指纹规则文件编写示例

more tanjiti.json

"apps": {
"Discuz!":{
"website": "www.discuz.net/forum.php",
"cats": [ 1 ],
"meta": { "generator": "Discuz"},
"headers": {"Set-Cookie": "_lastact.*_sid|_sid.*_lastact|_sid.*smile|smile.*_sid"},
"url": "/uc_server[/$]|uc_client[/$]",
"html": "Powered by (?:Discuz!|<a href=\"http://www\\.discuz\\.net/\"|UCenter)",
"implies": "php"
},
"PHP": {
"website": "php.net",
"cats": [ 27 ],
"headers": { "Server": "php/?([\\d.]+)?\\;confidence:40\\;version:\\1", "X-Powered-By": "php/?([\\d.]+)?\\;confidence:40\\;version:\\1", "Set-Cookie": "PHPSESSID" },
"url": "\\.php(?:$|\\?)"
}

}


二、php版本
原理
同perl版本,区别有两点:
1. HTTP请求部分:较之perl使用LWP发送HTTP请求,php使用curl发送HTTP请求
2. 规则匹配部分:指纹规则的匹配部分使用javascript语法,然后通过php的v8js模块来解析。(为什么要这样做呢?当返回响应体内容很多,指纹正则写的很烂的时候,会卡死在规则匹配这一过程中,现在的规则下sina,163等大站基本卡死!)

运行
PHP版的接口已经能直接使用了,只是需要替换规则文件,囧

第一步:安装php、curl及v8js

apt-get install php5-dev php-pear build-essential libv8-dev php5-curl

pecl install channel://pecl.php.net/v8js-0.1.3

echo extension=v8js.so >> /etc/php5/cli/php.ini

验证是否安装成功
php -m | grep v8js
v8js -----------OK

第二步:下载Wappalyzer脚本

git clone https://github.com/ElbertF/Wappalyzer.git

cp -R Wappalyzer/drivers/php/* .

cp Wappalyzer/share/js/wappalyzer.js js/

cp Wappalyzer/share/apps.json .  (指纹规则文件) 该规则文件的正则编写的有问题,所以我使用的以前版本的规则文件

cp /usr/lib/perl5/WWW/apps.json .

php版指纹识别程序结构如下:
index.php 主程序
Wappalyzer.php
WappalyzerException.php
js/driver.js js/wappalyzer.js
apps.json 指纹规则文件

第三步:验证是否成功

php index.php www.tanjiti.com

输出格式为
应用名,版本号,置信度,app类型 (比perl版本多了对版本号,置信度的获取)

CloudFlare, , 100%, cdn
Javascript Infovis Toolkit, , 100%, javascript-graphics
jQuery, , 100%, javascript-frameworks
Nginx, , 100%, web-servers
PHP, 5.5.9, 100%, programming-languages
Ubuntu, , 100%, operating-systems
WordPress, 4.0, 100%, cms, blogs

接下来的优化输出为json格式与批量处理uri同perl版本。

三、PHP版本补充知识
阅读源码的确能学到不少东西
(1)v8js基本使用
v8js的基本使用示例:使用php运行js

编写简单的js文件

vim test.js

var name = "tanjiti"
print(name," ",name.length, " characters")


使用php运行js

vim testV8.php

<?php

$start = microtime(true);

$v8 = new V8Js();


try{
$file = "test.js";
$result = $v8->executeString(file_get_contents($file),$file);
} catch (Exception $e){
print $e->getMessage()."\n";
exit;
}

$end = microtime(true);

$duration = $end - $start;

echo "\n$duration us\n";

?>

运行

php testV8.php
tanjiti 7 characters
0.018015146255493 us

(2) curl基本使用
使用curl向指定url发送请求,并将响应结果按StdClass结构存储响应体的url,host,html,headers四个部分

vim testCurl.php

<?php

if ( php_sapi_name() !== 'cli' ) {
exit('Run me from the command line');
}

$url = !empty($argv[1]) ? $argv[1] : '';

if ( !$url ) {
echo "Usage: php {$argv[0]} <url>\n";

exit(0);
}

$result = curl($url);
var_dump($result);

function curl($url)
{
echo 'cURL request: ' . $url . "\n";

$ch = curl_init($url); //初始化

curl_setopt_array($ch, array(//设置选项
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_HEADER => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 3, //重定向
CURLOPT_TIMEOUT => 5, //超时时间,单位s
CURLOPT_USERAGENT => 'Mozilla/5.0 (X11; Linux x86_64; rv:15.0) Gecko/20100101 Firefox/15.0.1' //User-Agent
));

$response = curl_exec($ch);

if ( curl_errno($ch) !== 0 ) {
throw new Exception('cURL error: ' . curl_error($ch));
}

$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

if ( $httpCode != 200 ) {
throw new Exception('cURL request returned HTTP code ' . $httpCode);
}

$result = new stdClass();

$result->url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);

$result->host = parse_url($result->url, PHP_URL_HOST);

$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);

$result->html = substr($response, $headerSize);

$result->html = mb_check_encoding($result->html, 'UTF-8') ? $result->html : utf8_encode($result->html);

$headers = trim(substr($response, 0, $headerSize));
$headers = preg_split('/^\s*$/m', $headers);
$headers = end($headers);
$lines = array_slice(explode("\r\n", $headers), 1);

foreach ( $lines as $line ) {
if ( strpos(trim($line), ': ') !== false ) {
list($key, $value) = explode(': ', $line);

$result->headers[strtolower($key)] = $value;
}
}

return $result;
}
?>


运行

php testCurl.php www.tanjiti.com/xss.php?a=lala
cURL request: www.tanjiti.com/xss.php?a=lala
object(stdClass)#1 (4) {
["url"]=>
string(37) "HTTP://www.tanjiti.com/xss.php?a=lala"
["host"]=>
string(15) "www.tanjiti.com"
["html"]=>
string(4) "lala"
["headers"]=>
array(11) {
["date"]=>
string(29) "Fri, 31 Oct 2014 10:08:50 GMT"
["content-type"]=>
string(9) "text/html"
["transfer-encoding"]=>
string(7) "chunked"
["connection"]=>
string(10) "keep-alive"
["set-cookie"]=>
string(133) "__cfduid=db05b3ccf4d2b4db66bb46b1058c616831414750130574; expires=Mon, 23-Dec-2019 23:50:00 GMT; path=/; domain=.tanjiti.com; HttpOnly"
["x-powered-by"]=>
string(20) "PHP/5.5.9-1ubuntu4.4"
["x-content-type-options"]=>
string(7) "nosniff"
["x-frame-options"]=>
string(10) "sameorigin"
["x-xss-protection"]=>
string(12) "1;mode=block"
["server"]=>
string(16) "cloudflare-nginx"
["cf-ray"]=>
string(20) "181f0dbc131a036e-LAX"
}
}

(3)正则

参考:
http://wappalyzer.com/
http://cn2.php.net/v8js/
  评论这张
 
阅读(4694)| 评论(0)
推荐

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017