{"id":6042,"date":"2026-05-01T01:04:10","date_gmt":"2026-05-01T06:04:10","guid":{"rendered":"https:\/\/www.incredigeek.com\/home\/?p=6042"},"modified":"2026-05-01T01:10:14","modified_gmt":"2026-05-01T06:10:14","slug":"cve-2026-41940-whm-cpanel-authentication-bypass-checking-for-indicators-of-compromise","status":"publish","type":"post","link":"https:\/\/www.incredigeek.com\/home\/cve-2026-41940-whm-cpanel-authentication-bypass-checking-for-indicators-of-compromise\/","title":{"rendered":"CVE-2026-41940 &#8211; WHM &amp; cPanel Authentication Bypass, Checking for Indicators of Compromise"},"content":{"rendered":"\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Checking using the official cPanel script<\/li>\n\n\n\n<li>Checking the access logs<\/li>\n\n\n\n<li>How to check the last time WHM was upgraded<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Checking using the official cPanel script<\/h2>\n\n\n\n<p>The instructions for using the official script are on the cPanel article.<\/p>\n\n\n\n<p><a href=\"https:\/\/support.cpanel.net\/hc\/en-us\/articles\/40073787579671-Security-CVE-2026-41940-cPanel-WHM-WP2-Security-Update-04-28-2026\">https:\/\/support.cpanel.net\/hc\/en-us\/articles\/40073787579671-Security-CVE-2026-41940-cPanel-WHM-WP2-Security-Update-04-28-2026<\/a><\/p>\n\n\n\n<p>Copy and paste the script into a shell file.  Run the script.<\/p>\n\n\n\n<p>Here is a copy of the script for convenience.<\/p>\n\n\n\n<pre class=\"wp-block-code has-dark-gray-background-color has-background\"><code lang=\"bash\" class=\"language-bash line-numbers\">#!\/bin\/bash\n# Scan for compromised session files\n\nSESSIONS_DIR=\"\/var\/cpanel\/sessions\"\nCOMPROMISED=0\n\necho \"[*] Scanning session files for injection indicators...\"\n\nfor session_file in \"$SESSIONS_DIR\"\/raw\/*; do\n    [ -f \"$session_file\" ] || continue\n    session_name=$(basename \"$session_file\")\n\n    # Check if this session is\/was pre-auth\n    preauth_file=\"$SESSIONS_DIR\/preauth\/$session_name\"\n\n    # IOC 0: Session has both token_denied AND cp_security_token and method=badpass origin (strong indicator of exploitation)\n    #\n    # token_denied is set by do_token_denied() in cpsrvd when a request\n    # supplies an incorrect security token. cp_security_token is the\n    # attacker-injected token value. This combination indicates:\n    #\n    #   1. Attacker injected a cp_security_token via newline payload\n    #   2. Attacker attempted to use the injected token\n    #   3. cpsrvd recorded the token mismatch (token_denied counter)\n    #      during the exploitation window before the session was\n    #      fully promoted\n    #\n    # In a legitimate session:\n    #   - token_denied is only present after a user-initiated\n    #     security token failure (rare, typically from expired bookmarks)\n    #   - It would never co-exist with a badpass origin AND an\n    #     attacker-controlled cp_security_token\n    #\n    # This IOC catches BOTH successful and failed exploitation attempts.\n    if grep -q '^token_denied=' \"$session_file\" &amp;&amp; \\\n       grep -q '^cp_security_token=' \"$session_file\"; then\n\n        # Extract values for triage context\n        token_val=$(grep '^cp_security_token=' \"$session_file\" | head -1 | cut -d= -f2)\n        denied_val=$(grep '^token_denied=' \"$session_file\" | head -1 | cut -d= -f2)\n        origin=$(grep '^origin_as_string=' \"$session_file\" | head -1 | cut -d= -f2-)\n        used=$(grep -a \"$token_val\" \/usr\/local\/cpanel\/logs\/access_log | grep -m1 \" 200 \")\n        external_auth=$(grep '^successful_external_auth_with_timestamp=' \"$session_file\")\n\n        # High confidence if origin is badpass (session was pre-auth)\n        if grep -q '^origin_as_string=.*method=badpass' \"$session_file\"; then\n                if [ -z \"$external_auth\" ] &amp;&amp; [ -z \"$used\" ]; then\n                        echo \"Found possible injected session file: $session_file\"\n                        echo \"  - No sign of usage\"\n                else\n                    echo \"[!] CRITICAL: Exploitation artifact - token_denied with injected cp_security_token: $session_file\"\n                    echo \"    - cp_security_token=$token_val\"\n                    echo \"    - token_denied=$denied_val\"\n                    echo \"    - origin=$origin\"\n                    echo \"    - Verdict: Session was pre-auth (badpass origin) with attacker-injected token\"\n                    echo \"    - USED:  $used\"\n                    COMPROMISED=1\n                fi\n        # Medium confidence but still suspicious for any session\n        else\n            echo \"[!] WARNING: Suspicious session with token_denied + cp_security_token: $session_file\"\n            echo \"    - cp_security_token=$token_val\"\n            echo \"    - token_denied=$denied_val\"\n            echo \"    - origin=$origin\"\n            echo \"    - Review manually: may be legitimate token expiration or exploitation attempt\"\n        fi\n    fi\n\n    # IOC 1: Pre-auth session with authenticated attributes\n    if [ -f \"$preauth_file\" ]; then\n        if grep -qE '^successful_external_auth_with_timestamp=' \"$session_file\"; then\n            echo \"[!] CRITICAL: Injected session detected: $session_file\"\n            echo \"    - Contains 'successful_external_auth_with_timestamp' in pre-auth session\"\n            COMPROMISED=1\n        fi\n    fi\n\n    # IOC 2: Any session with tfa_verified but no valid origin\n    if grep -q '^tfa_verified=1' \"$session_file\" &amp;&amp; \\\n       ! grep -q '^origin_as_string=.*method=handle_form_login' \"$session_file\" &amp;&amp; \\\n       ! grep -q '^origin_as_string=.*method=create_user_session' \"$session_file\" &amp;&amp; \\\n       ! grep -q '^origin_as_string=.*method=handle_auth_transfer' \"$session_file\"; then\n        echo \"[!] WARNING: Session with tfa_verified but suspicious origin: $session_file\"\n        COMPROMISED=1\n    fi\n\n    # IOC 3: Password field containing newlines (corrupted session file)\n    if grep -qzP '(?m)^pass=.*\\n.' \"$session_file\" 2>\/dev\/null; then\n        echo \"[!] CRITICAL: Multi-line pass value detected: $session_file\"\n        COMPROMISED=1\n    fi\ndone\n\nif [ \"$COMPROMISED\" -eq 0 ]; then\n    echo \"\"\n    echo \"[+] No indicators of compromise found.\"\nelse\n    echo \"\"\n    echo \"[!] INDICATORS OF COMPROMISE DETECTED - IMMEDIATE ACTION REQUIRED\"\n    echo \"    1. Purge all affected sessions\"\n    echo \"    2. Force password reset for root and all WHM users\"\n    echo \"    3. Audit \/var\/log\/wtmp and WHM access logs for unauthorized access\"\n    echo \"    4. Check for persistence mechanisms (cron, SSH keys, backdoors)\"\nfi<\/code><\/pre>\n\n\n\n<p>Example output:<\/p>\n\n\n\n<pre class=\"wp-block-code has-dark-gray-background-color has-background\"><code lang=\"apacheconf\" class=\"language-apacheconf\">[!] WARNING: Suspicious session with token_denied + cp_security_token: \/var\/cpanel\/sessions\/raw\/bob@incredigeek.com:v_u2HprLu6MtCvPP\n    - cp_security_token=\/cpsess1634897720\n    - token_denied=1\n    - origin=address=192.168.1.12,app=webmaild,creator=bob@incredigeek.com,method=handle_form_login,path=form,possessed=0\n    - Review manually: may be legitimate token expiration or exploitation attempt\n[!] CRITICAL: Multi-line pass value detected: \/var\/cpanel\/sessions\/raw\/bob@incredigeek.com:v_u2HprLu6MtCvPP\nFound possible injected session file: \/var\/cpanel\/sessions\/raw\/:QM4Mx7bOR3BF7hRv\n   - No sign of usage\n[!] CRITICAL: Multi-line pass value detected: \/var\/cpanel\/sessions\/raw\/:QM4Mx7bOR3BF7hRv\n[!] CRITICAL: Exploitation artifact - token_denied with injected cp_security_token: \/var\/cpanel\/sessions\/raw\/:Q3f8Ag2epeBuTaIZ \n   - cp_security_token=\/cpsess04396539398 \n   - token_denied=1 \n   - origin=address=100.96.3.23,app=whostmgrd,method=badpass \n   - Verdict: Session was pre-auth (badpass origin) with attacker-injected token \n[!] WARNING: Session with tfa_verified but suspicious origin: \/var\/cpanel\/sessions\/raw\/:Q3f8Ag2epeBuTaIZ \n\n[!] INDICATORS OF COMPROMISE DETECTED - IMMEDIATE ACTION REQUIRED \n   1. Purge all affected sessions \n   2. Force password reset for root and all WHM users \n   3. Audit \/var\/log\/wtmp and WHM access logs for unauthorized access \n   4. Check for persistence mechanisms (cron, SSH keys, backdoors)<\/code><\/pre>\n\n\n\n<p>Some of the results may be false positives, which means you may have to manually check and see if results are valid or not.<\/p>\n\n\n\n<p>\u2139\ufe0f It appears that there can be a limit to the total number of sessions available on a system. You may want to double check how old the session files are (<code>ls -lt \/var\/cpanel\/sessions\/raw<\/code>) to ensure you catch all login attempts.  It is theoretically possible that the system was compromised, but the session that did it is no longer available, meaning it would not show up in the script provided by cPanel.  You should still be able to check the access_logs.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Checking the access logs<\/h2>\n\n\n\n<p>This may not be the most fool proof way to check for a compromise, but it may help identify if an IP address has been authenticated and accessed restricted endpoints.<\/p>\n\n\n\n<p>Replace valid-ip-address1 and valid-ip-address2 with your IP addresses.<\/p>\n\n\n\n<pre class=\"wp-block-code has-dark-gray-background-color has-background\"><code class=\"\">grep \"listacct\\|terminal\\|json-api\" \/usr\/local\/cpanel\/logs\/access_log |  grep -v \"403\\|401\" | grep -v \"valid-ip-address1\\|valid-ip-address2\"<\/code><\/pre>\n\n\n\n<p>Basically, we are searching for any valid requests that contain listacct, terminal, or json-api.  <\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How to c<strong>heck the last time WHM was upgraded<\/strong><\/h2>\n\n\n\n<p>If your server is set to automatically update WHM, it may be beneficial to know when it last updated.  You can check the update logs in <code>\/var\/cpanel\/updatelogs<\/code> to check the time and version.<\/p>\n\n\n\n<p>As a shortcut, you can use the following command to group all of the version changes from all of the update log files.  <\/p>\n\n\n\n<pre class=\"wp-block-code has-dark-gray-background-color has-background\"><code class=\"\">head \/var\/cpanel\/updatelogs\/update.*.log -n 20 | grep version | sort<\/code><\/pre>\n\n\n\n<p>Example output:<\/p>\n\n\n\n<pre class=\"wp-block-code has-dark-gray-background-color has-background\"><code lang=\"apacheconf\" class=\"language-apacheconf\">[2026-04-29 23:12:04 -0000]   Running version '11.134.0.19' of updatenow.\n[2026-04-29 23:12:04 -0000]   Become an updatenow.static for version: 11.134.0.20\n[2026-04-29 23:12:04 -0000]   Detected version '11.134.0.19' from version file.\n[2026-04-29 23:12:04 -0000]   Switching to version 11.134.0.20 of updatenow to determine if we can reach that version without failure.\n[2026-04-29 23:12:04 -0000]   Target version set to '11.134.0.20'\n[2026-04-30 23:12:04 -0000]   Detected version '11.134.0.20' from version file.\n[2026-04-30 23:12:04 -0000]   Running version '11.134.0.20' of updatenow.\n[2026-04-30 23:12:04 -0000]   Target version set to '11.134.0.20'<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><\/h2>\n\n\n\n<p>Links:<\/p>\n\n\n\n<p><a href=\"https:\/\/labs.watchtowr.com\/the-internet-is-falling-down-falling-down-falling-down-cpanel-whm-authentication-bypass-cve-2026-41940\">https:\/\/labs.watchtowr.com\/the-internet-is-falling-down-falling-down-falling-down-cpanel-whm-authentication-bypass-cve-2026-41940<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/github.com\/watchtowrlabs\/watchTowr-vs-cPanel-WHM-AuthBypass-to-RCE.py\">https:\/\/github.com\/watchtowrlabs\/watchTowr-vs-cPanel-WHM-AuthBypass-to-RCE.py<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/hadrian.io\/blog\/cve-2026-41940-a-critical-authentication-bypass-in-cpanel\">https:\/\/hadrian.io\/blog\/cve-2026-41940-a-critical-authentication-bypass-in-cpanel<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Checking using the official cPanel script The instructions for using the official script are on the cPanel article. https:\/\/support.cpanel.net\/hc\/en-us\/articles\/40073787579671-Security-CVE-2026-41940-cPanel-WHM-WP2-Security-Update-04-28-2026 Copy and paste the script into a shell file. Run the script. Here is a copy of the script for convenience. &hellip; <a href=\"https:\/\/www.incredigeek.com\/home\/cve-2026-41940-whm-cpanel-authentication-bypass-checking-for-indicators-of-compromise\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[195,573],"tags":[1740,1739,196,7,235,503,382],"class_list":["post-6042","post","type-post","status-publish","format-standard","hentry","category-cpanel","category-security","tag-0-day","tag-0day","tag-cpanel-2","tag-linux-2","tag-logs","tag-security","tag-whm"],"_links":{"self":[{"href":"https:\/\/www.incredigeek.com\/home\/wp-json\/wp\/v2\/posts\/6042","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.incredigeek.com\/home\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.incredigeek.com\/home\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.incredigeek.com\/home\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.incredigeek.com\/home\/wp-json\/wp\/v2\/comments?post=6042"}],"version-history":[{"count":10,"href":"https:\/\/www.incredigeek.com\/home\/wp-json\/wp\/v2\/posts\/6042\/revisions"}],"predecessor-version":[{"id":6053,"href":"https:\/\/www.incredigeek.com\/home\/wp-json\/wp\/v2\/posts\/6042\/revisions\/6053"}],"wp:attachment":[{"href":"https:\/\/www.incredigeek.com\/home\/wp-json\/wp\/v2\/media?parent=6042"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.incredigeek.com\/home\/wp-json\/wp\/v2\/categories?post=6042"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.incredigeek.com\/home\/wp-json\/wp\/v2\/tags?post=6042"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}