漏洞復現------Webmin 遠程命令執行漏洞(CVE-2019-15107)

一,webmin簡介

什麼是webmin

  • Webmin是目前功能最強大的基於Web的Unix系統管理工具。管理員通過瀏覽器訪問Webmin的各種管理功能並完成相應的管理動作
    http://www.webmin.com/
  • Webmin 是一個用 Perl 編寫的基於瀏覽器的管理應用程序。
  • 是一個基於Web的界面,用於Unix的系統管理。使用任何支持表和表單的瀏覽器,可以設置用戶帳戶,Apache,DNS,文件共享等。

.
爲什麼用webmin

  • Linux系統因其高效穩定而受到廣大用戶的推崇與青睞,然後其管理有一定複雜性和學習週期。爲了降低 Linux系統的管理難度,有時候會對公司內的Linux主機或VPS系統預裝了網頁管理工具webmin.

  • 在這裏插入圖片描述


二,漏洞概述

1、漏洞編號:CVE-2019-15107

2、漏洞描述:該漏洞允許惡意第三方在缺少輸入驗證的情況下而執行惡意代碼

該漏洞由於password_change.cgi文件在重置密碼功能中存在一個代碼執行漏洞,該漏洞允許惡意第三方在缺少輸入驗證的情況下而執行惡意代碼

3、受影響的版本:Webmin<=1.920

4,漏洞利用條件:版本滿足要求,且服務器的配置文件允許修改密碼時,在不知道webmin的用戶和密碼條件下,可以任意執行代碼。


三,漏洞復現

(1)環境搭建

環境:webmin 1.910

使用docker搭建,在vulhub項目中有webmin漏洞復現的環境
在這裏插入圖片描述

https://192.168.44.144:10000/

在這裏插入圖片描述

首先進入容器,修改root用戶密碼(不然無法登錄的啊。。。)

在這裏插入圖片描述

再次登錄
在這裏插入圖片描述

    漏洞需要開啓密碼重置功能。
    
     在控制界面 https://ip:10000/webmin/edit_session.cgi?xnavigation=1

在這裏插入圖片描述

在服務器上查看webmin的配置文件

 cat /etc/webmin/miniserv.conf 

在這裏插入圖片描述

(2)exp

抓包獲得改密碼的請求包

POST /password_change.cgi HTTP/1.1
Host: 192.168.44.144:10000
Connection: close
Content-Length: 52
Cache-Control: max-age=0
Origin: https://192.168.44.144:10000
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Sec-Fetch-Site: same-origin
Referer: https://192.168.44.144:10000/session_login.cgi
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: redirect=1; testing=1; sessiontest=1; sid=x

user=root&pam=1&expired=2&old=123456&new1=11&new2=11
  • 在這裏插入圖片描述

嘗試利用 || 執行命令

  • 在這裏插入圖片描述

思考之後,考慮有可能root是系統用戶,而不是webmin的用戶

嘗試隨便寫一個用戶和密碼

在這裏插入圖片描述

嘗試執行反彈shell命令
①kali監聽9000端口
.
②用burp suite ,對命令編碼後執行

  • 在這裏插入圖片描述
    在這裏插入圖片描述
    .

③kali收到shell

  • 在這裏插入圖片描述

四,漏洞分析

出問題的地方就是這個password_change.cgi

  1 #!/usr/bin/perl
  2 # password_change.cgi
  3 # Actually update a user's password by directly modifying /etc/shadow
  4 
  5 BEGIN { push(@INC, "."); };
  6 use WebminCore;
  7 
  8 $ENV{'MINISERV_INTERNAL'} || die "Can only be called by miniserv.pl";
  9 &init_config();
 10 &ReadParse();
 11 &get_miniserv_config(\%miniserv);
 12 $miniserv{'passwd_mode'} == 2 || die "Password changing is not enabled!";
 13 
 14 # Validate inputs
 15 $in{'new1'} ne '' || &pass_error($text{'password_enew1'});
 16 $in{'new1'} eq $in{'new2'} || &pass_error($text{'password_enew2'});
 17 
 18 # Is this a Webmin user?
 19 if (&foreign_check("acl")) {
 20         &foreign_require("acl", "acl-lib.pl");
 21         ($wuser) = grep { $_->{'name'} eq $in{'user'} } &acl::list_users();
 22         if ($wuser->{'pass'} eq 'x') {
 23                 # A Webmin user, but using Unix authentication
 24                 $wuser = undef;
 25                 }
 26         elsif ($wuser->{'pass'} eq '*LK*' ||
 27                $wuser->{'pass'} =~ /^\!/) {
 28                 &pass_error("Webmin users with locked accounts cannot change ".
 29                             "their passwords!");
 30                 }
 31         }
 32 if (!$in{'pam'} && !$wuser) {
 33         $miniserv{'passwd_cindex'} ne '' && $miniserv{'passwd_mindex'} ne '' ||
 34                 die "Missing password file configuration";
 35         }
 37 if ($wuser) {
 38         # Update Webmin user's password
 39         $enc = &acl::encrypt_password($in{'old'}, $wuser->{'pass'});
 40         $enc eq $wuser->{'pass'} || &pass_error($text{'password_eold'},qx/$in{'old'}/);
 41         $perr = &acl::check_password_restrictions($in{'user'}, $in{'new1'});
 42         $perr && &pass_error(&text('password_enewpass', $perr));
 43         $wuser->{'pass'} = &acl::encrypt_password($in{'new1'});
 44         $wuser->{'temppass'} = 0;
 45         &acl::modify_user($wuser->{'name'}, $wuser);
 46         &reload_miniserv();
 47         }
 48 elsif ($gconfig{'passwd_cmd'}) {
 49         # Use some configured command
 50         $passwd_cmd = &has_command($gconfig{'passwd_cmd'});
 51         $passwd_cmd || &pass_error("The password change command <tt>$gconfig{'passwd_cmd'}</tt> was not found");
 52 
 53         &foreign_require("proc", "proc-lib.pl");
 54         &clean_environment();
 55         $ENV{'REMOTE_USER'} = $in{'user'};      # some programs need this
 56         $passwd_cmd .= " ".quotemeta($in{'user'});
 57         ($fh, $fpid) = &proc::pty_process_exec($passwd_cmd, 0, 0);
 58         &reset_environment();
 59         while(1) {
 60                 local $rv = &wait_for($fh,
 61                            '(new|re-enter).*:',
 62                            '(old|current|login).*:',
 63                            'pick a password',
 64                            'too\s+many\s+failures',
 65                            'attributes\s+changed\s+on|successfully\s+changed',
 66                            'pick your passwords');
 67                 $out .= $wait_for_input;
 68                 sleep(1);
 69                 if ($rv == 0) {

。。。。。。

漏洞分析文章 http://www.cnhackhy.com/archives/541.html

作者分析這個漏洞是有很多故事的啊


五,漏洞修復

直接升級到1.930版本

臨時修補方案,可以定位漏洞代碼所在的行,然後剔除

在github上下載password_change.cgi文件

  • 在這裏插入圖片描述
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章