CTF KHS 2018 — Reversing Python (Part 7)

Reversing Python (Part 7)

Мои познания ещё далеки от гуру в питоне, но синтаксис я уже изучил.

Поэтому, в то время пока Стас штурмовал стеганографию, я разбирал строки кода небольшого скрипта.

#!/usr/bin/python2.7
import random 
lr = '\x64'
print '''
___________.__               _________              __           
\__    ___/|  |__   ____    /   _____/ ____ _____  |  | __ ____  
  |    |   |  |  \_/ __ \   \_____  \ /    \\__  \ |  |/ // __ \ 
  |    |   |   Y  \  ___/   /        \   |  \/ __ \|    <\  ___/ 
  |____|   |___|  /\___  > /_______  /___|  (____  /__|_ \\___  >
                \/     \/          \/     \/     \/     \/    \/ 

'''
the_key_is_bellow='bmVlZCBvbmx5IDEw'
chains = [0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x74, 0x72, 0x6f, 0x6c, 0x6c] # dGhpcyBpcyBhIHRyb2xs
db = '\x6e'
ef = '\x63'
chars = []
keys = [0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x21, 0x21] # cGFzc3dvcmQhIQ==
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] # %69%74%73%20%6e%6f%74%20%74%68%61%74%20%65%61%73%79
lock = lock + 10
ty = '\x61'
lock = lock / 2
auth = [0x6b, 0x65, 0x65, 0x70, 0x20, 0x74, 0x72, 0x79, 0x69, 0x6e, 0x67] # 6b65657020747279696e67
lock = lock - lock_pick
gh = '\x6e'
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

Эти 58 строк кода заняли у меня 1.5 часа анализа переменных, шифров и подсказки от бота:

Задание:Reversing Python
Points: 15
Описание: В этот раз змея запуталась настолько, что не понятно, где ее хвост, а где голова. Все, что тебе надо — это разобраться в этой путанице и найти ее голову. Говорят, что длина змеи 10 метров.

10 метров как можно догадаться — длина флага — 10 символов.

При запуске скрипт генерирует случайное число с помощью random.randint(0, 0x3e8) и выводит в строке «Your number is …»

Естественно были мысли что флаг как-то связан с этим числом, но оказалось что оно здесь лишь для отвлечения внимания.

Пришла умная мысль что разбирать работу скрипта нужно с конца… Точнее со строк которые запрашивают «username»

Я немного схитрил и указал в коде вывести username при любом неправильном вводе

''''
if user_input == slither:
    pass

else:
    print 'username must be '+slither
    exit()
''''

 

Отлично, мы узнали username, но вот с паролем нам так не повезёт

Скрипт выдаёт только первый символ пароля — «u» Значит надо думать шире…

Первая буква username «a» является переменной » a =’\x61′ «а это значит что перед нами кодировка HEX… Идём дальше

Всего в скрипте 4 основных переменных: chains, keys, lock_pick и lock. Password и Auth лишь для отвлечения внимания и по факту нигде не используются.

lock_pick генерирует случайное число, а lock сначала умножает его на 2, затем добавляет 10, делит на 2 и вычитает исходное число lock_pick.

На примере 169 проведём эти вычисления — «((169*2)+10)/2-169 = 5» И это независимо от того, какое значение примет lock_pick.

Далее разберем цикл для keys и chains. Каждый из них по своему модифицирует указанные ранее значения в массивах keys и chains.

^ — знак карет — Бинарный «Исключительное ИЛИ» оператор копирует бит только если бит присутствует в одном из операндов, но не в обоих сразу.

Например первый знак в переменной keys: 5 ^ 0x70 = 117, а str(chr(117)) это «u»

 

Можно по буквам перебрать, а можно цикл написать… кому как удобнее)

Включайте мозг и пробуйте…