این ssh/sshd رو که همه ما روزانه استفاده میکنیم و اینا یه هندشیک میزنن و یه کانال انکریپتد بین کلاینت و سرور بالا میارن و روی همون کانال امن، کل ترافیک شل رو عبور میدن.

بعد دو راه هست که این ssh/sshd بتونن این کانال امن رو ایجاد کنن و شما یا پسووردت رو میزنی و یا اینکه یه کلید ست میکنی که هربار نخوای پسوورد وارد کنی و خب اکثر آدما هم همون کلید رو ست میکنن.
حالا یوزر های سیستمی مثل root یا daemon فقط با کلید باید لاگین بشن و کلا نباید با پسوورد لاگین بشن این خودش یه لایه دفاعی هست که کسی نتونه پسوورد رو بدزده یا بروت فورس کنه و دسترسی روت بگیره.
خب چطور لاگین با پسوورد رو از کار بندازیم؟
ما میریم داخل etc/shadow و هش واقعی رو برمیداریم و جاش یه * میذاریم.
چرا * میذاریم؟ چون * هش معتبر نیست و هیچ پسووردی با هش شدن به * نمیرسه پس لاگین با پسوورد غیرممکن میشه و فقط با su یا sudo یا کلید ssh میتونی بری داخل.
حالا شما داری ssh میزنی به سرور و میخوای اطلاعات دیسک رو بخونی و ما میدونیم که دیسک یه سخت افزاره و هر برنامه ای اجازه نداره بره بلاک های دیسک رو بخونه و فقط کرنل از طریق درایور دیسک و فایل سیستم اجازه دارن که دیسک رو بخونن، پس sshd برای خوندن etc/shadow باید یه syscall به کرنل بده و کرنل از filesystem ردش کنه و بعد جواب رو برگردونه بالا.
حالا این syscall ها سطح پایین و خام و دست و پا گیرن و اینجاس که libc میاد دقیقا همین چالش رو حل کنه و مثلا glibc روی دبیان یا musl روی الپاین این پیچیدگی هارو داخل توابع ساده بسته بندی میکنن و مثلا getspnam برای خوندن شادو هست و crypt برای هش کردن پسوورد ورودی، پس sshd خودش syscall نمیزنه و الگوریتم هش پیاده نمیکنه بلکه کاملا به libc وابسته هست.
پس فلوی چک پسوورد sshd اینه: هش واقعی رو از شدو بگیر -> پسوورد ورودی رو بده به crypt -> نتیجه رو با strcmp مقایسه کن.
حالا crypt دو جور خروجی داره و یا هش واقعی رو میده و اگه نتونه هش کنه، یه NULL/* برمیگردونه.
خب، حالا پروتکل ssh هیچ محدودیتی روی فیلد پسوورد نمیذاره و پسوورد یه رشته با طول متغیره که از کلاینت به سرور میره و سمت سرور هم هیچکس داخل sshd چک نمیکنه که طول این پسوورد چقدر هست و زارت پاسش میده به crypt ، پس مهاجم میتونه که هر رشته ای با هر طولی که خواست بفرسته و sshd هم دوشواری نداره و هرچی شما بهش بدی رو پاس میده به crypt ، ولی لایه زیرین که میشه libc/musl اتفاقا یه سقف ۲۵۶ بایتی داره و اینجاس که sshd و musl باهم توافق نظر ندارن و یکیشون طول پسوورد براش مهم نیست ولی اون یکی مهمه.
خب یادته که ما اومدیم پسوورد root رو گذاشتیم * که کسی نتونه با پسوورد لاگین کنه؟
بعد یادته که crypt دو جور خروجی داشت و اگه به ارور میخورد، NULL / * برمیگردوند؟
و خب اینجاس که مهاجم بجای یه پسوورد ۲۵۶ بایتی، یه پسوورد ۲۵۷ بایتی میفرسته و crypt هم به ارور میخوره و * برمیگردونه و نتیجه اش چی میشه؟
خروجی crypt یدونه * هست و پسوورد root شما هم یدونه * هست:
* = * // true!
تامام، هکر با sshole از سرور شما دسترسی root گرفت!