Write-up/Wargame

[Dreamhack wargame] rev-basic-3

da1seun9 2023. 9. 4. 23:24

문제

image

분석

프로그램 실행

image

프로그램을 받아서 실행했더니, 바로 종료된다.

ida pro

image

ida pro를 이용해서 파일을 보자.

나는 프로그램을 실행했을 때, 나타나는 문자열을 검색해서 해당 부분의 코드들을 볼 것이다.

[shift + f12]를 사용해서 문자열 검색을 해보자.

image

"Input:"이 보인다. 더블클릭해서 들어가보자.

image

여기서 Input: 부분을 누르고, 해당 문자열을 참조하는 코드를 보고 싶으므로 [x]키를 눌러보자

image

들어간다.

image

[f5]을 누르면 어셈블리어가 C언어로 보기 쉽게 바뀐다.

image

코드분석: sub_140001120()
__int64 sub_140001120()
{
  char v1; // [rsp+20h] [rbp-118h]

  memset(&v1, 0, 0x100ui64);
  sub_1400011B0("Input : ");
  sub_140001210("%256s", &v1);
  if ( (unsigned int)sub_140001000(&v1) )
    puts("Correct");
  else
    puts("Wrong");
  return 0i64;
}

sub_140001120 함수의 작동방식은 다음과 같다.

  1. v1 문자형 변수를 선언한다.
  2. memset 함수를 통해 변수를 초기화한다. (v1변수를 0으로 0x100만큼 초기화)
  3. 이후 sub_1400011B0 (= printf)를 통해 "Input : "를 출력한다.
    sub_140001210 (= scanf)에서 256바이트만큼의 string을 받아 v1에 넣는다.
  4. if 분기문을 사용해서 sub_140001000 함수가 참일 시 "Correct"이 아닐 시 "Wrong" 이 뜨게 한다.

그렇다면 우리는 sub_140001000함수가 무엇인지 알아볼 필요가 있다.
더블클릭해서 함수를 자세히 보자

코드분석: 함수 sub_140001000()
signed __int64 __fastcall sub_140001000(__int64 a1)
{
  int i; // [rsp+0h] [rbp-18h]

  for ( i = 0; (unsigned __int64)i < 0x18; ++i )
  {
    if ( byte_140003000[i] != (i ^ *(unsigned __int8 *)(a1 + i)) + 2 * i )
      return 0i64;
  }
  return 1i64;
}

  1. int i를 선언한다.

  2. i=0인 상태에서 i가 0x18까지 i를 증가시킬 때까지, for 반복문 안의 if분기문을 돌린다.

  3. byte_140003000[i] != (i^(*a1+i)의 값)+2의 수식으로 나타낼 수 있다. 풀이하자면 i xor a1[i] +2를 뜻하는 것이다.

    ※ *(a1+i) == a1[i] == v1[i] == *(v1+i) 이다.

XOR은 특이한 연산자이다.

A ^ B = C

C ^ B = A

C ^ A = B

위 식에서 A와 C를 알고 있을 때, B를 구하기 위해서는 A와 C를 XOR 연산을 하면 된다.

즉, 위 식은 x != i ^ y+2 이라 할 때(x = Byte_140003000[i], y= a1[i]),

y = (x-2) ^ i 방정식이 성립된다는 것으로 해결 할 수 있다.

그렇다면, byte_140003000[i]에 문자열이 들어가 있고, 이것을 XOR 연산을 통해 특정 문자열을 꺼낸다고 가정할 수 있다.

그렇게 완성된 것이 Flag 일 것이다.

한번 보자.

image

역시나 byte_140003000[32]로서 16진수로 아스키 문자들이 들어가 있는 것을 알 수 있다.

코드로 풀자.

풀이

#!/usr/bin/env python3
asc=[0x49,0x60,0x67,0x74,0x63,0x67,0x42,0x66,0x80,0x78,0x69,0x69,0x7B,0x99,0x6D,0x88,0x68,0x94,0x9F,0x8D,0x4D,0xA5,0x9D,0x45]
arr=[(asc[i] - (2 * i))^i for i in range(0,len(asc))]

for i in range(0,len(arr)):
    asc[i]=chr(arr[i])
flag=''.join(asc)
print(flag)

image

끝.

'Write-up > Wargame' 카테고리의 다른 글

[pwnable.kr] fd  (0) 2023.11.12
[Dreamhack wargame] rev-basic-4  (1) 2023.11.12
[Dreamhack wargame] Quiz: x86 Assembly 2 풀이  (0) 2022.09.25
[Dreamhack wargame] Quiz: x86 Assembly 1 풀이  (2) 2022.09.25
Abex's Crackme #4  (1) 2021.04.27