ANTICHAT

ANTICHAT (https://forum.antichat.xyz/index.php)
-   Задания/Квесты/CTF/Конкурсы (https://forum.antichat.xyz/forumdisplay.php?f=112)
-   -   CTF для новичков KHS 2018 (Part 7) - Reversing Python (https://forum.antichat.xyz/showthread.php?t=1626353)

clevergod 16.01.2019 19:15

Reversing Python (Part 7)

Данный таск выполнял мой колега и друг Антон и разбор будет с его слов.

Мои познания ещё далеки от гуру в питоне, но синтаксис я уже изучил.
Поэтому, в то время пока @clevergod штурмовал стеганографию, я разбирал строки кода небольшого скрипта.

Python:


Код:

#!/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 символов.

https://forum.antichat.xyz/attachmen...8c128d3c16.png

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

Естественно были мысли что флаг как-то связан с этим числом, но оказалось что оно здесь лишь для отвлечения внимания.
Пришла умная мысль что разбирать работу скрипта нужно с конца... Точнее со строк которые запрашивают "username"
Я немного схитрил и указал в коде вывести username при любом неправильном вводе

Python:


Код:

''''
if user_input == slither:
    pass
else:
    print 'username must be '+slither
    exit()
'''
'

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

https://forum.antichat.xyz/attachmen...167f1f657b.png

Скрипт выдаёт только первый символ пароля - "u" Значит надо думать шире...

https://forum.antichat.xyz/attachmen...ef53a614e9.png

Первая буква 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"

Можно по буквам перебрать, а можно цикл написать... кому как удобнее)
Включайте мозг и пробуйте...

Тем, кто пропустил что-то, задач было 11: Brain, Finde the cat, FTP-authentication, Reversing Python, Steganography 2, Steganography 3, Steganography 4, Steganography 5, WTFilee, Command & Control, Command & Control2


Время: 22:59