Reverse Engineering

Challenge
Link

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.

packeta - main
__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,