في هذه المقالة ، سننظر في حلول 3 مهام من الموقع
pwnable.kr .
المعلومات التنظيميةخاصةً لأولئك الذين يرغبون في تعلم شيء جديد وتطويره في أي من مجالات أمن المعلومات والحاسوب ، سأكتب وأتحدث عن الفئات التالية:
- PWN.
- التشفير (التشفير) ؛
- تقنيات الشبكات (الشبكة) ؛
- عكس (الهندسة العكسية) ؛
- إخفاء المعلومات (Stegano) ؛
- بحث واستغلال مواطن الضعف WEB.
بالإضافة إلى ذلك ، سوف أشارك تجربتي في الطب الشرعي للكمبيوتر ، وتحليل البرامج الضارة والبرامج الثابتة ، والهجمات على الشبكات اللاسلكية وشبكات المناطق المحلية ، وإجراء عمليات pentests واستغلال الكتابة.
حتى تتمكن من معرفة المقالات الجديدة والبرامج والمعلومات الأخرى ، أنشأت
قناة في Telegram ومجموعة لمناقشة أي مشاكل في مجال التصنيف الدولي للأمراض. أيضًا ، سأدرس شخصيًا طلباتك الشخصية وأسئلتك واقتراحاتك وتوصياتك
شخصيًا وسأجيب على الجميع .
يتم توفير جميع المعلومات للأغراض التعليمية فقط. لا يتحمل مؤلف هذا المستند أية مسؤولية عن أي ضرر يلحق بشخص ما نتيجة استخدام المعرفة والأساليب التي تم الحصول عليها نتيجة لدراسة هذا المستند.
مشكلة حل coin1
نضغط على الأيقونة بعملة coin1 ، ويتم تزويدنا بالعنوان والمنفذ للاتصال.

بعد الاتصال ، يُعرض علينا لعب اللعبة وتوفير قواعد اللعبة. كما أنها تمنحنا 60 ثانية لإكمالها ، لذلك يتعين علينا أتمتة كل شيء.

وفقًا لقواعد اللعبة ، فإنهم يعطوننا N عملات معدنية ، كل منها يزن 10 ، باستثناء واحدة - وزنها 9. يتم منحنا عدد الفرص (جولات) C للعبة واحدة. في كل جولة ، نرسل مؤشرات العملة ، ويتم إعطاء الوزن الإجمالي أيضًا. وبالتالي ، باستخدام
البحث الثنائي ، سوف نجد العملة المطلوبة.
دعنا نكتب الرمز. للبدء ، قم بإنشاء اتصال بالخادم وقبول وتحليل الأرقام N و C.
from pwn import * r = remote('pwnable.kr', 9007) r.recv() s = r.recv() print(s) n = int(s.split(' ')[0][2:]) c = int(s.split('=')[2].split('\n')[0]) print(n, c)

ممتاز. الآن سنقوم بكتابة جزء لاجتياز مستوى واحد. للقيام بذلك ، نحتاج إلى مجموعة من القيم من 1 إلى N + 1 ودورة من الخطوات C ، في كل تكرار سيتم إرسال نصف الصفيف منه. إذا كان الوزن الذي تم إرجاعه في الإجابة مقسومًا على 10 بدون الباقي ، فستكون عملتنا في جزء آخر من المجموعة. وبالتالي ، سوف نقسم النصف الآخر مرة أخرى ونفعل الشيء نفسه به ، إلخ. حتى يتم اكتشاف العملة.
mas = range(1,n+1) for i in range(c): s = "" if len(mas)==1: mas.append(mas[0]) for j in mas[:len(mas)/2]: s += (str(j)+" ") print(s) r.send(s+"\n") nr = r.recv() print(nr) if int(nr) % 10: mas = mas[:len(mas)/2] else: mas = mas[len(mas)/2:] r.send(str(mas[0])+"\n") print(r.recv())

أضف الآن هذا الحل إلى الحلقة لإكمال جميع المستويات.
from pwn import * r = remote('pwnable.kr', 9007) r.recv() for level in range(1, 101): s = r.recvline() n = int(s.split(' ')[0][2:]) c = int(s.split('=')[2].split('\n')[0]) mas = range(1,n+1) for i in range(c): s = "" if len(mas)==1: mas.append(mas[0]) for j in mas[:len(mas)/2]: s += (str(j)+" ") r.send(s+"\n") nr = r.recv() if int(nr) % 10: mas = mas[:len(mas)/2] else: mas = mas[len(mas)/2:] r.send(str(mas[0])+"\n") r.recvline() if level%5==0: print("Check "+str(level)+"/100") print(r.recv())

نحن نسلم العلم ونحصل على نقاط.
حل وظيفة العوامة
نضغط على الأيقونة الأولى بعملة coin1 ، ويتم تزويدنا بالعنوان والمنفذ للاتصال. يقولون أيضًا أنك بحاجة للفوز بمليون دولار.

بعد الاتصال ، يُعرض علينا لعب لعبة والاستفسار عن الاستعداد.

بعد إجابتنا ، انتقل إلى القائمة ، ابدأ اللعبة ، وتعلم القواعد ، أو أخرج من اللعبة.

بدء لعبة جديدة.

غالبًا ما توجد مثل هذه المهام في CTF ومن المفيد أن نعرف عنها. على الأرجح لا يوجد معالج للأرقام السالبة. وبالتالي ، إذا دخلت -999500 وخسرت ، فسيتم طرح رقم سالب من مصرفنا ، أي أنه يتم إضافة رقم موجب (500 - (-500) = 500 + 500 = 1000). نحن نقدم -1000000.


نحن نسلم العلم ونحصل على نقطة أخرى.
حل لوتو السعي
نضغط على الأيقونة الأولى مع لوتو التوقيع ، وقيل لنا إننا بحاجة إلى الاتصال عبر SSH بضيف كلمة المرور.

عند الاتصال ، نرى الشعار المقابل.

دعونا نعرف ما هي الملفات الموجودة على الخادم ، وكذلك ما هي الحقوق التي لدينا.

دعنا نرى نتائج الكود. #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> unsigned char submit[6]; void play(){ int i; printf("Submit your 6 lotto bytes : "); fflush(stdout); int r; r = read(0, submit, 6); printf("Lotto Start!\n"); //sleep(1); // generate lotto numbers int fd = open("/dev/urandom", O_RDONLY); if(fd==-1){ printf("error. tell admin\n"); exit(-1); } unsigned char lotto[6]; if(read(fd, lotto, 6) != 6){ printf("error2. tell admin\n"); exit(-1); } for(i=0; i<6; i++){ lotto[i] = (lotto[i] % 45) + 1; // 1 ~ 45 } close(fd); // calculate lotto score int match = 0, j = 0; for(i=0; i<6; i++){ for(j=0; j<6; j++){ if(lotto[i] == submit[j]){ match++; } } } // win! if(match == 6){ system("/bin/cat flag"); } else{ printf("bad luck...\n"); } } void help(){ printf("- nLotto Rule -\n"); printf("nlotto is consisted with 6 random natural numbers less than 46\n"); printf("your goal is to match lotto numbers as many as you can\n"); printf("if you win lottery for *1st place*, you will get reward\n"); printf("for more details, follow the link below\n"); printf("http://www.nlotto.co.kr/counsel.do?method=playerGuide#buying_guide01\n\n"); printf("mathematical chance to win this game is known to be 1/8145060.\n"); } int main(int argc, char* argv[]){ // menu unsigned int menu; while(1){ printf("- Select Menu -\n"); printf("1. Play Lotto\n"); printf("2. Help\n"); printf("3. Exit\n"); scanf("%d", &menu); switch(menu){ case 1: play(); break; case 2: help(); break; case 3: printf("bye\n"); return 0; default: printf("invalid menu\n"); break; } } return 0; }
لا يوجد شيء مثير للاهتمام في الوظيفة الرئيسية (). وظيفة play () مهمة ، بعد التحليل الذي سوف نفهم منطق البرنامج. أولاً ، ندخل 6 قيم ، ثم يقوم البرنامج المزيف العشوائي بإنشاء 6 قيم أخرى في النطاق (1-45) ، وبعد ذلك تتم مقارنة هذين التسلسلين. نحصل على العلم مع 6 مباريات. لكن الشيك يتم بشكل غير صحيح. وبالتالي ، في كل دورة ، تتم مقارنة كل حرف من التسلسل الذي تم إدخاله بكل حرف تم إنشاؤه.

وبالتالي ، سوف نقوم بإدخال 6 أحرف متطابقة في كل مرة حتى نحصل على العلم. دخلت !!!!!! ، وحصلت على العلم 7 مرات.

نسلم العلم ونحصل على نقطتين. نراكم في المقالات التالية!
نحن في قناة برقية:
قناة في برقية .