Skip to content

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.