浅析国内指纹识别技术(附带小工具)

前言

初学web安全的时候,找漏洞都是用北极熊扫描器扫出来的网站title来有目的性的‘刷’漏洞,后来随着网络主机的交替,ip的改变,北极熊扫出来的title也越来越不准确了。

大约在一月初开始打算扫全网的80端口,其中半个月时间调用了差不多7、8台服务器去扫描,扫了接近一半的中国ip段。但是发现结果不是特别满意,后来又在GitHub上找到了一个项目:

https://github.com/nanshihui/Scan-T

这个就很不错,可惜只是Django和Nmap结合起来,模仿了类似Shodan的东西,但是只有主机信息识别,也不是很满足。

构思

最近在构思一个想法,现有的扫描器像awvs,AppScan,Nessus等都是基于web爬虫,然后根据爬取的地址去扫描。这样会给网站造成很大的负担,并且容易触发防火墙,被限制拒绝访问。

但是现有的poc有很多,如果扫描器开始是基于web指纹识别,如果识别出web指纹,然后针对web框架使用poc去验证,反而效果会更好。

那么问题来了,怎么识别web指纹呢?

1. 基于web网站独有的favicon.ico的md5 比对网站类型;

2. 基于规则识别web站特征去识别;

3. 基于爬虫爬出来的网站目录比对web信息。

利弊

再说说这三种方法的利弊。

第一种速度最快,但也是最不准确的一种。因为大部分的favicon.ico都可以去更改,那么就会造成很大的误差。

1.png

 

第二种特征去识别可以寻找网站的css 、js代码的命名规则,也可以找关键字,以及head cookie等等,但是弊端是收集这些规则会耗费很久的时间。

 2.png

 

第三种感觉准确性比较高,但是如果改了目录结构就会造成问题,而且一部分网站有反爬虫机制,会造成一些困扰。

总体来看,最好的是三种结合在一起。但是想做成轻量级的,于是选择了第二种。

分析

首先规则是个问题,但是国内与Shodan,钟馗之眼相同的搜索引擎就很开源的把规则放了出来。

3.png

 

然后用爬虫爬下来。

4.png

 

大概有1412中可识别出来的。

这样就简单了。

url = input('输入要识别的网址')
if url.startswith('http://'):
    url = url
else:
    url = 'http://'+url
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 UBrowser/6.0.1471.914 Safari/537.36'}
response = requests.get(url=url,headers=headers)

bresponse = BeautifulSoup(response.text,"lxml")
title = bresponse.findAll('title')                            #title
for i in title:
    title = i.get_text()
head = response.headers
response = response.text

header = ''
for key in head.keys():                             # header集合
    header = header+key+':'+head[key]
print('收集主页信息完毕')

先把信息收集出来,分成title、body以及header。

body = {'content="WordPress':'WordPress','wp-includes':'WordPress',
        'pma_password':'phpMyAdmin',
        'AdaptCMS':'AdaptCMS',
        'TUTUCMS':'tutucms','Powered by TUTUCMS':'tutucms',
        'Powered by 1024 CMS':'1024 CMS','1024 CMS (c)':'1024 CMS',
        'Publish By JCms2010':'捷点 JCMS',
        'webEdition':'webEdition',
        'Powered by phpshe':'phpshe','phpshe':'phpshe',
        '/theme/2009/image&login.asp':'北京清科锐华CEMIS',
        'css/25yi.css':'25yi','Powered by 25yi':'25yi',
        '/bundles/oroui/':'oroCRM',
        'Powered by SeaCms':'海洋CMS','seacms':'海洋CMS',
        '/images/v7/cms.css':'qibosoft v7',
        'opac_two':'北创图书检索系统',
        'dayrui/statics':'dayrui系列CMS',
        'upload/moban/images/style.css':'ASP168 欧虎','default.php?mod=article&do=detail&tid':'ASP168 欧虎',
        'Powered by FineCMS':'FineCMS','dayrui@gmail.com':'FineCMS','FineCMS':'FineCMS',}

写一个rule的模块,里面分别把body、title、header以字典的形式分开来。

def scan_head():
    headrule = rule.head
    web_information = 0
    for key in headrule.keys():
        if '&' in key:
            keys = re.split('&',key)
            if re.search(keys[0],header,re.I) and re.search(keys[1],response,re.I) :
                web_information = headrule[key]
                break
            else:
                continue
        else:
            req = re.search(key,header,re.I)
            if req:
                web_information = headrule[key]
                break
            else:
                continue
    return web_information

比对关键字输出。

最后结果如下。

import requests
from bs4 import BeautifulSoup
import re
import rule
import sys

url = input('输入要识别的网址')
if url.startswith('http://'):
    url = url
else:
    url = 'http://'+url
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 UBrowser/6.0.1471.914 Safari/537.36'}
response = requests.get(url=url,headers=headers)
bresponse = BeautifulSoup(response.text,"lxml")
title = bresponse.findAll('title')                            #title
for i in title:
    title = i.get_text()
head = response.headers
response = response.text

header = ''
for key in head.keys():                             # header集合
    header = header+key+':'+head[key]
print('收集主页信息完毕')

def scan_title():
    titlerule = rule.title
    web_information = 0
    for key in titlerule.keys():
        req = re.search(key,title,re.I)
        if req:
            web_information = titlerule[key]
            break
        else:
            continue
    return web_information

def scan_head():
    headrule = rule.head
    web_information = 0
    for key in headrule.keys():
        if '&' in key:
            keys = re.split('&',key)
            if re.search(keys[0],header,re.I) and re.search(keys[1],response,re.I) :
                web_information = headrule[key]
                break
            else:
                continue
        else:
            req = re.search(key,header,re.I)
            if req:
                web_information = headrule[key]
               
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值