[HackCTF] static 풀이 (250p)
Wargame/HackCTF

[HackCTF] static 풀이 (250p)

문제 종류 - Reversing
사용한 툴 - Ghidra

 

풀이

로직 해석하는데 엄청 오랜시간이 걸렸다...

IDA에 넣었으나, 제대로된 로직이 뜨지 않는 관계로 Ghidra에 넣어봤다.

String을 검색해봤는데, ELF를 실행하면 나오는 Nope. 문자열이 검색되었다. 해당 로직으로 이동해보자.

해당 부분 슈도코드이다.

undefined8 FUN_00100a3a(int param_1,long param_2)

{
  int iVar1;
  char *__s1;
  
  __s1 = getenv("team_name");
  if ((__s1 == (char *)0x0) || (iVar1 = strncmp(__s1,"bi0s",4), iVar1 != 0)) {
    printf("Nope.");
  }
  else {
    if (param_1 == 2) {
      iVar1 = FUN_0010087c(__s1,*(undefined8 *)(param_2 + 8),*(undefined8 *)(param_2 + 8));
      if (iVar1 == 1) {
        FUN_00100830(*(undefined8 *)(param_2 + 8));
      }
      else {
        printf("Better luck next time!");
      }
    }
    else {
      printf("usage: chall <input>");
    }
  }
  return 0;
}

getenv로 team_name이 bi0s인지 검사하고, if문을 실행한다.

if문은 인자의 개수를 검사하고, FUN_0010087c 함수를 통과해 flag를 출력하는 방식이다.

FUN_0010087c 함수로 이동해보자. 다음은 함수의 슈도코드이다.

undefined8 FUN_0010087c(char *param_1,char *param_2)

{
  size_t sVar1;
  ulong uVar2;
  char *local_70;
  byte local_68 [32];
  undefined8 local_48;
  undefined8 local_40;
  undefined4 local_38;
  undefined2 local_34;
  undefined local_32;
  undefined4 local_30;
  undefined4 local_28;
  uint local_24;
  int local_20;
  int local_1c;
  
  local_20 = 0;
  local_24 = 0;
  local_48 = 0x3931383137313631; //local_34 + local_38 + local_40 + local_48 = 4919197161836291817161 (Little Endian)
  local_40 = 0x3731363138333632;
  local_38 = 0x31393139;
  local_34 = 0x3439;
  local_32 = 0;
  local_70 = param_1;
  sVar1 = strlen(param_2);
  if (sVar1 == 0x16) {
    local_1c = 0;
    while (uVar2 = SEXT48(local_1c), sVar1 = strlen(local_70), uVar2 < sVar1) { //local_20 값 구하기
      local_20 = local_20 + local_70[local_1c];
      local_1c = local_1c + 1;
    }
    local_30 = 0;
    local_20 = local_20 / 0x1e; //12
    while (local_24 != 0x16) {
      if ((local_24 & 1) == 0) { //짝, 홀수 로직
        local_68[(int)local_24] = param_2[(int)local_24] + 4;
      }
      else {
        local_68[(int)local_24] = param_2[(int)local_24] - 4;
      }
      local_68[(int)local_24] = local_68[(int)local_24] ^ (byte)local_20; //Key값 도출 부분 XOR 연산 수행
      local_24 = local_24 + 1;
    }
    local_28 = 0;
    sVar1 = strlen((char *)local_68);
    local_1c = (int)sVar1;
    do {
      local_1c = local_1c + -1;
      if (local_1c < 0) {
        return 1;
      }
      sVar1 = strlen((char *)local_68);
    } while (*(char *)((long)&local_70 + (sVar1 - (long)local_1c) + 7) ==
             *(char *)((long)&local_48 + (long)local_1c));
  }
  return 0;
}

다음은 알아보기 쉽게 C로 대충 변환한 코드이다.

#include <stdio.h>
int main() {
	char local_70[5] = "bi0s";
	char param_2[23] = "4919197161836291817161";
	char local_68[32] = "";
	int sVar1 = 22;
	int local_1c;
	int local_20;
	int local_24;
	int local_30;
	unsigned long uVar2;

	local_20 = 0;

	if (sVar1 == 22) {
		local_1c = 0;
		for (uVar2 = 0; uVar2 < 4; uVar2++)
			local_20 = local_20 + local_70[uVar2];
	}
	local_30 = 0;
	local_20 = local_20 / 30;

	for (local_24 = 0; local_24 != 22; local_24++) {
		if ((local_24 & 1) == 0) { 
			local_68[local_24] = param_2[local_24] + 4;
		}
		else {
			local_68[local_24] = param_2[local_24] - 4;
		}
		local_68[local_24] = local_68[local_24] ^ local_20;
	}
}

먼저 Key값을 찾아내자. Key값은 4919197161836291817161 와 12를 XOR 연산하면 나온다.

Key = 85=5=5;=:=4?:>5=4=;=:=

이제 구한 Key를 갖고, flag 값을 찾아보자.

param_2 = '85=5=5;=:=4?:>5=4=;=:='
local_68 = []

for local_24 in range(0,22):
	if local_24 & 1 == 0:
		local_68.append(ord(param_2[local_24]) - 4)
	else:
		local_68.append(ord(param_2[local_24]) + 4)

for i in range(0,22):
	print(chr(local_68[i]), end='')

'Wargame > HackCTF' 카테고리의 다른 글

[HackCTF] Basic_BOF #2 풀이 (100p)  (0) 2020.07.14
[HackCTF] Basic_BOF #1 풀이 (100p)  (0) 2020.07.14
[HackCTF] Keygen 풀이 (200p)  (0) 2020.07.12
[HackCTF] Strncmp 풀이 (150p)  (0) 2020.07.12
[HackCTF] Handray 풀이 (100p)  (0) 2020.07.12