I looked at the sourcecode for bowie.pl and found a bunch of input requests and string match checks. The answers were generally yes or no. Response is "You're doing a thing" until the final run. After each correct answer, a portion of a gif was decoded from base64 and stored to a variable. Here's a code snippet showing a test for a "no" response:
print "You're doing a thing...\n";
my $input = <STDIN>;
$input = trim($input);
if ($input eq ("\x6E" . chr(4423 - 4312))) {
After several rounds, there's another base64 string that contains more script code. These have to be decoded in order to retrieve the entire list of tests that will get one to the flag.
So, what I want to do is capture all the cleartext if statements down to the base64 string with more script (marked by "eval"), decode it, capture the if ($input ) line, isolate the base64 string after eval MIME::Base64::decode(" down to "); and do it again. I'm going to write a program to decode and reassemble the important lines of the entire program (if or eval), modify it so the answers are supplied at runtime, and see what happens. Luckily all the lines I needed to work on had a common format, so simple tests and stripping of characters sufficed. I am most comfortable in Python, so I translated the perl strings in the if statements into Python form and ran the eval on the new string. To make the iterate function generic, I read the entire file into a variable as a single string, then broke it up based on occurrences of newline. This way, the same logic would apply whether it was the initial file read or a decode of the base64 string. It's written in Python 2.7. If using Python 3, I would have to import base64 and call the decode function differently
Here's the code:
#!/usr/bin/python
# recursively work through the many rounds of base64 encoding
def iterate(a):
iNl = a.find('\n')
iStart = 0
while iNl != -1:
line = a[iStart:iNl]
iStart = iNl+1
iNl = a.find('\n',iStart)
if line.find('if (') != -1:
line = line.strip()+'\n'
line = line[line.find('eq (')+3:len(line)-4]
line = line.replace('.','+')
print eval(line)
else:
if line.find('eval') != -1:
b64start = line.find('(') + 1
b64end = line.find(')')
iterate(line[b64start:b64end].decode('base64'))
fIn = open("bowie.pl")
a = fIn.read()
iterate(a)
fIn.close()
Ran the program and got response:
./decode_bowie.py |perl bowie.pl
You're doing a thing...
You're doing a thing...
You're doing a thing...
You're doing a thing...
... (a bunch more of these were removed)
You're doing a thing...
You're doing a thing...
You're doing a thing...
You did a thing!
ls -l *.gif
-rw-r--r-- 1 john john 110403 Aug 19 11:02 entrevue.gif
A gif (entrevue.gif) was created giving the password: PAN{L3ts_533_h0W_U_deal_w_th1s_little_511CE}