CTF ওয়াকথ্রু: স্যান্ডবক্সড XSS
এই পাঠে যা শিখবেন
- L26-এর Reflected/Stored/DOM XSS ও এস্কেপিং-ভিত্তিক ডিফেন্স আবার ঝালাই করা
- একজন CTF সলভারের ধাপে-ধাপে চিন্তাপ্রক্রিয়া — payload জমা দেওয়া থেকে "solved" নিশ্চিত করা পর্যন্ত
- একটি অটোমেটেড CTF checker আসলে কীভাবে কাজ করে (এবং আমাদের সিমুলেশন কীভাবে সেটিকে সরলীকৃত করেছে)
- ঠিক একই পেলোড একটি সঠিকভাবে এস্কেপ করা রেন্ডারারের বিরুদ্ধে কেন ব্যর্থ হয়
১ · চ্যালেঞ্জ পরিস্থিতি — টয় গেস্টবুক
কল্পনা করুন একটি অনুমোদিত CTF প্ল্যাটফর্মে একটি ছোট্ট চ্যালেঞ্জ আছে: একটি সাধারণ
গেস্টবুকGuestbookএকটি ওয়েব পেজ যেখানে ভিজিটররা মন্তব্য জমা দিতে পারে এবং সেগুলো পরে অন্য ভিজিটরদের কাছে প্রদর্শিত হয় — Stored XSS শেখানোর জন্য একটি ক্লাসিক টয় উদাহরণ।
অ্যাপ, যেখানে ভিজিটররা একটি মন্তব্য জমা দিতে পারে এবং সেটি সাথে সাথে "রেন্ডার" হয়ে দেখানো হয়। চ্যালেঞ্জের ফ্ল্যাগ
পাওয়ার শর্ত: এমন একটি ইনপুট জমা দিন যাতে আপনার <script> ট্যাগ HTML-এস্কেপ না হয়ে
হুবহু আউটপুটে থেকে যায় — এটিই প্রমাণ করে যে অ্যাপটি Stored XSS-এর জন্য দুর্বল (L26-এর মূল সংজ্ঞা অনুযায়ী)।
পুরো "গেস্টবুক" আসলে একটি ইন-মেমরি Python লিস্ট, এবং কোনো real ব্রাউজার আমাদের পেলোড এক্সিকিউট করছে না — আমরা শুধু স্ট্রিং হিসেবে যাচাই করছি পেলোডটি এস্কেপড ফর্মে আছে নাকি raw ফর্মে। কোর্সের CLAUDE.md সুরক্ষা নিয়ম অনুযায়ী এই পাঠে কোনো real নেটওয়ার্ক কল বা real ব্রাউজার এক্সিকিউশন নেই।
২ · একজন CTF সলভারের চিন্তাপ্রক্রিয়া
একটি বাস্তব CTF চ্যালেঞ্জে হাতে বসে একজন সলভার সাধারণত এই ধাপগুলো অনুসরণ করেন —
- ধাপ ১ · বেসলাইন পরীক্ষা — প্রথমে একটি নিরীহ ইনপুট (যেমন সাধারণ টেক্সট) জমা দিয়ে দেখুন অ্যাপটি স্বাভাবিকভাবে কাজ করছে কি না।
- ধাপ ২ · প্রোবিং — একটি ছোট্ট বিশেষ ক্যারেক্টার (যেমন
<বা") দিয়ে দেখুন সেটি এস্কেপ হয়ে<হয়ে যাচ্ছে, নাকি হুবহু থেকে যাচ্ছে। - ধাপ ৩ · ক্লাসিক পেলোড — যদি এস্কেপিং না দেখেন, তাহলে ক্লাসিক টেস্ট পেলোড
<script>alert('XSS')</script>জমা দিন। - ধাপ ৪ · যাচাই — রেন্ডার হওয়া আউটপুট পরীক্ষা করে দেখুন পেলোডটি হুবহু (unescaped) আছে কি না — বাস্তব CTF-এ এখানেই একটি হেডলেস ব্রাউজার-চেকার
alert()ফায়ার হলো কি না তা স্বয়ংক্রিয়ভাবে যাচাই করে "solved" মার্ক করে।
৩ · কোড দিয়ে সমাধান — ইনসিকিউর বনাম সিকিউর রেন্ডারার
নিচে L26-এর ঠিক একই render_comment() প্যাটার্নের দুটি ভার্সন আছে — একটি ইনসিকিউর (raw স্ট্রিং
ফেরত দেয়), একটি সিকিউর (html.escape() ব্যবহার করে)। সাথে আছে একটি ctf_check_solved()
ফাংশন যা রেন্ডার হওয়া আউটপুটে raw <script> ট্যাগ আছে কি না তা যাচাই করে — এটিই এই সিমুলেশনে
আমাদের "স্বয়ংক্রিয় CTF checker"।
import html
# টয় "গেস্টবুক" — CTF চ্যালেঞ্জের ব্যাকএন্ড, ইন-মেমরি লিস্ট (L26-এর প্যাটার্ন)
guestbook = []
def render_comment_insecure(comment):
"""ইনসিকিউর ভার্সন — raw string ফেরত দেয়, কোনো এস্কেপিং নেই।"""
guestbook.append(comment)
return f"<div class='comment'>{comment}</div>"
def render_comment_secure(comment):
"""সিকিউর ভার্সন — html.escape() দিয়ে আউটপুট এনকোড করা।"""
return f"<div class='comment'>{html.escape(comment)}</div>"
def ctf_check_solved(rendered_output):
"""CTF checker সিমুলেশন — বাস্তব CTF-এ এটি হেডলেস ব্রাউজারে alert() ফায়ার
হলো কি না চেক করে; এখানে real ব্রাউজার নেই বলে raw <script> ট্যাগ
unescaped অবস্থায় আউটপুটে আছে কি না তা যাচাই করছি।"""
return "<script>" in rendered_output
payload = "<script>alert('XSS')</script>"
print("ধাপ ১ · পেলোড জমা দেওয়া হলো:", payload)
print()
insecure_output = render_comment_insecure(payload)
print("ইনসিকিউর গেস্টবুকে রেন্ডার হলো:", insecure_output)
print("CTF checker ফলাফল:", "SOLVED" if ctf_check_solved(insecure_output) else "NOT SOLVED")
print()
secure_output = render_comment_secure(payload)
print("সিকিউর গেস্টবুকে রেন্ডার হলো: ", secure_output)
print("CTF checker ফলাফল:", "SOLVED" if ctf_check_solved(secure_output) else "NOT SOLVED")
ইনসিকিউর ভার্সনে পেলোড হুবহু থেকে যায় — ctf_check_solved() তখন True ফেরত দেয়,
অর্থাৎ চ্যালেঞ্জ "SOLVED"। সিকিউর ভার্সনে html.escape() পেলোডের < ও
>-কে </>-তে রূপান্তর করে দেয়, ফলে
ctf_check_solved() কখনোই raw <script> খুঁজে পায় না — চ্যালেঞ্জ "NOT SOLVED"।
এটিই প্রমাণ করে html.escape()-এর মতো আউটপুট-এনকোডিং XSS-এর বিরুদ্ধে কার্যকর ডিফেন্স।
৪ · কেন এটি শুধুই একটি সিমুলেশন
বাস্তব CTF প্ল্যাটফর্মে একটি স্বয়ংক্রিয় হেডলেস ব্রাউজার (যেমন Puppeteer বা Selenium) সত্যিই আপনার
জমা দেওয়া পেলোড রেন্ডার করে এবং alert() বা document.cookie-এর মতো কোনো
সাইড-ইফেক্ট সত্যিই ঘটেছে কি না তা মনিটর করে ফ্ল্যাগ ইস্যু করে। এই পাঠে কোনো real ব্রাউজার নেই বলে আমরা
সেই পুরো প্রক্রিয়াকে একটি সরল স্ট্রিং-চেক দিয়ে সরলীকৃত করেছি — যুক্তিটা (unescaped payload = vulnerable)
হুবহু একই থাকে।
একটি XSS চ্যালেঞ্জ সমাধান করা মানেই "হ্যাকিং" নয় — এটি একটি নিয়ন্ত্রিত, অনুমোদিত পরিবেশে একটি নির্দিষ্ট দুর্বলতা প্যাটার্ন যাচাই করা। ঠিক একই পদ্ধতিগত চিন্তা (বেসলাইন → প্রোব → পেলোড → যাচাই) একজন পেশাদার পেনিট্রেশন টেস্টার তার লিখিত-অনুমোদিত এনগেজমেন্টে প্রয়োগ করেন (L01, L02)।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ বাস্তব CTF প্ল্যাটফর্মে একটি হেডলেস ব্রাউজার ব্যবহার করে চেক করা হয়, এখানে আমরা কেন শুধু স্ট্রিং ম্যাচিং ব্যবহার করলাম?
এই কোর্সের কোড সেলগুলো সম্পূর্ণ স্যান্ডবক্সড ও ইন-মেমরি (L01, CLAUDE.md সুরক্ষা নিয়ম) — কোনো real
ব্রাউজার এক্সিকিউট করা এখানে সম্ভব বা নিরাপদ নয়। তবে মূল যুক্তিটি অভিন্ন: যদি একটি
<script> ট্যাগ এস্কেপ ছাড়া আউটপুটে থেকে যায়, তাহলে একটি real ব্রাউজারে সেটি
এক্সিকিউট হতোই — স্ট্রিং-চেক সেই একই সিদ্ধান্তে পৌঁছানোর একটি নিরাপদ, সরলীকৃত উপায়।
প্র ০২ "বেসলাইন → প্রোব → পেলোড → যাচাই" পদ্ধতি কেন সরাসরি ক্লাসিক পেলোড দিয়ে শুরু করার চেয়ে ভালো?
বেসলাইন ও প্রোবিং ধাপ আপনাকে বলে দেয় ঠিক কী ধরনের এস্কেপিং (যদি থাকে) প্রয়োগ হচ্ছে — এটি না জেনে সরাসরি একটি জটিল পেলোড ব্যবহার করলে ব্যর্থতার কারণ বোঝা কঠিন হয় (এস্কেপিং আছে? পেলোড ভুল? অন্য কোনো ফিল্টার আছে?)। ধাপে-ধাপে পরীক্ষা প্রতিটি সম্ভাবনাকে আলাদাভাবে নিশ্চিত করে — এটি একটি পদ্ধতিগত, পুনরাবৃত্তিযোগ্য প্রক্রিয়া, শুধু অনুমান নয়।
প্র ০৩ এই একই টেকনিক অনুমোদিত CTF প্ল্যাটফর্মের বাইরে একটি real ওয়েবসাইটে প্রয়োগ করলে আইনি অবস্থা কী দাঁড়ায়?
L01-এ শেখা মূলনীতি অনুযায়ী — কৌশল একই থাকলেও, লিখিত অনুমতি ছাড়া কোনো real সিস্টেমে এই পেলোড টেস্ট করা অনুমোদিত অ্যাক্সেস আইন লঙ্ঘন করে, এমনকি যদি কোনো প্রকৃত ক্ষতি না হয়। CTF প্ল্যাটফর্ম নিজেই টেস্টিং-এর জন্য স্পষ্ট অনুমতি দেয় বলেই এটি বৈধ অনুশীলন — এই অনুমতিটাই একমাত্র পার্থক্য।
অনুশীলন
-
পরীক্ষা করুন: উপরের কোড সেলে
payload-কে একটি নিরীহ স্ট্রিং (যেমন "Hello!") দিয়ে বদলে দিন এবং দেখুনctf_check_solved()উভয় রেন্ডারারের জন্য কী ফলাফল দেয়।একটি নিরীহ পেলোডে কোনো
<script>ট্যাগই নেই, তাই উভয় রেন্ডারারের (ইনসিকিউর ও সিকিউর) আউটপুটেইctf_check_solved()"NOT SOLVED" ফেরত দেবে — এটি প্রমাণ করে চেকারটি শুধু নির্দিষ্ট পেলোড প্যাটার্নের জন্যই ট্রিগার হয়, যেকোনো ইনপুটের জন্য নয়। -
চিন্তা করুন: যদি
ctf_check_solved()শুধু"<script>"-এর বদলে"alert"শব্দটি খুঁজত, তাহলে কি এটি এখনও একটি নির্ভরযোগ্য চেকার হতো?না — "alert" শব্দটি এস্কেপ করা টেক্সটেও (যেমন একজন ব্যবহারকারী লিখেছে "please alert me") উপস্থিত থাকতে পারে, ফলে false positive হবে। এটিই দেখায় কেন বাস্তব CTF checker-রা আসল ব্রাউজার এক্সিকিউশন পর্যবেক্ষণ করে (side-effect সত্যিই ঘটল কি না), নিছক টেক্সট-ম্যাচিং দিয়ে নয় — আমাদের সরলীকরণটি শুধু শেখার উদ্দেশ্যে, প্রোডাকশন-গ্রেড checker ডিজাইনের জন্য নয়।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৬০টি পাঠ M12-এর পরের পাঠ — রেড টিম বনাম ব্লু টিম এক্সারসাইজ।
- Discrete Mathematics কোর্স সহায়ক কোর্স লজিক ও প্যাটার্ন-বিশ্লেষণের গাণিতিক ভিত্তি শিখতে দেখুন।
- System Design & Software Architecture কোর্স সঙ্গী কোর্স ইনপুট ভ্যালিডেশন ও আউটপুট এনকোডিং কীভাবে বড় সিস্টেমে ডিজাইন হয় তা শিখতে দেখুন।
- সব Courses দেখুন ABCL TECH C, C++, Python, Java, JavaScript, DSA, DBMS, Discrete Mathematics, System Design ও Cybersecurity — সব এক জায়গায়।