콘텐츠로 건너뛰기

ez_rev

문제 설명

함수가 너무 많아요…! 해결해주세요!

Decompiled-src

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char v3; // cl
  int v4; // edx
  int v5; // ecx
  int v6; // r8d
  int v7; // r9d
  bool v8; // cf
  bool v9; // zf
  int v10; // edx
  __int64 v11; // rcx
  const char *v12; // rsi
  char *v13; // rdi
  char _0[40]; // [rsp+0h] [rbp+0h] BYREF
  unsigned __int64 vars28; // [rsp+28h] [rbp+28h]

  vars28 = __readfsqword(0x28u);
  _printf_chk(1, (unsigned int)"Input: ", (_DWORD)envp, v3);
  _isoc99_scanf((unsigned int)"%26s", (unsigned int)_0, v4, v5, v6, v7, _0[0]);
  shift_right(_0, 3LL);
  xor_with_key(_0, off_4E50F0);
  shift_left(_0, 3LL);
  xor_with_key(_0, off_4E50F0);
  shift_right(_0, 3LL);
  v11 = 26LL;
  v12 = "|l|GHyRrsfwxmsIrietznhIhj";
  v13 = _0;
  do
  {
    if ( !v11 )
      break;
    v8 = (unsigned int)*v12 < (unsigned __int8)*v13;
    v9 = *v12++ == (unsigned __int8)*v13++;
    --v11;
  }
  while ( v9 );
  if ( (!v8 && !v9) == v8 )
    _printf_chk(1, (unsigned int)"Correct!", v10, v11);
  else
    _printf_chk(1, (unsigned int)"KKKKKKKKKKKKK", v10, v11);
  return 0;
}

Anlaysis

시험삼아 Input에다가 ABCDEFG~Z까지 26자리 문자열을 입력해보았다.
하나씩 함수가 어떻게 처리되는지 살펴보자.

shift_right(_0, 3LL);

rbp 값을 확인해보면 함수가 수행된 이후에는
XYZABCD~W로 3만큼 오른쪽 회전되었다.

xor_with_key(_0, off_4E50F0);

.data:00000000004E50F0 off_4E50F0      dq offset aQksrkqs      ; DATA XREF: main+4B↑r
.data:00000000004E50F0                                         ; main+67↑r
.data:00000000004E50F0                                         ; "qksrkqs"

__int64 __fastcall xor_with_key(__int64 a1, __int64 a2)
{
  int v3; // r12d
  __int64 result; // rax
  int v5; // esi
  __int64 v6; // rcx

  v3 = ((__int64 (*)(void))j_strlen_ifunc)();
  result = j_strlen_ifunc(a2);
  if ( v3 > 0 )
  {
    v5 = result;
    v6 = 0LL;
    do
    {
      *(_BYTE *)(a1 + v6) ^= *(_BYTE *)(a2 + (int)v6 % v5);
      result = v6++;
    }
    while ( result != v3 - 1 );
  }
  return result;
}

rbp 값을 확인해보면 이번에는 “qksrkqs” 문자열과 함께 XOR을 수행한다.
XYZABCD~W로

지금까지 한 과정을 파이썬3 코드로 나타내면 다음과 같다.

def shift_right(my_str, n):
    return my_str[len(my_str)-n:] + my_str[0:len(my_str)-n]
    
def xor_with_key(my_str, key):
    xored_str = list(my_str)
    for i in range(len(my_str)):
        xored_str[i] = chr((xored_str[i] ^ (key[i % len(key)])) & 0xff)
    xored_str = ''.join(xored_str).encode('utf-8')
    return xored_str

off_4E50F0 = b'qksrkqs'

my_input = b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
my_input = shift_right(my_input, 3)
my_input = xor_with_key(my_input, off_4E50F0)

print(my_input)

#Output
#b')2)3)274-4:";8=&==; !"?&$<'

그 외 남은 함수들과 수행 과정을 살펴보면,

shift_left(_0, 3LL);
왼쪽으로 문자열을 3만큼 회전

xor_with_key(_0, off_4E50F0);
“qksrkqs” 문자열과 함께 한번 더 XOR을 수행

shift_right(_0, 3LL);
오른쪽으로 문자열을 3만큼 회전

그렇게 수행을 마친 문자열이 v12인 “|l|GHyRrsfwxmsIrietznhIhj”과 같으면 “Correct” 문자열을 띄울 것이다.

Solution

지금까지 했던 과정을 역으로 하면 된다.

shift_right를 했다면, shift_left
xor을 했다면, 한번더 xor,
shift_left를 했다면, shift_right를 하면 된다

from pwn import *
context.log_level = 'debug'
context(arch='amd64', os='linux')
warnings.filterwarnings('ignore')

p = process('./prob')

off_4E50F0 = b'qksrkqs'
v12 = b'|l|GHyRrsfwxmsIrietznhIhj'

def shift_right(my_str, n):
    return my_str[len(my_str)-n:] + my_str[0:len(my_str)-n] 

def shift_left(my_str, n):
    return my_str[n:] + my_str[0:n] 

def xor_with_key(my_str, key):
    xored_str = list(my_str)
    for i in range(len(my_str)):
        xored_str[i] = chr((xored_str[i] ^ (key[i % len(key)])) & 0xff)
    xored_str = ''.join(xored_str).encode('utf-8')
    return xored_str

# decrypt
v12 = shift_left(v12, 3)
v12 = xor_with_key(v12, off_4E50F0)
v12 = shift_right(v12, 3)
v12 = xor_with_key(v12, off_4E50F0)
v12 = shift_left(v12, 3)
print(v12)

p.sendline(v12)

p.interactive()

FLAG

DH{ShiftxorShiftxorShift}

태그:

답글 남기기