2018 Dimi CTF Prequal mm

main에서는 그냥 입력받고 sub_85A 함수 호출 해주는데 이 함수에서 마지막에 비교해서 리턴 값이 1이면 Correct 틀리면 Wrong을 출력해준다.

_BOOL8 __fastcall sub_85A(const char *a1)
{
  int v1; // ST1C_4
  int i; // [rsp+14h] [rbp-21Ch]
  int v4; // [rsp+18h] [rbp-218h]
  __int16 s1[260]; // [rsp+20h] [rbp-210h]
  unsigned __int64 v6; // [rsp+228h] [rbp-8h]

  v6 = __readfsqword(0x28u);
  v4 = strlen(a1);
  memset(s1, 0, 0x200uLL);
  for ( i = 0; i < v4; ++i )
  {
    v1 = (unsigned __int16)rand();
    s1[i] = v1 * a1[i] % (v1 + 1);
  }
  return memcmp(s1, &unk_201020, 0x74uLL) == 0;
}

main에서 시드값을 6051로 설정해주었고 rand() 값들을 가져와서 연산해주고 미리 저장된 테이블과 비교해준다.

from ctypes import *

libc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')
libc.srand(6051)
table = [0xA8, 0x73, 0x0CC, 0x39, 0x0A, 0x4E, 0x85, 0x8D, 0x0F2, 0x0D1, 0x76, 0x77, 0x2E, 0x27, 0x31, 0x0AB, 0x34, 0x8F, 0x59, 0x46, 0x0AC, 0x0E7, 0x8, 0x0A3, 0x4D, 0x15, 0x9F, 0x7D, 0x23, 0x71, 0x0DB, 0x0F8, 0x0C4, 0x49, 0x0B8, 0x5B, 0x74, 0x22, 0x76, 0x0DD, 0x9D, 0x0C2, 0x48, 0x70, 0x0AE, 0x52, 0x61, 0x13, 0x8C, 0x0C9, 0x0A6, 0x73, 0x0A, 0x87, 0x70, 0x88, 0x8D, 0x74, 0x69, 0x6, 0x8F, 0x8C, 0x0A9, 0x0E8, 0x0B1, 0x40, 0x0BF, 0x0DA, 0x0C7, 0x76, 0x3D, 0x13, 0x0B2, 0x52, 0x59, 0x9E, 0x76, 0x0BE, 0x48, 0x0E2, 0x0DD, 0x0E4, 0x0C5, 0x0A6, 0x6E, 0x85, 0x0B7, 0x0FA, 0x65, 0x24, 0x0F7, 0x0F6, 0x1C, 0x0F4, 0x93, 0x6E, 0x5A, 0x53, 0x0DA, 0x16, 0x54, 0x4C, 0x6D, 0x16, 0x0A4, 0x87, 0x0F, 0x9F, 0x0DD, 0x29, 0x0A3, 0x51, 0x27, 0x13, 0x3A, 0x0B1]
flag = ""
for i in range(0,len(table),2):
	tmp = libc.rand()
	for j in range(256):
		if (tmp * j % (tmp+1)) & 0xff == table[i]:
			flag += chr(j)
			break
print flag

FLAG : dimi{ca1cul4t3d_inv3rs3?_0r_us3d_z3?_0h_y0u_ar3_4_F0Ol_;)}