آسیب پذیری PHP2Shell: دو آسیبپذیری بحرانی با امکان اجرای کد از راه دور
روز ۲۹ مهر ۱۴۰۵ (۲۱ اکتبر ۲۰۲۶) تیم PHP برای دو آسیبپذیری بحرانی در هسته PHP وصله اضطراری منتشر کرد. این دو باگ به مهاجم اجازه میدهند بدون نام کاربری و رمز، روی سرور شما کد اجرا کند. اگر سروری دارید که سایت PHP (وردپرس، ووکامرس، لاراول و …) روی آن اجراست، همین امروز باید آن را بررسی کنید.
در این آموزش قدمبهقدم یاد میگیرید چطور بفهمید سرورتان آسیبپذیر است، چطور وصلهاش کنید و چطور مطمئن شوید وصله واقعاً اعمال شده است. دستورها برای سرورهای سیپنل و سرورهای بدون کنترل پنل (Ubuntu، Debian، AlmaLinux و Rocky) نوشته شدهاند.
مشتریان هاست اشتراکی تککلود: سرورهای میزبانی تککلود وصله شدهاند و نیازی به هیچ کاری از طرف شما نیست. این آموزش برای کسانی است که سرور مجازی یا اختصاصی خودشان را مدیریت میکنند.
PHP2Shell چیست و چقدر جدی است؟
PHP2Shell نام دو آسیبپذیری با شناسههای CVE-2026-109618 و CVE-2026-109619 است. هر دو امتیاز ۹٫۲ از ۱۰ (بحرانی) گرفتهاند و اجرای کد از راه دور بدون احراز هویت را ممکن میکنند.
- CVE-2026-109618: وقتی PHP با کمبود حافظه روبهرو میشود، ممکن است وسط آمادهسازی دادههای درخواست متوقف شود و حافظه را در وضعیت ناقص رها کند.
- CVE-2026-109619: بخشی از اطلاعات یک درخواست بعد از پایان آن در حافظه میماند و درخواست بعدی روی همان پروسه ممکن است از آن استفاده کند.
چند نکته که این ماجرا را جدیتر میکند:
- مشکل در خود PHP است، نه در وردپرس یا یک افزونه. پس بهروز بودن سایت کمکی نمیکند.
- همه روشهای اجرای PHP درگیرند: PHP-FPM، mod_php، php-cgi و LiteSpeed. بیشترین ریسک برای mod_php است.
- جزئیات باگ یک روز قبل از انتشار وصله لو رفت و گزارشهایی از تلاش برای سوءاستفاده منتشر شده است.
کدام نسخهها آسیبپذیرند؟
همه نسخههای PHP از ۵٫۴ تا ۸٫۵٫۱۱ آسیبپذیرند. نسخههای اصلاحشده رسمی:
| شاخه PHP | نسخه امن |
|---|---|
| 8.5 | 8.5.12 به بالا |
| 8.4 | 8.4.27 به بالا |
| 8.3 | 8.3.36 به بالا |
| 8.2 | 8.2.35 به بالا |
| 8.1 و قدیمیتر | نسخه رسمی ندارد؛ فقط وصله backport از سمت سیپنل یا توزیع لینوکس |
اگر سایتی روی PHP 8.1 یا قدیمیتر دارید، این بهترین زمان برای مهاجرت به 8.2 یا بالاتر است.
دو اشتباه رایج قبل از شروع
بیشتر مدیران سرور در این مرحله فکر میکنند کار تمام است، در حالی که سرور هنوز آسیبپذیر است. قبل از دستورها، این دو نکته را بدانید.
۱. خروجی php -v کافی نیست. این دستور نسخه PHP خط فرمان (CLI) را نشان میدهد. سایتهای شما ممکن است با نسخه دیگری از طریق PHP-FPM یا LiteSpeed اجرا شوند. روی سرورهای سیپنل معمولاً چند نسخه PHP همزمان نصب است و باید همه را چک کنید.
۲. نصب پکیج جدید بدون ریاستارت فایده ندارد. پروسههایی که قبل از آپدیت بالا آمدهاند، نسخه قدیمی PHP را در حافظه نگه میدارند. تا PHP-FPM و وبسرور ریاستارت نشوند، سایتها با کد آسیبپذیر اجرا میشوند.
نکته درباره نسخههای backport: توزیعهایی مثل Ubuntu و Debian و همچنین سیپنل برای نسخههای قدیمی، وصله را بدون تغییر شماره اصلی نسخه اعمال میکنند. مثلاً PHP اوبونتو ۲۴٫۰۴ بعد از وصله هم «8.3.6» نشان میدهد. در این حالت باید شماره کامل پکیج را با جدول وصلهها مقایسه کنید.
بررسی و وصله در سرور سیپنل
سیپنل نسخههای اصلاحشده 8.2.35، 8.3.36، 8.4.27 و 8.5.12 را در EasyApache 4 منتشر کرده و برای PHP 7.4، 8.0 و 8.1 هم وصله را backport کرده است. اگر آپدیت خودکار فعال باشد، احتمالاً پکیجها نصب شدهاند. اما باید مطمئن شوید.
قدم ۱: نسخه همه PHPهای نصبشده را ببینید
با SSH و کاربر root وارد سرور شوید و این دستور را اجرا کنید:
for p in /opt/cpanel/ea-php*/root/usr/bin/php /opt/alt/php*/usr/bin/php; do
[ -x "$p" ] && echo "$p => $($p -v | head -1)"
done
خروجی را با جدول نسخههای امن مقایسه کنید. نمونه خروجی یک سرور وصلهشده:
/opt/cpanel/ea-php82/root/usr/bin/php => PHP 8.2.35 (cli)
/opt/cpanel/ea-php83/root/usr/bin/php => PHP 8.3.36 (cli)
/opt/cpanel/ea-php85/root/usr/bin/php => PHP 8.5.12 (cli)
برای PHP 7.4، 8.0 و 8.1 شماره نسخه تغییر نمیکند. شماره release پکیج را ببینید:
rpm -qa 'ea-php*-php-cli' | sort
قدم ۲: پکیجها را آپدیت کنید
اگر نسخهای قدیمی دیدید:
/usr/local/cpanel/scripts/upcp
dnf upgrade 'ea-php*' # در CentOS 7 بهجای dnf از yum استفاده کنید
روی سیپنل نصبشده روی Ubuntu:
apt update && apt install --only-upgrade 'ea-php*'
اگر CloudLinux دارید: نسخههای alt-php از مخزن CloudLinux میآیند، نه سیپنل. با dnf upgrade 'alt-php*' آپدیت کنید. انتشار این پکیجها تدریجی بوده، پس صفحه وضعیت CloudLinux را هم چک کنید.
قدم ۳: سرویسها را ریاستارت کنید
/scripts/restartsrv_apache_php_fpm
/scripts/restartsrv_httpd
/scripts/restartsrv_cpanel_php_fpm
/usr/local/lsws/bin/lswsctrl restart # فقط اگر LiteSpeed دارید
دستور سوم PHP داخلی خود سیپنل را ریاستارت میکند. این PHP برای وبمیل، phpMyAdmin و رابط سیپنل و WHM استفاده میشود و از اینترنت در دسترس است.
قدم ۴: مطمئن شوید پروسه قدیمی نمانده
زمان نصب پکیجها را ببینید:
rpm -qa --last 'ea-php*' | head -5
سپس زمان شروع پروسههای PHP و وبسرور را ببینید:
ps -eo pid,lstart,user,cmd | grep -E 'php-fpm|lsphp|httpd|litespeed' | grep -v grep
همه پروسهها باید بعد از زمان نصب پکیجها شروع شده باشند. اگر پروسهای قدیمیتر دیدید، قدم ۳ را تکرار کنید.
نسخه PHP داخلی سیپنل را هم چک کنید:
/usr/local/cpanel/3rdparty/bin/php -v | head -1
قدم ۵: نسخهای که سایت واقعاً اجرا میکند را ببینید
مطمئنترین روش، تست از دید خود سایت است. USER و DOMAIN را با مقادیر خودتان عوض کنید:
echo '<?php echo PHP_VERSION, " ", php_sapi_name();' > /home/USER/public_html/v-check.php
curl -s https://DOMAIN/v-check.php; echo
rm -f /home/USER/public_html/v-check.php
اگر سایتها روی نسخههای مختلف PHP هستند، این تست را برای هر نسخه یک بار انجام دهید. حتماً فایل را بعد از تست پاک کنید.
سایتهای روی نسخههای خیلی قدیمی
سیپنل فقط PHP 7.4، 8.0 و 8.1 را backport کرده است. برای دیدن اینکه هر سایت روی کدام نسخه است:
whmapi1 php_get_vhost_versions | grep -E 'vhost:|version:'
سایتهای روی ea-php56 تا ea-php73 وصلهای ندارند و باید از بخش MultiPHP Manager در WHM به نسخه جدیدتر منتقل شوند.
بررسی و وصله در سرور بدون کنترل پنل
روی سرور بدون پنل، وصله از همان جایی میآید که PHP را از آن نصب کردهاید: مخزن رسمی توزیع، مخزن Ondřej Surý (برای Ubuntu و Debian) یا مخزن Remi (برای خانواده RHEL). پس اول بفهمید PHP از کجا آمده است.
Ubuntu و Debian
قدم ۱: نسخههای نصبشده و منبع آنها را ببینید
ls /etc/php/
dpkg -l | awk '/^ii +php[0-9]/{print $2, $3}'
apt-cache policy php8.3-fpm # 8.3 را با نسخه خودتان عوض کنید
اگر در خروجی apt-cache policy آدرس ppa.launchpadcontent.net/ondrej یا packages.sury.org دیدید، PHP شما از مخزن Ondřej است. در غیر این صورت از مخزن رسمی توزیع آمده است.
قدم ۲: آپدیت کنید
apt update
apt install --only-upgrade $(dpkg -l | awk '/^ii +php[0-9]/{print $2}')
قدم ۳: مطمئن شوید وصله در پکیج هست
apt changelog php8.3-fpm 2>/dev/null | grep -E 'CVE-2026-10961(8|9)'
اگر هر دو شناسه CVE در خروجی بود، پکیج وصله را دارد. میتوانید نسخه پکیج را با این جدول هم مقایسه کنید:
| سیستمعامل | شاخه PHP | اولین نسخه وصلهشده پکیج |
|---|---|---|
| Ubuntu 22.04 | 8.1 | 8.1.2-1ubuntu2.28 |
| Ubuntu 24.04 | 8.3 | 8.3.6-0ubuntu0.24.04.13 |
| Ubuntu 26.04 | 8.5 | 8.5.4-0ubuntu1.5 |
| Debian 12 | 8.2 | 8.2.35-1~deb12u1 |
| Debian 13 | 8.4 | 8.4.27-1~deb13u1 |
| مخزن Ondřej Surý | 8.2 تا 8.5 | 8.2.35، 8.3.36، 8.4.27، 8.5.12 |
Ubuntu 20.04 و قدیمیتر وصله را فقط از طریق اشتراک Ubuntu Pro دریافت میکنند.
قدم ۴: سرویسها را ریاستارت کنید
systemctl restart 'php*-fpm'
systemctl restart apache2 # یا: systemctl restart nginx
اگر Apache با mod_php دارید (پکیج libapache2-mod-php)، ریاستارت apache2 کافی است. این حالت پرخطرترین حالت است؛ در صورت امکان به PHP-FPM مهاجرت کنید.
AlmaLinux، Rocky Linux و RHEL
قدم ۱: نسخهها و منبع را ببینید
rpm -qa | grep -E '^php|^php[0-9]+-php' | sort
dnf repolist
اگر مخزن remi در لیست بود و پکیجهایی مثل php83-php-fpm دارید، PHP از مخزن Remi آمده است.
قدم ۲: ببینید وصله منتشر شده یا نه
dnf clean metadata
dnf updateinfo list --cve CVE-2026-109618
dnf check-update 'php*'
در زمان نوشتن این مقاله، Red Hat هنوز وصله منتشر نکرده بود و AlmaLinux در حال آمادهسازی آن بود. Remi هم اعلام کرده بود بهروزرسانی همان روز را ندارد. اگر وصله هنوز نیامده، بخش «راهکار موقت» را اجرا کنید و این دستورها را روزانه تکرار کنید.
قدم ۳: آپدیت و ریاستارت
dnf upgrade 'php*'
systemctl restart php-fpm httpd # یا nginx بهجای httpd
systemctl restart 'php*-php-fpm' # اگر از Remi با نامهای SCL استفاده میکنید
قدم ۴: تأیید وصله
rpm -q --changelog php-fpm | head -15
مرحله آخر برای همه توزیعها
دقیقاً مثل سیپنل، زمان شروع پروسهها را با زمان آپدیت مقایسه کنید و نسخه را از دید سایت تست کنید (قدم ۴ و ۵ بخش سیپنل):
ps -eo pid,lstart,cmd | grep -E 'php-fpm|apache2|httpd' | grep -v grep
اگر فعلاً نمیتوانید وصله کنید
تنها راهحل کامل، آپدیت PHP است. توسعهدهندگان هسته PHP هم صریحاً همین را گفتهاند. اما اگر وصله برای سیستمعامل شما هنوز منتشر نشده، این کارها ریسک را کم میکنند:
۱. غیرفعال کردن session upload progress. تیم PHP این تنظیم را برای بستن بخشی از مسیرهای حمله پیشنهاد کرده است، نه همه آنها. باید در تنظیمات سطح سرور باشد، نه در .user.ini یا ini_set():
session.upload_progress.enabled = 0
- سیپنل: از WHM، بخش MultiPHP INI Editor، برای هر نسخه PHP این گزینه را خاموش کنید.
- Ubuntu و Debian: در فایل
/etc/php/8.3/fpm/php.ini(با نسخه خودتان). - خانواده RHEL: در فایل
/etc/php.iniیا فایل php.ini مخزن Remi.
بعد از تغییر، PHP-FPM و وبسرور را ریاستارت کنید.
۲. فایروال وب (WAF). اگر Imunify360 دارید، مطمئن شوید رولست آن بهروز است. نسخه 8.83 به بعد الگوی اکسپلویت عمومی را روی Apache بلاک میکند، اما روی LiteSpeed فقط آن را ثبت میکند. پس روی سرورهای LiteSpeed به WAF تکیه نکنید.
۳. خاموش کردن سایتهای غیرضروری. سایتهای آزمایشی، قدیمی یا رهاشده را تا زمان وصله از دسترس خارج کنید.
بعد از وصله: بررسی نفوذ احتمالی
وصله جلوی حملههای بعدی را میگیرد، اما اگر کسی قبل از آن وارد شده باشد، درِ پشتیاش سر جایش میماند. جزئیات باگ از ۲۸ مهر لو رفته بود، پس فاصله این تاریخ تا زمان وصله سرورتان را بررسی کنید.
فایلهای PHP جدید یا تغییرکرده. تاریخ دوم را با زمان وصله سرور خودتان عوض کنید. مسیر /home/*/public_html مخصوص سیپنل است؛ روی سرور بدون پنل معمولاً /var/www است:
find /home/*/public_html -type f -name '*.php' \
-newermt '2026-10-20' ! -newermt '2026-10-22 06:00' -ls 2>/dev/null | head -100
دنبال این نشانهها باشید:
- فایل PHP داخل پوشههایی مثل
uploadsیاcache - اسمهای تصادفی و بیمعنی
- کد مبهمشده با
eval،base64_decodeیاgzinflate
آپدیت عادی وردپرس و افزونهها هم در این لیست دیده میشود و طبیعی است.
کرانجابها و پروسههای مشکوک:
ls -lt --time-style=long-iso /var/spool/cron/ /var/spool/cron/crontabs/ 2>/dev/null | head
ps -eo user,pid,etime,cmd --sort=-etime | grep -vE '^(root|mysql|nobody)' | head -40
اسکن بدافزار. روی سرورهای دارای Imunify360:
imunify360-agent malware on-demand start --path /home
روی سرورهای دیگر میتوانید از ابزارهایی مثل ImunifyAV (رایگان) یا Maldet استفاده کنید.
اگر نشانه نفوذ دیدید، قبل از پاک کردن هر چیزی از سرور نسخه پشتیبان بگیرید و فایلهای مشکوک را برای بررسی نگه دارید.
نیاز به کمک دارید؟
اگر وقت یا فرصت این بررسیها را ندارید یا مطمئن نیستید سرورتان امن شده، تیم فنی تککلود میتواند سرور مجازی یا اختصاصی شما را بررسی، وصله و ایمن کند. برای ثبت درخواست با پشتیبانی تککلود تماس بگیرید.
پرسشهای متداول
من هاست اشتراکی دارم. باید کاری بکنم؟ خیر. وصله PHP روی هاست اشتراکی وظیفه شرکت میزبان است. سرورهای تککلود وصله شدهاند. فقط وردپرس و افزونههایتان را بهروز نگه دارید.
وردپرس من آخرین نسخه است. باز هم آسیبپذیرم؟ بله، اگر PHP سرور وصله نشده باشد. این باگ در خود PHP است و حمله قبل از اجرای کد وردپرس اتفاق میافتد.
php -v نسخه جدید را نشان میدهد. یعنی امن هستم؟ نه لزوماً. این دستور فقط نسخه خط فرمان را نشان میدهد. باید PHP-FPM و وبسرور را هم ریاستارت کنید و نسخه را از دید سایت چک کنید.
PHP 7.4 دارم. چه کنم؟ روی سیپنل، وصله backport برای 7.4 منتشر شده است. اما 7.4 سالهاست پشتیبانی رسمی ندارد. بهترین کار مهاجرت به PHP 8.2 یا بالاتر است.
تنظیم session.upload_progress کافی نیست؟ نه. این تنظیم فقط بخشی از مسیرهای حمله را میبندد. تنها راهحل کامل، آپدیت PHP است.