145 أسطر
5.7 KiB
Bash
145 أسطر
5.7 KiB
Bash
#!/usr/bin/env bash
|
|
#
|
|
# ghaymah_ssl_ports_privileges.sh
|
|
#
|
|
# Three light-touch, passive checks against ghaymah.systems:
|
|
# 1. SSL/TLS configuration
|
|
# 2. Common port reachability (curated list, single connect attempt each -
|
|
# NOT a full 65535-port scan)
|
|
# 3. Privilege/access-control exposure (unauthenticated GET/OPTIONS only -
|
|
# no login attempts, no credential guessing,
|
|
# no exploitation)
|
|
#
|
|
# SCOPE / ETHICS NOTE
|
|
# --------------------
|
|
# This script only sends single, standard requests per check (the same kind
|
|
# of traffic a browser or a public attack-surface scanner already generates).
|
|
# It does not flood, brute-force, authenticate, or attempt to exploit
|
|
# anything. Still: only run this against a target you have real, documented
|
|
# authorization to test. If you don't already have a written scope from
|
|
# Ghaymah's security team (which hosts/paths are in scope, a time window,
|
|
# and a contact in case something trips their monitoring), get that in
|
|
# writing before running this - an informal "they said it's fine" for an
|
|
# exam is good context, but a scoped engagement letter is what actually
|
|
# protects you if their SOC flags the traffic.
|
|
|
|
set -uo pipefail
|
|
|
|
TARGET="ghaymah.systems"
|
|
URL="https://${TARGET}"
|
|
TIMEOUT=5
|
|
|
|
pass() { printf " \033[32m[PASS]\033[0m %s\n" "$1"; }
|
|
fail() { printf " \033[31m[FAIL]\033[0m %s\n" "$1"; }
|
|
info() { printf " \033[36m[INFO]\033[0m %s\n" "$1"; }
|
|
warn() { printf " \033[33m[WARN]\033[0m %s\n" "$1"; }
|
|
|
|
command -v curl >/dev/null 2>&1 || { echo "curl is required."; exit 1; }
|
|
command -v openssl >/dev/null 2>&1 || { echo "openssl is required."; exit 1; }
|
|
|
|
echo "=================================================="
|
|
echo " Ghaymah Cloud - SSL / Ports / Privilege Checks"
|
|
echo " Target: $TARGET"
|
|
echo " Date: $(date -u +"%Y-%m-%d %H:%M UTC")"
|
|
echo "=================================================="
|
|
|
|
##############################################
|
|
# 1. SSL / TLS Configuration
|
|
##############################################
|
|
echo ""
|
|
echo "--- [1] SSL / TLS Configuration ---"
|
|
|
|
CERT_INFO=$(echo | openssl s_client -connect "${TARGET}:443" -servername "$TARGET" 2>/dev/null \
|
|
| openssl x509 -noout -dates -subject -issuer 2>/dev/null)
|
|
if [[ -n "$CERT_INFO" ]]; then
|
|
echo "$CERT_INFO" | sed 's/^/ /'
|
|
pass "Certificate retrieved"
|
|
else
|
|
fail "Could not retrieve certificate"
|
|
fi
|
|
|
|
for version in tls1 tls1_1 tls1_2 tls1_3; do
|
|
if echo | timeout "$TIMEOUT" openssl s_client -connect "${TARGET}:443" -"$version" 2>/dev/null | grep -q "Cipher is"; then
|
|
case $version in
|
|
tls1|tls1_1) fail "Deprecated protocol accepted: $version (should be disabled)" ;;
|
|
tls1_2) info "tls1_2 supported" ;;
|
|
tls1_3) pass "tls1_3 supported" ;;
|
|
esac
|
|
else
|
|
if [[ "$version" == "tls1" || "$version" == "tls1_1" ]]; then
|
|
pass "$version correctly rejected"
|
|
else
|
|
info "$version not negotiated by this openssl build (may be a local limitation)"
|
|
fi
|
|
fi
|
|
done
|
|
|
|
CIPHER_LINE=$(echo | openssl s_client -connect "${TARGET}:443" -servername "$TARGET" 2>/dev/null | grep "Cipher :")
|
|
[[ -n "$CIPHER_LINE" ]] && info "Negotiated cipher:${CIPHER_LINE#*:}"
|
|
|
|
##############################################
|
|
# 2. Common Port Reachability (curated, not a full scan)
|
|
##############################################
|
|
echo ""
|
|
echo "--- [2] Common Port Reachability (curated list only) ---"
|
|
|
|
declare -A COMMON_PORTS=(
|
|
[21]="FTP" [22]="SSH" [23]="Telnet" [25]="SMTP"
|
|
[80]="HTTP" [443]="HTTPS" [3306]="MySQL" [3389]="RDP"
|
|
[5432]="PostgreSQL" [6379]="Redis" [8080]="HTTP-alt" [8443]="HTTPS-alt"
|
|
)
|
|
|
|
for port in "${!COMMON_PORTS[@]}"; do
|
|
if timeout 2 bash -c "cat < /dev/null > /dev/tcp/${TARGET}/${port}" 2>/dev/null; then
|
|
case $port in
|
|
80|443) pass "Port $port (${COMMON_PORTS[$port]}) open - expected for a web platform" ;;
|
|
*) warn "Port $port (${COMMON_PORTS[$port]}) open - review whether this should be public" ;;
|
|
esac
|
|
else
|
|
info "Port $port (${COMMON_PORTS[$port]}) closed/filtered"
|
|
fi
|
|
sleep 0.3 # deliberately slow - this is a light check, not a rapid scan
|
|
done
|
|
|
|
##############################################
|
|
# 3. Privilege / Access-Control Exposure
|
|
##############################################
|
|
echo ""
|
|
echo "--- [3] Privilege / Access-Control Exposure ---"
|
|
|
|
info "Checking allowed HTTP methods..."
|
|
ALLOW=$(curl -sS -X OPTIONS -D - "$URL" -o /dev/null --max-time "$TIMEOUT" | grep -i "^Allow:" | tr -d '\r')
|
|
if [[ -n "$ALLOW" ]]; then
|
|
echo " $ALLOW"
|
|
if echo "$ALLOW" | grep -qiE "PUT|DELETE|TRACE"; then
|
|
warn "Potentially risky HTTP method(s) advertised"
|
|
else
|
|
pass "No obviously risky HTTP methods advertised"
|
|
fi
|
|
else
|
|
info "No Allow header returned (OPTIONS may simply not be implemented)"
|
|
fi
|
|
|
|
# Common sensitive/admin paths - single unauthenticated GET each, checking
|
|
# ONLY whether the path is reachable, not attempting to use anything found.
|
|
SENSITIVE_PATHS=(
|
|
"/admin" "/.env" "/.git/config" "/wp-admin"
|
|
"/server-status" "/debug" "/actuator/health" "/.well-known/security.txt"
|
|
)
|
|
|
|
for path in "${SENSITIVE_PATHS[@]}"; do
|
|
code=$(curl -sS -o /dev/null -w "%{http_code}" --max-time "$TIMEOUT" "${URL}${path}")
|
|
if [[ "$code" == "200" ]]; then
|
|
warn "$path returned HTTP 200 - review whether this should be publicly reachable"
|
|
else
|
|
pass "$path not exposed (HTTP $code)"
|
|
fi
|
|
sleep 0.2
|
|
done
|
|
|
|
echo ""
|
|
echo "=================================================="
|
|
echo " Done. WARN lines need human review - some may be"
|
|
echo " intentional (e.g. security.txt SHOULD return 200)."
|
|
echo "=================================================="
|