32C3 CTF - ey_or

We have a large (24MB) x86_64 ELF executable. It’s very difficult to reverse engineer this size. Instead, one of the printable strings looked interesting.

$ strings ey_or
    (...)
] ==secret
] ==f
 secret len ==l
 [ ] ==buffer
 0 ==i
 0 ==j
 "Enter Password line by line\n" sys .out .writeall
  #str .fromArray secret bxor
  txt .consume .u
  =j
[ buffer _ len dearray j ] =buffer
[ secret _ len dearray j eq { } { 1 sys .exit } ? * ] =secret
  i 1 add =i
  i l eq {
  buffer f bxor str .fromArray sys .out .writeall
 0 sys .exit
} { } ? *
} sys .in .eachLine
"ey_or" sys .freeze

There are many more strings look like this, but this is the longest one. This should be the actual code of this program. After some google, we’ve found that it’s in Elymas language. According to its documentation, it does something like this:

secret = [ ???? ]
f = [ ???? ]
l = len(secret)
buffer = []
i = 0
j = 0
print "Enter Password line by line"
for line in sys.stdin.readlines():
    j = read_int(line)
    buffer = buffer + [j]
    if secret[i] != j:
        sys.exit(1)
    i += 1
    if i == l:
        print to_string(map(lambda x,y: x^y, buffer, f))
        sys.exit(0)

Using the exit code, we can brute force the secret byte by byte. Here’s the solver:

import sys
import subprocess

ans = []
while True:
    for j in range(256):
        if j % 16 == 15:
            print j
        p = subprocess.Popen("./ey_or.elf", stdin=subprocess.PIPE, stdout=subprocess.PIPE)
        for x in ans:
            p.stdin.write(str(x) + '\n')
        p.stdin.write(str(j) + '\n')
        p.stdin.close()
        ret = p.wait()
        if ret != 1:
            ans.append(j)
            print ans
            break

Running for few minutes, we have the correct input sequence.

[36, 30, 156, 30, 43, 6, 116, 22, 211, 66, 151, 89, 36, 82, 254, 81, 182, 134, 24, 90, 119, 6, 88, 137, 64, 197, 251, 15, 116, 220, 161, 94, 154, 252, 139, 11, 41, 215, 27, 158, 143, 140, 54, 189, 146, 48, 167, 56, 84, 226, 15, 188, 126, 24]

Entering these to the program gives us the flag 32C3_wE_kNoW_EvErYbOdY_LiKeS_eLyMaS

Other posts (list)


안드로이드 앱 패킷 캡쳐하기
32C3 CTF - blobberry
32C3 CTF - ey_or
32C3 CTF - gurke
Regex Crossword Solver with Z3