JWT Token নিয়ে গল্প!
সব পুরনো গল্পের মত আজকের গল্পও ছোট রাখার চেষ্টা করব। কিছু জিনিস শিখতে শিখতে, আমরা সেগুলোর হালকা পাতলা সিকিউরিটি নিয়ে আলোচনা করব। সাথে আজকের এই গল্পের মূল আকর্ষণ হবে, একটা ছোট hands-on। আশা করি, সবাই সেটা নিজে নিজে একবার করে হলেও করে দেখবেন।
JWT Token কি ? শুরুতে সংক্ষেপে বলে নেই, আমার নিজের একটা গল্প বলে।
JWT Token এর সাথে প্রথম পরিচয় Designed Inc. এ কাজ শুরু করার ভিতর দিয়ে। আমাদের সব কিছু তখন AWS এ ছিল। গুড়ি গুড়ি সব সার্ভিস, একটা-আর-একটার সাথে সারাদিন গুতাগুতি করে। আমি নতুন, হা’ করে সেগুলো বুঝার চেষ্টা করতে থাকি দিন রাত…।
যাই হোক, ডেভেলপমেন্টের সময় সময় ও অর্থ বাঁচাতে, সব সার্ভিস আমরা লোকালি Run করতাম সাধারণত। এখানেই JWT আমাকে প্রথম মুগ্ধ করে দিল।
আমরা Production এ, ইউজার Authentication এর জন্য যে, auth0 ব্যবহার করতাম। লোকালেও সেই একই account দিয়েই লগইন করতাম। সাথে যখন GraphQL এ query করা লাগত, auth0 সার্ভার থেকে পাঠানো JWT token, হেডারে লাগিয়ে দিলেই, লোকাল Dynamo DB সার্ভার আমাদের ডাটা দিয়ে দিত।
আমি পুরা বিষয়টা দেখে পুরাই মুগ্ধ। কে যে কই থেকে, গোপনে সব করে ফেলতেছে, তা বোঝা দায় হয়ে গেল।
আমার গল্প কি বোঝা গেছে? আর একটু তাহলে যোগ করি, বুঝতে সুবিধা হবে…
ইন্ডিপেন্ডেন্ট সার্ভিস আর্কিটেকচারে, সবাই স্বাধীন। প্রতিটি মডিউল/সার্ভিস স্বাধীন। তাহলে, প্রতিটি স্বাধীন মডিউল একে অন্যর সাথে কথা বলার সময়, নিজেদের পরিচয় নিশ্চিত করার জন্য কি বার বার লগইন করবেন? যদি না করেন, তাহলে তারা আপনাকে চিনবে কিভাবে? আর আপনার পরিচয় নিশ্চিত না হয়ে, সে আপনাকে যদি ডেটা দেয়, তাহলে সিস্টেমের তো বারটা বেজে যাবে।
ইন্ডিপেন্ডেন্ট সার্ভিস আর্কিটেকচারে, ক্লাসিকাল লগইন মেকানিজমের পরে, Authentication সার্ভার এসব ক্ষেত্রে একটা JWT Token পাঠায়ে দেয়। যা অনেকটা আগের দিনের রাজ রাজাদের সিল মোহরের মতন। যাই হোক, ক্লাইন্ট সেই টোকেন পেয়ে, আরাম করে মাথায় বসিয়ে, অন্যান্য সার্ভিসকে কল করবে। অনন্য সার্ভিস সেই সিল মোহর মিলিয়ে, তাকে ডেটা দিয়ে দেয়। আর না মিললে, তাকে বের করে দেয়।
গল্পটা আসলে যত সোজা এর ভিতরে অনেক মার প্যাঁচ আছে। সেগুলো ভাল করে জানতে নিচের লিঙ্কে যেতে হবে। সেখানে অনেক বিস্তারিত আলোচনা আছে-
https://hasura.io/blog/best-practices-of-using-jwt-with-graphql/
অনেক তো JWT Token এর গুণগান হল। এবার একটু দোষ ত্রুটি খুঁজে দেখা যাক।
উপরের লিঙ্ক যারা পড়েন নাই। তারা এই ত্রুটি খুঁজে বের করার সময় অনেক আনন্দ পাবেন ঠিকই, কিন্তু অনেক গুরুত্বপূর্ণ জিনিস মিস করে যাবেন। এক্ষেত্রে আ মার সাজেশন হল, hands-on পড়ার পরে লিঙ্কটি পড়া। খুব সহজেই অনেক কিছু বুঝতে সাহায্য করবে।
এখন কাজের কথায় ফিরি। এই অংশ পুরোটাই হাতে কলমে আমরা দেখব। প্রশ্ন পেতে চলে যান নিচের লিঙ্কে। এখানে আমাদের কাজ হবে একটা Flag খুঁজে বের করা। যা কোথাও লুকানো আছে। আমরা JWT এর vulnerability ব্যবহার করে সেই লুকানো Flag বের করব।
http://35.197.254.240/admingatefirst/
কি মনে হচ্ছে, এই সাইটে লগইন করা যাবে?
আসলে তো সবই দিয়ে রেখেছে তারা। তাহলে দেরি না করে, লগ ইন করে ফেলি। দেখি ভিতরে Flag পাই কি না?
এই test ইউজার দিয়ে লগইন করে আসলে আমাদের কোন ফায়দা নেই, তা দেখা যাচ্ছে। কোন flag আসলে দৃশ্যমান নয়।
আমরা সাধারণ ভাবে, ধরে নিতে পারি admin ইউজার হলে, হয়ত Flag টা পাওয়া যেতে পারে। আমাদের কাছে যেহেতু admin এর username, password নেই, আমরা বসে বসে ট্রায়েল & ইরোর খেলা খেলতে পারি। নতুবা, একটু স্মার্ট রাস্তায় এগোতে পারি।
আমরা এ ধাপের জন্য Burp Suite ব্যবহার করব। এটা অনেকটা Postman এর মত Application, ছোট করে বললে। এছাড়াও এর আরও অনেক অসাধারণ ফিচার আছে।
Burp Suite এ যদি আমরা পুরো লগইন সাইকেল inspect করি আমরা দেখব সার্ভার লগইন successful হলে একটা JWT Token পাঠাচ্ছে, Authentication: Bearer হিসেবে response header এর সাথে( নিচের ছবিতে, এখানে request header এ দেখানো হচ্ছে)।
আমরা এবার প্রাপ্ত JWT Token টা নিয়ে, একটু ঘুরে আসি jwt.io সাইট থেকে। দেখি সেখানে কিছু পাওয়া যায় নাকি? JWT Token যারা আগে দেখেন নাই, তাদের জন্য বলে রাখি- এই token তিন ভাগে বিভক্ত। আর token টি Base64 encoded থাকে।
১/ Header ২/ Payload ৩/ Signature
এদের ভিতরে কি থাকে? ছবি দেখে বুঝে নেন 😛
আমাদের টোকেনকে decode করলে আমরা নিচের চিত্রর মতন পাব।
এখন মাজার একটা কথা শেয়ার করি। JWT Token ডিফল্ট HS256( HMAC-SHA256) Alogrithm ব্যবহার করে। HS256 Algorithm মূলত secret base cryptographic hash function, যা payload এর সাথে shared secret যোগ করে hash তৈরি করে থাকে। যখন কোন স্বাধীন সার্ভিস এই token verify করতে যাবে, তারও কাছে এই shared secret থাকতে হবে, ভ্যালিড hash তৈরি করে, verify করার জন্য।
আমরা যদি একটু খাটুনি করি, আমরা কি এই shared secret কে উদ্ধার করতে পারব? যদি পারি, তাহলে কিন্তু আমরা ইচ্ছা মত ভ্যালিড সিগনেচার দিয়ে স্বাধীন সার্ভিস কে কল দিতে পারব। আর সে বোকা হয়ে আমাদের গোপন ডেটা দিয়ে দিবে।
আরও বিস্তারিত জানতে পড়ে ফেলুন-
দেখি, আমরা brute force করে সেই কাঙ্ক্ষিত secret টা কি পেতে পারি নাকি?
এজন্য আমরা https://github.com/Sjord/jwtcrack application এর সাহায্য নিব। কতগুলো worldlist দিয়ে আমরা Token এর secret কে জানার জন্য brut force এটাক করব।
আহ ! secret key পাওয়া গেছে। ওয়াও!!! (জীবন কিন্তু এমন ফ্লিম না, এটা মনে রাখবেন)
এবার আর কে পায় আমাদের? ইচ্ছা মত payload বানিয়ে sign করে, application এর সার্ভিসকে কল দিব। দেখব কি ঘটে ?
আমরা পেয়ে গেলাম, আমাদের নতুন জাল JWT Token।
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkYXRhIjoie1widXNlcm5hbWVcIjpcImFkbWluXCIsXCJyb2xlXCI6XCJhZG1pblwifSJ9.8R-KVuXe66y_DXVOVgrEqZEoadjBnpZMNbLGhM8YdAc
আমারা এখন Burp Suite এর সাহায্যে Authentication : Bearer এ নতুন টোকেন বসিয়ে request send করব। আর দেখব, কি ফলাফল আসে-
আমরা দেখতে পাচ্ছি, সার্ভার বোকা হয়ে, আমাদের admin ভেবে, তার গোপন flag পাঠিয়ে দিয়েছে।
উপরের আলোচনা বুঝতে, সাপোর্টইং লিঙ্ক গুলো পড়তে হবে, আবারো বলছি। গল্প ছোট রাখতে, অনেক অতৃপ্তি রেখে যেতে হচ্ছে 🙁
আর অনেকে JWT Token দিয়ে নাকি password এর হ্যাশও পাঠান শুনি। দয়া করে, নতুন কোন কিছু নিয়ে কাজ করতে গেলে, অল্প হলেও তা নিয়ে, পড়া লেখা করবেন। সেটার কাজ কি? কিভাবে ব্যবহার করবেন ইত্যাদি ইত্যাদি। কোড পাইলেই লিখতে, দৌড়ে যাবেন না!!!
আমাদের উপরের গল্প থেকে যা শিখতে পারি, সারাংশ করলে তা দাঁড়ায়-
১/ default settings এ, কোন কিছুই ব্যবহার না করা।
২/ asymmetric key algorithm ব্যবহার করা।
৩/ symmetric key algorithm ব্যবহার যদি করাই হয়, সেক্ষেত্রে শক্তিশালী shared key ব্যবহার করা।
৪/ JWT Token এর মাধ্যমে sensitive data না পাঠানো।
৫/ কোন কিছু সবাই ব্যবহার করে বলে ভালো, এটা না ভাবা। 0 Trust নীতি অবলম্বন করা।
৬/ যেন কোন lib, framework … ব্যবহারের পূর্বে, তার সঠিক ও নিরাপদ ব্যবহার সম্পর্কে সম্যক ধারণা রাখার চেষ্টা করা।
আর আজীবন মনে রাখবেন default configuration হল যে কোন software, network device, server … এর জন্য মৃত্যু ফাঁদ।
আজ এ পর্যন্তই। বিদায়। আর ফিডব্যাক দিতে ভুলবেন না।
কৃতজ্ঞতা স্বীকার- Cyber Talents
204
Vai…….agun….
Thanks
ভাই OAuth/OpenID নিয়ে একটা লিখে ফেলেন।