The next task is a little harder than the previous. Open task2 in IDA and see that file not stripped, cool!  ```Cint __cdecl main(int argc, const char **argv, const char **envp){  const char *v3; // r3  char *v4; // r2  int v7; // r0  int v8; // r1  _WORD *v9; // r4  const char *v10; // r4  int v11; // r7  int v12; // r0  int v13; // r6  size_t size; // r7  void *key_der; // r4  size_t v16; // r0  int mode; // r3  int file; // [sp+0h] [bp-40h]  char ses; // [sp+4h] [bp-3Ch]  char v21; // [sp+14h] [bp-2Ch]
  v3 = "SUPERSECRETSTRING";  v4 = &v2;;  do...                                         // cp v3 to v21  *v9 = *(_WORD *)v3;  if ( argc != 3    || (v10 = argv[1], v11 = strcmp(argv[1], "decrypt"), v12 = strcmp(v10, "encrypt"), v13 = v12, v11) && v12 )  {    puts("Usage task2 <encrypt/decrypt> <name file>");    exit(0);  }  size = read_file(&file, (int)argv[2]);  prepare_tee_session(&ses);  key_der = malloc(0x20u);  memset(key_der, 173, 0x20u);  v16 = strlen(&v21);  memcpy(key_der, &v21, v16);  mode = v13;  if ( v13 )    mode = 1;  derive_key((int)&ses, (int)key_der, 0x20, mode);  finalize_op(&ses, &file, size);  if ( v13 )    printf("Your FLAG %s\n", "Hello_world");  save_file((const void **)&file, (int)argv[2], size);  terminate_tee_session(&ses);  free(key_der);  return 0;}```We see that there is a certain derive of a key and the finalize op of the decryption or encryption operation. The key is derive on the basis of the SUPERSECRETSTRING string padded to length with 32 bytes `0xad`. In func `read_file` seen that file will padding with zero bytes to length multiple 16. When a file is encrypted / decrypted, it is saved to the same file. Ok, lets check func `derive_key` and `finalize_op`.```Cnt __fastcall derive_key(int *ses, int key, int key_len, int mode){  int result; // r0  int v9; // [sp+0h] [bp-58h]  TEEC_Operation op; // [sp+4h] [bp-54h]
  memset(&op, 0, 0x3Cu);  op.paramTypes = 21;  op.params[0].tmpref = key;  op.params[1].tmpref = key_len;  op.params[3].tmpref = mode;  result = TEEC_InvokeCommand(ses + 2, 1, &op, &v9;;  if ( result )    errx(1, "TEEC_InvokeCommand failed with code 0x%x origin 0x%x", result, v9);  return result;}``````Cvoid __fastcall finalize_op(int ses, void **file, size_t size){  void *out_buf; // r6  int v7; // r2  int v8; // [sp+0h] [bp-58h]  TEEC_Operation s; // [sp+4h] [bp-54h]
  memset(&s, 0, 0x3Cu);  out_buf = malloc(size);  s.paramTypes = 101;  s.params[0].tmpref = (uint32_t)*file;  s.params[1].tmpref = size;  s.params[3].tmpref = (uint32_t)out_buf;  s.imp = size;  v7 = TEEC_InvokeCommand(ses + 8, 2, &s, &v8;;  if ( v7 )    errx(1, "TEEC_InvokeCommand failed with code 0x%x origin 0x%x", v7, v8);  free(*file);  *file = out_buf;}````derive_key` sends key and mode (dec / enc),` finalize_op` sends input data and output buffer to TA. There is nothing to watch now, close client and open TA same way as in first task.Find `TA_InvokeCommandEntryPoint` function by xrefs to same string. Found 2 supported command is finalize_op, and derive_key named by the same names in client. ```Cint __fastcall TA_InvokeCommandEntryPoint(int sessionContext, int commandID, int paramTypes, int params){  if ( commandID == 1 )    return derive_key((_DWORD *)sessionContext, paramTypes, (int *)params);  if ( commandID == 2 )    return finalize_op(sessionContext, paramTypes, params);  sub_5DA("TA_InvokeCommandEntryPoint", 213, 1, 1, "Command ID 0x%x is not supported", commandID, params, paramTypes);  return 0xFFFF000A;}signed int __fastcall derive_key(_DWORD *sessionContext, int paramTypes, TEEC_Parameter *params){  int xor_key; // [sp+18h] [bp+8h]  int v8; // [sp+1Ch] [bp+Ch]  int size; // [sp+28h] [bp+18h]  int key; // [sp+2Ch] [bp+1Ch]  int v12; // [sp+34h] [bp+24h]  int i; // [sp+38h] [bp+28h]  int v14; // [sp+3Ch] [bp+2Ch]
  v12 = 21;  if ( paramTypes != 21 )    return 0xFFFF0006;  *sessionContext = params[2].tmpref;  if...  v14 = allocate_operation(sessionContext + 1, 0x10000110u, *sessionContext, 0x100u);// TEE_ALG_AES_CBC_NOPAD  if ( v14 )  {    sub_5DA("derive_key", 44, 1, 1, "Failed to allocate operation");    sessionContext[1] = 0;  }  else  {    key = params->tmpref;    size = params[1].tmpref;    getprop(0xFFFFFFFF, "unictf.2020.data.key", &xor_key);// 0x41    for ( i = 0; i <= 15; ++i )      *(_BYTE *)(i + key) ^= (_BYTE)i + (_BYTE)xor_key;    v14 = allocate_transient_object(0xA0000010, 256, sessionContext + 2);// TEE_TYPE_AES    if ( v14 )    {      sub_5DA("derive_key", 63, 1, 1, "Failed to allocate transient object");      sessionContext[2] = 0;    }    else    {      sub_1140E((int)&v8, 0xC0000000, key, size);// secret value      v14 = TEE_PopulateTransientObject(sessionContext[2], &v8, 1);      if ( !v14 )        return 0;      sub_5DA("derive_key", 72, 1, 1, "TEE_PopulateTransientObject failed, %x", v14);    }  }  if...  sessionContext[1] = 0;  if...  sessionContext[2] = 0;  return v14;}``` Okey general key derive is: ```pythonkey = list(b"SUPERSECRETSTRING"+b"\xad"*(32-17))for i in range(16):    key[i]^=(0x41+i)```check finalyze func to get iv```Csigned int __fastcall finalize_op(int *session, int paramtypes, TEEC_Parameter *params){  int v6; // r3  char iv[16]; // [sp+1Ch] [bp+8h]  int v10; // [sp+2Ch] [bp+18h]  int v12; // [sp+34h] [bp+20h]
  v12 = 101;  if ( paramtypes != 101 )    return 0xFFFF0006;  v10 = TEE_SetOperationKey(session[1], session[2]);  if ( v10 )  {    sub_5DA("finalize_op", 107, 1, 1, "TEE_SetOperationKey failed %x", v10);    if ( session[1] )      sub_340A(session[1]);    session[1] = 0;    if ( session[2] )      sub_111F6(session[2]);    session[2] = 0;    v6 = v10;  }  else  {    memset((int)iv, 0, 0x10);    sub_3CBA(session[1], iv, 0x10);    v6 = sub_4062(session[1], params->tmpref, params[1].tmpref, params[2].tmpref, &params[3].tmpref);  }  return v6;}```Now try decrypt with this key flag  ```Pythonfrom Crypto.Cipher import AES
flag=open("flag.enc","rb").read()key = list(b"SUPERSECRETSTRING"+b"\xad"*(32-17))for i in range(16):    key[i]^=(0x41+i)key_b=b""for i in key:    key_b+=i.to_bytes(1,"little")cipher = AES.new(key_b, AES.MODE_CBC, b"\x00"*16)cipher.decrypt(flag)>>> b'unictf{A4@1n_F1l3_ENCRYPTION}\n\x00\x00'```Decrypt private.enc```pythonprivate = open("Private.enc","rb").read()cipher = AES.new(key_b, AES.MODE_CBC, b"\x00"*16)private = cipher.decrypt(private)with open("private.der","wb") as f:    f.write(private)```And lets try to solve next task