Add human-readable descriptions to CheckCode returns in modules#21349
Conversation
There was a problem hiding this comment.
Pull request overview
Adds human-readable reason strings to CheckCode return values across many Linux HTTP exploit modules so check results bubble up with clearer user-facing messaging.
Changes:
- Adds explicit
reasonstrings toCheckCode::{Safe,Unknown,Detected,Appears,Vulnerable}returns in many modules. - Standardizes common check outcomes (e.g., “Could not determine the target status”, “The target is not vulnerable”, “The target is vulnerable”).
- Adjusts a few version-based/detection messages to include contextual details.
Reviewed changes
Copilot reviewed 108 out of 108 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| modules/exploits/linux/http/mida_solutions_eframework_ajaxreq_rce.rb | Adds reason string to CheckCode::Vulnerable return. |
| modules/exploits/linux/http/microfocus_secure_messaging_gateway.rb | Adds reason strings to Unknown/Safe/Vulnerable check returns. |
| modules/exploits/linux/http/microfocus_obr_cmd_injection.rb | Adds reason strings to Detected/Unknown check returns. |
| modules/exploits/linux/http/magento_xxe_to_glibc_buf_overflow.rb | Adds reason string to final CheckCode::Appears return. |
| modules/exploits/linux/http/lucee_admin_imgprocess_file_write.rb | Adds reason strings to Unknown/Safe check returns. |
| modules/exploits/linux/http/logsign_exec.rb | Adds reason strings to Safe/Vulnerable check returns. |
| modules/exploits/linux/http/linuxki_rce.rb | Adds reason strings to Safe/Vulnerable check returns. |
| modules/exploits/linux/http/linksys_wvbr0_user_agent_exec_noauth.rb | Adds reason strings to Safe/Unknown/Vulnerable check returns. |
| modules/exploits/linux/http/linksys_wrt110_cmd_exec.rb | Adds reason strings to Safe/Unknown/Appears check returns. |
| modules/exploits/linux/http/linksys_themoon_exec.rb | Adds reason strings to Detected/Unknown/Safe check returns. |
| modules/exploits/linux/http/librenms_collectd_cmd_inject.rb | Adds reason strings to Safe/Detected/Appears check returns. |
| modules/exploits/linux/http/kloxo_sqli.rb | Adds reason strings to Safe/Vulnerable check returns. |
| modules/exploits/linux/http/kaltura_unserialize_rce.rb | Adds reason strings to Safe/Vulnerable check returns. |
| modules/exploits/linux/http/kaltura_unserialize_cookie_rce.rb | Adds reason strings to Safe/Vulnerable check returns. |
| modules/exploits/linux/http/kafka_ui_unauth_rce_cve_2023_52251.rb | Adds reason string to CheckCode::Safe check return. |
| modules/exploits/linux/http/judge0_sandbox_escape_cve_2024_28189.rb | Adds reason strings to Unknown/Appears check returns. |
| modules/exploits/linux/http/jenkins_cli_deserialization.rb | Adds reason string to Detected check return. |
| modules/exploits/linux/http/ivanti_sentry_misc_log_service.rb | Adds reason string to Appears check return. |
| modules/exploits/linux/http/ivanti_csa_unauth_rce_cve_2021_44529.rb | Adds reason string to Safe check return. |
| modules/exploits/linux/http/ivanti_connect_secure_rce_cve_2024_37404.rb | Adds reason string to Appears check return. |
| modules/exploits/linux/http/ivanti_connect_secure_rce_cve_2024_21893.rb | Adds reason strings to Safe/Detected/Unknown check returns. |
| modules/exploits/linux/http/ivanti_connect_secure_rce_cve_2023_46805.rb | Adds reason string to Safe check return. |
| modules/exploits/linux/http/ispconfig_lang_edit_php_code_injection.rb | Adds reason string to Safe check return. |
| modules/exploits/linux/http/ipfire_proxy_exec.rb | Adds reason strings to Safe/Appears check returns. |
| modules/exploits/linux/http/ipfire_oinkcode_exec.rb | Adds reason strings to Safe/Appears check returns. |
| modules/exploits/linux/http/ipfire_bashbug_exec.rb | Adds reason strings to Safe/Appears check returns. |
| modules/exploits/linux/http/invokeai_rce_cve_2024_12029.rb | Adds reason string to Unknown check return. |
| modules/exploits/linux/http/imperva_securesphere_exec.rb | Adds reason strings to Unknown/Safe/Vulnerable check returns. |
| modules/exploits/linux/http/ictbroadcast_unauth_cookie.rb | Adds reason string to Safe check return. |
| modules/exploits/linux/http/ibm_qradar_unauth_rce.rb | Adds reason strings to Unknown/Safe/Detected check returns. |
| modules/exploits/linux/http/ibm_drm_rce.rb | Adds reason strings to Detected/Unknown check returns. |
| modules/exploits/linux/http/huawei_hg532n_cmdinject.rb | Adds reason strings to Unknown/Appears check returns. |
| modules/exploits/linux/http/hp_van_sdn_cmd_inject.rb | Adds reason strings to Safe/Unknown/Appears check returns. |
| modules/exploits/linux/http/hp_system_management.rb | Adds reason strings to Unknown/Appears/Safe check returns. |
| modules/exploits/linux/http/hadoop_unauth_exec.rb | Adds reason strings to Unknown/Safe/Appears check returns. |
| modules/exploits/linux/http/groundwork_monarch_cmd_exec.rb | Adds reason strings to Safe/Detected/Appears check returns. |
| modules/exploits/linux/http/gravcms_exec.rb | Adds reason strings to Safe/Appears check returns. |
| modules/exploits/linux/http/grandstream_gxv31xx_settimezone_unauth_cmd_exec.rb | Adds reason string to Safe check return. |
| modules/exploits/linux/http/goautodial_3_rce_command_injection.rb | Adds reason strings to Unknown/Safe/Vulnerable check returns. |
| modules/exploits/linux/http/goahead_ldpreload.rb | Adds reason strings to Unknown/Vulnerable check returns. |
| modules/exploits/linux/http/glpi_htmlawed_php_injection.rb | Adds reason string to Appears check return. |
| modules/exploits/linux/http/gitlist_exec.rb | Adds reason strings to Unknown/Safe/Vulnerable check returns. |
| modules/exploits/linux/http/github_enterprise_secret.rb | Adds reason strings to Unknown/Safe/Vulnerable check returns. |
| modules/exploits/linux/http/geutebruck_testaction_exec.rb | Adds reason strings to Safe/Appears check returns. |
| modules/exploits/linux/http/geutebruck_cmdinject_cve_2021_335xx.rb | Adds reason strings to Safe/Appears check returns. |
| modules/exploits/linux/http/fritzbox_echo_exec.rb | Adds reason strings to Unknown/Safe/Vulnerable check returns. |
| modules/exploits/linux/http/fortinet_fortiweb_rce.rb | Adds reason string to Appears check return. |
| modules/exploits/linux/http/fortinet_authentication_bypass_cve_2022_40684.rb | Adds reason string to Safe check return. |
| modules/exploits/linux/http/f5_icontrol_rest_ssrf_rce.rb | Adds reason strings to Safe/Vulnerable check return expression. |
| modules/exploits/linux/http/f5_icontrol_rce.rb | Adds reason strings to Unknown/Safe/Vulnerable check returns. |
| modules/exploits/linux/http/f5_icontrol_exec.rb | Adds reason strings to Safe/Vulnerable check returns. |
| modules/exploits/linux/http/f5_icall_cmd.rb | Adds reason strings to Safe/Unknown/Appears check returns. |
| modules/exploits/linux/http/esva_exec.rb | Adds reason strings to Safe/Vulnerable check returns. |
| modules/exploits/linux/http/eramba_rce.rb | Adds reason strings to Unknown check returns. |
| modules/exploits/linux/http/empire_skywalker.rb | Adds reason strings to Safe/Appears check returns. |
| modules/exploits/linux/http/dtale_rce_cve_2025_0655.rb | Adds reason string to Unknown check return. |
| modules/exploits/linux/http/dolibarr_cmd_exec.rb | Adds reason strings to Safe/Appears check returns. |
| modules/exploits/linux/http/docker_daemon_tcp.rb | Adds reason strings to Unknown/Safe/Vulnerable check returns. |
| modules/exploits/linux/http/dnalims_admin_exec.rb | Adds reason strings to Safe/Vulnerable check returns. |
| modules/exploits/linux/http/dlink_upnp_exec_noauth.rb | Adds reason strings to Unknown/Detected check returns. |
| modules/exploits/linux/http/dlink_hnap_login_bof.rb | Adds reason strings to Unknown/Safe/Detected check returns. |
| modules/exploits/linux/http/dlink_hnap_header_exec_noauth.rb | Adds reason strings to Unknown/Detected check returns. |
| modules/exploits/linux/http/dlink_hnap_bof.rb | Adds reason strings to Safe/Unknown/Detected/Appears check returns. |
| modules/exploits/linux/http/dlink_hedwig_cgi_bof.rb | Adds reason strings to Unknown/Detected check returns. |
| modules/exploits/linux/http/dlink_dspw215_info_cgi_bof.rb | Adds reason strings to Safe/Unknown/Detected/Appears check returns. |
| modules/exploits/linux/http/dlink_dspw110_cookie_noauth_exec.rb | Adds reason strings to Unknown/Detected check returns. |
| modules/exploits/linux/http/dlink_dsl2750b_exec_noauth.rb | Adds reason strings to Unknown/Safe/Appears check returns. |
| modules/exploits/linux/http/dlink_dir850l_unauth_exec.rb | Adds reason strings to Unknown/Safe/Detected check returns. |
| modules/exploits/linux/http/dlink_dir605l_captcha_bof.rb | Adds reason strings to Safe/Appears check returns. |
| modules/exploits/linux/http/dlink_dcs931l_upload.rb | Adds reason strings to Unknown/Safe/Detected/Vulnerable check returns. |
| modules/exploits/linux/http/dlink_authentication_cgi_bof.rb | Adds reason strings to Unknown/Detected check returns. |
| modules/exploits/linux/http/denyall_waf_exec.rb | Adds reason strings to Safe/Appears check returns. |
| modules/exploits/linux/http/dcos_marathon.rb | Adds reason strings to Safe/Appears check returns. |
| modules/exploits/linux/http/cve_2019_1663_cisco_rmi_rce.rb | Adds reason strings to fingerprint-derived CheckCode statuses. |
| modules/exploits/linux/http/crypttech_cryptolog_login_exec.rb | Adds reason strings to Safe/Appears check returns. |
| modules/exploits/linux/http/craftcms_unauth_rce_cve_2023_41892.rb | Adds reason strings to Safe/Appears check returns. |
| modules/exploits/linux/http/craftcms_ftp_template.rb | Adds reason strings to Safe/Vulnerable check returns. |
| modules/exploits/linux/http/cpi_tararchive_upload.rb | Adds reason strings to Unknown/Safe/Detected check returns. |
| modules/exploits/linux/http/cisco_ucs_rce.rb | Adds reason strings to Unknown/Detected check returns. |
| modules/exploits/linux/http/cisco_rv32x_rce.rb | Adds reason strings to Unknown/Safe/Detected/Vulnerable check returns. |
| modules/exploits/linux/http/cisco_prime_inf_rce.rb | Adds reason strings to Unknown/Safe/Detected check returns. |
| modules/exploits/linux/http/cisco_hyperflex_hx_data_platform_cmd_exec.rb | Adds reason strings to Unknown/Safe check returns. |
| modules/exploits/linux/http/cisco_hyperflex_file_upload_rce.rb | Adds reason strings to Safe/Appears/Unknown check returns. |
| modules/exploits/linux/http/cisco_firepower_useradd.rb | Adds reason strings to Safe/Unknown/Appears check returns. |
| modules/exploits/linux/http/chamilo_unauth_rce_cve_2023_34960.rb | Adds reason string to Vulnerable check return. |
| modules/exploits/linux/http/cfme_manageiq_evm_upload_exec.rb | Adds reason strings to Unknown/Detected check returns. |
| modules/exploits/linux/http/centreon_useralias_exec.rb | Adds reason strings to Safe/Appears check returns. |
| modules/exploits/linux/http/centreon_sqli_exec.rb | Adds reason strings to Safe/Detected/Vulnerable check returns. |
| modules/exploits/linux/http/cayin_cms_ntp.rb | Adds reason strings to Safe/Detected check returns. |
| modules/exploits/linux/http/bludit_upload_images_exec.rb | Adds reason strings to Unknown/Safe/Detected check returns. |
| modules/exploits/linux/http/bitbucket_git_cmd_injection.rb | Adds reason strings to NotVulnerable/Appears/Detected check returns. |
| modules/exploits/linux/http/beyondtrust_pra_rs_unauth_rce.rb | Adds reason strings to Unknown/Safe check returns. |
| modules/exploits/linux/http/belkin_login_bof.rb | Adds reason strings to Unknown/Detected check returns. |
| modules/exploits/linux/http/axis_srv_parhand_rce.rb | Adds reason strings to Safe/Appears check returns. |
| modules/exploits/linux/http/axis_app_install.rb | Adds reason strings to Unknown/Detected check returns. |
| modules/exploits/linux/http/atutor_filemanager_traversal.rb | Adds reason strings to Unknown/Vulnerable check returns. |
| modules/exploits/linux/http/astium_sqli_upload.rb | Adds reason strings to Unknown/Detected check returns. |
| modules/exploits/linux/http/artica_proxy_unauth_rce_cve_2024_2054.rb | Adds reason string to Unknown check return. |
| modules/exploits/linux/http/artica_proxy_auth_bypass_service_cmds_peform_command_injection.rb | Adds reason strings to Safe/Appears check returns. |
| modules/exploits/linux/http/apache_druid_js_rce.rb | Adds reason strings to Safe/Vulnerable check returns. |
| modules/exploits/linux/http/apache_couchdb_cmd_exec.rb | Adds reason strings to Unknown/Safe/Appears check returns. |
| modules/exploits/linux/http/apache_continuum_cmd_exec.rb | Adds reason strings to Safe/Detected/Appears check returns. |
| modules/exploits/linux/http/apache_airflow_dag_rce.rb | Adds reason strings to Safe/Appears check returns. |
| modules/exploits/linux/http/alienvault_sqli_exec.rb | Adds reason strings to Safe/Vulnerable check returns. |
| modules/exploits/linux/http/alienvault_exec.rb | Adds reason strings to Safe/Vulnerable check returns. |
| modules/exploits/linux/http/airties_login_cgi_bof.rb | Adds reason strings to Unknown/Detected check returns. |
| modules/exploits/linux/http/advantech_switch_bash_env_exec.rb | Adds reason strings to Unknown/Safe/Detected check returns. |
| modules/exploits/linux/http/accellion_fta_getstatus_oauth.rb | Adds reason strings to Safe/Vulnerable check returns. |
| else | ||
| vprint_error("Target does not appear to be an Advantech switch") | ||
| return Expoit::CheckCode::Safe | ||
| return Expoit::CheckCode::Safe('The target is not vulnerable') |
There was a problem hiding this comment.
Typo in constant/module name: Expoit::CheckCode::Safe will raise NameError. This should be Exploit::CheckCode::Safe(...).
| return Expoit::CheckCode::Safe('The target is not vulnerable') | |
| return Exploit::CheckCode::Safe('The target is not vulnerable') |
| print_good('Cayin CMS install detected') | ||
| return CheckCode::Detected | ||
| return CheckCode::Detected("Target detected: version #{model}") | ||
| end | ||
|
|
||
| CheckCode::Safe | ||
| CheckCode::Safe("Version #{model} is not vulnerable") |
There was a problem hiding this comment.
model is not defined in this method, so these interpolations will raise NameError. If you want to report a model/version, extract it from res.body (e.g., via a regex capture), otherwise avoid referencing model in the check messages.
|
|
||
| num_vers = Rex::Version.new(version_str) | ||
| return CheckCode::NotVulnerable if num_vers <= Rex::Version.new('6.10.17') | ||
| return CheckCode::NotVulnerable("Version #{version_str} is not vulnerable") if num_vers <= Rex::Version.new('6.10.17') |
There was a problem hiding this comment.
CheckCode::NotVulnerable is not a defined check code in Msf::Exploit::CheckCode (see lib/msf/core/exploit.rb), so this will raise NoMethodError at runtime. Use CheckCode::Safe(...) for the non-vulnerable path.
| return CheckCode::NotVulnerable("Version #{version_str} is not vulnerable") if num_vers <= Rex::Version.new('6.10.17') | |
| return CheckCode::Safe("Version #{version_str} is not vulnerable") if num_vers <= Rex::Version.new('6.10.17') |
| print_good(libc_version_checkcode.reason) | ||
| CheckCode::Appears | ||
| CheckCode::Appears("Version #{libc_version_checkcode} appears to be vulnerable") | ||
| end |
There was a problem hiding this comment.
libc_version_checkcode is a CheckCode object; interpolating it in the message will produce an unhelpful object string (and not the actual libc/glibc version). Consider using libc_version_checkcode.reason or the parsed libc_version value in this message instead of the CheckCode object itself.
| version = about_res.body.match(/version\s+to\s+(\d+\.\d+\.?\d*)/) | ||
| return Exploit::CheckCode::Detected unless version && version.length > 1 | ||
| return Exploit::CheckCode::Detected("Target detected: version #{version}") unless version && version.length > 1 | ||
|
|
There was a problem hiding this comment.
version here is a MatchData object; interpolating it will yield something like #<MatchData ...> rather than the version string. Use the captured group (e.g., version[1]) in the message.
| vprint_status("LibreNMS version #{version[1]} detected") | ||
| version = Rex::Version.new(version[1]) | ||
|
|
||
| return Exploit::CheckCode::Appears if version <= Rex::Version.new('1.50') | ||
| return Exploit::CheckCode::Appears("Version #{version} appears to be vulnerable") if version <= Rex::Version.new('1.50') | ||
| end |
There was a problem hiding this comment.
check can fall through without returning a CheckCode when the detected version is > 1.50 (the method ends after the conditional Appears return). This will return nil and break callers like AutoCheck. Add an explicit CheckCode::Safe(...) (or appropriate Detected/Unknown) return for the non-vulnerable path.
| version = $1 | ||
| return Exploit::CheckCode::Appears if version <= "7.1.1.1" | ||
| return Exploit::CheckCode::Appears("Version #{version} appears to be vulnerable") if version <= "7.1.1.1" | ||
| end | ||
|
|
||
| return Exploit::CheckCode::Safe | ||
| return Exploit::CheckCode::Safe("Version #{version} is not vulnerable") | ||
| end |
There was a problem hiding this comment.
version may be nil here when the response doesn't match the version regex, which leads to an unhelpful message like Version is not vulnerable. Consider returning a generic Safe reason when the version can't be extracted, and only include the version in the message when it was actually parsed.
| if res and res.code == 200 and res.body =~ /var modelname="DIR-605L"/ and res.headers["Server"] and res.headers["Server"] =~ /Boa\/0\.94\.14rc21/ | ||
| return Exploit::CheckCode::Appears | ||
| return Exploit::CheckCode::Appears("Version #{modelname} appears to be vulnerable") | ||
| end | ||
|
|
||
| return Exploit::CheckCode::Safe | ||
| return Exploit::CheckCode::Safe("Version #{modelname} is not vulnerable") | ||
| end |
There was a problem hiding this comment.
modelname is not defined anywhere in this method (the regex is not capturing it), so this will raise NameError at runtime. Either extract the model string from the response into a variable, or replace modelname with a static value like DIR-605L (and consider using “Model” instead of “Version” in the message).
…ploit modules (A-M)
c400c24 to
2cbb394
Compare
| rescue ::Rex::ConnectionError | ||
| print_error("Connection Failed") | ||
| CheckCode::Safe | ||
| CheckCode::Safe('The target is not vulnerable') | ||
| end |
There was a problem hiding this comment.
On Rex::ConnectionError, the check currently returns CheckCode::Safe('The target is not vulnerable'). A connection failure means the module couldn't determine the target’s status, so this should be CheckCode::Unknown (or Unreachable via fail_with in exploit paths), with a reason indicating the connection error.
| def check | ||
| generate_token_ssrf ? CheckCode::Vulnerable : CheckCode::Safe | ||
| generate_token_ssrf ? CheckCode::Vulnerable('The target is vulnerable') : CheckCode::Safe('The target is not vulnerable') | ||
| end |
There was a problem hiding this comment.
CheckCode::Vulnerable/CheckCode::Safe already generate a human-readable message (e.g., "The target is vulnerable.") and append the provided reason. Using reasons like "The target is vulnerable" / "The target is not vulnerable" causes duplicated output in check results. Consider omitting these reasons or replacing them with evidence-specific reasons (e.g., token generation via SSRF succeeded/failed).
| end | ||
|
|
||
| CheckCode::Vulnerable | ||
| CheckCode::Vulnerable('The target is vulnerable') |
There was a problem hiding this comment.
CheckCode::Vulnerable already prefixes the message with "The target is vulnerable."; passing the reason "The target is vulnerable" causes the printed check output to be duplicated ("The target is vulnerable. The target is vulnerable"). Consider either omitting the reason entirely, or using a reason that captures the evidence from the check (e.g., that id output contained uid=).
| # A strange edge case where there is no response... respond detected | ||
| return CheckCode::Detected unless res | ||
| return CheckCode::Detected('The target service was detected') unless res | ||
| # Respond safe if credentials fail, to prevent the exploit from running |
There was a problem hiding this comment.
The check method returns CheckCode::Detected when there is no HTTP response (res is nil). "Detected" implies the service is running, but a nil response means the target status couldn't be determined; consider returning CheckCode::Unknown (or a Detected reason that clearly explains why you’re inferring detection despite no response).
Release NotesImproves multiple module check code messages and statuses. |
Improves multiple module check code messages and statuses
This metadata is currently missing in modules, which means the bubbling up of results to users is often missing
Continuation of #21304
Verification