çalıştırmak için:
bash php_cve_audit.sh # standart tarama bash php_cve_audit.sh --refresh # önce paket metadata'sını yenile (apt/dnf/yum/brew) bash php_cve_audit.sh --deep # ayrıca dosya sisteminde php binary'si ara (yavaş) bash php_cve_audit.sh --no-color # renksiz çıktı (çıktı terminal değilse otomatik) bash php_cve_audit.sh --helpgithub üzerinden erişmek isterseniz.
https://github.com/mehmetkuruyuz/php-cve-audit
Alttaki kodu nasıl kullanacaksınız.
nano php_cve_audit.sh;
içeriği kopyala - yapıştır
yukardaki komutları uygula
#!/usr/bin/env bash
# =============================================================================
# https://github.com/mehmetkuruyuz
# php_cve_audit.sh - Sistemdeki TÜM PHP kurulumlarını bulur ve
# CVE-2026-109618 / CVE-2026-109619 (RCE) açısından denetler.
#
# Desteklenen: Debian/Ubuntu (apt), RHEL/Alma/Rocky/CentOS/Fedora (dnf/yum),
# Plesk, cPanel EA-PHP, CloudLinux alt-php, DirectAdmin, Remi SCL,
# aaPanel, LiteSpeed/CyberPanel lsphp, Homebrew (macOS), kaynaktan derleme,
# çalışan php-fpm süreçleri (Linux /proc).
# Bash 3.2+ uyumlu (macOS dahil), root gerekmez ama root ile daha çok şey görür.
#
# Kullanım:
# bash php_cve_audit.sh # standart tarama
# bash php_cve_audit.sh --refresh # önce paket metadata'sını yenile (apt/dnf)
# bash php_cve_audit.sh --deep # ayrıca dosya sisteminde php binary'si ara (yavaş)
# bash php_cve_audit.sh --no-color
#
# Çıkış kodu: 0 = hepsi yamalı, 1 = açık var, 2 = belirsiz durum var
# =============================================================================
CVE_RE='CVE-2026-10961[89]'
FIX_DATE=20261021 # Upstream yamanın yayınlandığı gün (YYYYMMDD)
PATCH_82="8.2.35"; PATCH_83="8.3.36"; PATCH_84="8.4.27"; PATCH_85="8.5.12"
REFRESH=0; DEEP=0; COLOR=1
for a in "$@"; do
case "$a" in
--refresh) REFRESH=1 ;;
--deep) DEEP=1 ;;
--no-color) COLOR=0 ;;
-h|--help) sed -n '2,21p' "$0"; exit 0 ;;
esac
done
[ -t 1 ] || COLOR=0
if [ $COLOR -eq 1 ]; then
R=$'\e[31m'; G=$'\e[32m'; Y=$'\e[33m'; B=$'\e[1m'; D=$'\e[2m'; N=$'\e[0m'
else R=; G=; Y=; B=; D=; N=; fi
# ---------- yardımcılar ------------------------------------------------------
have() { command -v "$1" >/dev/null 2>&1; }
realp() {
if have realpath; then realpath "$1" 2>/dev/null
elif readlink -f / >/dev/null 2>&1; then readlink -f "$1"
else (cd "$(dirname "$1")" 2>/dev/null && echo "$(pwd -P)/$(basename "$1")"); fi
}
# ver_ge A B -> A >= B ise 0 (saf bash, sort -V gerektirmez)
ver_ge() {
local IFS=.; local a=($1) b=($2) i
for i in 0 1 2; do
local x=${a[$i]:-0} y=${b[$i]:-0}
x=${x%%[!0-9]*}; y=${y%%[!0-9]*}; x=${x:-0}; y=${y:-0}
[ "$x" -gt "$y" ] && return 0
[ "$x" -lt "$y" ] && return 1
done; return 0
}
# "Oct 21 2026" -> 20261021
build_num() {
local m d y; set -- $1; m=$1; d=$2; y=$3
case "$m" in Jan)m=01;;Feb)m=02;;Mar)m=03;;Apr)m=04;;May)m=05;;Jun)m=06;;
Jul)m=07;;Aug)m=08;;Sep)m=09;;Oct)m=10;;Nov)m=11;;Dec)m=12;;*)return 1;;esac
[ -n "$y" ] && printf '%s%s%02d' "$y" "$m" "$((10#$d))"
}
patched_for() {
case "$1" in 8.2) echo $PATCH_82;; 8.3) echo $PATCH_83;; 8.4) echo $PATCH_84;; 8.5) echo $PATCH_85;; esac
}
PM=""
if have dpkg-query && have apt-cache; then PM=apt
elif have rpm && have dnf; then PM=dnf
elif have rpm && have yum; then PM=yum
elif have brew; then PM=brew; fi
if [ $REFRESH -eq 1 ]; then
echo "${D}Paket metadata'sı yenileniyor...${N}"
case "$PM" in
apt) apt-get update -qq >/dev/null 2>&1 ;;
dnf|yum) $PM -q makecache >/dev/null 2>&1 ;;
brew) brew update >/dev/null 2>&1 ;;
esac
fi
# ---------- 1) PHP binary'lerini topla --------------------------------------
CANDS=""
add() { [ -f "$1" ] && [ -x "$1" ] && CANDS="$CANDS
$1"; }
shopt -s nullglob 2>/dev/null
for p in \
/usr/bin/php /usr/bin/php[0-9]* /usr/sbin/php-fpm* /usr/local/bin/php /usr/local/sbin/php-fpm \
/opt/plesk/php/*/bin/php /usr/local/psa/admin/bin/php \
/opt/cpanel/ea-php*/root/usr/bin/php /usr/local/cpanel/3rdparty/bin/php \
/opt/alt/php*/usr/bin/php \
/usr/local/php[0-9]*/bin/php /usr/local/php/bin/php \
/opt/remi/php*/root/usr/bin/php \
/www/server/php/*/bin/php \
/usr/local/lsws/lsphp*/bin/php /usr/local/lsws/lsphp*/bin/lsphp \
/opt/php*/bin/php /opt/php/*/bin/php \
/opt/homebrew/opt/php*/bin/php /usr/local/opt/php*/bin/php \
/opt/homebrew/bin/php
do add "$p"; done
have php && add "$(command -v php)"
# Çalışan PHP süreçleri (php-fpm, lsphp vb.) - Linux
if [ -d /proc ]; then
for e in /proc/[0-9]*/exe; do
t=$(readlink "$e" 2>/dev/null) || continue
case "$(basename "$t")" in php|php[0-9]*|php-fpm*|php-cgi*|lsphp*) add "$t";; esac
done
fi
if [ $DEEP -eq 1 ]; then
echo "${D}Dosya sistemi taranıyor (--deep)...${N}"
while IFS= read -r f; do add "$f"; done < <(
find / -xdev \( -path /proc -o -path /sys -o -path /dev -o -path '*/node_modules' \) -prune -o \
-type f \( -name php -o -name 'php[0-9]*' -o -name 'php-fpm*' -o -name 'php-cgi*' -o -name 'lsphp*' \) \
-perm -u+x -print 2>/dev/null | grep -vE '\.(ini|conf|d)$|/doc/|/man/')
fi
# realpath ile tekilleştir
BINS=""; SEEN=" "
while IFS= read -r c; do
[ -z "$c" ] && continue
r=$(realp "$c"); [ -z "$r" ] && continue
case "$SEEN" in *" $r "*) continue;; esac
SEEN="$SEEN$r "; BINS="$BINS
$r"
done <<EOF
$CANDS
EOF
# ---------- 2) her binary'yi analiz et ---------------------------------------
vendor_of() {
case "$1" in
/opt/plesk/*) echo plesk ;;
/usr/local/psa/*) echo plesk-panel ;;
/opt/cpanel/*) echo cpanel ;;
/usr/local/cpanel/*) echo cpanel-internal ;;
/opt/alt/*) echo cloudlinux ;;
/opt/remi/*) echo remi ;;
/www/server/*) echo aapanel ;;
/usr/local/lsws/*) echo litespeed ;;
*/Cellar/*|/opt/homebrew/*) echo brew ;;
/usr/local/php*) [ -d /usr/local/directadmin ] && echo directadmin || echo source ;;
*) echo "" ;;
esac
}
pkg_of() {
case "$PM" in
apt) dpkg -S "$1" 2>/dev/null | head -n1 | sed 's/: .*//; s/:.*//' ;;
dnf|yum) rpm -qf --qf '%{NAME}\n' "$1" 2>/dev/null | grep -v 'not owned' | head -n1 ;;
esac
}
cve_in_changelog() { # $1 = paket
[ -z "$1" ] && return 1
case "$PM" in
apt)
for f in /usr/share/doc/"$1"/changelog.Debian.gz /usr/share/doc/"$1"/changelog.gz; do
[ -f "$f" ] && gzip -dc "$f" 2>/dev/null | grep -qE "$CVE_RE" && return 0
done ;;
dnf|yum) rpm -q --changelog "$1" 2>/dev/null | grep -qE "$CVE_RE" && return 0 ;;
esac
return 1
}
update_of() { # $1 = paket -> bekleyen sürüm varsa yazar
[ -z "$1" ] && return
case "$PM" in
apt)
apt-cache policy "$1" 2>/dev/null | awk '
/Installed:/{i=$2} /Candidate:/{c=$2}
END{ if (i!="" && c!="" && i!="(none)" && i!=c) print c }' ;;
dnf|yum)
local cflag="-C"; [ $REFRESH -eq 1 ] && cflag=""
$PM -q $cflag check-update "$1" 2>/dev/null | awk -v p="$1" '$1 ~ "^"p"\\." {print $2; exit}' ;;
esac
}
upload_progress_of() { # efektif değer (cli veya fpm'in kendi php.ini'si)
local v
v=$("$1" -i 2>/dev/null | awk -F' => ' '/^session\.upload_progress\.enabled/{print $2; exit}')
[ -z "$v" ] && { echo "-"; return; }
case "$v" in On|on|1) echo On;; *) echo Off;; esac
}
TOTAL=0; OPEN=0; UNSURE=0; HINTS=""; UP_ON=0
hint() { case "$HINTS" in *"$1"*) ;; *) HINTS="$HINTS
- $1";; esac; }
printf "\n${B}%s${N}\n" "DURUM KAYNAK SÜRÜM BUILD UPL YOL / NOT"
printf '%s\n' "------------------------------------------------------------------------------------------"
while IFS= read -r bin; do
[ -z "$bin" ] && continue
out=$("$bin" -v 2>/dev/null | head -n1)
ver=$(printf '%s' "$out" | sed -nE 's/^PHP ([0-9]+\.[0-9]+\.[0-9]+).*/\1/p')
[ -z "$ver" ] && continue # php değil / çalışmadı
TOTAL=$((TOTAL+1))
branch=${ver%.*}
bdate=$(printf '%s' "$out" | sed -nE 's/.*built: ([A-Za-z]{3} +[0-9]+ [0-9]{4}).*/\1/p')
bnum=$(build_num "$bdate")
bshow=${bnum:-?}; [ -n "$bnum" ] && bshow="${bnum:0:4}-${bnum:4:2}-${bnum:6:2}"
vendor=$(vendor_of "$bin"); pkg=""
if [ -z "$vendor" ] || [ "$vendor" = cpanel ] || [ "$vendor" = cloudlinux ] || [ "$vendor" = remi ] || [ "$vendor" = plesk ]; then
pkg=$(pkg_of "$bin")
fi
[ -z "$vendor" ] && { [ -n "$pkg" ] && vendor="$PM" || vendor=source; }
upl=$(upload_progress_of "$bin"); [ "$upl" = On ] && UP_ON=$((UP_ON+1))
st=""; note=""
pv=$(patched_for "$branch")
if cve_in_changelog "$pkg"; then
st=OK; note="paket changelog'unda CVE yaması var ($pkg)"
elif [ -n "$pv" ] && ver_ge "$ver" "$pv"; then
st=OK; note=">= $pv"
else
upd=$(update_of "$pkg")
case "$branch" in
8.2|8.3|8.4|8.5)
if [ -n "$upd" ]; then st=AÇIK; note="güncelleme mevcut: $upd"
elif [ -n "$pkg" ] && [ -n "$bnum" ] && [ "$bnum" -ge $FIX_DATE ]; then
st=?; note="yeni build, distro backport olabilir; changelog'da CVE yok"
elif [ -n "$pkg" ]; then
st=AÇIK; note="gereken $pv (veya distro backport'u) - güncelleme görünmüyor, --refresh deneyin"
else st=AÇIK; note="gereken $pv"; fi ;;
7.4|8.0|8.1)
if [ -n "$upd" ]; then st=AÇIK; note="EOL; güncelleme mevcut: $upd"
elif [ -n "$bnum" ] && [ "$bnum" -ge $FIX_DATE ]; then
st=?; note="EOL; $bshow tarihli build - vendor yamalı olabilir, doğrulayın"
else st=AÇIK; note="EOL; upstream yaması yok, vendor build'i gerekli"; fi ;;
*) st=AÇIK; note="EOL ($branch) - yama yok; kaldırın/izole edin (TuxCare vb.)" ;;
esac
fi
case "$st" in
OK) col=$G ;;
AÇIK) col=$R; OPEN=$((OPEN+1)) ;;
*) col=$Y; UNSURE=$((UNSURE+1)) ;;
esac
ucol=$G; [ "$upl" = On ] && ucol=$Y
case "$st" in OK) stp="OK ";; AÇIK) stp="AÇIK ";; *) stp="? ";; esac
printf "${col}%s${N} %-11s %-9s %-11s ${ucol}%-5s${N} %s\n" "$stp" "$vendor" "$ver" "$bshow" "$upl" "$bin"
printf " ${D}↳ %s${N}\n" "$note"
if [ "$st" != OK ]; then
case "$vendor" in
plesk|plesk-panel) hint "Plesk: plesk installer update" ;;
cpanel|cpanel-internal) hint "cPanel: /scripts/upcp (veya: yum update 'ea-php*')" ;;
cloudlinux) hint "CloudLinux: yum update 'alt-php*'" ;;
directadmin) hint "DirectAdmin: cd /usr/local/directadmin/custombuild && ./build update && ./build php n" ;;
remi) hint "Remi: dnf upgrade 'php*'" ;;
aapanel) hint "aaPanel: Panel > App Store > PHP > Update" ;;
litespeed) hint "LiteSpeed: yum/apt ile 'lsphp*' paketlerini güncelleyin" ;;
brew) hint "Homebrew: brew update && brew upgrade php" ;;
apt) hint "Debian/Ubuntu: apt-get update && apt-get install --only-upgrade '$pkg' (veya: apt-get upgrade)" ;;
dnf|yum) hint "RHEL ailesi: $PM upgrade 'php*'" ;;
source) hint "Kaynaktan derleme: yamalı sürümle yeniden derleyin ($bin)" ;;
esac
fi
done <<EOF
$BINS
EOF
# ---------- 3) Plesk paneli ayrıca ------------------------------------------
if have plesk; then
pv=$(plesk version 2>/dev/null | grep -oE '18\.0\.[0-9]+(\.[0-9]+)?' | head -n1)
mi=$(echo "$pv" | cut -d. -f3); up=$(echo "$pv" | cut -d. -f4); up=${up:-0}
echo
if [ -n "$mi" ] && { [ "$mi" -gt 81 ] || { [ "$mi" -eq 81 ] && [ "$up" -ge 4 ]; } || { [ "$mi" -eq 80 ] && [ "$up" -ge 11 ]; }; }; then
echo "${G}OK${N} Plesk panel $pv (sw-engine yamalı)"
else
echo "${R}AÇIK${N} Plesk panel ${pv:-?} -> 18.0.81 Update 4 gerekli"
OPEN=$((OPEN+1)); hint "Plesk: plesk installer update"
fi
fi
# ---------- 4) özet ----------------------------------------------------------
echo
echo "${B}Özet:${N} $TOTAL PHP bulundu | ${R}açık: $OPEN${N} | ${Y}belirsiz: $UNSURE${N} | upload_progress On: $UP_ON"
[ $TOTAL -eq 0 ] && echo "PHP bulunamadı. Özel bir yoldaysa --deep ile deneyin."
if [ -n "$HINTS" ]; then
echo; echo "${B}Önerilen güncelleme komutları:${N}$HINTS"
fi
if [ $UP_ON -gt 0 ]; then
echo; echo "${Y}Not:${N} UPL=On olanlarda 'session.upload_progress.enabled = Off' önerilir"
fi
echo
echo "${D}Belirsiz (?) = sürüm numarası değişmeden backport edilmiş olabilir; paketin changelog'unu/vendor duyurusunu kontrol edin.${N}"
[ $OPEN -gt 0 ] && exit 1
[ $UNSURE -gt 0 ] && exit 2
exit 0