在获得对远程服务器的初始访问权限后,我们通常处于低权限用户上下文环境中,这并未赋予我们对目标系统的完全控制权。为了获得完全访问权限,我们需要寻找一个系统内部或本地的漏洞,以便将我们的权限提升至 Linux 上的 root 用户或 Windows 上的 administrator/SYSTEM 用户级别。下面我们来探讨一些常见的权限提升方法。
提权检查清单
成功获取对目标主机的初始访问后,我们需要对其进行彻底的枚举,以寻找可能被利用来获取更高权限的潜在漏洞。网上可以找到许多包含各种检查项和对应命令的检查清单和速查表。其中,HackTricks是一个极佳的资源,提供了针对 Linux 和 Windows 本地权限提升的详尽检查清单。另一个优秀的资源库是 PayloadsAllTheThings,同样包含了 Linux 和 Windows 的检查清单。我们必须开始尝试各种命令和技术,并熟悉它们,以了解可能导致权限提升的多种弱点。
枚举脚本
上述的许多命令可以通过运行脚本自动执行,通过脚本生成报告并查找任何弱点。我们可以运行许多脚本来自动化枚举服务器,这些脚本通过执行常见命令来返回有趣的发现。一些常见的 Linux 枚举脚本包括 LinEnum和 linuxprivchecker,Windows 枚举脚本则包括 Seatbelt和 JAWS。
另一个有用的服务器枚举工具是 Privilege Escalation Awesome Scripts SUITE (PEASS),该工具维护良好以保持更新,并包含用于枚举 Linux 和 Windows 的脚本。
注意:这些脚本会运行大量用于识别漏洞的已知命令,并产生大量”噪音”,可能会触发防病毒软件或安全监控软件的警报。这可能会阻止脚本运行,甚至触发系统已被入侵的警报。在某些情况下,我们可能需要进行手动枚举而不是运行脚本。
以运行 PEASS 中的 Linux 脚本 LinPEAS 为例:
guhusf@htb[/htb]$ ./linpeas.sh
...SNIP...
Linux Privesc Checklist: https://book.hacktricks.xyz/linux-unix/linux-privilege-escalation-checklist
LEYEND:
RED/YELLOW: 99% a PE vector
RED: You must take a look at it
LightCyan: Users with console
Blue: Users without console & mounted devs
Green: Common things (users, groups, SUID/SGID, mounts, .sh scripts, cronjobs)
LightMangenta: Your username
====================================( Basic information )=====================================
OS: Linux version 3.9.0-73-generic
User & Groups: uid=33(www-data) gid=33(www-data) groups=33(www-data)
...SNIP...
如我们所见,脚本运行后开始收集信息并以良好的格式显示报告。让我们讨论一下应该在这些脚本输出中寻找的一些常见漏洞。
内核漏洞利用
当我们遇到运行旧操作系统的服务器时,应首先寻找可能存在的内核漏洞。如果服务器没有通过最新的更新和补丁进行维护,那么它很可能容易受到在未打补丁的 Linux 和 Windows 版本上发现的特定内核漏洞利用攻击。
例如,上述脚本显示 Linux 版本为 3.9.0-73-generic。如果我们通过谷歌搜索此版本的漏洞利用,或使用 searchsploit,可能会发现 CVE-2016-5195,即 DirtyCow(脏牛)。我们可以搜索并下载 DirtyCow 漏洞利用程序,然后在服务器上运行它以获得 root 访问权限。
同样的概念也适用于 Windows,未打补丁/旧版本的 Windows 存在许多漏洞,有各种可用于权限提升的漏洞。需要注意的是,内核漏洞利用可能导致系统不稳定,在生产系统上运行它们之前应格外小心。最好在实验环境中尝试它们,并且只有在获得客户明确批准和协调后才在生产系统上运行。
易受攻击的软件
另一个需要关注的是已安装的软件。例如,我们可以在 Linux 上使用 dpkg -l命令,或在 Windows 上查看 C:\Program Files目录,来了解系统上安装了哪些软件。我们应该为任何已安装的软件寻找公开的漏洞利用,特别是如果正在使用的版本较旧,包含未打补丁的漏洞。
用户权限
获取服务器访问权限后,另一个关键方面是检查我们有权访问的用户所拥有的权限。如果我们被允许以 root 身份(或作为其他用户)运行特定命令,那么我们可能能够将权限提升至 root/system 用户,或获得作为其他用户的访问权限。以下是一些利用特定用户权限的常见方法:
- Sudo
- SUID
- Windows Token Privileges
Linux 中的 sudo命令允许用户以其他用户身份执行命令。它通常用于允许低权限用户以 root 身份执行命令,而无需给予他们 root 用户的完全访问权限。这通常是因为某些命令只能由 root 运行(如 tcpdump),或允许用户访问某些仅限 root 的目录。我们可以使用 sudo -l命令检查我们拥有哪些 sudo 权限:
guhusf@htb[/htb]$ sudo -l
[sudo] password for user1:
...SNIP...
User user1 may run the following commands on ExampleServer:
(ALL : ALL) ALL
上面的输出表明我们可以使用 sudo 运行所有命令,这赋予了我們完全访问权限,我们可以使用 sudo su命令切换到 root 用户:
guhusf@htb[/htb]$ sudo su -
[sudo] password for user1:
whoami
root
上面的命令需要密码才能使用 sudo 运行任何命令。但在某些情况下,我们可能被允许执行某些应用程序或所有应用程序,而无需提供密码:
guhusf@htb[/htb]$ sudo -l
(user : user) NOPASSWD: /bin/echo
NOPASSWD条目显示 /bin/echo命令可以在无密码的情况下执行。如果我们通过漏洞获取了服务器访问权限但没有用户密码,这将非常有用。如上所示,它指定了 user,我们可以以该用户身份运行 sudo,而不是 root。为此,我们可以使用 -u user来指定用户:
guhusf@htb[/htb]$ sudo -u user /bin/ echo Hello World!
Hello World!
一旦找到我们可以使用 sudo 运行的特定应用程序,我们就可以寻找方法来利用它以获取 root shell。GTFOBins包含了一个命令列表以及如何通过 sudo 利用它们。我们可以搜索我们拥有 sudo 权限的应用程序,如果它存在,它会告诉我们为了利用已有的 sudo 权限获取 root 访问权限所需执行的确切命令。
LOLBAS也包含了一个 Windows 应用程序列表,我们可以利用这些应用程序来执行某些功能,例如以下载文件或以特权用户身份执行命令。
计划任务
在 Linux 和 Windows 中,都有方法可以在特定时间间隔运行脚本以执行任务。例如,每小时运行一次防病毒扫描,或每 30 分钟运行一次备份脚本。通常有两种方法可以利用计划任务(Windows)或定时任务(Linux)来提升我们的权限:
- 添加新的计划任务/定时任务
- 诱使它们执行恶意软件
最简单的方法是检查是否允许我们添加新的计划任务。在 Linux 中,维护计划任务的常见形式是通过定时任务。如果我们对其拥有写权限,可以利用某些特定目录来添加新的定时任务。这些目录包括:
/etc/crontab/etc/cron.d/var/spool/cron/crontabs/root
如果我们能向一个被定时任务调用的目录写入内容,我们可以编写一个包含反向 shell 命令的 bash 脚本,该脚本在执行时应向我们发送一个反向 shell。
暴露的凭证
接下来,我们可以寻找我们可以读取的文件,并检查它们是否包含任何暴露的凭证。这在配置文件、日志文件和用户历史记录文件(Linux 中的 .bash_history和 Windows 中的 PSReadLine)中非常常见。我们在开头讨论的枚举脚本通常会查找文件中可能的密码并将其提供给我们,如下所示:
...SNIP...
[+] Searching passwords in config PHP files
[+] Finding passwords inside logs (limit 70)
...SNIP...
/var/www/html/config.php: $conn = new mysqli(localhost, 'db_user', 'password123');
如上所示,数据库密码 ‘password123’ 被暴露,这将允许我们登录到本地 MySQL 数据库并查找有趣的信息。我们还可以检查密码是否被重复使用,因为系统用户可能将其密码用于数据库,这可能允许我们使用相同的密码切换到该用户,如下所示:
guhusf@htb[/htb]$ su -
Password: password123
whoami
root
我们也可以使用用户凭证通过 SSH 以该用户身份登录服务器。
SSH 密钥
最后,我们来讨论 SSH 密钥。如果我们对特定用户的 .ssh目录具有读取权限,我们可以读取其私钥(位于 /home/user/.ssh/id_rsa或 /root/.ssh/id_rsa),并利用它登录服务器。如果我们能读取 /root/.ssh/目录并能读取 id_rsa文件,我们可以将其复制到我们的机器上,并使用 -i标志来登录:
guhusf@htb[/htb]$ vim id_rsa
guhusf@htb[/htb]$ chmod 600 id_rsa
guhusf@htb[/htb]$ ssh root@10.10.10.10 -i id_rsa
root@10.10.10.10#
请注意,在将密钥创建到我们的机器上后,我们使用了命令 chmod 600 id_rsa来更改文件的权限,使其更具限制性。如果 SSH 密钥权限宽松,例如可能被其他人读取,SSH 服务器将阻止其正常工作。
如果我们发现自己对用户的 .ssh/目录具有写权限,可以将我们的公钥放入用户的 SSH 目录下的 /home/user/.ssh/authorized_keys文件中。这种技术通常在已获得该用户 shell 访问权限后,用于获取 SSH 访问权限。当前的 SSH 配置不会接受由其他用户写入的密钥,因此只有在我们已经控制了该用户时才会生效。我们必须首先使用 ssh-keygen生成一个新密钥,并使用 -f标志指定输出文件:
guhusf@htb[/htb]$ ssh-keygen -f key
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): *******
Enter same passphrase again: *******
Your identification has been saved in key
Your public key has been saved in key.pub
The key fingerprint is:
SHA256:...SNIP... user@parrot
The key's randomart image is:
+---[RSA 3072]----+
| ..o.++.+ |
...SNIP...
| . ..oo+. |
+----[SHA256]-----+
这将给我们两个文件:key(我们将使用 ssh -i来指定它)和 key.pub(我们将复制到远程机器)。让我们复制 key.pub,然后在远程机器上,将其添加到 /root/.ssh/authorized_keys中:
user@remotehost$ echo "ssh-rsa AAAAB...SNIP...M= user@parrot" >> /root/.ssh/authorized_keys
现在,远程服务器应该允许我们使用我们的私钥以该用户身份登录:
guhusf@htb[/htb]$ ssh root@10.10.10.10 -i key
root@remotehost#
如我们所见,我们现在可以作为 root 用户 SSH 登录了。”Linux 权限提升”和”Windows 权限提升”模块将更详细地介绍如何使用这些方法进行权限提升,以及其他许多方法。




