Reverse Engineering
Paranoia (100 pts)
Grip (100 pts)
Sperm Rev (100 pts)
Risks (205 pts)
Packeta (460 pts)
Mips (477 pts)
Orgalorg (498 pts)
Paranoia (100 pts)
Description
im baby
Author: miyako
nc 20.80.240.190 1234
Solution
Given ELF 64 bit file, open it using IDA.
int __fastcall main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // eax
int v4; // ebx
int v5; // eax
unsigned __int64 i; // [rsp+8h] [rbp-18h]
v3 = time(0LL);
srand(v3);
for ( i = 0LL; i <= 0x11; ++i )
{
v4 = flag[i];
v5 = rand();
printf("%i ", v4 ^ ((unsigned __int8)(((unsigned int)(v5 >> 31) >> 24) + v5) - ((unsigned int)(v5 >> 31) >> 24)));
}
putchar(10);
return 0;
Basically it just do xor with random value with seed current time (time(0)). To get the plaintext we can do the same process. To overcome delay issue, we can do little bruteforce from current time.
from ctypes import CDLL
import time
from pwn import *
libc = CDLL("libc.so.6")
current = int(time.time())
r = remote("20.80.240.190", 1234)
ct = list(map(int, r.recvline().strip().split(b" ")))
for i in range(current, current-10, -1):
libc.srand(i)
tmp_flag = b""
for v4 in ct:
v5 = libc.rand()
tmp_flag += bytes([v4 ^ (((((v5 >> 31) >> 24) + v5) - ((v5 >> 31) >> 24)) & 0xff)])
print(i, tmp_flag)
r.interactive()
Flag: akasec{n0t_t00_m4ny_br41nc3lls_l3ft}
Grip (100 pts)
Description
its...its...Grippy
Author: miyako
Solution
Given ELF 64 bit, open it using IDA.
__int64 __fastcall main(int a1, char **a2, char **a3)
{
__int64 v3; // rbx
__int64 v4; // rbx
__int64 v5; // rbx
__int64 v6; // rbx
__int64 v7; // rbx
__int64 v8; // rbx
__int64 v9; // rbx
__int64 v10; // rbx
__int64 v11; // rbx
unsigned __int64 i; // [rsp+18h] [rbp-C8h]
_QWORD *v14; // [rsp+20h] [rbp-C0h]
__int64 v15; // [rsp+30h] [rbp-B0h]
__int64 v16; // [rsp+38h] [rbp-A8h]
__int64 v17; // [rsp+40h] [rbp-A0h]
__int64 v18; // [rsp+48h] [rbp-98h]
__int64 v19; // [rsp+50h] [rbp-90h]
__int64 v20; // [rsp+58h] [rbp-88h]
__int64 v21; // [rsp+60h] [rbp-80h]
__int64 v22; // [rsp+68h] [rbp-78h]
__int64 v23; // [rsp+70h] [rbp-70h]
__int64 v24; // [rsp+78h] [rbp-68h]
__int64 v25; // [rsp+80h] [rbp-60h]
__int64 v26; // [rsp+88h] [rbp-58h]
__int64 v27; // [rsp+90h] [rbp-50h]
__int64 v28; // [rsp+98h] [rbp-48h]
__int64 v29; // [rsp+A0h] [rbp-40h]
char v30[13]; // [rsp+A8h] [rbp-38h]
__int64 v31; // [rsp+B5h] [rbp-2Bh]
unsigned __int64 v32; // [rsp+C8h] [rbp-18h]
v32 = __readfsqword(0x28u);
v15 = 0xB21E71BA177BBAA7LL;
v16 = 0xF2F2DAD7F679BA96LL;
v17 = 0xBA32C30AB77BBAF2LL;
v18 = 0xCBD3D5C3D1DBD14ALL;
v19 = 0xC9C4C481D848BAC3LL;
v20 = 0xBA22B77BBA84C0EFLL;
v21 = 0xC0EFC94ABA2AA77BLL;
v22 = 0xEF48BAD483DBD384LL;
v23 = 0xBACDC9C284DE81D2LL;
v24 = 0x3516A77BBA2EB77BLL;
v25 = 0xEA19F2F2F2F23EB7LL;
v26 = 0x22F7B644FD3EB779LL;
v27 = 0x3EB779307BB00271LL;
v28 = 0xF33EB77122F7A67ALL;
v29 = 0xBA621084E93E8F71LL;
*(_QWORD *)v30 = 0xD7F6D9BA960AB779LL;
*(_QWORD *)&v30[5] = 0x86F2F2F2DAD7F6D9LL;
v31 = 0x313BF2F2F2F21AF7LL;
for ( i = 0LL; i <= 0x8C; ++i )
*((_BYTE *)&v15 + i) ^= 0xF2u;
v14 = mmap(0LL, 0x8DuLL, 6, 34, -1, 0LL);
v3 = v16;
*v14 = v15;
v14[1] = v3;
v4 = v18;
v14[2] = v17;
v14[3] = v4;
v5 = v20;
v14[4] = v19;
v14[5] = v5;
v6 = v22;
v14[6] = v21;
v14[7] = v6;
v7 = v24;
v14[8] = v23;
v14[9] = v7;
v8 = v26;
v14[10] = v25;
v14[11] = v8;
v9 = v28;
v14[12] = v27;
v14[13] = v9;
v10 = *(_QWORD *)v30;
v14[14] = v29;
v14[15] = v10;
v11 = v31;
*(_QWORD *)((char *)v14 + 125) = *(_QWORD *)&v30[5];
*(_QWORD *)((char *)v14 + 133) = v11;
((void (__fastcall *)(_QWORD))v14)(0LL);
puts(":3");
return 0LL;
}
We can see that there is mmap function called then the address from mmap (v14) used to store value of static value xored with 0xf2. At the end, v14 called in the main function. From those information we can assume that value on address v14 contains valid assembly because it called in the end. So dump the bytecode then open it again using decompiler.
from Crypto.Util.number import *
ct = []
ct.append(0xB21E71BA177BBAA7)
ct.append(0xF2F2DAD7F679BA96)
ct.append(0xBA32C30AB77BBAF2)
ct.append(0xCBD3D5C3D1DBD14A)
ct.append(0xC9C4C481D848BAC3)
ct.append(0xBA22B77BBA84C0EF)
ct.append(0xC0EFC94ABA2AA77B)
ct.append(0xEF48BAD483DBD384)
ct.append(0xBACDC9C284DE81D2)
ct.append(0x3516A77BBA2EB77B)
ct.append(0xEA19F2F2F2F23EB7)
ct.append(0x22F7B644FD3EB779)
ct.append(0x3EB779307BB00271)
ct.append(0xF33EB77122F7A67A)
ct.append(0xBA621084E93E8F71)
ct.append(0xD7F6D9BA960AB779)
ct.append(0x86F2F2F2DAD7F6D9)
pt = []
for i in ct:
tmp = long_to_bytes(i)[::-1]
for j in tmp:
pt.append(j ^ 0xf2)
pt[-4] = 0xc3
out = open("dump.bin", "wb")
out.write(bytes(pt))
3 null bytes at the end will cause error on decompile process, so put 0xc3 (ret) to overcome the issue.
unsigned __int64 sub_0()
{
unsigned int i; // [rsp+Ch] [rbp-34h]
__int64 v2; // [rsp+10h] [rbp-30h]
_DWORD v3[3]; // [rsp+18h] [rbp-28h]
__int64 v4; // [rsp+24h] [rbp-1Ch]
unsigned __int64 v5; // [rsp+38h] [rbp-8h]
v5 = __readfsqword(0x28u);
v2 = 0x3139212731232923i64;
v3[0] = 909538090;
*(_QWORD *)&v3[1] = 0x2671292176321D3Bi64;
v4 = 0x3F3B30762C73201Di64;
for ( i = 0; i <= 0x1B; ++i )
*((_BYTE *)&v3[-2] + i) ^= 0x42u;
return v5 - __readfsqword(0x2825042Bu);
}
Now we have the code, then just convert it to python and get the flag.
from Crypto.Util.number import *
ct = []
ct.append(0x3139212731232923)
ct.append(0x3636732A)
ct.append(0x2671292176321D3B)
ct.append(0x3F3B30762C73201D)
flag = b""
for i in ct:
tmp = long_to_bytes(i)[::-1]
for j in tmp:
flag += bytes([j ^ 0x42])
print(flag)
Flag: akasec{sh1tty_p4ck3d_b1n4ry}
Sperm Rev (100 pts)
Description
before baby rev, there was sperm rev <3
solve it fast to win another race in your life.
Author: Pengolian
Solution
Given ELF 64 bit, open it using IDA. Nothing useful in available function, check on strings.
Flag: AKASEC{strings_b35t_t00l_1n_r3v3r5e_eng1n33r1ng}
Risks (205 pts)
Description
theres this pretty cool isa called riscv it sounds awesome.
Author: miyako
Solution
Given ELF 64 bit RISCV file, open it using ghidra. Rename some known function to make it easily to understand.
undefined8 main(void)
{
char cVar1;
long lVar2;
undefined8 local_30;
long local_28;
long local_20;
long local_18;
local_28 = 0;
local_30 = 0;
printf_("whats the flag: ");
local_18 = getline_(&local_28,&local_30,_stdin);
*(local_18 + -1 + local_28) = 0;
local_20 = local_28;
FUN_00101ad4(local_28);
FUN_00101346(local_20);
FUN_00100c8c(local_20);
FUN_00100786(local_20);
lVar2 = strlen_(local_28);
if ((lVar2 == 0x20) && (cVar1 = compare_value(local_20), cVar1 == '\x01')) {
puts_("good job!");
return 0;
}
puts_("nuh uh");
return 0;
}
So there are 5 custom functions in the program.
FUN_00101ad4, FUN_00101346, FUN_00100c8c, and FUN_00100786 process our input with some operation such as xor and add.
compare_value validate our processed input with static value
From those informations we can get the valid input by utilizing z3. Below is my solution
from z3 import *
from Crypto.Util.number import *
inp = [BitVec("x{}".format(i), 64) for i in range(4)]
s = Solver()
param_1 = [0 for _ in range(4)]
# FUN_00101ad4
param_1[0] = inp[0] + 0x75978f47ac76cf;
param_1[1] = inp[1] + 0xff889b2d229768ef;
param_1[0] = param_1[0] ^ 0x76bf86ade5d5cc;
param_1[2] = inp[2] + 0x760f38b4bc69dc;
param_1[0] = param_1[0] ^ 0x559f46365cee21;
param_1[0] = param_1[0] + 0x5c6476bf0d4a19;
param_1[0] = param_1[0] ^ 0xed41cda9780;
param_1[2] = param_1[2] ^ 0x1e555c027a4e43;
param_1[3] = inp[3] + 0xfff29f96915a6e96;
param_1[0] = param_1[0] ^ 0x4c46c321e8dc3d;
param_1[2] = param_1[2] + 0x440d7b5dafb63c;
param_1[3] = param_1[3] ^ 0x39549dd6e1299b;
param_1[0] = param_1[0] + 0xff80a83276856f6b;
param_1[0] = param_1[0] + 0x3869018f758dd0;
param_1[0] = param_1[0] + 0xfff507f694ac1618;
param_1[0] = param_1[0] + 0xffaef9a6a60ac41c;
param_1[2] = param_1[2] ^ 0x4bb739ae97e2b2;
param_1[0] = param_1[0] ^ 0xb9c189c728744;
param_1[3] = param_1[3] ^ 0x63b60e480e2904;
param_1[1] = param_1[1] + 0x70ea19e458d1dd;
param_1[0] = param_1[0] ^ 0x1c380c9255dc4a;
param_1[0] = param_1[0] ^ 0x72195b264896c6;
param_1[0] = param_1[0] + 0xb58f5721006db;
param_1[1] = param_1[1] + 0xfff1a19d465554d0;
param_1[1] = param_1[1] + 0x45c8dee1a136cd;
param_1[1] = param_1[1] + 0xff95aa1bc2ad9c07;
param_1[3] = param_1[3] + 0xffed79b44c733cd6;
param_1[0] = param_1[0] + 0x27d894eb9caa9b;
param_1[3] = param_1[3] + 0xff9cb13f334ec53a;
param_1[3] = param_1[3] + 0x3c2a0d8d36145a;
param_1[1] = param_1[1] + 0x30a473f940b5dd;
param_1[2] = param_1[2] + 0x7239ea8aa2bc49;
param_1[1] = param_1[1] + 0x71e89e42b8b132;
param_1[1] = param_1[1] + 0xff887455a5eb36fd;
param_1[2] = param_1[2] + 0xffc07313a3962d72;
param_1[2] = param_1[2] + 0xffcf924d075d2a72;
param_1[1] = param_1[1] ^ 0x3707089012b521;
param_1[2] = param_1[2] + 0x12b99b0e57e3bb;
param_1[1] = param_1[1] + 0x3e897bb78bc162;
param_1[2] = param_1[2] + 0xffc244c1f804fc9b;
param_1[3] = param_1[3] ^ 0x21e211817f468b;
param_1[3] = param_1[3] + 0x44c0052fcca332;
param_1[1] = param_1[1] + 0x4f53af9faf8acf;
param_1[1] = param_1[1] + 0x2fda660863a649;
param_1[1] = param_1[1] + 0xffa9f06d0990b3ac;
param_1[2] = param_1[2] + 0x2e93addef2df4f;
param_1[3] = param_1[3] + 0x4531b2344b641b;
param_1[3] = param_1[3] + 0xfff8e89a72f8e26c;
param_1[1] = param_1[1] + 0x15c6da9bc36ed0;
param_1[2] = param_1[2] ^ 0x738278f8599e2d;
param_1[1] = param_1[1] ^ 0x44dd76d42e4513;
param_1[1] = param_1[1] + 0xffb57183e089ceb4;
param_1[2] = param_1[2] ^ 0x27972fbdfd287c;
param_1[0] = param_1[0] ^ 0x7eb9039a2b6bf0;
param_1[2] = param_1[2] + 0xffc75c67f5de1b31;
# FUN_00101346
param_1[0] = param_1[0] ^ 0x131e29f760409;
param_1[1] = param_1[1] + 0x23fe2dd7650a73;
param_1[1] = param_1[1] + 0xfff70308e97acf79;
param_1[2] = param_1[2] + 0xffb870f6f2950920;
param_1[0] = param_1[0] ^ 0x58bd244826ef43;
param_1[2] = param_1[2] + 0xffdc5874e8d03bbc;
param_1[1] = param_1[1] + 0xffb3ce0944bbfc19;
param_1[0] = param_1[0] ^ 0x38b3e1c4b3be14;
param_1[3] = param_1[3] ^ 0x6de4b0dccee1f8;
param_1[2] = param_1[2] + 0x48e99a2ccfbefa;
param_1[2] = param_1[2] + 0x2803831f197314;
param_1[2] = param_1[2] ^ 0x7fd3195c5e8bfb;
param_1[1] = param_1[1] + 0x2311f9e5515a6d;
param_1[3] = param_1[3] + 0x29e99994341bad;
param_1[2] = param_1[2] + 0xffa46f41e698229f;
param_1[0] = param_1[0] ^ 0x16097f9beb9df8;
param_1[2] = param_1[2] ^ 0x58f5f5f9e64f77;
param_1[2] = param_1[2] + 0xffce81bd3383de95;
param_1[0] = param_1[0] + 0x1437a45ffed077;
param_1[2] = param_1[2] + 0x4ec7609899b599;
param_1[3] = param_1[3] + 0x77832406a422ee;
param_1[0] = param_1[0] ^ 0xa299bfabd147f;
param_1[0] = param_1[0] + 0xff9731d63e0a4ce9;
param_1[0] = param_1[0] ^ 0x3ea0b669b87301;
param_1[0] = param_1[0] ^ 0x7bc3ff2762eeb0;
param_1[0] = param_1[0] + 0x2ff3559df23d95;
param_1[2] = param_1[2] + 0xffb0934ca254c450;
param_1[0] = param_1[0] + 0xff8b3b8d33d104e1;
param_1[3] = param_1[3] ^ 0x2f268e55029508;
param_1[2] = param_1[2] + 0xffe1c76d94c5b270;
param_1[3] = param_1[3] ^ 0x5575918734e1cd;
param_1[0] = param_1[0] + 0xffe368f50fe7ff81;
param_1[0] = param_1[0] ^ 0x22b615021c1680;
param_1[0] = param_1[0] + 0xff95c819c49f5170;
param_1[2] = param_1[2] + 0x485e655976a7ee;
param_1[0] = param_1[0] + 0x6f4847b022b253;
param_1[1] = param_1[1] ^ 0x392622311d6f3d;
param_1[1] = param_1[1] + 0xffb3096849dd7eb3;
param_1[3] = param_1[3] ^ 0x6e8b5de620fa;
param_1[3] = param_1[3] + 0x21d4322fefd286;
param_1[3] = param_1[3] + 0xffe14e96454625c5;
param_1[3] = param_1[3] ^ 0x4757d3b35495bb;
param_1[1] = param_1[1] + 0xffc4845886e53673;
param_1[0] = param_1[0] ^ 0x57617d2db4d1c4;
param_1[0] = param_1[0] ^ 0x69bd97ec881da;
param_1[2] = param_1[2] ^ 0x57ac6bbc11593;
param_1[2] = param_1[2] ^ 0x5c2cbf22512aa3;
param_1[2] = param_1[2] + 0x1860e298e3c0d5;
param_1[2] = param_1[2] + 0xffe6f1b24728fb11;
param_1[0] = param_1[0] + 0x4561b3931db109;
param_1[0] = param_1[0] ^ 0x1a70a95138d536;
param_1[2] = param_1[2] + 0x32ff8082367e19;
param_1[3] = param_1[3] + 0xff99a53e605869f2;
param_1[0] = param_1[0] + 0x1e359449108efb;
param_1[0] = param_1[0] + 0xff9338172cb899f9;
param_1[0] = param_1[0] + 0x33dbc3093cba9e;
param_1[1] = param_1[1] + 0x7d005d760e8a00;
param_1[0] = param_1[0] ^ 0x630abe094f2fcb;
param_1[2] = param_1[2] ^ 0x5c693ca6ad4098;
param_1[2] = param_1[2] ^ 0x1218c2c1fc6aab;
param_1[2] = param_1[2] ^ 0x78d35fbb138c9c;
param_1[3] = param_1[3] + 0x42dfb926a777d2;
param_1[3] = param_1[3] ^ 0x3f60fd507495c5;
param_1[1] = param_1[1] + 0x2cca6aa235fa04;
param_1[0] = param_1[0] + 0x5a8e68db17f162;
param_1[0] = param_1[0] + 0x1287bd45883bda;
param_1[0] = param_1[0] + 0xffe7b46bbeb822c6;
param_1[3] = param_1[3] + 0x5234b2a7901fd8;
param_1[3] = param_1[3] + 0xa856e4c03b946;
param_1[1] = param_1[1] ^ 0x6312ec05f527a4;
param_1[1] = param_1[1] + 0x46ce8a9c234e2f;
param_1[3] = param_1[3] + 0x171cfaebba97ed;
# FUN_00100c8c
param_1[2] = param_1[2] ^ 0x21552380a54ebd;
param_1[2] = param_1[2] ^ 0x217fe5a723014c;
param_1[2] = param_1[2] + 0xff929930c56e6594;
param_1[2] = param_1[2] ^ 0x7eb96f8929799a;
param_1[3] = param_1[3] + 0x67d0ff39897513;
param_1[3] = param_1[3] + 0x26a2f35c92df10;
param_1[2] = param_1[2] + 0xffd5d8a901dbebd6;
param_1[2] = param_1[2] + 0xad9fcf45aef6;
param_1[2] = param_1[2] + 0xffc53d1702ef8aa8;
param_1[0] = param_1[0] + 0x591ac5d1939c8b;
param_1[2] = param_1[2] ^ 0x33d94a84565532;
param_1[2] = param_1[2] ^ 0x308afb7e01e13e;
param_1[3] = param_1[3] + 0xffb48db7039082e1;
param_1[2] = param_1[2] ^ 0x55662e74858cf1;
param_1[3] = param_1[3] + 0xffa5b828a6179210;
param_1[1] = param_1[1] ^ 0x1638c6225c560d;
param_1[2] = param_1[2] ^ 0x40641fcdaf2a6d;
param_1[0] = param_1[0] + 0x1907586d8aaec6;
param_1[1] = param_1[1] ^ 0x2ac0e1d87fbfd3;
param_1[0] = param_1[0] + 0x4903ecf455fa05;
param_1[1] = param_1[1] + 0xff84efef75a89283;
param_1[2] = param_1[2] ^ 0x575e02c2ec2e98;
param_1[2] = param_1[2] ^ 0x5686c924044043;
param_1[0] = param_1[0] + 0xffa75728515de781;
param_1[0] = param_1[0] + 0x6c40d33a5de8b4;
param_1[0] = param_1[0] + 0xffae776809930118;
param_1[1] = param_1[1] + 0x77250c081305ce;
param_1[2] = param_1[2] + 0xffeff0d64a3fb770;
param_1[3] = param_1[3] + 0x1106386668917b;
param_1[2] = param_1[2] ^ 0x2a958285eaabc6;
param_1[1] = param_1[1] + 0x17e82fdc4bb7e6;
param_1[2] = param_1[2] + 0x6e5b6deacda2b3;
param_1[1] = param_1[1] + 0xffe4362cd469721d;
param_1[1] = param_1[1] ^ 0x46a8ddb8e7831e;
param_1[0] = param_1[0] + 0x5ef639bb0d96fc;
param_1[3] = param_1[3] ^ 0x540dd0d8537808;
param_1[3] = param_1[3] + 0xffd7468d44d84bfc;
param_1[2] = param_1[2] + 0xffb5048de8c6e26a;
param_1[0] = param_1[0] ^ 0x457b282105f5ff;
param_1[1] = param_1[1] ^ 0x2eff779ebf04ee;
param_1[1] = param_1[1] ^ 0x282c4c9602a8d1;
param_1[0] = param_1[0] ^ 0x5892a99ecd56db;
param_1[1] = param_1[1] + 0x7306fd8fb4ac48;
param_1[3] = param_1[3] + 0x4b3f6ca9126599;
param_1[3] = param_1[3] + 0xffed5514bbd0b395;
param_1[0] = param_1[0] + 0x19b2a80c1ebde0;
param_1[2] = param_1[2] ^ 0x34ab995333d7bc;
param_1[0] = param_1[0] ^ 0x4b803835540e77;
param_1[2] = param_1[2] ^ 0x4aaf3dd459117d;
param_1[3] = param_1[3] ^ 0x45b9bf142dd7b9;
param_1[0] = param_1[0] + 0xffdae06e2a1c7254;
param_1[1] = param_1[1] + 0xff805d1980ad21aa;
param_1[0] = param_1[0] + 0xff8aba0c42d40896;
param_1[0] = param_1[0] + 0x425422cc59e30;
param_1[0] = param_1[0] + 0x235f71339ac927;
param_1[2] = param_1[2] + 0xffb282c744cb6616;
param_1[2] = param_1[2] + 0xffa61489eb15d360;
param_1[0] = param_1[0] ^ 0x8db3daacc3ff9;
param_1[2] = param_1[2] ^ 0x97368bc6e7d41;
param_1[3] = param_1[3] ^ 0x86c96f6b4510f;
param_1[2] = param_1[2] ^ 0x1951f11deeb2fa;
param_1[1] = param_1[1] + 0x5dc2de99056b51;
param_1[2] = param_1[2] + 0xffb654da8cc4cb5f;
# FUN_00100786
param_1[3] = param_1[3] + 0xffdb0267f30481de;
param_1[0] = param_1[0] + 0xd349975ed71ce;
param_1[3] = param_1[3] + 0x396b3ec36373cc;
param_1[3] = param_1[3] ^ 0x2d2d96a9d4da30;
param_1[2] = param_1[2] ^ 0x656498272858da;
param_1[2] = param_1[2] + 0xffb3ad5ab10bc1f3;
param_1[0] = param_1[0] + 0x23b2f30be0e9ab;
param_1[0] = param_1[0] + 0xff99bef8c799559b;
param_1[0] = param_1[0] + 0xffe049bda2d90572;
param_1[2] = param_1[2] + 0xff9d4568f99d45eb;
param_1[2] = param_1[2] ^ 0x26ed48b4153eb0;
param_1[2] = param_1[2] ^ 0x1af75e7b5b8c5f;
param_1[2] = param_1[2] + 0xffe9fc2941b7bd92;
param_1[1] = param_1[1] ^ 0x4b4b690f995f73;
param_1[0] = param_1[0] + 0xffa3bcbff21dd191;
param_1[2] = param_1[2] ^ 0x6feb10d533c4b1;
param_1[1] = param_1[1] + 0xffb8a8e39fec3250;
param_1[2] = param_1[2] + 0xffdb2496d81b4293;
param_1[0] = param_1[0] + 0xffb778b645f31de9;
param_1[0] = param_1[0] ^ 0x531e0306cda7a9;
param_1[2] = param_1[2] ^ 0x3521f52cd98bf4;
param_1[1] = param_1[1] + 0xff880d1e8951a4a0;
param_1[2] = param_1[2] + 0x3858d7d314a793;
param_1[2] = param_1[2] + 0xffd7c92ed6f1e27a;
param_1[1] = param_1[1] + 0x37f1e8ac57fd21;
param_1[2] = param_1[2] + 0x794d667495ec53;
param_1[0] = param_1[0] + 0xf80ea376dfe9c;
param_1[2] = param_1[2] + 0x7077ef6357df45;
param_1[1] = param_1[1] + 0xfffe413b9b12d6da;
param_1[3] = param_1[3] + 0x562536f5f8bacf;
param_1[3] = param_1[3] + 0xff9f07032cf0845d;
param_1[0] = param_1[0] ^ 0x4ba91df7d06027;
param_1[0] = param_1[0] + 0xfff6ae6bcf2ebbbc;
param_1[3] = param_1[3] ^ 0x55cdaa7dfb2afc;
param_1[3] = param_1[3] + 0x318ce149b3a1fc;
param_1[3] = param_1[3] + 0xffd5d916adc11571;
param_1[0] = param_1[0] + 0xffc3560b3c7ef5e9;
param_1[1] = param_1[1] + 0xa8c0f5e148a9e;
param_1[2] = param_1[2] ^ 0x7b607330d80f26;
param_1[0] = param_1[0] ^ 0x3c139ff1892f4f;
param_1[1] = param_1[1] + 0x1f63d4725b825e;
param_1[3] = param_1[3] + 0x6be58b7a89dd9d;
param_1[1] = param_1[1] ^ 0x67b81b10716f5;
param_1[1] = param_1[1] + 0x70efa9f526c942;
param_1[3] = param_1[3] ^ 0x411eb7ecadc3cb;
param_1[3] = param_1[3] ^ 0x250c9395e3a054;
param_1[0] = param_1[0] + 0x78f186d15f1e3b;
# compare_function
s.add(param_1[0] == 0x3167deae217139c1)
s.add(param_1[1] == 0x6745aeaf0c9a62e5)
s.add(param_1[2] == 0x62664d91c2da0c7b)
s.add(param_1[3] == 0x7ee01bea8defde65)
print(s.check())
model = s.model()
flag_bytes = b""
for i in inp:
flag_bytes += long_to_bytes(model[i].as_long())[::-1]
print(flag_bytes)
Flag: akasec{1n_my_b4g_0n3_s3c0nd_0n3}
Packeta (460 pts)
Description
Balança o ombrin', vai, vai Balança o ombrin', vai, vai
Balança o ombrin' Jogadinha do Packeta
Author: Pengolian
Solution
Given 2 ELF 64 bit files which are flag and packeta. First, open packeta using IDA. There are many function in the program, rename each function.
__int64 __fastcall main(int a1, char **a2, char **a3)
{
__int64 v3; // rdi
__int64 v4; // rdx
__int64 v5; // r8
__int64 v6; // r9
__int64 v7; // rdx
__int64 v8; // r8
__int64 v9; // r9
__int64 v10; // rdx
__int64 v11; // r8
__int64 v12; // r9
int fd; // [rsp+1Ch] [rbp-54h]
__int64 v15; // [rsp+20h] [rbp-50h] BYREF
void *v16; // [rsp+28h] [rbp-48h]
size_t len; // [rsp+30h] [rbp-40h]
_BYTE *v18; // [rsp+38h] [rbp-38h]
void *v19; // [rsp+40h] [rbp-30h]
void *v20; // [rsp+48h] [rbp-28h]
unsigned __int64 v21; // [rsp+58h] [rbp-18h]
v21 = __readfsqword(0x28u);
v16 = 0LL;
if ( a1 <= 1 )
{
printf("Usage:\n$> %s your_elf_binary", *a2);
exit(1);
}
fd = open(a2[1], 0, a3);
if ( !fd )
exit(1);
len = lseek(fd, 0LL, 2);
if ( len == -1LL )
{
close(fd);
exit(1);
}
v16 = mmap(0LL, len, 3, 2, fd, 0LL);
if ( v16 == (void *)-1LL )
exit(1);
close(fd);
v18 = malloc(0x40uLL);
if ( !v18 )
exit(1);
if ( !sub_17CD(v16, v18) )
exit(1);
v19 = malloc(8LL * *((unsigned __int16 *)v18 + 30));
if ( !v19 )
exit(1);
v3 = 8LL * *((unsigned __int16 *)v18 + 28);
v20 = malloc(v3);
if ( !v20 )
exit(1);
call_memcpy_1(v3, (__int64)v18, v4, (__int64)v19, v5, v6, v15, (__int64)v16, len, (__int64)v18, (__int64)v19);
call_memcpy_2(
v3,
(__int64)v18,
v7,
(__int64)v19,
v8,
v9,
v15,
(__int64)v16,
len,
(__int64)v18,
(int)v19,
(__int64)v20);
generate_key();
call_rc4(v3, (__int64)v18, v10, (__int64)v19, v11, v12, v15, (__int64)v16, len, (__int64)v18, (__int64)v19);
write_to_file((__int64)&v15);
return 0LL;
}
generate_key function
unsigned __int64 sub_1CE2()
{
int i; // [rsp+8h] [rbp-68h]
time_t timer; // [rsp+10h] [rbp-60h] BYREF
__int64 v3; // [rsp+18h] [rbp-58h]
char v4[72]; // [rsp+20h] [rbp-50h] BYREF
unsigned __int64 v5; // [rsp+68h] [rbp-8h]
v5 = __readfsqword(0x28u);
v3 = 4919LL;
time(&timer);
srand(v3 + timer % 500);
strcpy(v4, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
for ( i = 0; i <= 15; ++i )
byte_5020[i] = v4[rand() % 62];
return v5 - __readfsqword(0x28u);
}
So basically it generate key based on (current time % 500) + 4919. From that information we know that the possibility of the key only 500 (possible to brute).
call_rc4 function
unsigned __int64 __fastcall sub_1464(
__int64 a1,
__int64 a2,
__int64 a3,
__int64 a4,
__int64 a5,
__int64 a6,
int a7,
__int64 a8,
int a9,