众亦信安,中意你啊!
点不了吃亏,点不了上当,设置星标,方能无恙!
一、smbclient浅析
简介
模拟SMB客户端进行SMB连接;
协议:SMB;
测试环境
win2019(DC):192.168.1.4
win10(attack):192.168.1.3
win2016(目标主机):192.168.1.10
测试命令如下:
python smbclient.py domain.local/administrator:"Admin@123"@192.168.1.10
相关截图如下:
代码解读
主函数处理解析输入参数后,初始化SMBConnection()
类,进行SMB协商;继续调用smbClient.login()
函数进行身份认证;
接着调用MiniImpacketShell
类,生成一个cmd命令行,通过输入自带命令来对目标SMB服务器进行交互,测试命令中输入shares(列出所有共享目录);
进入do_shares()
函数中,接着调用self.smb.listShares()
函数,进行RPC 连接,接口为srvsvc,再调用srvs.hNetrShareEnum()查询共享文件路径;
对应流量如下:
报错解决
报错内容:module 'collections' has no attribute 'Callable'
import collections
collections.Callable = collections.abc.Callable
总结
本次对smbclient.py脚本代码进行简单的分析,该脚本实现了简单的SMB客户端对服务器的各种操作。
二、secretsdump浅析
简介
调用各种技术来转储哈希值(离线+在线)
测试环境
win2019(DC):192.168.1.4
win10(attack):192.168.1.3
测试命令
python secretsdump.py domain.local/administrator:"Admin@123"@192.168.1.4
代码解读
主函数调用parse_target()函数获取输入的域名、用户名、密码、目标主机,下面的多个if判断是否符合离线破解条件,也就是输入时只有LOCAL,例子如下:
# 离线破解ntds
python secretsdump.py -system/root/vssown/SYSTEM-ntds /root/vssown/ntds.dit LOCAL
处理输入参数后,将参数带入到DumpSecrets类中,并调用类中的dump()函数;
self.__connectSvcCtl()
、self.__checkServiceStatus()
、self.__connectWinReg()
;self.__connectSvcCtl()
函数中,该函数连接目标主机的SCMR服务管理器self.__checkServiceStatus()
函数中,该函数查看目标主机上远程注册表服务(RemoteRegistry)是否处于开启状态,如果未开启就将其开启;self.__connectWinReg()
函数中,该函数连接目标主机的远程注册表服务;self.__remoteOps.getBootKey()
函数,通过遍历目标主机的远程注册表中特定目录的值通过解析拼装获取bootKey;self.__remoteOps.checkNoLMHashPolicy()
函数查看目标域内是否开启了NoLmHash策略(是否存储LMHash);self.__useKeyListMethod
为真,也就是设置了-use-keylist参数(Kerb-Key-List-Req攻击,通过RODC获取可复制的用户hash);self.__isRemote
是否为True,进入if中调用self.__remoteOps.saveSAM()
函数;进入self.__remoteOps.saveSAM()
函数中,接着调用self.__retrieveHive('SAM')
函数,步骤如下:
rrp.hOpenLocalMachine -- 打开目标注册表,获取句柄;
rrp.hBaseRegCreateKey -- 打开储存hivename键的句柄;
rrp.hBaseRegSaveKey -- 获取hivename的值并保存到8位随机值的tmp文件中;
rrp.hBaseRegCloseKey -- 关闭存储hivename 键的句柄;
rrp.hBaseRegCloseKey -- 关闭注册表句柄;
再初始化RemoteFilel类将获取的
self.__smbConnection.connectTree('ADMIN$')
连接目标ADMIN$文件夹;self.__remoteOps.saveSAM()
的结果SAMFileName带入到初始化SAMHashes类中;self.__hive.open()
函数,也就是RemoteFile类中的open()函数;self.__smbConnection.readFile()
函数,循环读取tmp文件,每次读4096个字节直到读取至文件末尾;self.__findRootKey()
函数;将文件读取指针调整到文件开头,再从新读取该tmp文件获取rootkey,在此SAMHashes类初始化函数中重要的函数已解读完毕;self.__remoteOps.saveSECURITY()
函数,也就是RemoteOperations类中的saveSECURITY()函数;self.__retrieveHive('SECURITY')
获取目标主机注册表中security的值并保存到特定目录中,再通过SMB协议获取该文件;根上面获取sam的值一样,所以就不详细介绍了;self.__LSASecrets.dumpCachedHashes()
函数解密缓存域登录信息;self.__LSASecrets.dumpSecrets()
函数解密转储 LSA Secrets;self.__isRemote
不提去ntds.dit,接着初始化NTDSHashes类,并调用类中的dump()函数;self.__remoteOps.connectSamr()
函数连接目标samr服务,获取目标Domain句柄和DomainId;self.__resumeSession.beginTransaction()
函数创建一个临时文件,后续会将获取内容写入该文件中;因为我们没有设置获取特定域用户hash或者ldapFilter,所以进入else条件中,while循环status不变就一直循环,进入循环先调用`self.__remoteOps.getDomainUsers()`函数获取目标域内所有用户;
对应流量如下:
self.__remoteOps.DRSCrackNames()
函数获取crackedName;self.__drsr
为空,继续调用self.__connectDrds()
函数;__connectDrds()
函数中,先进行DRSUAPI前期的epm请求、rpc绑定等操作;self.__remoteOps.DRSGetNCChanges()
函数从域控上的 NC 副本复制更新,再调用self.__decryptHash()
函数解密获取请求用户的hash并输出到控制台上,最后调用self.__resumeSession.writeResumeData()
函数将解密的域用户sid写入到上面创建的临时文件中;接着调用self.__decryptSupplementalInfo()
函数,该函数是解密用户账户的 Supplemental Credentials 信息,特别是 Kerberos Keys,并将解密后的信息存储在字典中;
继续NTDSHashes类的dump()函数中,如果获取到了kerberosKey则调用self.__perSecretCallback()
函数将kerberosKey处理并输出到控制台上,如果没有报错将执行finally条件中的代码关闭相关文件流;
总结
本次对secretsdump.py脚本代码进行简单分析,只是将平时内网常用的参数功能进行分析,该脚本代码量较大,相对来讲比较复杂,而且里面涉及到一些解密相关的操作,没有详细解读,本文仅针对了流量层进行了解读。
原文始发于微信公众号(众亦信安):impacket解读(三. smbclient、secretsdump)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论