...

مهندسی معکوس مودم 5G مدل ZLT X28

مودم ZLT X28
11 بازدید
۱۴۰۵-۰۸-۱۸
15 دقیقه
  • نویسنده: علی نادری
  • درباره نویسنده: ---

این روزها دیگه برای استفاده از 5G توی ایران لازم نیست فقط سراغ گوشی بریم. اگه محل زندگی یا کارمون پوشش داشته باشه، یه مودم 5G هم می‌تونه اینترنت خونه یا محل کار رو تأمین کنه. البته هنوز همه‌جا پوشش یکسانی نداره؛ قبل از خرید باید ببینیم توی محل استفاده چه وضعی داریم. نقشه اندازه‌گیری کاربران nPerf یکی از راه‌های دیدن پوشش ثبت‌شده شبکه هست.

اگه توی بازار ایران دنبال مودم 5G گشته باشید، احتمالاً اسم ZLT X28 رو زیاد دیدید؛ یکی از مدل‌های شناخته‌شده و پرطرفدار این بازاره. خیلی جاها با عنوان استوک عرضه می‌شه و نمونه‌های اپراتوری آنلاک‌شده‌ش هم توی بازار هست. مقایسه X28 با GT525 هم به رواج X28 در بازار مودم‌های استوک اشاره داره. X28 یه CPE هست؛ یعنی همون دستگاهی که سمت ما قرار می‌گیره، اینترنت رو از شبکه سلولی می‌گیره و با Wi-Fi و کابل شبکه به دستگاه‌های خونه یا محل کار می‌رسونه.

 

مودم 5G مدل ZLT X28

ولی چیزی که من رو کنجکاو کرد فقط 5G نبود. زیر قاب این مودم یه پردازنده چهارهسته‌ای ARM داریم، مقداری حافظه و یه سیستم‌عامل لینوکسی. خب با این سخت‌افزار چرا فقط به امکانات پنل سازنده محدود باشیم؟ می‌شه روی خودش WireGuard یا OpenVPN راه انداخت؟ می‌شه OpenWrt معمولی داشته باشیم و اینترنت سیم‌کارت رو هم از دست ندیم؟ پروژه من از همین سؤال‌ها شروع شد.

مودم من اینترنت می‌داد، ولی اون تنظیمات و ابزارهایی که از یه روتر لینوکسی می‌خواستم توی دسترسم نبود. می‌خواستم LuCI و UCI معمول OpenWrt رو داشته باشم، شبکه رو خودم مدیریت کنم و VPN راه بندازم. فقط یه شرط مهم داشتم: اینترنت سلولی و اطلاعات اختصاصی برد باید سالم می‌موند. از دسترسی به سیستم و راه‌انداختن پنل وب شروع کردم؛ جلوتر که رفتم، پای NAND، زنجیره بوت و ارتباط لینوکس با مودم هم وسط اومد.

توی این مجموعه، مسیر کارم روی پروژه ZLT X28 OpenWrt رو تعریف می‌کنم. تا اینجا همه تست‌ها روی یه دستگاه، یه سیم‌کارت و یه اپراتور انجام شده؛ پس هر چیزی که روی مودم من جواب داده، لزوماً روی همه X28ها جواب نمی‌ده. دستگاه از قبل SIM-unlock بود؛ دسترسی Linux که در ادامه توضیح می‌دم، فرایندی جدا از بازکردن قفل سیم‌کارت هست.

چرا نصب LuCI پایان کار نبود؟

اولین نکته جالب این بود که فریمور کارخانه خودش بر پایه OpenWrt 19.07 بود و Kernel نسخه 4.19.205 داشت. ولی دیدن اسم OpenWrt توی فایل‌ها به این معنی نبود که همه‌چیز مثل یه OpenWrt معمولی کار می‌کنه. در بررسی اولیه، باینری netifd وجود داشت، اما در فهرست پردازش‌های نمونه‌برداری‌شده اجرا نمی‌شد. در عوض lan_mgr، wan_mgr و چند سرویس سازنده شبکه رو مدیریت می‌کردن. حتی آدرس LAN ثبت‌شده در UCI با آدرس واقعی رابط زنده تفاوت داشت.

اینجا یه دردسر مهم داشتیم: صفحه Interfaces ممکنه تنظیمی رو نشون بده که مالک واقعی رابط از اون استفاده نمی‌کنه. فشردن Save & Apply هم می‌تونه سرویس دیگه‌ای رو با همون تنظیمات قدیمی فعال و دسترسی رو قطع کنه. برای همین قبل از درست‌کردن ظاهر صفحه، باید می‌فهمیدم چه برنامه‌ای واقعاً LAN، WAN، DHCP و فایروال رو کنترل می‌کنه.

در مرحله اول، روی همون فریمور کارخانه LuCI رو تعمیر کردم. فایل‌های قالب و منو ناقص بودن، بعضی صفحات خطای 404 داشتند و محدودیت ACL باعث می‌شد Overview منتظر بمونه. اصلاح مسیر انتهایی URL هم لازم بود، چون mini_httpd با /cgi-bin/luci/ مانند uhttpd رفتار نمی‌کرد. در اون دوره LuCI روی پورت 4153 و SSH روی 2222 بود؛ رابط وب سازنده روی پورت‌های 80 و 443 باقی ماند.

اما نمایش پروتکل یا صفحه فایروال، شاهد کنترل واقعی شبکه نیست. مستند بررسی اولیه دستگاه همین مرز رو ثبت می‌کنه. تصمیم بعدی این بود که RootFS مستقلی بسازم: مدیریت شبکه با netifd و سرویس‌های استاندارد باشه، و از لایه سازنده فقط وابستگی‌های لازم سخت‌افزار باقی بمونه.

واقعاً چه سخت‌افزاری داریم؟

برای شناخت برد، نام تجاری کافی نیست. مشخصات زیر از گزارش سخت‌افزار، تحلیل معماری، Device Tree و مشاهدات دستگاه گرفته شدن.

بخش مشخصات این نمونه مرز شواهد
SoC MediaTek MT6890، خانواده T750 شناسه نرم‌افزاری، Device Tree و شناسایی USB
پردازنده لینوکس چهار Cortex-A55، معماری aarch64 بازه فرکانس ثبت‌شده ۵۰۰ تا ۲۰۰۰ MHz
پلتفرم سلولی Quectel RG500L-EU شناسایی فریمور و USB؛ نوشته زیر شیلد بررسی نشده
Wi-Fi MediaTek MT7915، دو باند شناسه PCI برابر 14c3:7915 و درایور زنده
سوییچ MT7531AE خروجی swconfig list
RAM ۱ GiB؛ سهم قابل مشاهده Linux حدود ۶۲۸ MiB مقدار کل از نقشه حافظه؛ بخشی برای مودم رزرو شده
فلش NAND، با ۵۱ پارتیشن مجموع پارتیشن‌ها ۱۰۲۲٫۵ MiB؛ ظرفیت ۱ GiB استنباط می‌شه
Kernel کارخانه و تصویر فعلی 4.19.205 کرنل سازنده حفظ شده

این مشخصات رو برای همین برد در نظر بگیرید؛ هنوز همه نسخه‌های بازار رو بررسی نکردم. حتی نمونه‌های دیگه‌ای از X28 با تاریخ ساخت متفاوت Kernel گزارش شدن. یکسان بودن عدد 4.19.205 هم برای جابه‌جایی ماژول‌ها کافی نیست؛ تنظیمات، patchها و ABI باید مطابق باشن.

چرا لینوکس تمام RAM رو نمی‌بینه؟

در این پلتفرم، مودم سلولی از حافظه سیستم استفاده می‌کنه. خلاصه ظرفیت در گزارش سخت‌افزار شامل حدود ۲۵۶ MiB برای تصویر و حافظه کاری مودم، حدود ۱۰۹ MiB حافظه مشترک و بخش‌های رزروشده دیگه برای firmwareهاست. این نواحی قبل از آغاز Linux کنار گذاشته می‌شن. بیکار بودن مودم اون‌ها رو خودکار به حافظه آزاد Linux تبدیل نمی‌کنه.

در Device Tree هم دو توصیف حافظه با اندازه‌های متفاوت دیده شده و نقشه مؤثر به اصلاحات Bootloader وابسته‌ست. برای همین حذف یه reserved-memory برای زیادکردن RAM، آزمایش بی‌خطری نیست. ممکنه لینوکس و Baseband روی یه ناحیه بنویسند. برای استفاده روزمره، MemAvailable شاخص مناسب‌تری از MemFree هست؛ برای تغییر Kernel باید کل قرارداد حافظه هنگام بوت روشن بشه.

عکس برد چه می‌گه و چه نمی‌گه؟

 

پشت برد آبی ZLT X28 با شیلدهای فلزی و جای سه‌سوراخ UART در گوشه بالای چپ

تصویر ۱ — نمای پشت برد آزمایش‌شده؛ مسیر فایل توی مخزن: docs/images/x28-board-back.jpg. شیلدهای فلزی محل بخش‌های پوشیده برد رو نشون می‌دن و footprint سه‌سوراخ در گوشه بالای چپ، نقطه ورود ما به کنسول هست. این عکس مدرک شناسایی قطعات زیر شیلد نیست؛ برای اون‌ها به شواهد نرم‌افزاری تکیه کرده‌ام.

شماره چاپ‌شده روی برد، TZ7.823.432 X28، در تطبیق نمونه اهمیت داره. قبل از هر سیم‌کشی باید مطمئن شویم همون سمت و جهت عکس رو می‌بینیم. چرخاندن برد، تعبیر «چپ» و «راست» رو عوض می‌کنه؛ نام سیگنال و اندازه‌گیری مهم‌تر از حافظه تصویری ماست.

اولش فقط حدس می‌زدیم این footprint مربوط به UART باشه. یه بررسی پیوستگی در ۲۰۲۶-۱۰-۲۳ حتی به نتیجه نادرست درباره زمین رسید. بعداً سیم‌کشی و دریافت موفق روی خود دستگاه، pinout رو تأیید کرد. این اشتباه رو هم نگه داشتم، چون نتیجه اولین اندازه‌گیری همیشه جواب آخر نیست. حتی اسم فایلی مثل uart-candidate هم وضعیت کنونی شواهد رو تعیین نمی‌کنه.

UART؛ کنسولی که باید اول فقط شنید

UART رابط سریال ناهم‌زمان هست. برای شنیدن خروجی Bootloader و Kernel به TX برد، RX مبدل و زمین مشترک نیاز داریم. در اولین capture، TX مبدل وصل نبود؛ برای همین چیزی به دستگاه ارسال نمی‌شد. این روش اجازه داد زنجیره بوت رو قبل از دستکاری تنظیمات کنسول ببینم.

 

نمای نزدیک footprint سه‌سوراخ UART در پشت برد X28 و کادر سفید پیرامون اون

تصویر ۲ — نمای نزدیک محل UART؛ مسیر مخزن: docs/images/x28-uart-candidate.jpg. تصویر برای پیداکردن footprint مفید هست. نام‌گذاری سیگنال‌ها از آزمون ثبت‌شده در راهنمای Recovery میاد، نه از حدس شکل پدها. قبل از اتصال، جهت رو با نمای کامل برد تطبیق دهید.

محل طبق جهت مرجع راهنمای Recovery سیگنال برد اتصال
سوراخ سمت راست TX، سطح بیکار ۱٫۸ V به RX مبدل از مسیر تبدیل سطح
سوراخ وسط GND زمین مشترک برد، مبدل و تبدیل‌کننده
سوراخ سمت چپ RX، منطق ۱٫۸ V برای capture اولیه قطع؛ برای ارسال از تبدیل سطح

هشدار الکتریکی: این footprint پایه VCC نداره. خروجی تغذیه ۳٫۳ یا ۵ ولت مبدل رو به اون وصل نکنید. TX یه مبدل ۳٫۳ ولتی نباید مستقیم به RX برد وصل بشه. مدار تبدیل سطح باید برای منطق ۱٫۸ ولت مناسب باشه. تغذیه برد از مسیر اصلی خودش تأمین می‌شه.

صرف خواندن TX هم همیشه با یه مبدل ۳٫۳ ولتی جواب نمی‌ده؛ آستانه تشخیص High می‌تونه بالاتر از ۱٫۸ ولت باشه. در تجربه ثبت‌شده، خواندن مستقیم نویز تولید می‌کرد. زمین قطع یا بد هم در همه baudها بایت‌های تصادفی یا 0xFF می‌داد؛ چشمک‌زدن LED مبدل، دریافت درست رو ثابت نمی‌کنه.

نمونه ماژول USB به TTL با پایه‌های TXD، RXD، GND و خروجی‌های تغذیه

 

تصویر ۳ — نمونه مبدل USB به TTL. پایه‌های TXD و RXD برای ارسال و دریافت داده هستن؛ وجود پایه 3V3 روی ماژول به معنی سازگاری مستقیم سیگنال‌ها با UART یک‌وهشت‌ولتی X28 نیست. پایه‌های تغذیه این مبدل رو به footprint سه‌سوراخ مودم وصل نمی‌کنیم.

سرعت این نمونه 921600، هشت بیت داده، بدون parity و یه stop bit هست؛ همون 8N1. عدد از console=ttyS0,921600n1 و دریافت متن خوانا تأیید شد. گزارش 115200 برای نمونه‌ای دیگه وجود داره، اما اون رو جایگزین اندازه‌گیری این برد نکردم. برای تبدیل سطح، از ماژول TXS0108E استفاده کردم و ولتاژ ۱٫۸ ولت مورد نیاز رو با یه رگولاتور تأمین کردم. عکس چیدمان واقعی رو پایین می‌بینید.

تبدیل سطح با TXS0108E و رگولاتور ۱٫۸ ولت

 

نمونه ماژول تبدیل سطح TXS0108E با کانال‌های A و B و پایه OE

تصویر ۴ — نمونه ماژول TXS0108E برای تبدیل سطح سیگنال. روی این تصویر، تغذیه سمت A با VA و سمت B با VB مشخص شده؛ نوشته روی ماژول من برای تغذیه سمت A، V1 بود. اسم پایه‌ها رو با ماژول خودتون تطبیق بدید، نه فقط جای اون‌ها در عکس.

برای این اتصال، فقط پایین‌آوردن ولتاژ تغذیه کافی نبود؛ خود سیگنال‌های UART هم باید بین منطق ۳٫۳ ولت مبدل و ۱٫۸ ولت برد جابه‌جا می‌شدن. تبدیل سطح سیگنال رو TXS0108E انجام می‌داد. خروجی ۱٫۸ ولت رگولاتور رو به V1 سمت A و OE ماژول وصل کردم: V1 تغذیه سمت کم‌ولتاژ رو می‌گرفت و OE با همین سطح High، ماژول رو فعال می‌کرد. رگولاتور رو به‌جای level shifter توی مسیر TX یا RX نمی‌ذاریم.

 

چیدمان واقعی مدار اتصال UART مودم X28 با بردبورد، تبدیل سطح و رگولاتور

تصویر ۵ — عکس چیدمان مدار خودم؛ مسیر فایل از ریشه مخزن: docs/images/uart-circut.jpeg. ماژول تبدیل سطح روی بردبورد، رگولاتور در جلوی عکس و مودم بازشده سمت راست دیده می‌شن. این عکس روش استفاده‌شده رو مستند می‌کنه؛ برای تشخیص تک‌تک سیم‌ها و شماره کانال‌ها باید pinout رو هم داشته باشیم، نه اینکه از رنگ سیم‌ها حدس بزنیم.

طبق مشخصات TXS0108E در سایت TI، این قطعه دو تغذیه جدا داره و باید VCCA ≤ VCCB باشه. برای تبدیل سطح اینجا، سمت A مربوط به منطق 1.8 V برد و سمت B مربوط به منطق 3.3 V مبدله؛ یعنی VCCA=1.8 V و VCCB=3.3 V. زمین برد، مبدل، ماژول و رگولاتور هم باید مشترک باشه. روی ماژولی که من استفاده کردم، پایه تغذیه سمت A با نام V1 مشخص شده بود؛ توی دیتاشیت تراشه الکترونیکی، اسم این تغذیه VCCA هست. OE هم به همون خروجی ۱٫۸ ولت رگولاتور وصل بود. موقع استفاده از ماژول دیگه، نوشته‌های روی برد و دیتاشیت رو تطبیق بدید؛ شماره کانال‌ها رو از روی رنگ سیم‌های عکس حدس نزنید.

نکته مهم همون قبلیه: این ۱٫۸ ولت برای سمت کم‌ولتاژ مبدل سطحه، نه برای تغذیه مودم از پدهای UART. مودم همچنان از ورودی تغذیه خودش روشن می‌شه. برای شنیدن لاگ، فقط مسیر TX برد به RX مبدل لازمه؛ TX مبدل رو تا وقتی نیاز به ارسال نداریم، قطع نگه می‌داریم.

یه دام نرم‌افزاری در macOS

در این آزمایش، اجرای جداگانه stty و سپس cat سرعت رو حفظ نکرد؛ تنظیمات با بسته‌شدن descriptor برگشت. نتیجه ظاهراً شبیه baud اشتباه بود. راه درست این بود که پورت یه بار باز و روی همون descriptor تنظیم بشه. سند Recovery از طرفی محدودیت ابزار screen در این نرخ رو ثبت کرده؛ انتخاب تصادفی ابزار ترمینال جای بررسی تنظیم واقعی پورت رو نمی‌گیره.

برای بازتولید capture، نمونه Python ثبت‌شده در گزارش UART رو ببینید. پورت با O_RDONLY باز می‌شه و TX مبدل هم فیزیکی قطع هست. فایل خام رو خصوصی نگه دارید: لاگ بوت می‌تونه MAC، شماره سریال و شناسه‌های سلولی داشته باشه. در مقاله فقط گزیده پالایش‌شده رو میارم.

ترتیب واقعی دسترسی؛ SSH قبل از پوسته UART بود

از CGI احرازهویت‌شده به Telnet موقت

ماجرا در واقع قبل از ساخته‌شدن مخزن شروع شده بود. در بررسی firmware نسخه 1.5.13، اتصال به پورت‌های 22،‏ 23 و 4153 رد می‌شد، اما پنل سازنده در دسترس بود. برای بررسی این مسیر روی دستگاه خودتون، اول با حساب Super Admin وارد پنل سازنده بشید؛ اینجا منظور حساب پنل وب هست، نه root لینوکس. بعد ابزار توسعه‌دهنده مرورگر رو باز کنید، به بخش Network برید و صفحه DMZ رو باز کنید. درخواست مربوط به /cgi-bin/http.cgi رو پیدا و با Copy as cURL کپی کنید. برای پیدا کردن ساختار درخواست هم می‌تونید فایل JavaScript همین صفحه رو در بخش Sources بررسی کنید.

درخواست رو باید با اطلاعات نشست معتبر خودتون بفرستید؛ کوکی نشست (session cookie) رو از درخواست مرورگر نگه دارید، اگر پنل اون رو ارسال می‌کنه. فقط کپی‌کردن URL کافی نیست: در JavaScript نسخه بررسی‌شده، مقدارهای sessionId و برای عملیات نوشتن token هم از sessionStorage به بدنه درخواست اضافه می‌شن. پس نباید فرض کنیم کوکی به‌تنهایی برای احراز هویت کافیه. نام و مقدار کوکی و این فیلدها رو از درخواست واقعی همون نسخه بردارید؛ هیچ‌کدوم رو در مقاله، اسکرین‌شات یا پیام عمومی منتشر نکنید.

نمونه زیر فقط وضعیت DMZ رو می‌خونه و تنظیمی رو تغییر نمی‌ده. آدرس و مقدارهای نمونه رو با اطلاعات دستگاه و نشست خودتون جایگزین کنید؛ اگر درخواست واقعی کوکی نداره، خط --cookie رو حذف کنید. برای اینکه اطلاعات نشست در تاریخچه shell نمونه ذخیره نشن، فرمان شامل مقدار واقعی رو در ترمینال paste نکنید؛ درخواست رو در یه فایل محلی با دسترسی محدود نگه دارید و بعد از کار پاک کنید.

 

دقت کنید که HTTP این نمونه به‌خاطر --data-raw از نوع POST هست، ولی فیلد method داخل JSON برابر GET هست و خواندن وضعیت رو درخواست می‌کنه. در مقابل، درخواست تغییر تنظیم DMZ با cmd=172،‏ method=POST و subcmd=6 در بدنه JSON ارسال می‌شد و فیلدهای enabled،‏ ip و token هم داشت. نمونه بالا فرمان بازکردن Telnet نیست؛ مرحله بعد روایت استفاده من از مسیر آسیب‌پذیر همون firmware هست.

مسیر آسیب‌پذیر، مقدار فیلد ip رو به اجرای فرمان shell می‌رسونه. با یه نشست معتبر پنل، مقدار IP حاوی جداکننده ; ارسال شد تا بعد از بخش اول، telnetd اجرا بشه. بخش فرمان واقعاً اجراشده این‌جور بود؛ این یه شرح تاریخی هست، نه درخواست HTTP کامل یا توصیه اجرای دوباره روی gateway:

 

پورت 2323 اول بسته بود و چند ثانیه بعد باز شد. درخواست غیرفعال‌کردن DMZ هم بلافاصله ارسال شد. در ادامه، دسترس‌پذیری پنل و وضعیت سرویس بررسی شد؛ اینجا فهمیدم نباید فقط به جواب موفق API اعتماد کنم، چون در تلاش‌های بعدی بعضی درخواست‌ها success برمی‌گردوندن ولی marker مورد انتظار ساخته نمی‌شد.

اثر عملیاتی این مرحله: تنظیم DMZ تغییر می‌کنه و یه سرویس ورود بدون رمزنگاری روی LAN باز می‌شه. این روش فقط با احراز هویت مالک و روی نمونه بررسی‌شده اجرا شد؛ session token و credential در مقاله نمیان. قبل از هر بازتولید، تنظیم اولیه DMZ، مسیر مدیریت مستقل و روش بستن listener باید مشخص باشن. این کار فلش firmware نیست، اما می‌تونه امنیت و ارتباط gateway زنده رو تغییر بده.

BusyBox shell داشتیم، اما هنوز root نبودیم

ورود به Telnet با حساب Linux از نوع admin موفق شد. banner،‏ BusyBox v1.30.1 و shell داخلی ash رو نشون می‌داد. خروجی واقعی id این بود:

 

پس BusyBox مرحله ارتقای دسترسی نبود؛ ابزارها و shell محیط بود. پردازش telnetd با root اجرا شده بود، ولی login کاربر رو به UID 1000 می‌بره. حساب پنل وب هم با حساب root در Linux یکی نبود. تلاش ورود root و su، shell ریشه تأییدشده ندادند. روش دومِ Telnet مستقیم و بدون login هم در اون مرحله قبل از اجرا متوقف شد؛ اون رو جزو مسیر موفق حساب نمی‌کنم.

برای root SSH از همون مسیر CGI دارای دسترسی بالاتر استفاده کردم تا فایل مجاز root و سرویس SSH رو آماده کنم. خواندن فایل‌ها و انتقال موقت کلید عمومی از Telnet ممکن بود، ولی کپی به مسیر محافظت‌شده با فرمان privileged انجام شد. برای همین ترتیب دقیق «Telnet و سپس خودکار root» نبود: Telnet محیط بررسی رو فراهم کرد و CGI هنوز برای عملیات ریشه لازم بود.

کلید عمومی، Dropbear و یه مسیر اشتباه

روی Mac کلید اختصاصی اتصال ساخته شد و فقط کلید عمومی به دستگاه رفت؛ کلید خصوصی روی میزبان ماند. Dropbear موجود در firmware با host key موقت و bind به 192.168.70.1:2222 راه افتاد. فایل محلی dropbear-start-original.py فرمان تاریخی زیر رو حفظ کرده؛ این فرمان سرویس باز می‌کنه و نباید فقط برای مشاهده وضعیت اجرا بشه:

 

گزینه -s ورود با password رو می‌بنده. بازبودن پورت هنوز ورود موفق نبود. کلید اول در /root/.ssh/authorized_keys قرار گرفت و login با public key رد شد. بعد از تلاش اولیه Ed25519، کلید RSA هم امتحان شد؛ چون مسیر مجوز کلید هنوز اشتباه بود، از اون شکست‌ها نمی‌شه به‌تنهایی ناسازگاری قطعی Ed25519 رو نتیجه گرفت.

آخرش مشکل از مسیر کلید بود. باید کلید رو جایی می‌گذاشتم که Dropbear این OpenWrt ازش می‌خونه. بخش عملیاتی ثبت‌شده در فایل محلی recovery-original.py این‌جور هست؛ قبل از بازنویسی این‌جور فایلی در دستگاه دیگه باید کلیدهای قبلی رو حفظ کرد:

 

فایل موقت فقط کلید عمومی بود. این بار اتصال با RSA جواب داد و بالاخره خروجی‌ای رو گرفتم که دنبالش بودم:

 

اسکریپت اتصال باقی‌مانده در you-are-a-senior-embedded-linux/outputs/router-root-ssh/connect.sh از کلید مشخص، IdentitiesOnly=yes،‏ known_hosts اختصاصی و StrictHostKeyChecking=yes استفاده می‌کنه. برای host key قدیمی، HostKeyAlgorithms=+ssh-rsa و برای کلید کاربر PubkeyAcceptedAlgorithms=+ssh-rsa فقط در همون اتصال اومدن؛ policy عمومی SSH میزبان شل نشده. فرمان خلاصه اتصال، بعد از آماده‌بودن همین تنظیمات، این‌جور بود:

 

بعد از تأیید root SSH، خاموش‌بودن DMZ و bind سرویس بررسی شد، listener موقت Telnet بسته شد و بسته‌بودن پورت اون تأیید شد. فایل‌های موقت کلید عمومی و markerهای setup هم پاک شدن. host key اون مرحله در /tmp بود؛ دوام سرویس بعد از reboot، کار جداگانه بعدی بود و از موفقیت اولین login نتیجه نمی‌شه. alias با نام router در ادامه، تنظیمات اتصال مالک رو خلاصه می‌کنه؛ تصویر native کنونی SSH روی پورت 22 داره.

UART بعد از این دسترسی تکمیل شد

دریافت کنسول هم با داشتن shell فرق داشت. فریمور کارخانه خروجی رو چاپ می‌کرد، ولی getty در inittab کامنت بود. Enter فقط echo می‌شد و login: نمی‌اومد. بعد از داشتن دسترسی مدیریتی موجود، تنظیم getty تغییر کرد. این مرحله روی overlay می‌نوشت و در سند Recovery همراه با نسخه پشتیبان و مسیر برگشت ثبت شده؛ راه به‌دست‌آوردن root اولیه نبود.

توی تصویر native، پیکربندی کنسول بعداً به askfirst برای ash تغییر کرد. این تفاوت امنیتی مهمه: وضعیت کنسول کارخانه رو نباید به تصویر جدید تعمیم داد. دسترسی فیزیکی به UART تصویر native می‌تونه shell ریشه بدهد؛ حفاظت از دستگاه فقط محدودکردن پورت شبکه نیست.

اولین بررسی‌ها؛ بدون راه‌اندازی سرویس‌های ناشناخته

برای شروع، اطلاعات موجود رو می‌خوندم. نمونه‌های زیر در مستندات پروژه اومدن و سیستم رو reconfigure نمی‌کنن:

 

از این سه مشاهده، سه لایه روشن می‌شه: نسخه و معماری Kernel، منبع RootFS و slot، و فایل‌سیستم‌ها و ماژول‌های فعال. خروجی کامل باید قبل از انتشار از شناسه‌های اختصاصی پاک بشه. عمداً به‌جای یه خروجی ساختگی برای دستگاه خواننده، معنی شواهد نمونه آزمایش رو توضیح می‌دم.

یه بار هم سر یه فرض به‌ظاهر ساده به دردسر خوردم: اجرای sms_mgr -h کمک چاپ نکرد و به فعالیت مودم و reboot منتهی شد. برنامه اختصاصی الزاماً قرارداد متداول خط فرمان رو رعایت نمی‌کنه. برای شناخت اون باید اول فایل، رشته‌ها، callerها و اسکریپت راه‌انداز رو بررسی کرد. گزینه‌ای که برای ابزار لینوکس بی‌خطر به نظر می‌رسه، برای یه ابزار vendor ممکنه فرمان عملیاتی باشه.

Linux میزبان و Baseband یه چیز نیستن

روی پردازنده کاربردی یا AP، Linux اجرا می‌شه؛ Baseband پردازنده و firmware مسئول شبکه رادیویی هست. در X28 بررسی‌شده، مسیر فعال میان این دو داخلی هست. فرمان‌های کنترلی از MIPC و پورت‌های CCCI می‌گذرن و بسته‌های IP از CCMNI و DPMAIF عبور می‌کنن. برای همین با یه روتر مجزا و مودم USB که فقط QMI یا MBIM رو فعال کنیم روبه‌رو نیستیم.

دیده‌شدن Quectel در USB هم این معماری رو نقض نمی‌کنه. Linux می‌تونه خودش یه USB gadget به کامپیوتر ارائه کنه. اون درگاه بیرونی با رابط داخلی AP و Baseband یکی نیست. این تمایز در قسمت سوم تعیین می‌کنه چرا x28_mipc نوشتم و چرا نصب یه بسته عمومی USB-modem کافی نبود.

لاگ بوت چه چیزی رو روشن کرد؟

capture مورخ ۲۰۲۶-۱۰-۲۶ نشون داد Preloader، LK و سپس Kernel اجرا می‌شن. گزیده زیر عین خطوط منتشرشده و پالایش‌شده گزارش بوت هست؛ خطوط میانی حذف شدن:

 

همراه با bootslot=b و ubi.mtd=42، این خروجی slot B رو برای اون capture مشخص می‌کنه. از طرفی وجود بررسی امضا در زنجیره رو نشون می‌ده. اما یه بوت موفق با فایل‌های اصلی ثابت نمی‌کنه که فایل تغییرکرده هم پذیرفته می‌شه یا شکست بررسی حتماً به slot دیگه می‌ره. برای پاسخ به اون سؤال‌ها، تحلیل مسیر خطا و آزمایش مستقل لازم بود.

در همین نقطه، تصویر کلی دستگاه به‌دست آمد: NAND با بخش‌های مشترک و جفت‌های A/B، Kernel مستقل از RootFS، و firmwareهای مودم که باید دست‌نخورده بمونن. هدف بعدی دیگه «فایل رو کجا کپی کنم؟» نبود؛ باید می‌فهمیدم دقیقاً چه چیزی رو می‌خونم و اگر نوشتن شکست خورد، چطور برمی‌گردم.

نتیجه و ادامه مسیر

تا این مرحله مشخصات اصلی نمونه، کنسول ۱٫۸ ولتی و ترتیب قابل مشاهده بوت روشن شده بود. دسترسی مدیریتی موجود رو به ابزار ثبت شواهد تبدیل کردم و محدودیت LuCI روی فریمور کارخانه رو شناختم. مهم‌تر اینکه هنوز هیچ نتیجه‌ای درباره recovery عمومی یا سازگاری تمام نسخه‌های X28 نگرفته بودم.

در قسمت دوم، از این دسترسی برای backup پارتیشن‌ها، بررسی NAND، شناخت A/B و آزمودن راه برگشت استفاده می‌کنم.

منابع و لینک‌های بیشتر

اطلاعات
11
0
0
اشتراک و حمایت
profile نویسنده: علی نادری متخصص الکترونیک

مقالات بیشتر

slide

پالت | بازار خرید و فروش قطعات الکترونیک

قطعات اضافه و بدون استفاده همیشه یکی از سرباره‌‌های شرکتها و طراحان حوزه برق و الکترونیک بوده و هست. پالت سامانه‌ای است که بصورت تخصصی اجازه خرید و فروش قطعات مازاد الکترونیک را فراهم می‌کند. فروش در پالت
family

آیسی | موتور جستجوی قطعات الکترونیک

سامانه آی سی سیسوگ (Isee) قابلیتی جدید و کاربردی از سیسوگ است. در این سامانه سعی شده است که جستجو، انتخاب و خرید مناسب تر قطعات برای کاربران تسهیل شود. جستجو در آیسی
family

سیسوگ‌شاپ | فروشگاه محصولات Quectel

فروشگاه سیسوگ مجموعه ای متمرکز بر تکنولوژی های مبتنی بر IOT و ماژول های M2M نظیر GSM، GPS، LTE، NB-IOT، WiFi، BT و ... جایی که با تعامل فنی و سازنده، بهترین راهکارها انتخاب می شوند. برو به فروشگاه سیسوگ
family

سیسوگ فروم | محلی برای پاسخ پرسش‌های شما

دغدغه همیشگی فعالان تخصصی هر حوزه وجود بستری برای گفتگو و پرسش و پاسخ است. سیسوگ فروم یک انجمن آنلاین است که بصورت تخصصی امکان بحث، گفتگو و پرسش و پاسخ در حوزه الکترونیک را فراهم می‌کند. پرسش در سیسوگ فرم
family

سیکار | اولین مرجع متن باز ECU در ایران

بررسی و ارائه اطلاعات مربوط به ECU (واحد کنترل الکترونیکی) و نرم‌افزارهای متن باز مرتبط با آن برو به سیکار
become a writer
نویسنده شو !

سیسوگ با افتخار فضایی برای اشتراک گذاری دانش شماست. برای ما مقاله بنویسید.

ارسال مقاله
become a writer
نویسنده شو !

سیسوگ با افتخار فضایی برای اشتراک گذاری دانش شماست. برای ما مقاله بنویسید.

ارسال مقاله

خانواده سیسوگ

سیسوگ‌شاپ

فروشگاه محصولات Quectel

پالت
سیسوگ فروم

محلی برای پاسخ پرسش‌های شما

سیسوگ جابز
سیسوگ
سیسوگ فروم
سی‌کار

اولین مرجع متن باز ECU در ایران

سیسوگ مگ
آی‌سی

موتور جستجوی قطعات الکترونیکی

سیسوگ آکادمی
پالت

بازار خرید و فروش قطعات الکترونیک

دیدگاه ها

become a writer
نویسنده شو !

سیسوگ با افتخار فضایی برای اشتراک گذاری دانش شماست. برای ما مقاله بنویسید.

ارسال مقاله
become a writer
نویسنده شو !

سیسوگ با افتخار فضایی برای اشتراک گذاری دانش شماست. برای ما مقاله بنویسید.

ارسال مقاله