Nmap脚本文件分析(AMQP协议为例)

来源:互联网 发布:java 日期格式化 编辑:程序博客网 时间:2024/05/23 01:29

二、AMQP协议

  AMQP协议的全称为: Advanced Message Queuing Protocol,提供统一消息服务的应用层标准高级消息队列协议;是应用层协议的一个开放标准,为面向消息的中间件设计,基于此协议的客户端与消息中间件可传递消息,并不
受客户端/中间件不同产品,不同开发语言等条件的限制。下图显示为AMQP的原理图,典型的生产消费消息模型:

 原理图1

 

原理图2

  各组件的作用如下:
   
 1)Broker:接收和分发消息的应用,比如:RabbitMQ Server就是Message Broker。

    2)Connection:publisher/consumer和broker之间的TCP连接。断开连接的操作只会在client端进行,Broker不会断开连接,除非出现网络故障或broker服务出现问题。

    3)Exchange:message到达broker的第一站,根据分发规则,匹配查询表中的routing key,分发消息到queue中去。常用的类型有:direct (point-to-point), topic (publish-subscribe) and fanout (multicast)。

    4)Queue: 消息最终被送到这里等待consumer取走。一个message可以被同时拷贝到多个queue中。

  在RabbitMQ实现中服务器允许的端口:参考(http://www.rabbitmq.com/networking.html)

 

  在Nmap探测时,使用的正是AMQP 0-9-1 Client,因此我们探测时探测端口5672。

  遵循什么格式与AMQP Server交互?参考(http://www.rabbitmq.com/resources/specs/amqp-xml-doc0-9-1.pdf)

 

 

  由上两幅图可以看出,AMQP客户端与服务器交互首先发送协议头:“AMQP0091”到服务器,服务器如果拒绝连接,则返回一个无效的协议头,Nmap的处理方式是根据返回的协议版本再次请求服务。

 

三、脚本文件分析

   amqp-info.nse文件:

复制代码
-- amqp库提供检索AMQP服务信息的基本函数,目前支持AMQP0-9和AMQP0-8协议-- 这个库包含一个AMQP类,这个类包含于AMQP通信及核心函数。local amqp = require "amqp" -- nmap模块是与nmap内部函数交互和数据结构化的API,API提供目标主机的详细信息-- 例如端口状态和版本探测结果;同时API也提供与Nsock交互的接口;文件中共48个函数。local nmap = require "nmap"-- 构建简要端口规则的函数,端口规则被多数scripts所使用,因此-- 这个模块提供最基本的测试,函数返回true or false。local shortport = require "shortport"-- 标准Nmap脚本引擎函数,这个模块包含各种实用的函数,由于太小不能以模块的形式给出。-- 该模块下有个module函数,作用跟Lua 5.1的module函数类似;-- 例如_ENV = stdnse.module("socks", stdnse.seeall)的作用就是定义一个以文件名socks-- 为变量的模块,这样方便我们修改,便于统一,印象笔记中有Lua moudle详解。local stdnse = require "stdnse"-- 从AMQP服务器上收集信息description = [[Gathers information (a list of all server properties) from an AMQP (advanced message queuing protocol) server.]]-- 用于控制脚本的选择 nmap --script default,safe;只运行safe和discovery类别的脚本categories = {"default", "discovery", "safe", "version"}-- 端口规则,当这个函数返回true的时候,执行action函数.portrule = shortport.version_port_or_service(5672, "amqp", "tcp", "open")action = function(host, port)  -- 调用amqp模块新建一个cli表,表里面包括好多属性,host/port/amqpsocket等。  local cli = amqp.AMQP:new( host, port )    -- 通过connect方法连接服务器,通过namp模块的connect()方法与底层取得联系  local status, data = cli:connect()    -- 如果status为nil或false,则返回下面的数据输出,data为error字符串,在nmap模块中可查到。  if not status then return "Unable to open connection: " .. data end    -- 如果连接成功,则进一步握手处理,数据解析也是在amqp.lua这个模块中解析  status, data = cli:handshake()    -- 如果status为nil或false则返回错误信息data  if not status then return data end  -- 断开连接  cli:disconnect()    -- 能够进行到这一步,说明没有错误出现,确定下来是AMQP协议了。  port.version.name = "amqp"  port.version.product = cli:getServerProduct()  port.version.extrainfo = cli:getProtocolVersion()  port.version.version = cli:getServerVersion()   -- 设置host,port表为新的状态。  nmap.set_port_version(host, port)  -- server_properties表存储了握手的所有信息  return stdnse.format_output(status, cli:getServerProperties())      -- 综上所述,如果我们想修改交互过程的包,以及解析返回的数据;  -- 关注amqp.lua模块的handshake()函数即可。end
复制代码

    函数预览图:

 

  内嵌库amqp.lua文件:

View Code

 

四、总结

   1)目前500多种脚本文件大致的执行流程类似,因为在脚本中可以拿到socket连接,可以与服务进行通信,拿到banner信息进行解析。

   2)更高级的用法需要了解每一个NSE的语句,通过这个例子,其他NSE脚本也不难理解。

   3)Nmap整体架构指的学习,有时间分析分析源码有助于对其他工具的理解。

五、参考文献

  http://www.cnblogs.com/frankyou/p/5283539.html   博客:RabbitMQ与AMQP协议详解

  http://www.rabbitmq.com/documentation.html    RabbitMQ Documentation

  http://www.rabbitmq.com/protocol.html          AMQP 0-9-1 协议文档

原创粉丝点击