XNUCA-2019,Wonderful but crazy challenges…

[TOC]

XNUCA_2019_bin_record

What a difficult and high quality game.😭

I Get Zero Flag! Teammate tql orz.

Clever_Bird

This Challenge’s attachment is an exe format file. You can see following dos game after runing Clever Bird.exe.

Apparently,you can get flag in two ways:

1.High Scores

2.Crack The Game

I choose analyse it by IDA Pro and X64dbg

Firstly,Program has a key point compare at .text:011F1DCA,only when this compare is true,can you get into the segment contains flag.

Here is a python script to get correct score.

import ctypes
def h2f(s):
    cp = ctypes.pointer(ctypes.c_int(s))
    fp = ctypes.cast(cp, ctypes.POINTER(ctypes.c_float))
    return fp.contents.value
def f2h(s):
    fp = ctypes.pointer(ctypes.c_float(s))
    cp = ctypes.cast(fp, ctypes.POINTER(ctypes.c_int))
    return cp.contents.value
if __name__=='__main__':
    X=0
    score=0
    while(int(((1.5-h2f(X)*h2f(X)*(score/2))*h2f(X)*100000000*10+5)/10)!=0x436AE):
        score+=1
        X=0x5F3759D8 - (f2h(score)>>1)
        if X!=0:
            X+=7
    print score

Then you will get the score:

# v12 == score
if ( v12 )
    {
      v16 = &v37;
      while ( 1 )
      {
        v17 = *v16++;
        if ( v17 != v12 % 2 + '0' )
          break;
        v12 /= 2;
        if ( !v12 )
          goto LABEL_20;
      }
    }


It still has a role to play after the compare:

In [33]: li =[]
    ...: score = 0x20002
    ...: while(1):
    ...:     bit = chr(score%2+ord('0'))
    ...:     li.append(bit)
    ...:     #print(score)
    ...:     score = score>>1
    ...:     if(score==0):
    ...:         break
    ...: 

In [34]: ''.join(li)
Out[34]: '010000000000000001'

The lastest key func:

      v18 = 0;
      v19 = 0;
      while ( *(&ConsoleCursorInfo[0].dwSize + v18) == ((unsigned __int8)(v11 >> v19) ^ (Dst[v18] - 48)) )
      {
        v19 += 8;
        ++v18;
        if ( v19 >= 32 )
        {
          v20 = sub_11F23E0(std::cout, (int)"congratulation,submit with format: flag{key}");
          std::basic_ostream<char,std::char_traits<char>>::operator<<(v20, sub_11F2620);
          sub_11F1F40(&Src);
          goto LABEL_27;
        }
      }

among this function,v11 is appearing before cmp edi, 436AEh , and you can get its value by Dynamic Commissioning. The values in *(&ConsoleCursorInfo[0].dwSize + v18) also similarly available.

v11:

*(&ConsoleCursorInfo[0].dwSize + v18):

Get Your flag:

if __name__=='__main__':
    key=0xA991E504
    b=[0x16,0xe4,0xb3,0xbd]
    out=''
    for i in range(len(b)):
        out+=chr((b[i]^((key>>(i*8))%0x100))+0x30)
    print out
#B1RD

Concat the B1RD with 010000000000000001.

flag{B1RD010000000000000001}

ooollvm

This program is compiled with llvm…I think it is sick for me. Official solution:

IDA Pro is not fit this challenge. I used the GUI version of radare2 named cutter:

As you can see, it is crazy. Once you want to do something like Viewing pseudocode,the tool will crash. So you only have one choice——Dynamic Commissioning.

Usually we use angr to solve this kind of challenge…So i’m glad to learn angr.

#Symbol execution
https://github.com/angr/angr-doc
https://github.com/angr/angr
https://xz.aliyun.com/t/3990
https://docs.angr.io/

damnV

Official solution: