by Eth007
Description
And Cush begat Nimrod: he began to be a mighty one in the earth.
Attachments
nimrod
In attachment a Nim compiled program is provided. Decompile it in Binary Ninja:
004116c0 TM__lV8EigCDqwNSDSAg6zOZ9cw_9:
004116c0 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 40 ...............@
004116d0 43 6f 72 72 65 63 74 21 00 00 00 00 00 00 00 00 Correct!........
004116e0 TM__lV8EigCDqwNSDSAg6zOZ9cw_7:
004116e0 22 00 00 00 00 00 00 00 22 00 00 00 00 00 00 40 "......."......@
004116f0 28 f8 3e e6 3e 2f 43 0c b9 96 d1 5c d6 bf 36 d8 (.>.>/C....\..6.
00411700 20 79 0e 8e 52 21 b2 50 e3 98 b5 c9 b8 a0 88 30 y..R!.P.......0
00411710 d9 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00415060 void* encryptedFlag__nimrod_10 = TM__lV8EigCDqwNSDSAg6zOZ9cw_7
00410020 int64_t NimMainInner()
00410020 {
00410020 echoBinSafe(&TM__lV8EigCDqwNSDSAg6zOZ9cw_2, 1);
00410020
00410081 if (eqeq___nimrod_69(
00410081 xorEncrypt__nimrod_46(
00410081 nsuStrip(readLine__systemZio_271(stdin), 1, 1,
00410081 &TM__lV8EigCDqwNSDSAg6zOZ9cw_4),
00410081 0x13371337),
00410081 encryptedFlag__nimrod_10))
004100a3 /* tailcall */
004100a3 return echoBinSafe(&TM__lV8EigCDqwNSDSAg6zOZ9cw_8, 1);
004100a3
0041008e /* tailcall */
0041008e return echoBinSafe(&TM__lV8EigCDqwNSDSAg6zOZ9cw_10, 1);
00410020 }
0040fdc0 uint128_t* xorEncrypt__nimrod_46(int64_t* arg1, int32_t arg2)
0040fdc0 {
0040fdc0 if (!arg1)
0040fdd4 {
0040ffd2 keystream__nimrod_20(arg2, 0);
0040ffe1 /* tailcall */
0040ffe1 return newSeq__nimrod_29(0);
0040fdd4 }
0040fdd4
0040fdde uint128_t* rax = keystream__nimrod_20(arg2, *(uint64_t*)arg1);
0040fde3 uint64_t rdi_1 = *(uint64_t*)arg1;
0040fde3
0040fded if (rdi_1 < 0)
0040fded {
0040fffc raiseRangeErrorI(rdi_1, 0, 0x7fffffffffffffff);
0040fffc /* no return */
0040fded }
omitted.. simple xor encryption
uint128_t* keystream__nimrod_20(int32_t arg1, uint64_t arg2)
0040fce0 {
0040fce0 if (arg2 < 0)
0040fcf4 {
0040fd9f raiseRangeErrorI(arg2, 0, 0x7fffffffffffffff);
0040fd9f /* no return */
0040fcf4 }
0040fcf4
0040fcfa int32_t rbx = arg1;
0040fcff uint128_t* result;
0040fcff int32_t rcx;
0040fcff int64_t rdx;
0040fcff result = newSeq__nimrod_29(arg2);
0040fcff
0040fd0a if (arg2)
0040fd0a {
0040fd0c uint64_t rbp_1 = 0;
0040fd0c
0040fd11 if (!result)
0040fd11 {
0040fd74 raiseIndexError2(0, -1, rdx, rcx);
0040fd74 /* no return */
0040fd11 }
0040fd11
0040fd4a do
0040fd4a {
0040fd1e int64_t rsi = *(uint64_t*)result;
0040fd22 rbx = rbx * 0x19660d + 0x3c6ef35f;
0040fd22
0040fd2b if (rsi <= rbp_1)
0040fd2b {
0040fd34 raiseIndexError2(rbp_1, rsi - 1, rdx, rcx);
0040fd34 /* no return */
0040fd2b }
0040fd2b
0040fd3e *(uint8_t*)((char*)result + rbp_1 + 0x10) = (char)(rbx >> 0x10);
0040fd43 rbp_1 += 1;
0040fd4a } while (arg2 > rbp_1);
0040fd0a }
0040fd0a
0040fd59 return result;
0040fce0 }
So essentiall the program does:
From the code, we can see that the Nim arrays has it sized stored at offset 0x00, and its data begins from 0x10. So we just compute the keystream and xor it with the encrypted flag in python:
key = 0x13371337
encrypted = "2200000000000000220000000000004028f83ee63e2f430cb996d15cd6bf36d820790e8e5221b250e398b5c9b8a08830d90a0000000000000000000000000000"
for ch in bytes.fromhex(encrypted)[0x10:]:
key = key * 0x19660d + 0x3c6ef35f
key %= 2 ** 32
print(chr(ch ^ ((key >> 0x10) & 0xFF)), end="")
Get flag: ictf{a_mighty_hunter_bfc16cce9dc8}
.