# DawgCTF 2025 - REV ## Suspicious script Thử thách này ta chỉ cần decode base64 2 lần ```python= s = b'''JAB7ACEAfQA9AFsAQwBIAGEAcgBdADEAMAA1ADsAJABhAD0AWwBTAHkAUwBUAEUAbQAuAHQARQBYAHQALgBFAG4AQwBvAEQAaQBuAGcAXQA6ADoAVQBOAGkAYwBPAGQARQAuAGcARQB0AFMAdABSAGkAbgBnACgAWwBjAG8ATgBWAGUAcgBUAF0AOgA6AEYAcgBPAG0AYgBhAHMAZQA2ADQAcwB0AFIASQBuAGcAKAAnAGYAUQBCADAAQQBHAGsAQQBlAEEAQgBsAEEASABzAEEAYQBBAEIAagBBAEgAUQBBAFkAUQBCAGoAQQBIADAAQQBPAHcAQQBwAEEARQBZAEEASgBBAEEAZwBBAEMAdwBBAGEAUQBCAHkAQQBIAFUAQQBKAEEAQQBvAEEARwBVAEEAYgBBAEIAcABBAEUAWQBBAFoAQQBCAGgAQQBHADgAQQBiAEEAQgB3AEEARgBVAEEATABnAEIAcwBBAEcATQBBAGQAdwBBAGsAQQBEAHMAQQBjAEEAQgAwAEEARwBZAEEASgBBAEEAZwBBAEgAUQBBAGMAdwBCAHAAQQBFAHcAQQBkAEEAQgB1AEEARwBVAEEAYgBRAEIAMQBBAEcAYwBBAGMAZwBCAEIAQQBDADAAQQBJAEEAQgBwAEEASABJAEEAVgBRAEEAdQBBAEcAMABBAFoAUQBCADAAQQBIAE0AQQBlAFEAQgBUAEEAQwBBAEEAWgBRAEIAdABBAEcARQBBAFQAZwBCAGwAQQBIAEEAQQBlAFEAQgBVAEEAQwAwAEEASQBBAEIAMABBAEcATQBBAFoAUQBCAHEAQQBHAEkAQQBUAHcAQQB0AEEASABjAEEAWgBRAEIATwBBAEQAMABBAGEAUQBCAHkAQQBIAFUAQQBKAEEAQQA3AEEASABRAEEAYgBnAEIAbABBAEcAawBBAGIAQQBCAEQAQQBHAEkAQQBaAFEAQgBYAEEAQwA0AEEAZABBAEIAbABBAEUANABBAEwAZwBCAHQAQQBHAFUAQQBkAEEAQgB6AEEASABrAEEAVQB3AEEAZwBBAEcAVQBBAA0ACgBiAFEAQgBoAEEARQA0AEEAWgBRAEIAdwBBAEgAawBBAFYAQQBBAHQAQQBDAEEAQQBkAEEAQgBqAEEARwBVAEEAYQBnAEIAaQBBAEUAOABBAEwAUQBCADMAQQBHAFUAQQBUAGcAQQA5AEEARwB3AEEAWQB3AEIAMwBBAEMAUQBBAE8AdwBBAGkAQQBIAEEAQQBhAFEAQgA2AEEAQwA0AEEAYwB3AEIAegBBAEcARQBBAGMAQQBBAHYAQQBHADQAQQBhAFEAQQB2AEEASAAwAEEASQBRAEEAMQBBAEgAUQBBAGMAQQBBAHgAQQBHAE0AQQBOAFEAQgBmAEEARwBRAEEAWgBRAEIAdwBBAEgAQQBBAE4AQQBCAHkAQQBGAGMAQQBlAHcAQgBHAEEARgBRAEEAUQB3AEIAbgBBAEgAYwBBAFkAUQBCAEUAQQBFAEEAQQBlAFEAQgB5AEEARwBFAEEAWQB3AEIAegBBAEQAbwBBAGMAZwBCAGwAQQBIAE0AQQBkAFEAQQB2AEEAQwA4AEEATwBnAEIAdwBBAEgAUQBBAFoAZwBBAGkAQQBEADAAQQBjAEEAQgAwAEEARwBZAEEASgBBAEEANwBBAEQAWQBBAE0AUQBBAHgAQQBGADAAQQBjAGcAQgBoAEEARQBnAEEAUQB3AEIAYgBBAEMAcwBBAE0AQQBBAHkAQQBEAEUAQQBYAFEAQgB5AEEARwBFAEEAUwBBAEIARABBAEYAcwBBAEsAdwBBADIAQQBEAEUAQQBNAFEAQgBkAEEASABJAEEAWQBRAEIASQBBAEUATQBBAFcAdwBBAHIAQQBEAFkAQQANAAoATgBBAEIAZABBAEgASQBBAFkAUQBCAEkAQQBFAE0AQQBXAHcAQQByAEEARABVAEEATQBnAEEAeABBAEYAMABBAGMAZwBCAGgAQQBFAGcAQQBRAHcAQgBiAEEAQwBzAEEATgBnAEEAeABBAEQARQBBAFgAUQBCAHkAQQBHAEUAQQBTAEEAQgBEAEEARgBzAEEASwB3AEEAeQBBAEQARQBBAE0AUQBCAGQAQQBIAEkAQQBZAFEAQgBJAEEARQBNAEEAVwB3AEEAcgBBAEQAawBBAE4AQQBCAGQAQQBIAEkAQQBZAFEAQgBJAEEARQBNAEEAVwB3AEEAcgBBAEQAUQBBAE0AUQBBAHgAQQBGADAAQQBjAGcAQgBoAEEARQBnAEEAUQB3AEIAYgBBAEMAcwBBAE8AUQBBADUAQQBGADAAQQBjAGcAQgBoAEEARQBnAEEAUQB3AEIAYgBBAEMAcwBBAE0AdwBBADEAQQBGADAAQQBjAGcAQgBoAEEARQBnAEEAUQB3AEIAYgBBAEMAcwBBAE4AUQBBADUAQQBGADAAQQBjAGcAQgBoAEEARQBnAEEAUQB3AEIAYgBBAEMAcwBBAE4AUQBBAHgAQQBEAEUAQQBYAFEAQgB5AEEARwBFAEEAUwBBAEIARABBAEYAcwBBAEsAdwBBAHkAQQBEAEUAQQBNAFEAQgBkAEEASABJAEEAWQBRAEIASQBBAEUATQBBAFcAdwBBAHIAQQBEAFUAQQBPAFEAQgBkAEEASABJAEEAWQBRAEIASQBBAEUATQBBAFcAdwBBAHIAQQBEAEEAQQBNAEEAQQB4AEEARgAwAEEADQAKAGMAZwBCAGgAQQBFAGcAQQBRAHcAQgBiAEEAQwBzAEEATQBRAEEAMQBBAEYAMABBAGMAZwBCAGgAQQBFAGcAQQBRAHcAQgBiAEEAQwBzAEEATQBBAEEAdwBBAEQARQBBAFgAUQBCAHkAQQBHAEUAQQBTAEEAQgBEAEEARgBzAEEASwB3AEEANABBAEQAUQBBAFgAUQBCAHkAQQBHAEUAQQBTAEEAQgBEAEEARgBzAEEASwB3AEEANQBBAEQAawBBAFgAUQBCAHkAQQBHAEUAQQBTAEEAQgBEAEEARgBzAEEASwB3AEEAdwBBAEQARQBBAE0AUQBCAGQAQQBIAEkAQQBZAFEAQgBJAEEARQBNAEEAVwB3AEEAcgBBAEQARQBBAE4AUQBCAGQAQQBIAEkAQQBZAFEAQgBJAEEARQBNAEEAVwB3AEEAcgBBAEQATQBBAE0AZwBBAHgAQQBGADAAQQBjAGcAQgBoAEEARQBnAEEAUQB3AEIAYgBBAEMAcwBBAE4AUQBBAHgAQQBEAEUAQQBYAFEAQgB5AEEARwBFAEEAUwBBAEIARABBAEYAcwBBAEsAdwBBADUAQQBEAEUAQQBNAFEAQgBkAEEASABJAEEAWQBRAEIASQBBAEUATQBBAFcAdwBBAHIAQQBEAGMAQQBPAFEAQgBkAEEASABJAEEAWQBRAEIASQBBAEUATQBBAFcAdwBBAHIAQQBEAEEAQQBPAEEAQgBkAEEASABJAEEAWQBRAEIASQBBAEUATQBBAFcAdwBBAHIAQQBEAEkAQQBPAFEAQgBkAEEASABJAEEAWQBRAEIASQBBAEUATQBBAA0ACgBXAHcAQQByAEEARABnAEEATgBRAEIAZABBAEgASQBBAFkAUQBCAEkAQQBFAE0AQQBXAHcAQQByAEEARABjAEEATgBnAEIAZABBAEgASQBBAFkAUQBCAEkAQQBFAE0AQQBXAHcAQQA5AEEARQBZAEEASgBBAEIANwBBAEgAawBBAGMAZwBCADAAQQBBAD0APQAnACkAKQA7ACQAewBAAH0AIAA9ACIAeAAiADsAJABiAD0AJABhAC4AVABvAEMAaABhAHIAQQByAHIAYQB5ACgAKQA7AFsAYQByAFIAYQBZAF0AOgA6AHIARQBWAGUAcgBTAGUAKAAkAGIAKQA7ACgAJABiACAALQBKAG8ASQBuACAAIgAiACkAIAB8ACAAJgAoACIAJAB7ACEAfQBlACQAewBAAH0AIgApAA==''' import base64 a = base64.b64decode(s) for i in a: if i != b'\x00': print(chr(i), end='') s = b'''fQB0AGkAeABlAHsAaABjAHQAYQBjAH0AOwApAEYAJAAgACwAaQByAHUAJAAoAGUAbABpAEYAZABhAG8AbABwAFUALgBsAGMAdwAkADsAcAB0AGYAJAAgAHQAcwBpAEwAdABuAGUAbQB1AGcAcgBBAC0AIABpAHIAVQAuAG0AZQB0AHMAeQBTACAAZQBtAGEATgBlAHAAeQBUAC0AIAB0AGMAZQBqAGIATwAtAHcAZQBOAD0AaQByAHUAJAA7AHQAbgBlAGkAbABDAGIAZQBXAC4AdABlAE4ALgBtAGUAdABzAHkAUwAgAGUA bQBhAE4AZQBwAHkAVAAtACAAdABjAGUAagBiAE8ALQB3AGUATgA9AGwAYwB3ACQAOwAiAHAAaQB6AC4AcwBzAGEAcAAvAG4AaQAvAH0AIQA1AHQAcAAxAGMANQBfAGQAZQBwAHAANAByAFcAewBGAFQAQwBnAHcAYQBEAEAAeQByAGEAYwBzADoAcgBlAHMAdQAvAC8AOgBwAHQAZgAiAD0AcAB0AGYAJAA7ADYAMQAxAF0AcgBhAEgAQwBbACsAMAAyADEAXQByAGEASABDAFsAKwA2ADEAMQBdAHIAYQBIAEMAWwArADYA NABdAHIAYQBIAEMAWwArADUAMgAxAF0AcgBhAEgAQwBbACsANgAxADEAXQByAGEASABDAFsAKwAyADEAMQBdAHIAYQBIAEMAWwArADkANABdAHIAYQBIAEMAWwArADQAMQAxAF0AcgBhAEgAQwBbACsAOQA5AF0AcgBhAEgAQwBbACsAMwA1AF0AcgBhAEgAQwBbACsANQA5AF0AcgBhAEgAQwBbACsANQAxADEAXQByAGEASABDAFsAKwAyADEAMQBdAHIAYQBIAEMAWwArADUAOQBdAHIAYQBIAEMAWwArADAAMAAxAF0A cgBhAEgAQwBbACsAMQA1AF0AcgBhAEgAQwBbACsAMAAwADEAXQByAGEASABDAFsAKwA4ADQAXQByAGEASABDAFsAKwA5ADkAXQByAGEASABDAFsAKwAwADEAMQBdAHIAYQBIAEMAWwArADEANQBdAHIAYQBIAEMAWwArADMAMgAxAF0AcgBhAEgAQwBbACsANQAxADEAXQByAGEASABDAFsAKwA5ADEAMQBdAHIAYQBIAEMAWwArADcAOQBdAHIAYQBIAEMAWwArADAAOABdAHIAYQBIAEMAWwArADIAOQBdAHIAYQBIAEMA WwArADgANQBdAHIAYQBIAEMAWwArADcANgBdAHIAYQBIAEMAWwA9AEYAJAB7AHkAcgB0AA==''' a = base64.b64decode(s) for i in a[::-1]: if i != b'\x00': print(chr(i), end='') ``` `Flag: DawgCTF{Wr4pped_5c1pt5!}` ## ShinyClean™ Rust Remover: Budget Edition ```c= __int64 shinyclean::main() { __int64 v1; // [rsp+8h] [rbp-100h] _BYTE s[23]; // [rsp+2Ah] [rbp-DEh] BYREF _BYTE v3[22]; // [rsp+41h] [rbp-C7h] BYREF _BYTE v4[9]; // [rsp+57h] [rbp-B1h] BYREF _BYTE v5[48]; // [rsp+60h] [rbp-A8h] BYREF _QWORD v6[4]; // [rsp+90h] [rbp-78h] BYREF _BYTE v7[48]; // [rsp+B0h] [rbp-58h] BYREF _BYTE *v8; // [rsp+E0h] [rbp-28h] void *v9; // [rsp+E8h] [rbp-20h] _BYTE *v10; // [rsp+F0h] [rbp-18h] void *v11; // [rsp+F8h] [rbp-10h] _BYTE *v12; // [rsp+100h] [rbp-8h] memset(s, 0, sizeof(s)); qmemcpy(v3, "{^HX|kyDym", 10); v3[10] = 0xC; v3[11] = 0xC; v3[12] = 0x60; v3[13] = 0x7C; v3[14] = 0xB; v3[15] = 0x6D; v3[16] = 0x60; v3[17] = 0x68; v3[18] = 0xB; v3[19] = 0xA; v3[20] = 0x77; v3[21] = 0x1E; strcpy(v4, "B"); v4[2] = 0; *(_WORD *)&v4[3] = 0; *(_DWORD *)&v4[5] = 0; do { if ( *(_QWORD *)&v4[1] >= 0x17uLL ) core::panicking::panic_bounds_check(*(_QWORD *)&v4[1], 23LL, &off_54578); s[*(_QWORD *)&v4[1]] = v3[*(_QWORD *)&v4[1]] ^ 0x3F; v1 = *(_QWORD *)&v4[1] + 1LL; if ( *(_QWORD *)&v4[1] == -1LL ) core::panicking::panic_const::panic_const_add_overflow((__int64)&off_545A8); ++*(_QWORD *)&v4[1]; } while ( v1 != 23 ); if ( (unsigned int)std::process::id() == 29485234 ) { v10 = s; v11 = &core::array::<impl core::fmt::Debug for [T; N]>::fmt; v12 = s; v8 = s; v9 = &core::array::<impl core::fmt::Debug for [T; N]>::fmt; v6[2] = s; v6[3] = &core::array::<impl core::fmt::Debug for [T; N]>::fmt; v6[0] = s; v6[1] = &core::array::<impl core::fmt::Debug for [T; N]>::fmt; core::fmt::Arguments::new_v1(v5, &unk_545C0, v6); return std::io::stdio::_print(v5); } else { core::fmt::Arguments::new_const(v7, &off_545E0); return std::io::stdio::_print(v7); } } ``` Thử thách này chỉ đơn giản là lấy giá trị của `v3` và xor với 0x3f ```python= enc = [0x7b, 0x5e, 0x48, 0x58, 0x7c, 0x6b, 0x79, 0x44, 0x79, 0x6d, 0x0c, 0x0c, 0x60, 0x7c, 0x0b, 0x6d, 0x60, 0x68, 0x0b, 0x0a, 0x77, 0x1e, 0x42] for i in enc: print(chr(i ^ 0x3f), end='') ``` `Flag: DawgCTF{FR33_C4R_W45H!}` ## Evanesco ```c= int __fastcall main(int argc, const char **argv, const char **envp) { char s[8]; // [rsp+0h] [rbp-A0h] BYREF unsigned __int64 v5; // [rsp+8h] [rbp-98h] unsigned __int64 v6; // [rsp+10h] [rbp-90h] unsigned __int64 v7; // [rsp+18h] [rbp-88h] unsigned __int64 v8; // [rsp+20h] [rbp-80h] unsigned __int64 v9; // [rsp+28h] [rbp-78h] unsigned __int64 v10; // [rsp+30h] [rbp-70h] unsigned __int64 v11; // [rsp+38h] [rbp-68h] unsigned __int64 v12; // [rsp+40h] [rbp-60h] unsigned __int64 v13; // [rsp+48h] [rbp-58h] unsigned __int64 v14; // [rsp+50h] [rbp-50h] unsigned __int64 v15; // [rsp+58h] [rbp-48h] unsigned __int64 v16; // [rsp+60h] [rbp-40h] unsigned __int64 v17; // [rsp+68h] [rbp-38h] unsigned __int64 v18; // [rsp+70h] [rbp-30h] unsigned __int64 v19; // [rsp+78h] [rbp-28h] unsigned __int64 v20; // [rsp+80h] [rbp-20h] unsigned __int64 v21; // [rsp+88h] [rbp-18h] char v22; // [rsp+90h] [rbp-10h] unsigned __int64 v23; // [rsp+98h] [rbp-8h] v23 = __readfsqword(0x28u); *(_QWORD *)s = 0x8481A0F38180A0F3LL; v5 = 0xB781A0F3A181A0F3LL; v6 = 0x8381A0F3A781A0F3LL; v7 = 0x8681A0F39481A0F3LL; v8 = 0xB581A0F3BB81A0F3LL; v9 = 0xA381A0F39F81A0F3LL; v10 = 0xAE81A0F3A181A0F3LL; v11 = 0xB481A0F39F81A0F3LL; v12 = 0xA781A0F3A181A0F3LL; v13 = 0xA281A0F39F81A0F3LL; v14 = 0xB481A0F3B581A0F3LL; v15 = 0xB581A0F39F81A0F3LL; v16 = 0xA381A0F39F81A0F3LL; v17 = 0xAE81A0F3A181A0F3LL; v18 = 0x9F81A0F3B481A0F3LL; v19 = 0xA981A0F3A881A0F3LL; v20 = 0xA581A0F3A481A0F3LL; v21 = 0xBF81A0F3BD81A0F3LL; v22 = 0; puts("Oops I spilled my invisibility potion all over the flag!"); puts("Can you find the flag for me?"); puts(s); puts("I hope you can find it!"); return 0; } ``` Nhìn vào đoạn chương trình, ta chỉ thấy có một dòng bất thường đó chính là `puts(s)`. Và khi `puts(s)` được thực hiện thì ta không thấy bất kì kí tự nào cả. Vì đây là kí tự không thể in được Dựa vào gợi ý của bài thực hiện `decode('utf-8')` và in ra mã unicode của nó ```python= values = [ 0x8481A0F38180A0F3, 0xB781A0F3A181A0F3, 0x8381A0F3A781A0F3, 0x8681A0F39481A0F3, 0xB581A0F3BB81A0F3, 0xA381A0F39F81A0F3, 0xAE81A0F3A181A0F3, 0xB481A0F39F81A0F3, 0xA781A0F3A181A0F3, 0xA281A0F39F81A0F3, 0xB481A0F3B581A0F3, 0xB581A0F39F81A0F3, 0xA381A0F39F81A0F3, 0xAE81A0F3A181A0F3, 0x9F81A0F3B481A0F3, 0xA981A0F3A881A0F3, 0xA581A0F3A481A0F3, 0xBF81A0F3BD81A0F3 ] for i in values: print(repr(i.to_bytes(8, 'little').decode('utf-8')), end=' ') ''' '\U000e0001\U000e0044' '\U000e0061\U000e0077' '\U000e0067\U000e0043' '\U000e0054\U000e0046' '\U000e007b\U000e0075' '\U000e005f\U000e0063' '\U000e0061\U000e006e' '\U000e005f\U000e0074' '\U000e0061\U000e0067' '\U000e005f\U000e0062' '\U000e0075\U000e0074' '\U000e005f\U000e0075' '\U000e005f\U000e0063' '\U000e0061\U000e006e' '\U000e0074\U000e005f' '\U000e0068\U000e0069' '\U000e0064\U000e0065' '\U000e007d\U000e007f' ''' ``` Ta thầy rằng trong mã unicode sẽ có chứa giá trị hex của flag. Bây giờ chỉ cần lấy chúng ra và ta sẽ có flag hoàn chỉnh ```python= values = [ 0x8481A0F38180A0F3, 0xB781A0F3A181A0F3, 0x8381A0F3A781A0F3, 0x8681A0F39481A0F3, 0xB581A0F3BB81A0F3, 0xA381A0F39F81A0F3, 0xAE81A0F3A181A0F3, 0xB481A0F39F81A0F3, 0xA781A0F3A181A0F3, 0xA281A0F39F81A0F3, 0xB481A0F3B581A0F3, 0xB581A0F39F81A0F3, 0xA381A0F39F81A0F3, 0xAE81A0F3A181A0F3, 0x9F81A0F3B481A0F3, 0xA981A0F3A881A0F3, 0xA581A0F3A481A0F3, 0xBF81A0F3BD81A0F3 ] # for i in values: # print(repr(i.to_bytes(8, 'little').decode('utf-8')), end=' ') flag = '' for i in values: flag += repr(i.to_bytes(8, 'little').decode('utf-8')).replace('\\U000e00', '').replace("\'", "") print(bytes.fromhex(flag)) ``` `Flag: DawgCTF{u_can_tag_but_u_cant_hide}` ## """Web challenge""" Thử thách này cho chúng ta một file WebAssembly. Vì vậy tôi sử dụng [diswasm](https://github.com/wasmkit/diswasm) ``` int $func1() { // offset=0xc int local_c; // offset=0x8 int local_8; // offset=0x4 int local_4; local_c = 0x0; local_8 = $func43(0x29); *((unsigned char *) local_8 + 0x29) = 0x0; local_4 = 0x0; label$1: { while (1) { if ((((local_4 < 0x28) & 0x1) == 0x0)) break label$1; *((unsigned char *) (local_8 + local_4)) = *((unsigned char *) (*((unsigned char *) local_4 + 0x10060) & 0xff) + 0x10000); local_4 = (local_4 + 0x1); break label$2; break ; }; }; $func3(0x100be /* "SUFFAH WEBDEVS!!!!!!!!\n" */ , 0x0); return local_c; } ``` Tôi để ý thấy có phần này đáng chú ý. Tóm lại phần này sẽ lấy 40 giá trị tại địa chỉ 0x10060 và ánh xạ vào bảng tại 0x10000 ``` /****INITIALIZED MEMORY DUMP****/ // 00010000: 6a 72 67 2f 21 37 25 5b 33 3d 46 2c 7c 32 75 41 : "jrg/!7%[3=F,|2uA" // 00010010: 6d 76 35 5c 59 29 58 7e 5d 53 5f 77 44 27 2a 45 : "mv5\\Y)X~]S_wD'*E" // 00010020: 22 47 4f 65 68 7a 3e 6c 40 57 38 71 60 34 63 43 : "\"GOehz>l@W8q`4cC" // 00010030: 56 3b 66 51 36 26 30 5e 52 2b 74 6f 42 23 28 64 : "V;fQ6&0^R+toB#(d" // 00010040: 70 31 4b 24 62 48 4e 3a 3c 50 4c 6e 55 54 79 5a : "p1K$bHN:<PLnUTyZ" // 00010050: 69 20 7d 3f 6b 61 2e 39 49 4a 2d 7b 4d 78 73 00 : "i }?ka.9IJ-{Mxs\x00" // 00010060: 1c 55 1b 02 2f 4d 0a 5b 46 22 1a 08 19 2f 2d 49 : "\x1cU\x1b\x02/M\n[F\"\x1a\b\x19/-I" // 00010070: 08 1a 0a 38 22 5c 1a 2d 19 19 08 5c 3c 4a 14 1a : "\b\x1a\n8\"\\\x1a-\x19\x19\b\\<J\x14\x1a" // 00010080: 29 08 3c 1c 08 30 19 52 2d 2b 20 20 20 30 58 30 : ")\b<\x1c\b0\x19R-+ 0X0" // 00010090: 78 00 2d 30 58 2b 30 58 20 30 58 2d 30 78 2b 30 : "x\x00-0X+0X 0X-0x+0" // 000100a0: 78 20 30 78 00 6e 61 6e 00 69 6e 66 00 4e 41 4e : "x 0x\x00nan\x00inf\x00NAN" // 000100b0: 00 49 4e 46 00 2e 00 28 6e 75 6c 6c 29 00 53 55 : "\x00INF\x00.\x00(null)\x00SU" // 000100c0: 46 46 41 48 20 57 45 42 44 45 56 53 21 21 21 21 : "FFAH WEBDEVS!!!!" .......... ``` **Script** ```python= lookup = "jrg/!7%[3=F,|2uAmv5\\Y)X~]S_wD'*E\"GOehz>l@W8q`4cCV;fQ6&0^R+toB#(dp1K$bHN:<PLnUTyZi }?ka.9IJ-{Mxs"; enc = [ 0x1C, 0x55, 0x1B, 0x02, 0x2F, 0x4D, 0x0A, 0x5B, 0x46, 0x22, 0x1A, 0x08, 0x19, 0x2F, 0x2D, 0x49, 0x08, 0x1A, 0x0A, 0x38, 0x22, 0x5C, 0x1A, 0x2D, 0x19, 0x19, 0x08, 0x5C, 0x3C, 0x4A, 0x14, 0x1A, 0x29, 0x08, 0x3C, 0x1C, 0x08, 0x30, 0x19, 0x52 ] flag = "" for i in range(len(enc)): flag += lookup[enc[i]] print(flag) ``` `Flag: DawgCTF{NO_3SC4P3_FROM_4SS3MBLY_W3BD3VS}` ## ShinyClean™ Rust Remover: Club Edition Chương này yêu cầu ta nhập một giá trị tối đa là 4bytes Sau đó lấy `v50` xor với giá trị vừa nhập và tính hash sha256 ```c= while ( 1 ) { v11 = core::iter::range::<impl core::iter::traits::iterator::Iterator for core::ops::range::Range<A>>::next(v56); v38 = v12; v56[2] = v11; v57 = v12; if ( !v11 ) break; v35 = v57; v68 = v57; v22 = v57 & 3; if ( v22 >= 4 ) core::panicking::panic_bounds_check(v22, 4LL, &off_6E8F8); if ( v57 >= 0x19 ) core::panicking::panic_bounds_check(v57, 25LL, &off_6E910); v50[v57] ^= *((_BYTE *)&v54 + v22); } sha256::digest(v58, v50); // So sánh chuỗi hash vừa tính với v49 v32 = <alloc::string::String as core::cmp::PartialEq<&str>>::eq(v58, v49); ``` Nếu chuỗi hash hợp lệ (tức là giải mã flag thành công) thì chương trình sẽ in ra flag Vì giá trị là 4bytes nên ta sẽ lấy format `Dawg` xor với 4 giá trị đầu tiên của `v50` để tìm code ![image](https://hackmd.io/_uploads/SytzewXJlg.png) `Flag: DawgCTF{4LL_RU57_N0_C4R!}` ## ShinyClean™ Rust Remover: Pro™ Edition ```c= v71 = 1; v43 = alloc::vec::Vec<T,A>::len(v68); v72[0] = <I as core::iter::traits::collect::IntoIterator>::into_iter(0LL, v43); v72[1] = v16; while ( 1 ) { v73 = core::iter::range::<impl core::iter::traits::iterator::Iterator for core::ops::range::Range<A>>::next(v72); v74 = v17; if ( !v73 ) break; v32 = v74; v84 = v74; if ( v74 > 0x15 ) { v71 = 0; break; } v75[0] = 0x7097E6D32231D9EALL; v75[1] = 0x6876FC611BA8A216LL; v76 = 666413947; v77 = -106; if ( v74 >= 0x15 ) core::panicking::panic_bounds_check(v74, 21LL, &off_75B10); v28 = *((_BYTE *)v75 + v74); v30 = (struct _Unwind_Exception *)<alloc::vec::Vec<T,A> as core::ops::index::Index<I>>::index(v68, v74, &off_75B28); if ( v28 != LOBYTE(v30->exception_class) ) { v71 = 0; break; } } ``` Chương trình này dựa vào input để ánh xạ bảng và so sánh lại với `v75`. Tuy nhiên tôi thấy việc tìm bảng giá trị với tôi khá khó khăn, nên tôi sử dụng cách bruteforce ![image](https://hackmd.io/_uploads/HJRoWvQyee.png) Đây là địa chỉ mà chương trình thực hiện so sánh ![image](https://hackmd.io/_uploads/rkcBMD71eg.png) Còn đây là địa chỉ của bảng sau khi được tính toán ```python= import gdb import string gdb.execute('file ./shinyclean_pro') gdb.execute('b *0x0000555555561A13') check = [0xea, 0xd9, 0x31, 0x22, 0xd3, 0xe6, 0x97, 0x70, 0x16, 0xa2, 0xa8, 0x1b, 0x61, 0xfc, 0x76, 0x68, 0x7b, 0xab, 0xb8, 0x27, 0x96] charset = string.ascii_letters + string.digits + "{}_?!" flag = "DawgCTF{" cnt = 8 while len(flag) < 21: for c in charset: print(f"Currentttttttttt: {flag}") test = flag + c + "a" * (19 - len(flag)) + '}' print(f"Tryingggggggg: {test}") gdb.execute(f"run <<< {test}") out = gdb.execute(f"x/bx 0x00005555555CEDD0 + {cnt}", to_string=True).split()[1] if int(out, 16) == check[cnt]: flag += c cnt += 1 break print(flag) gdb.execute('exit') ``` `Flag: DawgCTF{S0000_CL43N!}`