Hackquest2018。结果与写作。 第1-3天

一年一度的hackquest为期7天-要获得免费的Zerozeros门票,需要解决七个任务。 在本文中,我们建议您熟悉其中一些决定,并找出获奖者的姓名。 为了方便起见,我们将出版物分为两部分。



目录内容





第一天 加洛瓦


对于准备此作业的帮助,请感谢REhints
“挑战很容易,如下所述:下载二进制文件(通过:感染),对其进行反向工程,并恢复二进制文件将接受的两个秘密。 每个秘密都是一个ASCII字符串。 您需要先解决第一阶段,然后再攻击第二阶段。 祝你好运,愿加洛瓦与你同在!”

要获取标志,必须依次输入两个秘密值:

图片

通过消息的各行,我们进入函数:

对话功能
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; } 


达到“第2阶段已解锁!” ,则必须在函数sub_4014E0通过测试(字符串长度-16个字符)。 在“干得好!”之前 -在sub_42CEF0再次检查(第二行的长度小于40个字符)。

第一阶段


 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_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,也会重置它。
在python上,它看起来像这样:
 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() # 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) 


将找到的位转换为字符串,我们得到第一个键: ItWasJustAWarmUp

第二阶段


 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进行模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 

获得以下值:

来自:
  • x = 0x11CE9E8E6CF2B888
  • y = 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

第二天 Blackanwyte


对于准备作业的帮助,请感谢@leetmore的 Vlad Roskov。



单击链接时,我们看到以下内容:



我们被要求输入促销代码。 让我们看看页面打开时加载的文件。



浏览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)。


谷歌搜索,我们了解到我们面临着用Java编写的模拟器。
可执行文件的字节存储在变量code ,第32行将促销代码写入内存,第33行设置堆栈的地址。 从第41行可以看出该文件从地址“ 0x080485E0”开始。

保存可执行文件,并使用IDA查看其中的内容。


让我们转到blackbox_check。 在这里,我们看到了某种哈希函数。 在尝试寻找算法中的快速暴力或其他漏洞的机会失败了几次之后,我们注意到将破折号后的行的一部分复制到的缓冲区仅限于256个字符。

blackbox_check


我们使用checksec进行检查,看看堆栈是可执行的:
注意 -屏幕快照和vraytap作者的文本中,有关堆栈是否可执行的差异。 实际上,代码可以执行。


考虑到我们已经知道要在其中写入行的堆栈中的地址,由您决定将字节从“ e1ee757bc7fd00d5”行写入所需的地址。



我们通过控制台发送结果行并选择标志:

搜寻字串



搜索的行: Bl4CK_0r_wYT3_It5_z3r0Ni6hT



第三天 垫我


嘿,这个小组仍然使用旧式的邮件系统。 我们假设成员已经三十多岁了,密码就是这样。 尝试在那里找到缺陷。 他们的消息传递系统的电话是51.15.79.170,您知道吗? 我们可以截取他们的一部分身份验证请求。
您可以使用ytW81KkHaGOnaqiG7Gr4AA ==:XXnpfKJoUCufBm2ztTXGCN6wgqLeScU8 + XlL7Co5oHg =

1.发布“ ytW81KkHaGOnaqiG7Gr4AA ==:XXnpfKJoUCufBm2ztTXGCN6wgqLeScU8 + XlL7Co5oHg =”字符串后,我收到403错误。 如果更改一些字母-仍然收到403错误,它将更改字母计数-接收500错误。 经过一些研究,我意识到第一部分以base64解码的形式为16字节长,第二部分必须包含一些每个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 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/zh-CN439550/


All Articles