利用多个安全漏洞获得root权限的过程
利用多个安全漏洞获得root权限的过程
被测试的系统有一个功能:添加某个远程的服务器,保存必要的认证信息,后续会通过REST请求和rabbitmq持续获取一些数据。一部分主要流程如下图:
图中流程的第2、10、11存在安全隐患,在测试阶段通过伪造一个服务器并控制返回值,实现了命令注入。结合系统中另外一个进程权限的漏洞,最终获得root权限。Demo如下。后面会详细介绍证实的过程。
漏洞发现过程
不受信任的证书也可以建立连接
添加一个伪造的服务器时,获取到服务器的证书后仅显示了证书的一些基本信息,比如:
- Organization Unit
- Issued By
- Expires Date
- SHA-1 Thumbprint
最关键的信息,比如:”这个证书是否是可信任的“,没有以明显的方式提醒用户,很容易骗取用户的信任进行后续的操作。对比一些浏览器的行为,在使用浏览器访问不受信任的网站时,首先是警告用户告之风险。
shell命令注入
在流程图中的第10步,会创建一个linux 进程与RabbitMQ server建立连接。正常的进程如下:
|
|
其中”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是原始的服务器。
|
|
关于ssl.conf中用到的证书的生成和配置,不多做描述。
然后按照demo中的步骤添加这个伪造的服务器,经过进一步验证,以上推测全部正确。
然而该进程owner是一个普通用户,怎么才能得到root权限呢?
提权
首先查找了该用户具有写权限的所有可执行文件,然后逐一排查是否有可以利用的。在实际排查时,主要搜索可执行文件名和关键字sudo。果然,发现了一个坑。
|
|
然后把伪造服务器的response改成
|
|
然后使用系统的下载日志功能,触发并反弹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