Webmin RCE(CVE-2019-15107)简析

Webmin RCE(CVE-2019-15107)简析

写在前面

  • 这个CVE是@Ethan跟的,后来看文章时我觉得很有意思,就跟了一下。
  • 漏洞是由于黑客修改了SourceForge上的官方包并留下的后门,在github中并没有被污染。

简介

  • Webmin是一个基于Web的界面,用于Unix的系统管理。使用任何支持表和表单的浏览器,可以设置用户帐户,Apache,DNS,文件共享等。

  • 2019年8月10日,pentest上发布了Webmin CVE-2019-15107远程代码执行漏洞。

  • 该漏洞由于password_change.cgi文件在重置密码功能中存在一个代码执行漏洞,该漏洞允许恶意第三方在缺少输入验证的情况下而执行恶意代码,后经知道创宇404实验室发现,该漏洞的存在实则是SourceForge上某些版本的安装包和源码被植入了后门导致的。

Dockerfile构建

  • 踩过了一些环境搭建的坑后得到了两大版本的可以复现的dockerfile,直接上地址: https://github.com/HACHp1/webmin_docker_and_exp

复现

v1.920

首先在v1.920版本复现: 使用用户名:root,密码:pass登陆;之后进入webmin权限设置界面:

将提醒用户修改过期密码提示打钩并保存:

待webmin重启后,进入webmin user界面添加新用户(新建用户后登陆新用户才会进入修改密码界面):

勾选强制修改选项:

注销当前用户,登陆新用户,此时会要求修改密码:

截包,可以在old参数注入命令:

反弹shell:

v1.890

在@Ethan搜寻漏洞成因的过程中,发现在版本v1.890中有明显的后门代码,可以直接通过expired参数执行命令,在post参数中仅添加expired参数就能够执行命令(我直接写的脚本,就不截图了)。

EXP编写

  • 根据复现情况很容易可以写出EXP:https://github.com/HACHp1/webmin_docker_and_exp

漏洞原理以及修复方案分析

既然是后门,调用起来就比较容易,执行过程也比较好分析。

v1.890

  • 通过对比SourceForge上的污染版本和未污染的github版本,可以发现明显的后门:

  • 在后门版本中,后门执行代码为:$in{'expired'} eq '' || die $text{'password_expired'},qx/$in{'expired'}/;,代码使用qx直接执行了expired参数。而正常版本中,此处只是提示密码修改模式未开启:$miniserv{'passwd_mode'} == 2 || die "Password changing is not enabled!";。并且在之前没有任何if逻辑,使此处的RCE不需要其他条件便能执行(而在1.9x中,需要一些条件才能执行到系统命令)。

v1.920

  • 类似1.890版本,通过对比SourceForge上的污染版本和未污染的github版本,可以发现明显的后门:

  • 但是在1.920版本中,由于执行条件的问题,默认配置不能RCE;一般来讲,攻击者都是要使利用面尽可能的广的,但是此处攻击者的做法却使攻击成功的可能性大大降低,可能是由于攻击者自身对webmin的执行过程不熟悉,认为执行条件是默认条件而产生疏忽所致。
  • 代码执行主要流程如下: 首先,在第12行需要passwd_mode为2,也就是之前复现中的“将提醒用户修改过期密码提示打钩并保存”这步会将其设置为2。由于webmin默认并不会设置其为2,这一步就会使绝大多数受害机不会遭受RCE。

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

  • 此外,根据以下代码中的if ($wuser->{'pass'} eq 'x')可知,如果user是unix的权限用户(root),则将其复制为undef,此时将不会进入后门触发处,所以在利用后门时,需要使用非root的用户。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Is this a Webmin user?
if (&foreign_check("acl")) {
&foreign_require("acl", "acl-lib.pl");
($wuser) = grep { $_->{'name'} eq $in{'user'} } &acl::list_users();
if ($wuser->{'pass'} eq 'x') {
# A Webmin user, but using Unix authentication
$wuser = undef;
}
elsif ($wuser->{'pass'} eq '*LK*' ||
$wuser->{'pass'} =~ /^\!/) {
&pass_error("Webmin users with locked accounts cannot change ".
"their passwords!");
}
}
if (!$in{'pam'} && !$wuser) {
$miniserv{'passwd_cindex'} ne '' && $miniserv{'passwd_mindex'} ne '' ||
die "Missing password file configuration";
}
if ($wuser) {
# Update Webmin user's password
$enc = &acl::encrypt_password($in{'old'}, $wuser->{'pass'});
$enc eq $wuser->{'pass'} || &pass_error($text{'password_eold'},qx/$in{'old'}/);
$perr = &acl::check_password_restrictions($in{'user'}, $in{'new1'});
$perr && &pass_error(&text('password_enewpass', $perr));
$wuser->{'pass'} = &acl::encrypt_password($in{'new1'});
$wuser->{'temppass'} = 0;
&acl::modify_user($wuser->{'name'}, $wuser);
&reload_miniserv();
}

总结

  • 此CVE是由黑客以某种方式篡改了webmin的官方SourceForge代码而写入的后门。
  • 整个后门的逻辑比较简单,分析过程也比较顺利。
  • 在后门追踪的过程中,可以体会到很多技术以外的东西以及当年最初接触到黑客文化的一种侠义感(:)开始吹比);第一次接触到代码跟踪,在过程中学到了一些东西。

参考资料

  • https://blog.firosolutions.com/exploits/webmin/
  • https://www.4hou.com/technology/19803.html
  • https://paper.seebug.org/1019/
  • https://github.com/webmin/webmin/issues/947