رمزگشایی هش پسورد IBM i از دل QSYRUPWD
خلاصهٔ کاملتر
به گفتهٔ نویسنده، QSYRUPWD (بازیابی پسورد رمزنگاریشدهٔ کاربر) یه API روی IBM i هست که دادهٔ مربوط به پسورد یه پروفایل کاربری رو بهصورت رمزنگاریشده به فراخوان مجاز میده. IBM i همون پلتفرم سازمانی یکپارچهٔ IBM هست که ریشهش به خط AS/400 برمیگرده و هنوز تو کارهای حیاتی مثل ERP و مالی و لجستیک پرکاربرده. این API بیشتر برای کارهایی مثل همگامسازی و مهاجرت پسورد وجود داره، جایی که باید متن پسورد بدون لو رفتن جابهجا بشه.
نویسنده میگه تو یکی از تستهای نفوذ IBM i دید که سرور مشتری روی QPWDLVL = 2 تنظیم شده. مقدار سیستمی QPWDLVL هم قانونهای پسورد و هم فرمت verifierهایی که برای سازگاری نگه داشته میشن رو تعیین میکنه؛ سطح ۰ و ۱ روی DES، سطح ۲ و ۳ روی SHA-1 و سطح ۴ روی PBKDF2 هستن. مشکل اینجا بود که John the Ripper فرمتهای as400_des و as400_ssha1 رو برای مواد قدیمی IBM i داره، ولی خروجی QSYRUPWD روی سطح ۲ تا ۴ دیگه با این فرمتها نمیخوند؛ یعنی حتی با دسترسی کامل *ALLOBJ و *SECADM هم عملاً نمیشد ازش برای تست قدرت پسورد استفاده کرد. همین شد انگیزهٔ مهندسی معکوس.
نویسنده اول یه برنامهٔ کوچیک CL نوشت که QSYRUPWD رو با فرمت UPWD0100 صدا میزنه و بافر خروجی رو درمیاره. بعد با ابزار ردیابی STRTRC یه call trace گرفت و تو خروجیش سریع سراغ نمادهایی رفت که اسمشون بوی رمزنگاری میداد، مثل توابع مربوط به cipher عمومی و رمزگشایی AES. مرحلهٔ بعد با System Service Tools (SST) کد اسمبلی چند تا *SRVPGM رو دامپ کرد و دید کد کار حساس رو به روتینهای سطحپایینتر واگذار میکنه.
رد پا به یه مکانیزم فراخوان سیستمی به اسم SCV (Supervisor Call Vectored) رسید؛ اینجا رجیستر R10 شمارهٔ تابع رو مشخص میکنه و آرگومانها از R3 به بعد پاس داده میشن. با دنبالکردن جدول توابع SCV 10، نویسنده فهمید شمارهٔ تابع ۳۴۶ همون دستور CIPHER روی MI هست. برای دیدن پارامترها هم چون SST دیباگر کامل نیست، یه ترفند به اسم «بریکپوینت آدم فقیر» زد: دستور SCV رو به یه حلقهٔ بینهایتِ دواِنسترکشنی تبدیل کرد تا اجرا سر یه آدرس مشخص گیر کنه و بشه رجیسترها و حافظه رو بررسی کرد.
نتیجهٔ نهایی این شد که ساختار کنترلی CIPHER نشون میداد عملیات یه هش یکطرفه با الگوریتم SHA-1 هست و ورودیش هم به NT hash پسورد (یعنی MD4 روی UTF-16LE پسورد) با یه پیشوند ثابت گره خورده بود. نویسنده حاصل CIPHER رو دستی هم حساب کرد و دقیقاً با خروجی سیستم یکی درومد، پس مطمئن شد IBM چیزی تو خود الگوریتم SHA-1 دست نبرده و همون پیادهسازی استاندارده.
نکات کلیدی:
- QSYRUPWD روی IBM i دادهٔ پسورد رو رمزنگاریشده به فراخوان مجاز (*ALLOBJ و *SECADM) میده
- روی QPWDLVL سطح ۲ تا ۴ خروجی دیگه با فرمتهای IBM i در John the Ripper سازگار نیست
- نویسنده با ابزارهای بومی STRTRC، SST و دیساسمبلی مسیر رمزنگاری رو معکوس کرد
- کلید ماجرا دستور CIPHER بود که از طریق SCV 10 با شمارهٔ تابع ۳۴۶ فراخوانی میشه
- پشت پرده همون SHA-1 استاندارد روی NT hash پسورد استفاده میشه، بدون دستکاری الگوریتم




