سبعة أيام من القرصنة السنوية - سبعة مهام تحتاج إلى حل من أجل الحصول على تذاكر دخول مجانية إلى Zeronights. في هذه المقالة ، نقترح أن تكون على دراية بقرارات البعض منهم ، وكذلك معرفة أسماء الفائزين. للراحة ، سنقوم بتقسيم المنشور إلى قسمين.

المحتويات

اليوم الأول. جالوا
للحصول على مساعدة في إعداد هذه المهمة ، أشكر
REINts .
"التحدي سهلاً كما يلي: قم بتنزيل الملف الثنائي (تمريرة: مصابة) ، وقم بالهندسة العكسية واستعادة سريتين يقبلهما الثنائي. كل سر هو سلسلة ASCII. ستحتاج إلى حل المرحلة الأولى أولاً قبل مهاجمة الثانية. حظاً موفقاً وقد يكون جالوا معك! "للحصول على العلامة ، يجب إدخال قيمتين سريتين بالتتابع:

من خلال سطور الرسائل ندخل في الوظيفة:
DialogFuncBOOL __stdcall DialogFunc(HWND hWnd, UINT a2, WPARAM a3, LPARAM a4) { HWND v5; // eax HWND v6; // eax HWND v7; // eax HWND v8; // eax HWND v9; // eax HWND v10; // eax CHAR v11; // [esp+0h] [ebp-5Ch] CHAR String[20]; // [esp+2Ch] [ebp-30h] struct tagRECT Rect; // [esp+40h] [ebp-1Ch] UINT v14; // [esp+50h] [ebp-Ch] HDC hdc; // [esp+54h] [ebp-8h] unsigned int i; // [esp+58h] [ebp-4h] v14 = a2; if ( a2 == 20 ) { hdc = (HDC)a3; GetClientRect(hWnd, &Rect); SetMapMode(hdc, 8); SetWindowExtEx(hdc, 100, 100, 0); SetViewportExtEx(hdc, Rect.right, Rect.bottom, 0); FillRect(hdc, &Rect, hbr); return 1; } if ( v14 == 272 ) return 1; if ( v14 != 273 || HIWORD(a3) ) return 0; if ( (unsigned __int16)a3 == 1 ) { EndDialog(hWnd, (unsigned __int16)a3); return 1; } if ( (unsigned __int16)a3 != 1002 ) { if ( (unsigned __int16)a3 == 1004 ) { sub_42E7C0(&v11, 0, 42); if ( GetDlgItemTextA(hWnd, 1005, &v11, 42) <= 0x27 && (unsigned __int8)sub_42CEF0(&v11) ) { v9 = GetDlgItem(hWnd, 1004); EnableWindow(v9, 0); v10 = GetDlgItem(hWnd, 1005); EnableWindow(v10, 0); MessageBoxW(hWnd, L"Good job!", L"Success", 0); return 1; } MessageBoxW(hWnd, L"Keep trying!", L"Rejected", 0); } return 1; } if ( GetDlgItemTextA(hWnd, 1001, String, 18) != 16 || !(unsigned __int8)sub_4014E0(String) ) { MessageBoxW(hWnd, L"Keep trying!", L"Rejected", 0); return 1; } v5 = GetDlgItem(hWnd, 1002); EnableWindow(v5, 0); v6 = GetDlgItem(hWnd, 1001); EnableWindow(v6, 0); v7 = GetDlgItem(hWnd, 1005); EnableWindow(v7, 1); v8 = GetDlgItem(hWnd, 1004); EnableWindow(v8, 1); for ( i = 0; i < 0x28; ++i ) *((_BYTE *)&dword_442780 + i) ^= String[(signed int)i % 16]; MessageBoxW(hWnd, L"Stage #2 unlocked!", L"Accepted", 0); return 1; }
للوصول إلى
"المرحلة رقم 2 مقفلة!" ، يجب اجتياز الاختبار في الدالة
sub_4014E0
(طول السلسلة - 16 حرفًا). وقبل
"العمل الجيد!" - تحقق مرة أخرى في
sub_42CEF0
(طول السطر الثاني أقل من 40 حرفًا).
المرحلة رقم 1
char __cdecl sub_4014E0(char *a1) { int v1; // ecx unsigned __int128 var_1018[256]; // [esp+0h] [ebp-1018h] unsigned __int128 var_18; // [esp+1000h] [ebp-18h] int v5; // [esp+1010h] [ebp-8h] char v6; // [esp+1017h] [ebp-1h] sub_438740(0x1018u, v1); sub_43A460(var_1018, xmmword_4427A8, 0x1000u); sub_4010E0(a1, var_1018); sub_401250(var_1018, &var_18); v5 = sub_438845(var_18, &xmmword_442770, 0x10u); if ( !v5 ) v6 = 1; return v6; }
ضمن مصحح الأخطاء ، يمكنك التحقق من أن
sub_43A460
ينسخ البيانات من:

و
sub_438845
يقارن القيمة بـ:
.data:00442770 xmmword_442770 9698CA91EE29902C60D377C981589205h
يتم تقديم البيانات في شكل أرقام 128 بت ، لأنه تبين أنها أكثر ملاءمة في سياق مزيد من التحليل.
وظيفة Sub_4010E0 void __cdecl sub_4010E0(unsigned __int128 *a1, unsigned __int128 *a2) { signed int i; // [esp+4h] [ebp-8h] signed int j; // [esp+8h] [ebp-4h] for ( i = 0; i < 128; ++i ) { for ( j = 0; j < 128; ++j ) { if ( (*((_DWORD *)a1 + (j >> 5)) >> (j & 0x1F)) & 1 ) { if ( !((*((_DWORD *)a1 + ((j + 1) % 128 >> 5)) >> ((j + 1) % 128 & 0x1F)) & 1) ) *((_DWORD *)&a2[2 * i] + ((j + 128) >> 5)) &= ~(1 << ((j + -128) & 0x1F)); } else { *((_DWORD *)&a2[2 * i] + (j >> 5)) &= ~(1 << (j & 0x1F)); *((_DWORD *)&a2[2 * i] + ((j + 128) >> 5)) &= ~(1 << ((j + -128) & 0x1F)); } } } }
نفس الوظيفة في شكل مبسط إلى حد ما void __cdecl sub_4010E0(unsigned __int128 *a1, unsigned __int128 *a2) { signed int i; // [esp+4h] [ebp-8h] signed int j; // [esp+8h] [ebp-4h] signed int j_1; for ( i = 0; i < 128; ++i ) { for ( j = 0; j < 128; ++j ) { j_1 = (j + 1) % 128; if ( (*((_DWORD *)a1 + j / 32) >> (j % 32)) & 1 ) { if ( !((*((_DWORD *)a1 + j_1 / 32) >> (j_1 % 32)) & 1) ) *((_DWORD *)&a2[2 * i] + 4 + j / 32) &= ~(1 << (j % 32)); } else { *((_DWORD *)&a2[2 * i] + j / 32) &= ~(1 << (j % 32)); *((_DWORD *)&a2[2 * i] + 4 + j / 32) &= ~(1 << (j % 32)); } } } }
لكل زوج من الأرقام 128 بت التي تتناولها الوسيطة الثانية ، تعمل الدورة من خلال 128 بت من سلسلة الإدخال (الوسيطة الأولى) ، وإذا كانت البتة هي 0 ، فقم بإعادة تعيين البتات المقابلة (تقوم في الأساس بعملية AND). بالنسبة للرقم الثاني من زوج من البتات ، تتم إعادة تعيينه أيضًا إذا كانت البتة التالية في التسلسل هي 0.
في الثعبان ، يبدو مثل هذا:
def sub_4010E0(a1, a2): for i in range(128): a2[2 * i] &= a1 a2[2 * i + 1] &= a1 & (a1 >> 1)
وظيفة sub_401250 void __cdecl sub_401250(unsigned __int128 *a1, unsigned __int128 *a2) { signed int k; // [esp+4h] [ebp-Ch] signed int j; // [esp+8h] [ebp-8h] signed int i; // [esp+Ch] [ebp-4h] *(_QWORD *)a2 = 0i64; *((_QWORD *)a2 + 1) = 0i64; for ( i = 0; i < 128; ++i ) { for ( j = 0; j < 4; ++j ) *((_DWORD *)&a1[2 * i] + j) ^= *((_DWORD *)&a1[2 * i + 1] + j); for ( k = 0; k < 2; ++k ) *((_DWORD *)&a1[2 * i] + k) ^= *((_DWORD *)&a1[2 * i] + k + 2); LODWORD(a1[2 * i]) ^= DWORD1(a1[2 * i]); LODWORD(a1[2 * i]) ^= LODWORD(a1[2 * i]) >> 16; LODWORD(a1[2 * i]) ^= LODWORD(a1[2 * i]) >> 8; LODWORD(a1[2 * i]) ^= LODWORD(a1[2 * i]) >> 4; LODWORD(a1[2 * i]) ^= LODWORD(a1[2 * i]) >> 2; LODWORD(a1[2 * i]) ^= LODWORD(a1[2 * i]) >> 1; if ( a1[2 * i] & 1 ) *((_DWORD *)a2 + (i >> 5)) |= 1 << (i & 0x1F); } }
تطوي الوظيفة كل زوج ينتج عنه بت واحد ، وتؤدي XOR بين جميع البتات. تلقى 128 بت وتشكيل عدد مقارنة مع ما ورد أعلاه.
لإيجاد حل ، نستخدم حلالا z3.
مع عمليات الاستبدال البسيطة في جهاز كمبيوتر محمول ، نقوم بتحويل صفيف xmmword_4427A8 إلى نظام (الأصفار والأخرى الموجودة على اليسار هي الرقم xmmword_442770) from z3 import * init('../') def xor_bits(x): x = Extract(63, 0, x) ^ Extract(127, 64 ,x) x = Extract(31, 0, x) ^ Extract(63, 32, x) x = Extract(15, 0, x) ^ Extract(31, 16, x) x = Extract(7, 0, x) ^ Extract(15, 8, x) x = Extract(3, 0, x) ^ Extract(7, 4, x) x = Extract(1, 0, x) ^ Extract(3, 2, x) return Extract(0, 0, x) ^ Extract(1, 1, x) x = BitVec('x', 128) s = Solver()
تحويل البتات الموجودة إلى سلسلة ، نحصل على المفتاح الأول:
ItWasJustAWarmUp .
المرحلة رقم 2
bool __cdecl sub_42CEF0(char *a1) { bool result; // al __int64 v2; // [esp+0h] [ebp-3Ch] __int64 v3; // [esp+8h] [ebp-34h] __int64 v4; // [esp+10h] [ebp-2Ch] __int64 v5; // [esp+18h] [ebp-24h] __int64 v6; // [esp+20h] [ebp-1Ch] int v7; // [esp+28h] [ebp-14h] int v8; // [esp+2Ch] [ebp-10h] int v9; // [esp+30h] [ebp-Ch] int v10; // [esp+34h] [ebp-8h] int v11; // [esp+38h] [ebp-4h] v6 = *(_QWORD *)a1; v5 = *((_QWORD *)a1 + 1); v4 = *((_QWORD *)a1 + 2); v3 = *((_QWORD *)a1 + 3); v2 = *((_QWORD *)a1 + 4); (**off_444360)(off_444360, &v6, 0, off_44435C); (**off_444360)(off_444360, &v5, 0, off_44435C); (**off_444360)(off_444360, &v4, 0, off_44435C); (**off_444360)(off_444360, &v3, 0, off_44435C); (**off_444360)(off_444360, &v2, 0, off_44435C); v11 = 0; result = 0; if ( v6 == qword_442780 ) { v10 = 8; if ( v5 == __PAIR__(*((_DWORD *)&qword_442780 + 3), *((_DWORD *)&qword_442780 + 2)) ) { v9 = 16; if ( v4 == __PAIR__(*((_DWORD *)&qword_442780 + 5), *((_DWORD *)&qword_442780 + 4)) ) { v8 = 24; if ( v3 == __PAIR__(*((_DWORD *)&qword_442780 + 7), *((_DWORD *)&qword_442780 + 6)) ) { v7 = 32; if ( v2 == __PAIR__(*((_DWORD *)&qword_442780 + 9), *((_DWORD *)&qword_442780 + 8)) ) result = 1; } } } } return result; }
يتم تمثيل السلسلة التي تم إدخالها على أنها خمسة أرقام 64 بت ، تتم مقارنة نتيجة التحويل بالصفيف.

المشي تحت مصحح الأخطاء ، نرى تسلسل المكالمات الدالة التالية:

من الواضح حتى الآن أن الوسيطة الثالثة يتم تمريرها عبر سلسلة المكالمات ، وأحيانًا تكون الوحدة النمطية 2 قابلة للطي مع وحدة ، وأحيانًا مع الجزء التالي من سلسلة الإدخال (على الرغم من تخطي بعض البتات ، على سبيل المثال ، الأولى).
لنرى أين يحدث تحويل الرقم المحول ، مع وضع نقطة توقف على السجل في بايتات الذاكرة المقابلة:

أي يتم استبدال جزء الرقم بقيمة الوسيطة الثالثة ، ويتم تمرير قيمتها السابقة (المقلوبة في بعض الأحيان). يمكن افتراض حدوث التحويل التالي:
a3 = xor_all_bits(input & x) ^ y; output = ((input << 1) ^ z) | a3;
- يحدد x البتات التي لم يتم تخطيها في الخطوة الأولى ؛
- y يعتمد على عدد المرات التي تمت فيها إضافة وحدة (المعامل 2) ؛
- z تقابل البتات المقلوبة في الخطوة الثانية.
لتحديد الثوابت غير المعروفة ، نحصل على القيم المحولة للصفر والأرقام مع مجموعة بت واحدة. للقيام بذلك ، حدد عداد
extern i; i = 0;
وفي الدالة
sub_428FD0
قبل الجولة التالية ، وضعنا نقطة توقف بشرط يطبع قيمة الرقم بعد استدعاء الوظيفة ، ونضع قيمتها التالية وكرر استدعاء الوظيفة.
print(Qword(Qword(ebp+8))), i=i+1, (i<64)?patch_qword(Qword(ebp+8), __int64(1) << i)^(eip=0x428FE0):0,0
تم الحصول على القيم التالية:

من:
- س = 0x11CE9E8E6CF2B888
- ص = 1
- z = 0x8E2B550A6AEDD63A
في Python ، تبدو وظيفة التحويل كما يلي:
def xor_bits(x): a = 0 while x != 0: a ^= x & 1 x >>= 1 return a def round(x): x = ((x << 1) & 0xFFFFFFFFFFFFFFFF) | xor_bits(x & 0x8e2b550a6aedd63a) ^ 1 return x ^ 0x11CE9E8E6CF2B888 def encrypt(x): for _ in range(64): x = round(x) return x
والعكس له:
def rev_round(x): x ^= 0x11CE9E8E6CF2B888 a = x & 1 x >>= 1 if xor_bits(x & 0x8e2b550a6aedd63a) ^ 1 != a: x |= 1 << 63 return x def decrypt(x): for _ in range(64): x = rev_round(x) return x
بتطبيق التحويل على أرقام من مجموعة
qword_442780
، نحصل على السلسلة المطلوبة:
YourReversingSkillsAreImpressive_zN2018 .

اليوم الثاني بلاكانويت
للمساعدة في إعداد المهمة ، أشكر فلاد روسكوف من
@ letmore .

عند
النقر على
الرابط ، نرى ما يلي:

يطلب منا إدخال رمز ترويجي. لنرى أي الملفات يتم تحميلها عند فتح الصفحة.

بالنظر إلى whitebox.js ، نجد وظيفة تتحقق من الشفرة الترويجية: في المتغير
c
، يتم قراءة النص الذي تم إدخاله ؛ إنه يتحقق مما إذا كان يطابق التعبير العادي "/ \ d + - \ w + /" ، لذلك يجب أن يكون الرمز الترويجي من النموذج "1234-ABCD". بعد ذلك ، يتم تحويل الرقم إلى ثنائي ، الأصفار تتوافق مع "N" ، والوحدات - "Z". بعد إعادة ترتيب الأرقام من الصفيف
f
، في دورة مكونة من 4 أحرف من السلسلة الناتجة ، يتم أخذ التجزئة md5 ، ويتم التحقق من الأحرف الأربعة الأولى مع الأحرف المقابلة من السلسلة "7177a294cfa7b53371776be5cfa74ddf".
للحصول على الرقم الصحيح ، اكتب نصًا صغيرًا. نتيجة لذلك ، حصلنا على الرقم المطلوب ، الجزء الأول من الشفرة الترويجية: 234082018.

لقد اجتزنا الجزء الأول من الاختبار. دعنا ننتقل إلى الثانية:

يمكن ملاحظة أن القيمة التي يتم إرجاعها من وظيفة
blackbox_check
يتم فحصها ، وإذا لم يحدث أي خطأ ، وأنها تساوي "elee757bc7fd00d5" ، فسيتم إرسالها إلى الخادم. ومع ذلك ، في ملف whitebox.js لا يوجد ذكر ل
blackbox_check
، لذلك حان الوقت لفتح blackbox.js.
بعد أن تمكن محرر النصوص من فتح ملف طويل ، نرى وظيفة blackbox_check التي نحتاجها فيها ، وفيها سطر مثير للاهتمام (22). غوغلينغ ، نعلم أننا نواجه محاكي كتب في جافاسكريبت.
يتم تخزين بايت الملف القابل للتنفيذ في
code
المتغيرة ، والسطر 32 يسجل الرمز الترويجي في الذاكرة ، بينما يعين السطر 33 عنوان الحزمة. من السطر 41 ، يمكن ملاحظة أن الملف يبدأ ، بدءًا من العنوان "0x080485E0".
احفظ الملف القابل للتنفيذ وشاهد ما فيه باستخدام المؤسسة الدولية للتنمية. دعنا ننتقل إلى blackbox_check. هنا نرى نوعا من وظيفة التجزئة. بعد عدة محاولات فاشلة لإيجاد فرص للضعف الغاشم أو نقاط الضعف الأخرى في الخوارزمية ، نلاحظ أن المخزن المؤقت الذي يقتصر فيه جزء السطر بعد نسخ الشرطة على 256 حرفًا فقط.
نتحقق من checkec ونرى أن المكدس قابل للتنفيذ:
ملاحظة - في لقطة وفي نص مؤلف vraytap هناك اختلافات حول ما إذا كان المكدس قابل للتنفيذ. في الواقع ، يمكن تنفيذ التعليمات البرمجية.
نظرًا لأننا نعرف بالفعل العنوان في الحزمة حيث سيتم كتابة السطر الخاص بنا ، فإن الأمر متروك لك لتدوين البايتات من السطر "e1ee757bc7fd00d5" إلى العنوان المطلوب.

نرسل السطر الناتج من خلال وحدة التحكم والتقاط العلم:
خط
البحث :
Bl4CK_0r_wYT3_It5_z3r0Ni6hT
اليوم الثالث ضعني
مهلا ، لا تزال هذه المجموعة تستخدم نظام المراسلة القديم. نحن نفترض أن الأعضاء في الثلاثينيات من العمر وهذا هو تشفيرهم. حاول العثور على عيوب هناك. نظام الرسائل الخاص بهم هو في 51.15.79.170 وأنت تعرف ماذا؟ يمكننا اعتراض جزء من طلب المصادقة الخاص بهم.
يمكنك الاستفادة من ytW81KkHaGOnaqiG7Gr4AA ==: XXnpfKJoUCufBm2ztTXGCN6wgqLeScU8 + XlL7Co5oHg =1. لقد تلقيت خطأ 403 بعد المشاركة "ytW81KkHaGOnaqiG7Gr4AA ==: XXnpfKJoUCufBm2ztTXGCN6wgqLeScU8 + XlL7Co5oHg =" السلسلة. في حالة تغيير بعض الأحرف - لا يزال يتلقى خطأ 403 ، فإنه يغير عدد الأحرف - يتلقى 500 خطأ. بعد إجراء بعض التحقيقات ، أدركت أن الجزء الأول يجب أن يكون طوله 16 بايتًا في شكل base64-decoded ، ويجب أن يحتوي الجزء الثاني على بعض الكتل التي يبلغ طولها 16 بايتًا لكل منها. Seems first part is IV and second part – encoded data in CBC mode, and according to task name „pad” it is padding oracle attack.
2. Lets change last byte in base64 decoded form of second part (01.php script, total 256 possibilities). For one case instead of “403” error I have received message „Sir, your message is incorrect or it is not 48 bytes long”
01.php script <?php $s = "7177a294cfa7b53371776be5cfa74ddf"; $r = ""; for($i=0;$i<32;$i+=4) { for($j=0;$j<16;$j++) { $a = sprintf("%04b", $j); $a = str_replace("0", "Z", $a); $a = str_replace("1", "N", $a); if (substr(md5($a), 0, 4) == substr($s, $i, 4)) break; } if ($j == 16) die("Error 1: {$i}"); $r .= $a; echo md5($r).": ".$r."\r\n"; } $p = array(22,30,25,23,2,20,0,11,24,6,31,3,16,12,9,15,27,28,18,1,21,4,8,13,17,7,19,29,5,26,14,10); $s = str_repeat("_", 32); for($i=0;$i<32;$i++) $s[$p[$i]] = $r[$i]; echo $s."\r\n"; $a = 0; for($i=0;$i<32;$i++) { if ($s[$i] == 'Z') $a += (1<<$i); } echo $a."\r\n";
3. Lets decrypt message from task using padding oracle attack (scripts 02.php and 02b.php) – I have received string “Never gonna give you up\nNever go”.
02.php script<?php
$a = „ytW81KkHaGOnaqiG7Gr4AA==:XXnpfKJoUCufBm2ztTXGCN6wgqLeScU8+XlL7Co5oHg=“;
$a = explode(»:", $a);
$a[0] = base64_decode($a[0]);
$a[1] = base64_decode($a[1]);
file_put_contents(«01.bin», $a[0].$a[1]);
$s = $a[1];
$known = "";
for($i=1;$i<=16;$i++)
{
for($j=0;$j<256;$j++)
{
$iv = str_repeat(«A», 16-$i).((chr($j).$known) ^ str_repeat(chr($i), $i));
if (($r = send($iv, substr($s, 0, 16))) !== false)
{
echo $r."\r\n";
$known = chr($j).$known;
echo bin2hex($known)." ".($known ^ substr($a[0], -$i))."\r\n";
break;
}
}
if ($j == 256) die(«Error 1: {$i}»);
}
function send($a, $b)
{
$data = base64_encode($a).":".base64_encode($b);
$s = «POST / HTTP/1.0\r\n»;
$s.= «Host: 51.15.79.170\r\n»;
$s.= «Content-Length: ».strlen($data)."\r\n";
$s.= «User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0\r\n»;
$s.= "\r\n";
$s.= $data;
$r = "";
do {$socket =
fsockopen («51.15.79.170», 80);} while(!$socket);
fwrite($socket, $s);
while(!@feof($socket)) $r .= fread($socket, 4096);
fclose($socket);
if (strpos($r, «500 INTERNAL SERVER ERROR»)) die(«Error 2: {$data}»);
return (strpos($r, «403 FORBIDDEN») !== false)?false:$r;
}
Never gonna give you upHTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:49:08 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
0f0cc904c9a68b038e65 gonna give
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:49:25 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
270f0cc904c9a68b038e65 gonna give
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:50:10 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
db270f0cc904c9a68b038e65 r gonna give
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:51:11 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
b1db270f0cc904c9a68b038e65 er gonna give
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:52:15 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
cab1db270f0cc904c9a68b038e65 ver gonna give
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:53:19 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
b0cab1db270f0cc904c9a68b038e65 ever gonna give
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:54:15 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
84b0cab1db270f0cc904c9a68b038e65 Never gonna give
02b.php script <?php $a = "ytW81KkHaGOnaqiG7Gr4AA==:XXnpfKJoUCufBm2ztTXGCN6wgqLeScU8+XlL7Co5oHg="; $a = explode(":", $a); $a[0] = base64_decode($a[0]); $a[1] = base64_decode($a[1]); file_put_contents("01.bin", $a[0].$a[1]); $s = substr($a[1], 16); $iv2 = substr($a[1], 0, 16); $known = ""; for($i=1;$i<=16;$i++) { for($j=0;$j<256;$j++) { $iv = str_repeat("A", 16-$i).((chr($j).$known) ^ str_repeat(chr($i), $i)); if (($r = send($iv, substr($s, 0, 16))) !== false) { echo $r."\r\n"; $known = chr($j).$known; echo bin2hex($known)." ".($known ^ substr($iv2, -$i))."\r\n"; break; } } if ($j == 256) die("Error 1: {$i}"); } function send($a, $b) { $data = base64_encode($a).":".base64_encode($b); $s = "POST / HTTP/1.0\r\n"; $s.= "Host: 51.15.79.170\r\n"; $s.= "Content-Length: ".strlen($data)."\r\n"; $s.= "User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0\r\n"; $s.= "\r\n"; $s.= $data; $r = ""; do {$socket = @fsockopen("51.15.79.170", 80);} while(!$socket); fwrite($socket, $s); while(!@feof($socket)) $r .= fread($socket, 4096); fclose($socket); if (strpos($r, "500 INTERNAL SERVER ERROR")) die("Error 2: {$data}"); return (strpos($r, "403 FORBIDDEN") !== false)?false:$r; }
Never goHTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:50:12 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
67 o
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:51:11 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
a167 go
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:51:14 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
15a167 go
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:52:30 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
c715a167 r go
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:53:57 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
d6c715a167 er go
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:54:15 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
1bd6c715a167 ver go
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:54:28 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
631bd6c715a167 ever go
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:55:21 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
d1631bd6c715a167 Never go
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:55:43 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
21d1631bd6c715a167
Never go
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:55:47 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
2021d1631bd6c715a167 p
Never go
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:55:51 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
1d2021d1631bd6c715a167 up
Never go
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:56:07 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
821d2021d1631bd6c715a167 up
Never go
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:56:08 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
09821d2021d1631bd6c715a167 u up
Never go
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:56:52 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
8609821d2021d1631bd6c715a167 ou up
Never go
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:56:52 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
008609821d2021d1631bd6c715a167 you up
Never go
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:57:10 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
7d008609821d2021d1631bd6c715a167 you up
Never go
4. Ok, seems the message was truncated (should be 48 bytes long). Using google I have found some song with full phase "
Never gonna give you up\nNever gonna let you down ”. Lets encrypt it using padding oracle attack from last block till first block and iv (scripts 05.php and 04_brute.php).
04_brute.php script <?php $a = "ytW81KkHaGOnaqiG7Gr4AA==:XXnpfKJoUCufBm2ztTXGCN6wgqLeScU8+XlL7Co5oHg="; $a = explode(":", $a); $a[0] = base64_decode($a[0]); $a[1] = base64_decode($a[1]); file_put_contents("01.bin", $a[0].$a[1]); $s = hex2bin("ff4fba7f36536f04bd0a3f77b8b06dde"); $known = ""; for($i=1;$i<=16;$i++) { for($j=0;$j<256;$j++) { $iv = str_repeat("A", 16-$i).((chr($j).$known) ^ str_repeat(chr($i), $i)); if (($r = send($iv, substr($s, 0, 16))) !== false) { echo $r."\r\n"; $known = chr($j).$known; echo bin2hex($known)."\r\n"; break; } } if ($j == 256) die("Error 1: {$i}"); } function send($a, $b) { $data = base64_encode($a).":".base64_encode($b); $s = "POST / HTTP/1.0\r\n"; $s.= "Host: 51.15.79.170\r\n"; $s.= "Content-Length: ".strlen($data)."\r\n"; $s.= "User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0\r\n"; $s.= "\r\n"; $s.= $data; $r = ""; do {$socket = @fsockopen("51.15.79.170", 80);} while(!$socket); fwrite($socket, $s); while(!@feof($socket)) $r .= fread($socket, 4096); fclose($socket); if (strpos($r, "500 INTERNAL SERVER ERROR")) die("Error 2: {$data}"); return (strpos($r, "403 FORBIDDEN") !== false)?false:$r; }
05.php <?php $a = "ytW81KkHaGOnaqiG7Gr4AA==:XXnpfKJoUCufBm2ztTXGCN6wgqLeScU8+XlL7Co5oHg="; $a = explode(":", $a); $a[0] = base64_decode($a[0]); $a[1] = base64_decode($a[1]); $Q = "Never gonna give you up\nNever gonna let you down".str_repeat("\x10", 0x10); echo strlen($Q)."\r\n"; $e1 = substr($a[1], 0, 16); $d1 = $a[0] ^ "Never gonna give"; $e2 = $d1 ^ substr($Q, 48, 16); echo bin2hex($e2)."\r\n"; $d2 = hex2bin("9e3d4885d3be30498069cfc4992e73df"); $e3 = $d2 ^ substr($Q, 32, 16); echo bin2hex($e3)."\r\n"; $d3 = hex2bin("df36d50a16261f0ef36f4912ca900ab1"); $e4 = $d3 ^ substr($Q, 16, 16); echo bin2hex($e4)."\r\n"; $d4 = hex2bin("20c3540ec72fa0b486b5f0c868218360"); $e5 = $d4 ^ substr($Q, 0, 16); echo bin2hex($e5)."\r\n"; $a[0] = $e5; $a[1] = $e4.$e3.$e2.$e1; $data = base64_encode($a[0]).":".base64_encode($a[1]); $s = "POST / HTTP/1.0\r\n"; $s.= "Host: 51.15.79.170\r\n"; $s.= "Content-Length: ".strlen($data)."\r\n"; $s.= "User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0\r\n";
20c3540ec72fa0b486b5f0c868218360HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 23:51:49 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
60
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 23:52:05 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
8360
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 23:52:15 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
218360
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 23:52:52 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
68218360
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 23:53:56 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
c868218360
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 23:55:08 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
f0c868218360
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 23:56:09 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
b5f0c868218360
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 23:57:05 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
86b5f0c868218360
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 23:58:03 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
b486b5f0c868218360
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 23:58:59 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
a0b486b5f0c868218360
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 23:59:05 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
2fa0b486b5f0c868218360
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Wed, 24 Oct 2018 00:00:08 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
c72fa0b486b5f0c868218360
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Wed, 24 Oct 2018 00:00:10 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
0ec72fa0b486b5f0c868218360
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Wed, 24 Oct 2018 00:00:21 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
540ec72fa0b486b5f0c868218360
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Wed, 24 Oct 2018 00:01:21 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
c3540ec72fa0b486b5f0c868218360
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Wed, 24 Oct 2018 00:01:34 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
20c3540ec72fa0b486b5f0c868218360
64
94a0daa1cb371f1cd914d9b69b139e75
f05329a5bfdb4469f906bae4fd4104b1
ff4fba7f36536f04bd0a3f77b8b06dde
6ea6226bb50fc7dbe8db91e80f48f505
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Wed, 24 Oct 2018 00:01:51 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 73
Connection: close
Okey, I see you're from 80's, get in
< Wh4t_1f_R1ck_A3tl3y_Sm0ke_Cannab1s >