히공

ShaktiCTF 2021 - fusk 본문

write up/ShaktiCTF 2021

ShaktiCTF 2021 - fusk

heegong 2021. 4. 5. 09:46
728x90

문제

 

 

 

 

__int64 __fastcall main(int a1, char **a2, char **a3)
{
  unsigned int v3; // eax
  int v5; // [rsp+8h] [rbp-C8h]
  int i; // [rsp+Ch] [rbp-C4h]
  int v7[32]; // [rsp+10h] [rbp-C0h] BYREF
  char s[40]; // [rsp+90h] [rbp-40h] BYREF
  unsigned __int64 v9; // [rsp+B8h] [rbp-18h]

  v9 = __readfsqword(0x28u);
  v5 = 3;
  fgets(s, 32, stdin);
  for ( i = 0; i < strlen(s); ++i )
  {
    v3 = v5++;
    v7[i] = ((__int64 (__fastcall *)(_QWORD))((char *)&sub_11A8 + 1))(v3) ^ s[i];
  }
  if ( (unsigned int)sub_11E9(v7) )
    puts("You Win");
  else
    puts("Try Again..!");
  return 0LL;
}

메인 함수

 

 

v7[i] = ((__int64 (__fastcall *)(_QWORD))((char *)&sub_11A8 + 1))(v3) ^ s[i];

이 부분에서 &sub_11A8 + 1를 알아내기 위해 ida 리모트 디버깅을 사용했다.

 

 

 

__int64 __fastcall main(int a1, char **a2, char **a3)
{
  int v3; // eax
  int v5; // [rsp+8h] [rbp-C8h]
  int i; // [rsp+Ch] [rbp-C4h]
  int v7[32]; // [rsp+10h] [rbp-C0h] BYREF
  char s[40]; // [rsp+90h] [rbp-40h] BYREF
  unsigned __int64 v9; // [rsp+B8h] [rbp-18h]

  v9 = __readfsqword(0x28u);
  v5 = 3;
  fgets(s, 32, stdin);
  for ( i = 0; i < strlen(s); ++i )
  {
    v3 = v5++;
    v7[i] = sub_561FD63331A9(v3) ^ s[i];
  }
  if ( (unsigned int)sub_561FD63331E9(v7) )
    puts("You Win");
  else
    puts("Try Again..!");
  return 0LL;
}

리모트 디버깅을 사용하고 나면 깔끔하게 바뀐다.

 

 

 

 

v7[i] = sub_561FD63331A9(v3) ^ s[i];

여기서 사용하는 함수를 분석했다.

 

 

 

__int64 __fastcall sub_561FD63331A9(int a1)
{
  int v2; // ebx

  if ( a1 <= 1 )
    return (unsigned int)a1;
  v2 = sub_561FD63331A9(a1 - 1);
  return v2 + (unsigned int)sub_561FD63331A9(a1 - 2);
}

재귀함수다.

 

 

 

 

if ( (unsigned int)sub_561FD63331E9(v7) )
	puts("You Win");
else
  puts("Try Again..!");
return 0LL;

그 후 if문에서 사용되어지는 함수를 분석했다.

 

 

 

 

__int64 __fastcall sub_561FD63331E9(__int64 a1)
{
  unsigned int v2; // [rsp+10h] [rbp-8h]
  signed int i; // [rsp+14h] [rbp-4h]

  v2 = 1;
  for ( i = 0; (unsigned int)i <= 30; ++i )
  {
    if ( unk_561FD6334020[i] != *(_DWORD *)(4LL * i + a1) )
      v2 = 0;
  }
  return v2;
}

for문을 돌면서 int형 배열의 각 요소와 비교한다.

 

 

 

 

dd 71h, 6Bh, 64h, 63h, 79h, 7Ch, 41h, 43h, 3Fh, 0EBh, 9Ah
.rodata:0000000000002020                                         ; DATA XREF: sub_11E9+29↑o
.rodata:0000000000002020                 dd 148h, 20Fh, 3ABh, 651h, 0A2Bh, 100Ah, 1A00h, 2AADh
.rodata:0000000000002020                 dd 4559h, 6F97h, 0B555h, 12524h, 1DA52h, 2FF23h, 4D944h
.rodata:0000000000002020                 dd 7D8DCh, 0CB218h, 148AB3h, 213D78h, 35C7E8h

int형 배열이다.

 

 

 

 

 

def sub_561FD63331A9(a1):                       # 선형으로 바꾸기
    a = [0,1]
    if (a1 < 2):
        return a[a1]
    for j in range(2, a1+1):
        a.append(a[j-1] + a[j-2])
    return a[len(a)-1]




dword_561FD6334020 = [
    0x71,
    0x6b,
    0x64,
    0x63,
    0x79,
    0x7c,
    0x41,
    0x43,
    0x3f,
    0xeb,
    0x9a,
    0x148, 
    0x20F, 
    0x3AB, 
    0x651, 
    0xA2B, 
    0x100A, 
    0x1A00, 
    0x2AAD,
    0x4559, 
    0x6F97, 
    0xB555, 
    0x12524, 
    0x1DA52, 
    0x2FF23, 
    0x4D944,
    0x7D8DC, 
    0xCB218, 
    0x148AB3, 
    0x213D78, 
    0x35C7E8
]


v5 = 3
flag = ''
for i in range(30):
    v3 = v5
    v5+=1
    v7 = sub_561FD63331A9(v3)
    flag += chr((v7^dword_561FD6334020[i])&0xff)

print(flag)

선형 알고리즘으로 변형 후 복호화 코드를 통해 구했다.

 

 

 

플래그 : shaktictf{s1mpl3_movfu5ca7i0n}

 

 

 

 

퍼블

 

 

 

플래그 : shaktictf{s1mpl3_movfu5ca7i0n}

'write up > ShaktiCTF 2021' 카테고리의 다른 글

ShaktiCTF 2021 - Chunkies  (0) 2021.04.05
ShaktiCTF 2021 - PacMat  (0) 2021.04.05
ShaktiCTF 2021 - BomB  (0) 2021.04.05
ShaktiCTF 2021 - deceev  (0) 2021.04.05
ShaktiCTF 2021 - hack  (0) 2021.04.05
Comments