首页 > 系统相关 >通过DCERPC和ntlmssp获取Windows远程主机信息

通过DCERPC和ntlmssp获取Windows远程主机信息

时间:2024-03-15 11:11:23浏览次数:43  
标签:Target Windows ntlmssp bytes DCERPC Version x10 x01 x00

最初首发于:https://www.freebuf.com/articles/system/334948.html

前言

本文通过利用DCERPC协议的ping,并附加NTLMSSP认证信息来获取获取windows远程主机的版本号,主机名,所在域的域名,DNS等信息。

因为通过rpc进行探测的工具,大部分都是依托impacket来实现,而实战中通过挂代理进行内网探测速率和准确度都比较低,所以最好的方法是将脚本放到目标主机上,来进行内网探测信息收集,所以本文关注的点是想办法脱离impacket,在Socket RAW上的实现,这样能够减小工具的体积,并且其他语言也能够轻松复刻整个过程,便于应用到实战中。

成果

首先看一下成果,通过DCERPC协议的ping附带NTLMSSP来获取到目标的版本号,主机名,域名,DNS等信息。

协议介绍-RPC

RPC(Remote Procedure Call)远程过程调用协议,一种通过网络从远程计算机上请求服务,而不需要了解底层网络技术的协议。RPC它假定某些协议的存在,例如TCP/UDP等,为通信程序之间携带信息数据。在OSI网络七层模型中,RPC跨越了传输层和应用层,RPC使得开发,包括网络分布式多程序在内的应用程序更加容易。

过程

原理

通过看了一篇网络空间测绘核心技术之:协议识别(DCERPC篇)的文章之后,发现可以通过dcerpc的ping包+ntlmssp,epmapper接口,OXIDResolver接口,无需认证的情况下获取目标主机的版本号、主机名、多块网卡、注册到rpc的程序服务等信息。于是想自己实现一下。

对于通过OXIDResolver接口获取多块网卡的信息,已经有大佬实现了,再次不在赘述,重点是借鉴思路。

如下图所示当带上ntlmssp的时候,响应包,就会附带完整的系统版本号,主机名,域名等信息。

请求包:

响应包:

交互过程分析

正常的方式有两种,第一种看官方文档,下载idl接口文件,从头开始写码,另外一种是分析包的结构,寻找规律,尝试构包。

本文是选择后者。

接下来我们尝试抓流量分析包的情况,通过尝试对两台主机进行发包,看下一下是否有规律。

192.168.8.128-> 192.168.31.13

192.168.80.134-> 192.168.31.130

可以发现一共有4个数据包,前面是TCP握手不用管,通过分析对比后,可以发现两个请求包是一样,响应包也有一定规律。

分析包结构

请求包长度内容固定

第一个数据包 72 bytes(主要用于协商版本等等):

"\x05\x00\x0b\x03\x10\x00\x00\x00\x48\x00\x00\x00\x01\x00\x00\x00" \
"\xb8\x10\xb8\x10\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x00" \
"\x08\x83\xaf\xe1\x1f\x5d\xc9\x11\x91\xa4\x08\x00\x2b\x14\xa0\xfa" \
"\x03\x00\x00\x00\x33\x05\x71\x71\xba\xbe\x37\x49\x83\x19\xb5\xdb" \
"\xef\x9c\xcc\x36\x01\x00\x00\x00"

第二个数据包:

这个包中如果包含\x33\x05\x71\x71\xBA\xBE\x37\x49\x83\x19\xB5\xDB\xEF\x9C\xCC\x36则是x64,否则则为x86

"\x05\x00\x0c\x03\x10\x00\x00\x00\x3c\x00\x00\x00\x01\x00\x00\x00" \
"\xb8\x10\xb8\x10\x41\x1a\x00\x00\x04\x00\x31\x33\x35\x00\x00\x00" \
"\x01\x00\x00\x00\x00\x00\x00\x00\x33\x05\x71\x71\xba\xbe\x37\x49" \
"\x83\x19\xb5\xdb\xef\x9c\xcc\x36\x01\x00\x00\x00"

第三个数据包:

这个数据包中带着ntlmssp

"\x05\x00\x0b\x03\x10\x00\x00\x00\x78\x00\x28\x00\x03\x00\x00\x00" \
"\xb8\x10\xb8\x10\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x01\x00" \
"\xa0\x01\x00\x00\x00\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x00\x46" \
"\x00\x00\x00\x00\x04\x5d\x88\x8a\xeb\x1c\xc9\x11\x9f\xe8\x08\x00" \
"\x2b\x10\x48\x60\x02\x00\x00\x00\x0a\x02\x00\x00\x00\x00\x00\x00" \
"\x4e\x54\x4c\x4d\x53\x53\x50\x00\x01\x00\x00\x00\x07\x82\x08\xa2" \
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \
"\x06\x01\xb1\x1d\x00\x00\x00\x0f"

第四个数据包:

可以看到附带操作系统版本信息,主机名,域名,DNS域名,DNS主机名等信息。

"\x05\x00\x0c\x03\x10\x00\x00\x00\x26\x01\xe2\x00\x03\x00\x00\x00" \
"\xb8\x10\xb8\x10\x42\x1a\x00\x00\x04\x00\x31\x33\x35\x00\x00\x00" \
"\x01\x00\x00\x00\x00\x00\x00\x00\x04\x5d\x88\x8a\xeb\x1c\xc9\x11" \
"\x9f\xe8\x08\x00\x2b\x10\x48\x60\x02\x00\x00\x00\x0a\x02\x00\x00" \
"\x00\x00\x00\x00\x4e\x54\x4c\x4d\x53\x53\x50\x00\x02\x00\x00\x00" \
"\x06\x00\x06\x00\x38\x00\x00\x00\x05\x82\x89\xa2\x15\x71\x1e\x72" \
"\x12\x1a\x14\x3d\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x00\xa4\x00" \
"\x3e\x00\x00\x00\x0a\x00\x61\x4a\x00\x00\x00\x0f\x45\x00\x53\x00" \
"\x47\x00\x02\x00\x06\x00\x45\x00\x53\x00\x47\x00\x01\x00\x18\x00" \
"\x41\x00\x30\x00\x32\x00\x33\x00\x35\x00\x31\x00\x38\x00\x2d\x00" \
"\x4e\x00\x43\x00\x30\x00\x31\x00\x04\x00\x18\x00\x45\x00\x53\x00" \
"\x47\x00\x2e\x00\x33\x00\x36\x00\x30\x00\x45\x00\x53\x00\x2e\x00" \
"\x43\x00\x4e\x00\x03\x00\x32\x00\x41\x00\x30\x00\x32\x00\x33\x00" \
"\x35\x00\x31\x00\x38\x00\x2d\x00\x4e\x00\x43\x00\x30\x00\x31\x00" \
"\x2e\x00\x45\x00\x53\x00\x47\x00\x2e\x00\x33\x00\x36\x00\x30\x00" \
"\x45\x00\x53\x00\x2e\x00\x43\x00\x4e\x00\x05\x00\x18\x00\x45\x00" \
"\x53\x00\x47\x00\x2e\x00\x33\x00\x36\x00\x30\x00\x45\x00\x53\x00" \
"\x2e\x00\x43\x00\x4e\x00\x07\x00\x08\x00\xa8\xb3\x8f\xb4\xaa\x71" \
"\xd8\x01\x00\x00\x00\x00"

数据包结构解析

第四个数据包是不定长的,包括目标操作系统版本信息,主机名,域名,DNS域名,DNS主机名等信息。

规律:

从54位开始是dcerpc结构的内容

我们需要的内容在Auth Info:NTLMSSP,Connect AuthContextID(0)或者说NTLM Secure Service Provider下面。

即整体包的偏移122(0x70+0x0a)开始获取所需内容。

NTLM Secure Service Provider的结构

8 bytes:NTLMSSP identifier: NTLMSSP
8 bytes:NTLM Message Type: NTLMSSP_CHALLENGE (0x00000002)
2 bytes:Target Name的Length
2 bytes:Target Name的Maxlen
4 bytes:Target Name的Offset
4 bytes:Negotiate Flags: 0xa2898205, Negotiate 56, Negotiate 128, Negotiate Version, Negotiate Target Info, Negotiate Extended Security, Target Type Domain, Negotiate Always Sign, Negotiate NTLM key, Request Target, Negotiate UNICODE
8 bytes:NTLM Server Challenge: 15711e72121a143d
8 bytes:Reserved: 0000000000000000
2 bytes:Target Info 的Length
2 bytes:Target Info 的Maxlen
4 bytes:Target Info 的Offset
24 bytes:操作系统版本信息
剩下的全是Target Info的数据,属性有:
NetBIOS domain name
NetBIOS computer name
DNS domain name
DNS computer name
DNS tree name
Timestamp
End of list(0x00000000)

每个属性的结构为:

类型2bytes、长度2bytes、值(根据前面的长度)

根据上面的分析,通过socket构包,对回包进行偏移解析,获取所需字段内容,代码如下:

OS_Version_bytes = packet2[int('0xa0', 16) - 54 + 10:int('0xa0', 16) - 54 + 18]
Major_Version = int.from_bytes(OS_Version_bytes[0:1], byteorder='little')
Minor_Version = int.from_bytes(OS_Version_bytes[1:2], byteorder='little')
Build_Number = int.from_bytes(OS_Version_bytes[2:4], byteorder='little')
NTLM_Current_Reversion = int.from_bytes(OS_Version_bytes[7:8], byteorder='little')
OS_Verison = "Windows Version {0}.{1} Build {2} {3}".format(Major_Version, Minor_Version, Build_Number, digit)
Target_Info_Length_bytes = packet2[int('0xa0', 16) - 54 + 2:int('0xa0', 16) - 54 + 4]
Target_Info_Length = int.from_bytes(Target_Info_Length_bytes, byteorder='little')
Target_Info_bytes = packet2[-Target_Info_Length:-4]  # 最后四个0x00000000

发送第二个包解析代码

def get_osinfo(ip):
    global length
    osinfo = {
        "NetBIOS_domain_name": "",
        "DNS_domain_name": "",
        "DNS_computer_name": "",
        "DNS_tree_name": "",
    }
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        sock.settimeout(4)
        sock.connect((ip, 135))
        buffer_v2 = b"\x05\x00\x0b\x03\x10\x00\x00\x00\x78\x00\x28\x00\x03\x00\x00\x00\xb8\x10\xb8\x10\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x01\x00\xa0\x01\x00\x00\x00\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x00\x46\x00\x00\x00\x00\x04\x5d\x88\x8a\xeb\x1c\xc9\x11\x9f\xe8\x08\x00\x2b\x10\x48\x60\x02\x00\x00\x00\x0a\x02\x00\x00\x00\x00\x00\x00\x4e\x54\x4c\x4d\x53\x53\x50\x00\x01\x00\x00\x00\x07\x82\x08\xa2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x01\xb1\x1d\x00\x00\x00\x0f"
        sock.send(buffer_v2)
        packet2 = sock.recv(4096)
        digit = send_packet(ip)
        OS_Version_bytes = packet2[int('0xa0', 16) - 54 + 10:int('0xa0', 16) - 54 + 18]
        # print(test(OS_Version_bytes))
        Major_Version = int.from_bytes(OS_Version_bytes[0:1], byteorder='little')
        Minor_Version = int.from_bytes(OS_Version_bytes[1:2], byteorder='little')
        Build_Number = int.from_bytes(OS_Version_bytes[2:4], byteorder='little')
        NTLM_Current_Reversion = int.from_bytes(OS_Version_bytes[7:8], byteorder='little')
        OS_Verison = "Windows Version {0}.{1} Build {2} {3}".format(Major_Version, Minor_Version, Build_Number, digit)
        # print(OS_Verison)

        Target_Info_Length_bytes = packet2[int('0xa0', 16) - 54 + 2:int('0xa0', 16) - 54 + 4]
        Target_Info_Length = int.from_bytes(Target_Info_Length_bytes, byteorder='little')
        Target_Info_bytes = packet2[-Target_Info_Length:-4]  # 最后四个0x00000000
        print("[*] " + ip)
        print("\t[->]", "OS_Verison :", OS_Verison)
        for k in osinfo.keys():
            osinfo[k] = attribute_name(Target_Info_bytes)
            print("\t[->]", k, ":", osinfo[k])
            # print(attribute_name(Target_Info_bytes))
        length = 0
        osinfo["OS_Verison"] = OS_Verison
        result = {ip: osinfo}
        # print(result)
        return osinfo
    except Exception as e:
        # print(e)
        return -1
    finally:
        sock.close()


def attribute_name(Target_Info_bytes):
    global length
    att_name_length = int.from_bytes(Target_Info_bytes[length + 2:length + 4], byteorder='little')
    att_name = Target_Info_bytes[length + 4:length + 4 + att_name_length].replace(b"\x00", b"").decode(
        encoding="unicode_escape")
    length = length + 4 + att_name_length
    return att_name

上面也说了要通过第一个包判断目标操作系统的架构,代码如下:

def send_packet(ip):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        sock.settimeout(4)
        sock.connect((ip, 135))
        buffer_v1 = b"\x05\x00\x0b\x03\x10\x00\x00\x00\x48\x00\x00\x00\x01\x00\x00\x00\xb8\x10\xb8\x10\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x00\x08\x83\xaf\xe1\x1f\x5d\xc9\x11\x91\xa4\x08\x00\x2b\x14\xa0\xfa\x03\x00\x00\x00\x33\x05\x71\x71\xba\xbe\x37\x49\x83\x19\xb5\xdb\xef\x9c\xcc\x36\x01\x00\x00\x00"
        sock.send(buffer_v1)
        packet1 = sock.recv(1024)
        digit = "x86"
        if b"\x33\x05\x71\x71\xBA\xBE\x37\x49\x83\x19\xB5\xDB\xEF\x9C\xCC\x36" in packet1:
            digit = "x64"
        return digit
    except Exception as e:
        # print(e)
        return -1
    finally:
        sock.close()

注意:经过测试发送两个数据包不能在一个socket会话里面,否则第二个包的响应会不正常,要建立两个会话进行发送。

写成脚本

根据上面的分析,写成了多线程的脚本, 多线程实现扫描效果如下:

域内主机的话会显示域名,主机名,操作系统版本架构等信息,工作组主机则信息都是自己的主机名。

最后脚本放在了github:https://github.com/komomon/Dcerpc_Find_OSInfo

一起交流

关注公众号回复“加群”,添加Z2OBot 小K自动拉你加入Z2O安全攻防交流群分享更多好东西。

知识星球
团队建立了知识星球,不定时更新最新漏洞复现,手把手教你,同时不定时更新POC、内外网渗透测试骚操作。感兴趣的可以加一下。

参考文章:

Remote Enumeration of Network Interfaces without any Authentication: The OXID Resolver

SharpDetectionNTLMSSP

网络空间测绘核心技术之:协议识别(DCERPC篇)

https://payloads.online/archivers/2020-07-16/1/

标签:Target,Windows,ntlmssp,bytes,DCERPC,Version,x10,x01,x00
From: https://www.cnblogs.com/forforever/p/16369339.html

相关文章

  • 适用于 Windows 的 10 个顶级视频文件恢复软件
    如果您正在寻找可帮助您识别和恢复丢失视频的专用实用程序,那么您应该考虑利用本文中列出的适用于WindowsPC的最佳视频恢复软件的帮助。我们在最佳Windows视频恢复应用程序类别中个人推荐信息!什么是视频恢复软件?视频恢复实用程序或视频恢复软件是一种扫描、检测和提取......
  • Invicti v24.3.0 for Windows - Web 应用程序安全测试
    Invictiv24.3.0forWindows-Web应用程序安全测试InvictiStandard12Mar2024v24.3.0请访问原文链接:https://sysin.org/blog/invicti/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.orgInvicti是一种自动化但完全可配置的Web应用程序安全扫描程序,使您能够扫......
  • Windows压缩文件可以用 PowerShell中的Compress-Archive
    压缩单个文件Compress-Archive-Path"D:\tmp\test.txt"-DestinationPath"D:\tmp\test.zip"压缩多个文件Compress-Archive-Path"D:\tmp\test.txt","D:\tmp\test2.txt"-DestinationPath"D:\tmp\test2.zip"压缩文件夹Comp......
  • Windows启动MySQL
    1右键任务栏,选择任务管理器2选择服务并找到MySQL服务,确认此时状态为<已停止>3右键MySQL服务,选择开始,确认状态变更为<正在运行>......
  • Windows 配置 VSCode + neovim + leap.vim
    Windows配置VSCode+neovim+leap.vim安装VSCodeNeovim按照网上的教程来即可安装插件在vim配置文件中找到......
  • Windows powershell的初步学习使用第二课
           今天我们来学习Windowspowershell的指令。       上指令(参数为cmdlet):get-executionPolicy        作用为查询当前执行策略。       结果有以下几种情况:Restricted:脚本不能运行(默认设置)RemoteSigned:在本地创建脚本可以运行,但从......
  • Adobe大师版下载安装免费(全套创意软件Adobe大师版安装包下载)【Windows版】
    先说的Adobe大师版下载方式百度网盘下载:https://pan.baidu.com/s/1qb3iPg6V1UiDk9Lsefug9g?pwd=5tfu夸克网盘下载:https://pan.quark.cn/s/c514436a2e5a迅雷网盘下载:https://pan.xunlei.com/s/VNsbfVLgdKKqfuCKniPZCbFmA1?pwd=ewyf#也可以通过我们的网站找到我们:zhrk.yc......
  • Windows Server 2025 简体中文版下载 (Inside Preview, updated Mar 2024) - 下一代 W
    WindowsServer2025简体中文版下载(InsidePreview,updatedMar2024)-下一代Windows11ServerWindowsServer2025正式版发布在即请访问原文链接:https://sysin.org/blog/windows-server-2025/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.org我们知道Windo......
  • 若依(ruoyi-vue)后端部署windows系统
    一、下载idea并破解,防止时间久了没法打开访问IDEA官网,下载IDEA2023.2.3版本的安装包,下载链接如下:https://www.jetbrains.com/idea/download/卸载旧版本,安装新版本弹框会提示选择安装路径,我这里直接选择的默认安装路径C:\ProgramFiles\JetBrains\IntelliJIDEA......
  • 在Linux/Ubuntu/Debian中使用windows应用程序/软件
    Wine是一个兼容层,允许你在类Unix操作系统(包括Ubuntu)上运行Windows应用程序。以下是在Ubuntu上安装和使用Wine的基本步骤:在Ubuntu上安装Wine:更新软件包列表:打开终端并运行以下命令以确保你的软件包列表是最新的:sudoaptupdate安装Wine:使用以下命......