توضیح عمیق آسیبپذیریهای JWT (بخش اول)
سلام من بهروزم و امروز قراره یکی از پرطرفدارترین آسیبپذیریهایی که زیاد اسمش رو میشنوید با هم بررسی کنیم.
بله، درست حدس زدید، قراره در مورد JWT (JSON Web Token) صحبت کنیم.
این تکنولوژیه که شرکتها و افراد این روزا تو اپلیکیشنهای وبشون استفاده میکنن، و این روزها JWT همهجا ظاهر میشه.
مثلاً «فلانی با یک باگ JWT باندل گرفت» یا «توکن JWT ضعیف». این موضوع ترنده و فهمیدنش آسونه.
پس من اینجام؛ تو این مقاله با یه مثال عملی توضیح میدم که چطور این آسیبپذیری رو پیدا کنی، چطور exploit کنی.
یادت باشه، باگهای JWT انواع مختلفی دارن. امروز یکیشو پوشش میدیم، بقیهش شاید تو پستهای بعدی.
بریم سراغ اصل موضوع، JWT واقعاً چیه؟ ببین، اینها توکنهایی هستن که اغلب برای احراز هویت استفاده میشن.
ممکنه قبلاً با JWT روبهرو شده باشی اما نمیدونستی باید باهاش چی کار کنی، یا اصلاً نمیدونستی این چیه!!
ببین، JWT عمدتاً برای احراز هویت و همچنین مجوزدهی (authorization) استفاده میشه. حالا فرض میکنم تفاوت این دو رو میدونی، پس از سطح 1 شروع کنیم .
JWT چه شکلیه؟ ببین…
حالا، این که JWT فقط تو هدر Authorization: Bearer
باشه معنی نداره.
JWT میتونه هرجوری قرار بگیره، مثلاً تو کوکیها باشه، یا با یه پارامتر ساده مثل jwt
ارسال بشه.
این کاملاً بستگی به توسعهدهنده داره، ولی معمولاً تو هدر Authorization قرار میگیره.
توکنهای JWT رشتههایی هستند که با Base64 رمزگذاری شدن و از سه قسمت تشکیل میشن
هدر، پیلود و امضا، که با یک نقطه .
به هم وصل شدن.
هر قسمت خودش آسیبپذیریهای خاص خودش رو داره، ولی برای این مقاله ما فقط روی هدر و پیلود تمرکز میکنیم.
حالا میخوام کامل توجهت رو جمع کنی، این مهمترین بخشه.
میبینی سه قسمت وجود داره: هدر، پیلود و امضا. تو هدر دو تا چیزی هست که میتونی متوجه بشی.یکی الگوریتم و یکی هم نوع (type). الگوریتم یعنی الگوریتمی که برای ساخت این توکن استفاده شده، و نوع، نوع توکن رو نشون میده که همیشه JWT خواهد بود. الگوریتم ممکنه متفاوت باشه، میتونه SHA-256 باشه، میتونه RSA باشه، یا هر چیز دیگهای.
بعد بخش پیلود هست. حالا این مهمترین بخشه. تو بخش پیلود، دادههای اصلی قرار میگیرن.مثلاً نام، شناسهٔ کاربر، نقش (role)، هر چیزی که برای تایید کاربر استفاده میشه تو پیلود خواهد بود. و ما معمولاً برای پیدا کردن آسیبپذیریها پیلود رو دستکاری میکنیم.
حالا تصویر زیر رو ببین. تو تصویر پایین میتونی بخش پیلود یکی از اپلیکیشنها رو ببینی، و واضحاً پارامتری که username
و admin
هست رو میبینی.
حالا ممکنه تو فکر کنی: «اووه، بذار نامکاربری رو به هر کاربر دیگهای تغییر بدم و توکن JWT بسازم، یا فقط مقدار admin
رو از 0 به 1 عوض کنم و دوباره ارسال کنم — دسترسی میگیریم.»
ولی نه، همهچیز همیشه اینقدر آسون کار نمیکنه.
بیا جریان رو بفهمیم
پس JWT سه قسمت داره → header.payload.signature
حالا تو هدر، چیزی شبیه این داریم:
{
“alg”: “HS256”,
“typ”: “JWT”
}
یعنی از الگوریتم HS256 برای امضای توکن استفاده شده و نوع توکن JWT است.
پس در واقع این قسمت فقط به ما میگه چه الگوریتمی برای ساخت امضا استفاده شده، چیز عجیبی نیست، اما این بخش گاهی هم قابل سوءاستفادهست (بعداً در موردش صحبت میکنیم 👀).
حالا در پیلود، اینجاست که اطلاعات واقعیِ کاربر قرار داره:
{
"username": "behrouz"
}
ممکنه همچنین چیزهایی مثل user_id
،role
،isAdmin
،email
و غیره هم وجود داشته باشن.
نکته مهم:
این پیلود فقط با Base64 کدگذاری شده و به معنای رمزنگاری امن نیست.
پس بله، هر کسی میتونه اونو دیکد کنه و بخونه و مخفی نیست.
که همین یعنی ما میتونیم ببینیم چه مقادیری ارسال میشن…
حالا فرض کن تو پیلود چیزی شبیه به این ببینی:
{
"username": "behrouz"
}
و تو فکر میکنی — «خب، میدونم یه کاربر به اسم admin
وجود داره. چه میشه اگه فقط "username": "behrouz"
رو بذارم "admin"
و دوباره بفرستم؟»
به نظر منطقی میاد نه؟
تو توکن رو دیکد میکنی، پیلود رو ویرایش میکنی، دوباره انکد میکنی و میفرستی.
ولی حدس بزن چی میشه؟
کار نمیکنه 😐
چرا؟ چون امضا رو خراب کردی.حالا توکن تغییر کرده و امضای قبلی دیگه معتبر نیست.
بذار ساده و روان برات توضیح بدم:
چرا؟ چون امضا از روی هدر و پیلود (و یک کلید مخفی) ساخته میشه.
اینجا مهمترین بخش میاد: هدر و پیلود با استفاده از الگوریتمی که تو هدر گفته شده و یک کلید مخفی به امضا متصل میشن.
مثلاً فرض کن کلید مخفی NASA
باشه، هدر و پیلود با اون کلید امضا میشن و یک توکن ساخته میشه و سرور هم اون توکن رو نگه میداره.
وقتی توکن رو از مرورگر میفرستی، سرور دوباره امضا رو حساب میکنه و بررسی میکنه که آیا با امضای موجود مطابقت داره یا نه. پس اگر username
رو از behrouz
به admin
تغییر بدی، توکن تغییر میکنه و امضا هم مطابق نمیشه؛ در نتیجه سرور اون توکن رو قبول نمیکنه.
حالا میرسیم به بخش اکسپلویت
شاید حالا فکر کنی: «چطوری میتونیم این رو اکسپلویت کنیم یا اصلاً با این وجود باگ پیدا کنیم؟ مکانیسم که محکم به نظر میرسه.»
آره، مکانیسم اصولاً محکمِ، ولی گاهی پیادهسازی بهدرستی انجام نشده.
و اینجا نقطهایه که اولین آسیبپذیریمون شروع میشه، «تنزل الگوریتم به None
(Downgrading algorithm to None).»
کمی استراحت کن، تجدید قوا کن، چون حالا بخش جذاب شروع میشه. 😀
تنزیل الگوریتم به None
JWT رسماً از الگوریتم "none"
پشتیبانی میکنه که در اصل یعنی:
«این توکن نیازی به امضا نداره.»
معمولاً JWT از الگوریتمهایی مثل HS256
یا RS256
استفاده میکنه، که توکن با استفاده از یه کلید مخفی یا کلید خصوصی امضا میشه.
سرور اون کلید مخفی رو نگه میداره و باهاش تأیید میکنه که توکن تغییر نکرده.
اما وقتی الگوریتم روی "none"
قرار میگیره، هیچ امضا یا کلید مخفیای وجود نداره.
پس کل قضیه عوض میشه.
🧨 چهمیشه اگه alg = none
باشه؟
اگر هدر JWT به این شکل باشه:
{
"alg": "None",
"typ": "JWT"
}
بعد سرور فرض میکنه:
«اوه، این توکن از امضا استفاده نمیکنه. نیازی به بررسی نیست.»
که یعنی:
-
میتونی بخش امضا رو کامل حذف کنی
-
سرور هیچ چیزی رو بررسی نمیکنه
-
و صرفاً پیلود رو همانطور که هست قبول میکنه
🧪 پس چطور اکسپلویتش میکنیم؟
فرض کن بهعنوان یک کاربر عادی وارد میشی و یک JWT با این پیلود دریافت میکنی:
{
"sub": "1234567890",
"name": "John Doe",
"admin": false,
"iat": 1516239022
}
توکن را دیکُد کن
-
مقدار
"admin": false
را به"admin": true
تغییر بده. -
در هدر،
"alg": "HS256"
را به"alg": "none"
تغییر بده. -
بخش امضا (signature) را حذف کن.
توکن جدید را به سرور ارسال کن.
curl -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InVzZXIiLCJhZG1pbiI6MX0.q8De2tfygNpldMvn581XHEbVzobCkoO1xXY4xRHcdJ8' <http://BLURED/api/v1.0/example2?username=admin>
{
"message": "Welcome admin, you are an admin, "
}
چون سرور دیگه امضا رو بررسی نمیکنه (چون "alg": "none"
هست)، صرفاً هر چیزی که تو پیلود باشه — از جمله ادعای جعلیِ admin تو رو قبول میکنه.
الان بهعنوان ادمین باهات رفتار میکنن،بدون کلید مخفی، بدون امضای واقعی، هیچچیز. 😉
پارامترهای پیلود میتونن متفاوت باشن، باید با مغزِ خودت فکر کنی و تصمیم بگیری چه چیزهایی رو میتونی دستکاری یا تغییر بدی.
اگر به هک و امنیت علاقه داری دوره کلوپ امنیت ۱ و کلوپ پیشرفته رو از دست نده.کلاس به صورت خصوصی برگزار میشه.