I worked on this one up until close to the time the competition closed. I learned so much new stuff - new programming environment, new debuggers and tools, new languages that were compiled and such that my brain was mush. I did get to a little bit of valuable info, and will revisit to complete, I hope. Here's the only really relevant data I managed to obtain:
RedDelicious.app
Took a look at strings and theres a bunch that goes on with sub_100001ee0 involving the base64 string, abracadabra and such.
100002b90 is an important procedure where the first test is done. It takes two arguments
I did a test with the string 0123456789ABCDEF, figured out some logic and broke at 100002c7d and 100002d00 to catch the values in eax. Here's what I got:
Looking at C-strings in Hopper:
"LyY8TiwwJighJzRSNycvJyU3LzQ1GTc0JlA2ACcGBTcuUSc3JBkZLSoaS1EzUwotBwsDDTQbEiY3Mw0SNDcZVjcLKywjCTpKPApWTw=="
which decodes as:
"/&<N,0&(!'4R7'/'%7/45\x1974&P6\x00'\x06\x057.Q'7$\x19\x19-*\x1aKQ3S\n-\x07\x0b\x03\r4\x1b\x12&73\r\x1247\x19V7\x0b+,#\t:J<\nVO"
"av9vex8pocs4id2"
"abracadabra"
Running the code in Hopper, found a bit of interesting stuff:
procedure sub_100002b90:
arg0 (stored in r14 for this procedure) is my entered string, base64 encoded
>>> '4d4445794d7a51314e6a63344f5546435130524652673d3d'.decode('hex')
'MDEyMzQ1Njc4OUFCQ0RFRg=='
>>> 'MDEyMzQ1Njc4OUFCQ0RFRg=='.decode('base64')
'0123456789ABCDEF'
arg1 (stored in r12 for this procedure) looks like it will be a mask
>>> '61763276657838706f63733469643261763976657838706f'.decode('hex')
'av2vex8pocs4id2av9vex8po' av9vex8pocs4id2
>>>
Another round occurs, and here's the result.
arg0
>>> '4c444a384479674361554568435241414a6a46304969634a4a434d7158303153'.decode('hex')
'LDJ8DygCaUEhCRAAJjF0IicJJCMqX01S'
>>> 'LDJ8DygCaUEhCRAAJjF0IicJJCMqX01S'.decode('base64')
',2|\x0f(\x02iA!\t\x10\x00&1t"\'\t$#*_MR'
arg1
>>> '6162726263616462637261616272626361646162726161627261636164616272'.decode('hex')
'abrbcadbcraabrbcadabraabracadabr' abrbcadbcra
So, it looks likely that there's going to be an XOR against abracadabra and the av2vex8pocs4id2 keys. Trouble is, I kept trying to run code in the debugger instead of experimenting with the data I already had. I worked way too hard trying to get to
0000000100002ca9 call sub_1000045c0 or
0000000100002cbb call sub_1000045c0
Brain fries here :( Cried uncle, only 1 hour left.
What I should have done was realize that I was beating my head against a wall, stop doing that and try another method. I knew I had a base64 string and two keys. I knew I couldn't see a way of getting to those lines: I figured out the conditions required and it didn't look possible, but I kept trying. Yet I persisted on the failing path until I couldn't think any more.
--------------------------
Update:
I was so close! I knew it was going to be a couple of xors, had the keys and the string to work on. 10 minutes with a clear head:
#!/usr/bin/python
def xorstrings(sIn,sXor):
# This expects two strings and xors each of the longer string (sIn) with a rotating key (sXor)
sOut = ''
for i in range(0,len(sIn)):
sOut += (chr(ord(sIn[i])^ord(sXor[i%len(sXor)])))
return sOut
a = 'LyY8TiwwJighJzRSNycvJyU3LzQ1GTc0JlA2ACcGBTcuUSc3JBkZLSoaS1EzUwotBwsDDTQbEiY3Mw0SNDcZVjcLKywjCTpKPApWTw=='.decode('base64')
k1 = 'abracadabra'
k2 = 'av9vex8pocs4id2'
b = xorstrings(a,k1)
c = xorstrings(b.decode('base64'),k2)
print c.decode('base64')
--------------
./final.py
PAN{My_m0th3r_told_m3_2b3_w4ry_of_F@uns}