Skip to content

Add human-readable descriptions to CheckCode returns in modules#21349

Merged
cgranleese-r7 merged 1 commit intorapid7:masterfrom
adfoster-r7:improve-checkcode-messages-2
Apr 22, 2026
Merged

Add human-readable descriptions to CheckCode returns in modules#21349
cgranleese-r7 merged 1 commit intorapid7:masterfrom
adfoster-r7:improve-checkcode-messages-2

Conversation

@adfoster-r7
Copy link
Copy Markdown
Contributor

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

  • Ensure CI passes
  • Ensure the updated messages are sensical

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 reason strings to CheckCode::{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')
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in constant/module name: Expoit::CheckCode::Safe will raise NameError. This should be Exploit::CheckCode::Safe(...).

Suggested change
return Expoit::CheckCode::Safe('The target is not vulnerable')
return Exploit::CheckCode::Safe('The target is not vulnerable')

Copilot uses AI. Check for mistakes.
Comment on lines +77 to +81
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")
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.

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')
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
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')

Copilot uses AI. Check for mistakes.
Comment on lines 189 to 191
print_good(libc_version_checkcode.reason)
CheckCode::Appears
CheckCode::Appears("Version #{libc_version_checkcode} appears to be vulnerable")
end
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines 76 to 78
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

Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines 79 to 83
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
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines 84 to 89
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
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines 87 to 92
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
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 108 out of 108 changed files in this pull request and generated 4 comments.

Comment on lines 84 to 87
rescue ::Rex::ConnectionError
print_error("Connection Failed")
CheckCode::Safe
CheckCode::Safe('The target is not vulnerable')
end
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines 116 to 118
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
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Copilot uses AI. Check for mistakes.
end

CheckCode::Vulnerable
CheckCode::Vulnerable('The target is vulnerable')
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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=).

Copilot uses AI. Check for mistakes.
Comment on lines 104 to 106
# 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
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Copilot uses AI. Check for mistakes.
@cgranleese-r7 cgranleese-r7 self-assigned this Apr 22, 2026
@cgranleese-r7 cgranleese-r7 added the rn-enhancement release notes enhancement label Apr 22, 2026
@cgranleese-r7
Copy link
Copy Markdown
Contributor

Release Notes

Improves multiple module check code messages and statuses.

@github-project-automation github-project-automation Bot moved this from Todo to In Progress in Metasploit Kanban Apr 22, 2026
@cgranleese-r7 cgranleese-r7 merged commit 380911d into rapid7:master Apr 22, 2026
22 of 23 checks passed
@github-project-automation github-project-automation Bot moved this from In Progress to Done in Metasploit Kanban Apr 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

rn-enhancement release notes enhancement

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants