潮汐指纹识别的原理

简介: 潮汐指纹识别的原理

潮汐开源版本是利用了fofa的banner

首先,潮汐定义了一个cms_finger_list的cms列表,这个列表和sqllite数据表中的数据是一样的。

然后又当以了下面的东西,暂时没看懂是干啥的

self.W = '\033[0m'
self.G = '\033[1;32m'
self.R = '\033[1;31m'
self.O = '\033[1;33m'
self.B = '\033[1;34m'

而且这个潮汐指纹识别是基于http协议的识别,而不是说针对主机端口的扫描。虽然现在分析的代码是我改写了一遍的,但是基本上没啥变化,现在来进行分析。

cms = Cmsscanner(target_url, self.request_timeout, self.pwd)
fofa_finger = cms.run()

来看看Cmsscanner

def __init__(self, *params):
    self.target, self.request_timeout, self.pwd = params
    self.start = time.time()
    self.finger = []
    self.agent = {'UserAgent': 'Mozilla/5.0 (Windows; U; MSIE 9.0; WIndows NT 9.0; en-US))'}
    self.rtitle = re.compile(r'title="(.*)"')
    self.rheader = re.compile(r'header="(.*)"')
    self.rbody = re.compile(r'body="(.*)"')
    self.rbracket = re.compile(r'\((.*)\)')

调用的run方法如下

def run(self):
    try:
        header, body, title = self.get_info()
        for _id in range(1, int(self.count())):
            try:
                self.handle(_id, header, body, title)
            except Exception as e:
                pass
    except Exception as e:
        print(e)
    finally:
        return self.finger

里面调用了git_info方法,我们来看看它都做了啥

def get_info(self):
    """获取web的信息"""
    try:
        r = requests.get(url=self.target, headers=self.agent,
                         timeout=self.request_timeout, verify=False)
        content = r.text
        try:
            title = BS(content, 'lxml').title.text.strip()
            return str(r.headers), content, title.strip('\n')
        except:
            return str(r.headers), content, ''
    except Exception as e:
        pass

利用get方法,向目标发起普通的请求,得到结果,主要包含内容,title和响应头。然后run方法中再遍历数据库中每个指纹,进行处理。详细看看handle方法

def handle(self, _id, header, body, title):
    """取出数据库的key进行匹配"""
    name, key = self.check(_id)
    # 满足一个条件即可的情况
    if '||' in key and '&&' not in key and '(' not in key:
        for rule in key.split('||'):
            if self.check_rule(rule, header, body, title):
                self.finger.append(name)
                # print '%s[+] %s   %s%s' % (G, self.target, name, W)
                break
    # 只有一个条件的情况
    elif '||' not in key and '&&' not in key and '(' not in key:
        if self.check_rule(key, header, body, title):
            self.finger.append(name)
            # print '%s[+] %s   %s%s' % (G, self.target, name, W)
    # 需要同时满足条件的情况
    elif '&&' in key and '||' not in key and '(' not in key:
        num = 0
        for rule in key.split('&&'):
            if self.check_rule(rule, header, body, title):
                num += 1
        if num == len(key.split('&&')):
            self.finger.append(name)
            # print '%s[+] %s   %s%s' % (G, self.target, name, W)
    else:
        # 与条件下存在并条件: 1||2||(3&&4)
        if '&&' in re.findall(self.rbracket, key)[0]:
            for rule in key.split('||'):
                if '&&' in rule:
                    num = 0
                    for _rule in rule.split('&&'):
                        if self.check_rule(_rule, header, body, title):
                            num += 1
                    if num == len(rule.split('&&')):
                        self.finger.append(name)
                        # print '%s[+] %s   %s%s' % (G, self.target, name, W)
                        break
                else:
                    if self.check_rule(rule, header, body, title):
                        self.finger.append(name)
                        # print '%s[+] %s   %s%s' % (G, self.target, name, W)
                        break
        else:
            # 并条件下存在与条件:1&&2&&(3||4)
            for rule in key.split('&&'):
                num = 0
                if '||' in rule:
                    for _rule in rule.split('||'):
                        if self.check_rule(_rule, title, body, header):
                            num += 1
                            break
                else:
                    if self.check_rule(rule, title, body, header):
                        num += 1
            if num == len(key.split('&&')):
                self.finger.append(name)
                # print '%s[+] %s   %s%s' % (G, self.target, name, W)

再来看看针对每个规则是怎么处理的check_rule函数

def check_rule(self, key, header, body, title):
    """指纹识别"""
    try:
        if 'title="' in key:
            if re.findall(self.rtitle, key)[0].lower() in title.lower():
                return True
        elif 'body="' in key:
            if re.findall(self.rbody, key)[0] in body: return True

        else:
            if re.findall(self.rheader, key)[0] in header: return True

    except Exception as e:
        pass

也就是说,本质上就是在首页的title/header和body中找有没有符合的正则表达式规则,如果有,就找到一个。

目录
相关文章
|
搜索推荐 安全 生物认证
如何使用 FOFA 搜索引擎保姆级教程(附链接)
如何使用 FOFA 搜索引擎保姆级教程(附链接)
|
Ubuntu Linux 网络安全
使用Kali Linux虚拟机破解WiFi密码的一波三折及详细操作步骤
使用Kali Linux虚拟机破解WiFi密码的一波三折及详细操作步骤
5486 0
使用Kali Linux虚拟机破解WiFi密码的一波三折及详细操作步骤
|
Linux
如何使用 Linux `date` 命令来指定时区?
如何使用 Linux `date` 命令来指定时区?
2246 0
|
关系型数据库 MySQL 数据库
MySQL开启远程访问权限
默认情况下,mysql只允许本地登录,但是多数情况下,我们需要访问服务器上的数据库资源,此时就需要开放MySQL的远程访问权限。 本文主要讲解如何开启MySQL的远程访问权限。
38161 7
MySQL开启远程访问权限
|
4月前
|
JavaScript Linux API
【OpenClaw喂饭级教程】零基础阿里云/Mac/Linux/Win11本地部署步骤流程+免费大模型API配置及常见问题解答
OpenClaw(原Clawdbot)是一款轻量级开源AI Agent管理平台,支持多Agent智能协作、自定义技能集成与多渠道消息对接,2026年完成了多系统部署优化与阿里云百炼API原生适配,为新手提供了零成本搭建专属AI助手的完整路径。本文聚焦阿里云/MacOS/Linux/Windows11本地部署场景,详细拆解全流程步骤,配套阿里云百炼免费大模型API配置方案,并汇总新手高频报错的解决方案,确保零基础用户可直接复制命令完成部署,快速解锁AI Agent核心能力。
3613 2
|
5月前
|
人工智能 安全 数据安全/隐私保护
OpenClaw(Clawdbot)汉化版完整搭建指南 全平台安装+附阿里云上部署教程
在AI工具爆发的2026年,OpenClaw(曾用名Clawd、Moltbot)以黑马之姿崛起——一周内GitHub Stars从7800飙升至12万+,成为历史上增长最快的开源项目之一。这款由PSPDFKit创始人Peter Steinberger打造的通用AI助手,打破了普通聊天机器人的功能局限,能真正执行系统控制、浏览器自动化、邮件管理等实用任务。但原版全英文界面对中文用户不够友好,第三方团队推出的汉化版完美解决这一痛点,实现命令行与网页控制台的全中文适配,让国内用户轻松上手。
7108 13
|
5月前
|
前端开发 数据可视化 定位技术
什么是CMS,网站内容管理系统(CMS)详解与建站指南
本文系统介绍了网站内容管理系统(CMS)的核心概念、主要功能与应用场景,详细对比了主流开源与商业CMS的特点,并提供了从规划到上线的完整建站流程指南,帮助读者根据自身需求选择合适工具并高效构建数字平台。
1907 4
|
存储 SQL 开发框架
文件上传漏洞 原理利用防御实战
文件上传漏洞 原理利用防御实战
|
SQL Ubuntu Linux
安装和使用皮卡丘练习靶场
安装和使用皮卡丘练习靶场
|
安全 Shell 网络安全
文件上传漏洞(四)edjpgcom
文件上传漏洞(四)edjpgcom