Web网站程序类型指纹识别
web应用指纹识别,是web渗透信息收集最关键的一步,这方面开源的工具也非常多,像BlindElephant,whatweb 以及在非安全圈都很火的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特征
"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 -iWWW::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
三、PHP版本补充知识
阅读源码的确能学到不少东西
(1)v8js基本使用
v8js的基本使用示例:使用php运行js
编写简单的js文件
vim test.js
var name = "tanjiti"
print(name," ",name.length, " characters")
使用php运行js
<?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四个部分
<?php
if ( php_sapi_name() !== 'cli' ) {
exit('Run me from the command line');
}
$url = !empty($argv) ? $argv : '';
if ( !$url ) {
echo "Usage: php {$argv} <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 = $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"
}
}
页:
[1]