Tools to use

  • IDA

Summary

I think this is a interesting challenge. It is not too hard, but also not easy to solve. It requires calm :v

We need to connect server. solve file which it required and response ans. After 10times, we will have flag. (In fact, i communicated with server until it sent me flag :)))

Let’s solve it…

Solution

This challenge confused me by a lot of files – 3000 files @@. I spent 10mins throwing some of them to IDA. I found that all of them have same format

  • One input way: Type in something
  • One check function: Compare with given info
IDA source
  • One way output: Print something ( Correct or not)

It will be too easy challenge unless having 3000 files. Therefore, we decided to find similar points of them.

In check function, each file has a different char and different compare range

Check function of 1.bin

And a const array to check some of last bytes

&unk_2008 is const array and 4u is number of bytes will be compared.

Base on above analysis, we know what we need:

  • find number of first chars
  • find first char
  • find number of elements in const array
  • find const array

To make it simple, we should use hexview of IDA to see thier offset.

offset of first char

Because x86 and x64 have different offset, we have

  • number of first chars : offset 0x661 in x86 and 0x819 in x64
  • first char: offset 0x668 in x86 and 0x821 in x64
  • number of elements in const array: offset 0x6AA in x86 and 0x869 in x64
  • const array: offset 0x1008 in x86 and 0x1010 in x64

I wrote a python program connect server to pass this challenge

from pwn import * 
from pybase64 import *

baseLen = 0
lenSpecChar = 0
adrSpecChar = 0
c = 0

def makeBaseList(c, baseLen):
    for i in range(0, baseLen):
        arr.append(chr(c))

def detectMachineAndAns(target):
    f = open(target, 'rb')
    f.read(4)
    machine = f.read(1)
    f.close()
    if(ord(machine) == 1): #x86
        f = open(target, 'rb')
        f.read(0x661)
        baseLen = f.read(1)
        #print ord(baseLen)
        f.read(6)
        c = f.read(1)
        #print c
        makeBaseList(ord(c), ord(baseLen))
        f.read(65)
        lenSpecChar = f.read(1)
        print hex(ord(lenSpecChar))
        f.read(0x95D)
        #c = f.read(1)
        for i in range(0, ord(lenSpecChar)):
            c = f.read(1)
            arr.append(chr(ord(c)))

        f.close()
    else:
        f = open(target, 'rb')
        f.read(0x819)
        baseLen = f.read(1)
        print ord(baseLen)
        f.read(6)
        c = f.read(1)
        print c
        makeBaseList(ord(c), ord(baseLen))
        f.read(72)
        lenSpecChar = f.read(1)
        print hex(ord(lenSpecChar))
        f.read(0x7A6)
        #c = f.read(1)
        for i in range(0, ord(lenSpecChar)):
            c = f.read(1)
            arr.append(chr(ord(c)))

        f.close()

if __name__ == "__main__":
    sh = remote("re.ctf.nullcon.net", 1234)
    while(True):
        arr = []
        ans = ''
        target = sh.recvuntil("\n").strip()
        #print sh.recv()
        print target
        if len(target) > 9:
            break
        detectMachineAndAns(target)


        print arr
        ans = ''.join(arr)
	    #print ans
        sh.sendline(b64encode(ans))
        print sh.recvline()
       

I must encodebase64 answer because server require that.

After connect i got flag