→ BaltCTF NA300

| 3 Comments | No TrackBacks
We got a file called PPC300 and told to get 10000 points. File is a "Snake" video game written in Python and packet to exe using py2exe. Ofcourse you can play a game for fun and get a flag(or, oops - you can't, read ahead), but that's a good case for imporoving your Python bytecode reversing skills.
First, we extract bytecode from exe using py2exe extract.
Then try to disassemble it using dis, not so readable, but we can see the constants:
'Snake   Score:%s'    #caption template
100                   #points, incremented per eaten food
2000                  #speed tick increment
First idea was to patch a points incrementor constant and get a flag, it didn't work.
I decided to decompile bytecode to a human readable form, tried Uncompyle, then Decompyle with my patch, both didn't work, but decompilation errors were in different places.
I fixed the decompyle using some parser code pieces from Uncompyle and my patch (decompyle.patch) and got a readable source code (snake.p_).
As we can see - flag is generated from "fps" value, not from points. But the original source code has a mistake and you can't get a flag even if you get enough points: "f" is called with 1 parameter, but requires 2:
def f(fps, control):
    x = ((dumps(color) + dumps(control)) + dumps(fontsize))
    t = ''
    for i in x:
        t += hex((ord(i) ^ fps))[2:]

    return t

...
while mainloop:
...
    tickFPS = Clock.tick(fps)
    if (fps >= 101):
        pygame.display.set_caption(f(fps))
        screen.fill((0, 0, 0))
        tickFPS = Clock.tick(2000)

I made a script for flag generation and reported the mistake to authors.
from cPickle import dumps

color = (32, 32, 32)
fontsize = 35
fps = 1
control = 251

def f(fps, control):
    x = ((dumps(color) + dumps(control)) + dumps(fontsize))
    t = ''
    for i in x:
        t += hex((ord(i) ^ fps))[2:]

    return t


if __name__ == '__main__':
    while True:
        fps += 1
        control -= 1
        if (fps >= 101):
            print f(fps, control)
            break
Flag: 4d2c56576f2c56576f2c56576f1115546f4b2c5450546f4b2c56506f4b

No TrackBacks

TrackBack URL: http://smokedchicken.org/m/mt-tb.cgi/81

3 Comments

Well done :)
Although it looks outdated, www.depython.net successfully (and strangely) decompiles pyc file.

yea, certainly more fun, but I was wondering why an old (~5years) service handles that shit better than Uncompyle *_*

About this Entry

This page contains a single entry by kyprizel published on May 21, 2012 6:41 PM.

IDA: rename locals from a script was the previous entry in this blog.

PHDays CTF quals 2013, Real World 500 is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.