Herkese iyi forumlar, az çok güvenlik açığının ne olduğunu, neler yapabileceğini öğrendiniz. Kendi sunucusunu yönetenler için hızlı kontrol sağlamanız için gerekli bash kodu alttadır. kolay kullanım için kodu kopyalayın. Ssh üzerinden bash'e bağlanıp kodu çalıştırın. Açıklarınızın son durumunu kontrol edebilirsiniz.
ç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 --help
github ü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