Nmap识别MongoDB 6.0指纹

news2024/11/23 21:14:27

Nmap识别MongoDB 6.0指纹

朋友反馈一个问题,说使用Nmap扫描MongoDB服务时对于6.0以上的版本默认无法识别到服务版本信息。

如上图所示,对应的VERSION信息是空的,在提示信息中可以看到,官方推荐将指纹信息上传以帮助更新服务指纹,又或者可以通过Nmap的默认脚本mongodb-info来做版本识别。前一种方式需要等待官方做指纹文件更新或产品版本更新,后者使用脚本又会影响到扫描速度。如果想在当前的Nmap版本下不使用脚本来识别MongoDB 6.0以上版本,唯一的办法是使用Nmap内置的服务指纹将MongoDB 6.0服务版本识别出来。

Nmap服务指纹解析

Nmap默认的服务指纹文件位于/usr/share/nmap目录下,文件名是nmap-service-probes,根据默认端口27017可以找到Nmap识别MongoDB服务的内容:

上图中的匹配规则用到了四个指令:

  • Probe:为识别服务发送的字符串信息;
  • rarity:1-9范围的数字,是服务识别和可靠性的概率,数字越大,扫描概率越小,返回信息价值越低;
  • ports:服务识别常用的端口,效果与nmap的-p参数相同;
  • match:根据Probe指令发送字符串返回的信息,匹配服务指纹规则;

上图中用于识别MongoDB服务,通过TCP协议发送到服务端的字符串是:

\x41\0\0\0\x3a\x30\0\0\xff\xff\xff\xff\xd4\x07\0\0\0\0\0\0test.$cmd\0\0\0\0\0\xff\xff\xff\xff\x1b\0\0\0\x01serverStatus\0\0\0\0\0\0\0\xf0\x3f\0

match指令的格式包括:

  • 服务名称(service)
  • 匹配规则(pattern)
  • 版本信息(versioninfo)

以第一行的match指令为例:

match mongodb m|^.*version.....([\.\d]+)|s p/MongoDB/ v/$1/ cpe:/a:mongodb:mongodb:$1/
  • 服务名称:MongoDB
  • 匹配规则:m|^.*version.....([\.\d]+)|s,采用Perl格式的正则表达式,s表示包含换行符;
  • 版本信息:p/MongoDB/ v/$1/ cpe:/a:mongodb:mongodb:$1/,其中p指的是厂商信息,v指的是版本信息,这里引用自匹配规则里匹配的参数,cpe指的CPE(Common Platform Enumeration)格式,用于识别服务、操作系统和硬件;

CPE的格式如下:

cpe:/<part>:<vendor>:<product>:<version>:<update>:<edition>:<language>

除了v指令之外,CPE的第4个值也是产品版本信息,因此上图匹配规则中,只有第一行的规则可以用于识别MongoDB服务版本,通过匹配返回信息中的version信息来显示MongoDB版本。

MongoDB 5.0.1指纹解析

以MongoDB 5.0.1版本为例,当使用nmap对目标的27017端口进行扫描时:

nmap会发送上文中的Probe指令:

MongoDB响应数据包中可以匹配上文中第一条match指令:

因为在Nmap的扫描结果中,可以看到version(版本号)是p指令+指令,即“MongoDB v5.0.1”。

MongoDB有线协议

MongoDB有线协议(Wire Protocol)是请求/响应形式的TCP/IP的Socket,客户端和服务端通过该协议进行通讯,服务端实例(mongod和mongos)的默认端口是27017。

以MongoDB 6.0为例,客户端和服务端在通讯时的消息格式采用的是OP_MSG操作符,即采用以下格式对消息进行编码:

OP_MSG {
    MsgHeader header;           // standard message header
    uint32 flagBits;            // message flags
    Sections[] sections;        // data sections
    optional<uint32> checksum;  // optional CRC-32C checksum
}

其中,MsgHeader是标准信息头,客户端与服务端来往的消息都包含标准信息头(在SSL/TLS连接时没有checksum字段),其后才是消息内容(如OP_MSG结构中sections数组,数组每一项由Kind值开头,后接载体数据),标准信息头的结构如下:

struct MsgHeader {
    int32   messageLength; // total message size, including this
    int32   requestID;     // identifier for this message
    int32   responseTo;    // requestID from the original request
                           //   (used in responses from the database)
    int32   opCode;        // message type
}

MsgHeader中opCode消息类型会决定OP_MSG的结构,以OP_QUERY为例:

struct OP_QUERY {
    MsgHeader header;                 // standard message header
    int32     flags;                  // bit values of query options.  See below for details.
    cstring   fullCollectionName ;    // "dbname.collectionname"
    int32     numberToSkip;           // number of documents to skip
    int32     numberToReturn;         // number of documents to return
                                      //  in the first OP_REPLY batch
    document  query;                  // query object.  See below for details.
  [ document  returnFieldsSelector; ] // Optional. Selector indicating the fields
                                      //  to return.  See below for details.
}

OP_QUERY类型用于查询数据库中的集合,也是Nmap进行指纹识别时发送的请求消息类型,即上文图中的Probe指令。

但在MongoDB 5.1版本之后,OP_QUERY等消息类型已被淘汰,而相应的Nmap的服务指纹文件和NSE脚本中的服务识别脚本都未更新MongoDB的OP_MSG消息格式,因此无法正确识别出MongoDB的版本信息。

MongoDB 6.0指纹识别

知道MongoDB 5.0.1版本的指纹识别方式,以及MongoDB的OP_MSG消息格式,便可以通过抓取MongoDB 6.0的版本信息请求的流量,修改Nmap的服务探针文件nmap-service-probe来识别服务版本。

首先写一段Python代码作为客户端向MongoDB服务端发起版本信息的请求:

#!/bin/env python
 
import pymongo
 
client = pymongo.MongoClient("mongodb://192.168.168.133:27017")
server_status = client.admin.command("serverStatus")
print(server_status["version"])

同时,在脚本执行的同一环境下使用TCPDump抓取流量包

sudo tcpdump -i eth0 host 192.168.168.133 -w mongo.pcap

基于抓取的流量包进行分析,可以看到获得最终版本信息的请求头:

从/0x5f/0x00/0x00/0x00开始的便是Python脚本发送给MongoDB服务端的OP_MSG消息头,使用该十六进制字符串替换/usr/share/nmap/nmap-service-probes文件中的Probe指令,由于响应消息中的version匹配格式与原match指令中相同,所以不用变更match指令,这样即可实现对于MongoDB 6.0版本的识别。

但现在的识别仅是相当于流量重放的结果,不一定能够识别所有MongoDB 6.0的指纹,因此需要解析上面流量的OP_MSG消息,剥离出通用版本的OP_MSG请求。

根据6.0版本的OP_MSG格式,可以得知上图中的十六进制字符串的构成:

\x5f\x00\x00\x00:OP_MSG.MsgHeader.messageLength
\x51\xdc\xb0\x74:OP_MSG.MsgHeader.requestID
\x00\x00\x00\x00:OP_MSG.MsgHeader.responseTo
\xdd\x07\x00\x00:OP_MSG.MsgHeader.opCode
\x00\x00\x00\x00:OP_MSG.flagBits
\x00:OP_MSG.sections[0].kind
\x4a\x00\x00\x00\x10\x73\x65\x72\x76\x65\x72\x53\x74\x61\x74\x75\x73\x00\x01\x00\x00\x00\x03\x6c\x73\x69\x64\x00\x1e\x00\x00\x00\x05\x69\x64\x00\x10\x00\x00\x00\x04\x7c\xc1\xc2\x6c\xd7\x11\x40\x21\xb6\xf7\x5a\x52\x08\xaf\xca\x5e\x00\x02\x24\x64\x62\x00\x06\x00\x00\x00\x61\x64\x6d\x69\x6e\x00\x00:OP_MSG.sections[0].payload

核心部分是OP_MSG中sections的payload,使用Python中的bson模块对payload解析:(见评论区)

其中的lsid是客户端请求服务端的会话ID,是bson类型的UUID:7cc1c26cd7114021b6f75a5208afca5e。

因此,可以使用自定义生成uuid来创建能够查询MongoDB版本信息的OP_MSG消息头:

import socket
import bson
import binascii
import uuid
 
def send_op_msg_request(request):
    host = '192.168.168.133'
    port = 27017
 
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client.connect((host, port))
 
    client.sendall(request)
    response = client.recv(4096)
 
    client.close()
 
    return response
 
def build_op_msg_request():
    msg_header = b'\x5f\x00\x00\x00'  # total message size
    msg_header += b'\x00\x00\x00\x00'  # identifier for message
    msg_header += b'\x00\x00\x00\x00'  # request id
    msg_header += b'\xdd\x07\x00\x00'  # message type
 
    op_msg = msg_header + b'\x00\x00\x00\x00'  # message flags
 
    section = {
        'serverStatus': 1,
        'lsid': {'id': bson.binary.Binary(uuid.uuid4().bytes, bson.binary.UUID_SUBTYPE)},
        '$db': 'admin'
    }
 
    request = op_msg + b'\x00' + bson.encode(section)
 
    return request
 
op_msg_request = build_op_msg_request()
response = send_op_msg_request(op_msg_request)
 
print(response)

上面代码中的request值就是发送至服务端的OP_MSG消息,可以用于替换nmap-service-probe文件的指纹信息。

以下是更换指纹前后的对比效果:

更改指纹文件前

更改指纹文件后

参考材料

https://www.mongodb.com/docs/v6.0/reference/mongodb-wire-protocol/

https://www.mongodb.com/docs/v6.0/reference/bson-types/#std-label-bson-types

https://nmap.org/book/vscan-fileformat.html

洞源实验室
安全工程师:裴伟伟
2024 年 11 月 19 日 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2246247.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

论文阅读:A fast, scalable and versatile tool for analysis of single-cell omics data

Zhang, K., Zemke, N.R., Armand, E.J. et al. A fast, scalable and versatile tool for analysis of single-cell omics data. Nat Methods 21, 217–227 (2024). 论文地址&#xff1a;https://doi.org/10.1038/s41592-023-02139-9 代码地址&#xff1a;https://github.com…

飞凌嵌入式旗下教育品牌ElfBoard与西安科技大学共建「科教融合基地」

近日&#xff0c;飞凌嵌入式与西安科技大学共同举办了“科教融合基地”签约揭牌仪式。此次合作旨在深化嵌入式创新人才的培育&#xff0c;加速科技成果的转化应用&#xff0c;标志着双方共同开启了一段校企合作的新篇章。 出席本次签约揭牌仪式的有飞凌嵌入式梁总、高总等一行…

2024年11月21日Github流行趋势

项目名称&#xff1a;twenty 项目维护者&#xff1a;charlesBochet, lucasbordeau, Weiko, FelixMalfait, bosiraphael项目介绍&#xff1a;正在构建一个由社区支持的现代化Salesforce替代品。项目star数&#xff1a;21,798项目fork数&#xff1a;2,347 项目名称&#xff1a;p…

VSCode汉化教程【简洁易懂】

我们安装完成后默认是英文界面。 找到插件选项卡&#xff0c;搜索“Chinese”&#xff0c;找到简体&#xff08;更具你的需要&#xff09;&#xff08;Microsoft提供&#xff09;Install。 安装完成后选择Change Language and Restart。

Leetcode 生命游戏

以下是上述Java代码的算法思想及其逻辑的中文解释&#xff1a; 算法思想 这段代码实现了LeetCode第289题“生命游戏”的解决方案。核心思想是&#xff1a; 利用原地修改的方式&#xff08;in-place&#xff09;存储下一状态的变化&#xff1a; 通过引入额外的状态值&#xff0…

C++【面试重要题目】 只出现一次的数字的集合.

文章目录 前言一、前提要点补充二、题集总结 前言 本篇笔者将会对 cpp 中比较有意思的类型题目进行细致讲解 . 这类题同时也是面试中比较重要的算法题 , 其算法思想需要学者掌握. 以下题目均来自力扣 一、前提要点补充 ● 几个运用运算符 因为笔者介绍的题目均会用到二进制…

麒麟部署一套NFS服务器,用于创建网络文件系统

一、服务端共享目录 在本例中,kyserver01(172.16.200.10)作为客户端,创建一个目录/testdir并挂载共享目录;kyserver02(172.16.200.11)作为服务端,创建一个共享目录/test,设置为读写权限,要求客户端使用root登录时映射为nobody用户、非root登录时保持不变。 服务端启…

VBA技术资料MF228:移动形状并覆盖某单元格区域

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套&#xff0c;分为初级、中级、高级三大部分&#xff0c;教程是对VBA的系统讲解&#…

Python 数据分析核心库大全!

&#xff08;欢迎关注我的视频号&#xff09; &#x1f447;我的小册 45章教程:(小白零基础用Python量化股票分析小册) ,原价299&#xff0c;限时特价2杯咖啡&#xff0c;满100人涨10元。 大家好&#xff01;我是菜鸟哥&#xff01; 今天我们来聊点干货&#xff1a;Python 数据…

跨境出海安全:如何防止PayPal账户被风控?

今天咱们聊聊那些让人头疼的事儿——PayPal账户被风控。不少跨境电商商家反馈&#xff0c;我们只是想要安安静静地在网上做个小生意&#xff0c;结果不知道为什么&#xff0c;莫名其妙账户就被冻结了。 但其实每个封禁都是有原因的&#xff0c;今天就来给大家分享分享可能的原…

39页PDF | 毕马威_数据资产运营白皮书(限免下载)

一、前言 《毕马威数据资产运营白皮书》探讨了数据作为新型生产要素在企业数智化转型中的重要性&#xff0c;提出了数据资产运营的“三要素”&#xff08;组织与意识、流程与规范、平台与工具&#xff09;和“四重奏”&#xff08;数据资产盘点、评估、治理、共享&#xff09;…

数据科学与SQL:组距分组分析 | 区间分布问题

目录 0 问题描述 1 数据准备 2 问题分析 3 小结 0 问题描述 绝对值分布分析也可以理解为组距分组分析。对于某个指标而言&#xff0c;一个记录对应的指标值的绝对值&#xff0c;肯定落在所有指标值的绝对值的最小值和最大值构成的区间内&#xff0c;根据一定的算法&#x…

使用 PyTorch-BigGraph 构建和部署大规模图嵌入的完整教程

当涉及到图数据时&#xff0c;复杂性是不可避免的。无论是社交网络中的庞大互联关系、像 Freebase 这样的知识图谱&#xff0c;还是推荐引擎中海量的数据量&#xff0c;处理如此规模的图数据都充满挑战。 尤其是当目标是生成能够准确捕捉这些关系本质的嵌入表示时&#xff0c;…

23种设计模式-模板方法(Template Method)设计模式

文章目录 一.什么是模板方法模式&#xff1f;二.模板方法模式的特点三.模板方法模式的结构四.模板方法模式的应用场景五.模板方法模式的优缺点六.模板方法模式的C实现七.模板方法模式的JAVA实现八.代码解析九.总结 类图&#xff1a; 模板方法设计模式类图 一.什么是模板方法模…

.net的winfrom程序 窗体透明打开窗体时出现在屏幕右上角

窗体透明&#xff0c; 将Form的属性Opacity&#xff0c;由默认的100% 调整到 80%(尽量别低于50%)&#xff0c;这个数字越小越透明&#xff01; 打开窗体时出现在屏幕右上角 //构造函数 public frmCalendarList() {InitializeComponent();//打开窗体&#xff0c;窗体出现在屏幕…

DRNN 神经网络的Jacobian 信息辨识

DRNN 神经网络的 Jacobian 信息辨识 1. 基本原理 Jacobian 矩阵用于描述多输入多输出系统中输入和输出之间的偏导关系&#xff0c;其形式为&#xff1a; 对于 DRNN&#xff08;Dynamic Recurrent Neural Network&#xff09;&#xff0c;其动态特性使得 y(t)\mathbf{y}(t)y(t…

iptables网络安全服务详细使用

iptables防火墙概念说明 开源的基于数据包过滤的网络安全策略控制工具。 centos6.9 --- 默认防火墙工具软件iptables centos7 --- 默认防火墙工具软件firewalld&#xff08;zone&#xff09; iptables主要工作在OSI七层的二、三、四层&#xff0c;如果重新编译内核&…

《DAMA 数据管理知识体系指南》读书笔记 - 第 2 章 数据处理伦理

文章目录 1. 章节概述2. 核心概念与定义3. 重要方法与实践步骤4. 理论与实际结合5. 重点6. 理解与记忆要点7. 复习思考题标题图——书籍图片 WPS AI生成的XMind链接&#xff08;不用要源文件&#xff0c;下载不了&#xff09;&#xff1a; 【金山文档 | WPS云文档】 第2章 数据…

《线性代数的本质》

之前收藏的一门课&#xff0c;刚好期末复习&#xff0c;顺便看一看哈哈 课程链接&#xff1a;【线性代数的本质】合集-转载于3Blue1Brown官方双语】 向量究竟是什么 线性代数中最基础、最根源的组成部分就是向量&#xff0c;需要先明白什么是向量 不同专业对向量的看法 物理专…

AI 大模型如何重塑软件开发流程?——技术革新与未来展望

人工智能的蓬勃发展为许多领域注入了强劲动力&#xff0c;而在软件开发这一关键技术领域&#xff0c;AI 大模型的应用正在彻底改变传统流程。从代码自动生成到智能测试&#xff0c;再到协同开发和流程优化&#xff0c;AI 正逐步成为软件开发者的得力助手&#xff0c;也推动企业…