Snake¶
This one is an interesting one. It's a file snake.py, as the extension
suggests, written in python. So it should be pretty easy. Or is it? I will find out.
We are looking for a token that looks like HTB{username:password}, so I
suppose we have to find both the username and the password separately.
The file looks like this.
#!/usr/bin/python2.7 import random lr = '\x64' print ''' ___________.__ _________ __ \__ ___/| |__ ____ / _____/ ____ _____ | | __ ____ | | | | \_/ __ \ \_____ \ / \\__ \ | |/ // __ \ | | | Y \ ___/ / \ | \/ __ \| <\ ___/ |____| |___| /\___ > /_______ /___| (____ /__|_ \\___ > \/ \/ \/ \/ \/ \/ \/ ''' chains = [0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x74, 0x72, 0x6f, 0x6c, 0x6c] db = '\x6e' ef = '\x63' chars = [] keys = [0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x21, 0x21] nn = '\x61' lock_pick = random.randint(0, 0x3e8) lock = lock_pick * 2 password = [0x69, 0x74, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x65, 0x61, 0x73, 0x79] lock = lock + 10 ty = '\x61' lock = lock / 2 auth = [0x6b, 0x65, 0x65, 0x70, 0x20, 0x74, 0x72, 0x79, 0x69, 0x6e, 0x67] lock = lock - lock_pick gh = '\x6e' print 'The Snake Created by 3XPL017' print 'Your number is ' + str(lock_pick) for key in keys: keys_encrypt = lock ^ key chars.append(keys_encrypt) for chain in chains: chains_encrypt = chain + 0xA chars.append(chains_encrypt) aa = '\x61' rr = '\x6f' slither = aa + db + nn + ef + rr + gh + lr + ty print 'Authentication required' print '' user_input = raw_input('Enter your username\n') if user_input == slither: pass else: print 'Wrong username try harder' exit() pass_input = raw_input('Enter your password\n') for passes in pass_input: for char in chars: if passes == str(chr(char)): print 'Good Job' break else: print 'Wrong password try harder' exit(0) break
There's a lot of noise going on in here. The first thing to take a look at is
the username, which looks like it'll be easy to deobfuscate. The user_input
is compared to the variable slither, which is composed of aa and db and
so on. What I do next is I make a copy of this python script called
snake_user.py containing only the variables relevant, and then I add a print
statement for the slither variable. It looks like this.
#!/usr/bin/python2.7 lr = '\x64' db = '\x6e' ef = '\x63' nn = '\x61' ty = '\x61' gh = '\x6e' aa = '\x61' rr = '\x6f' slither = aa + db + nn + ef + rr + gh + lr + ty print(slither)
Running this like gives me a username, where x is a lowercase letter.
python snake_user.py xxxxxxxx
This is good, I now have a username. But I still need a working password. So
what is this code doing with the password? Again, I try to work backwards and
create a minimal file that only contains the variables I need. I save this in
the file snake_pass.py.
#!/usr/bin/python2.7 import random chars = [] keys = [0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x21, 0x21] lock_pick = random.randint(0, 0x3e8) lock = lock_pick * 2 lock = lock + 10 lock = lock / 2 lock = lock - lock_pick for key in keys: keys_encrypt = lock ^ key chars.append(keys_encrypt) print("".join([chr(a) for a in chars]))
This is not even the most minimal version. The lock_pick variable can be
removed, and the lock variable always ends up at 5.
Next I run this, and get a password.
python snake_pass.py xxxxxxxxxx
I run the original snake.py and put in both the username and the password
to confirm, and it does indeed work. I try the token as HTB{username:password},
and it works.