Created
September 1, 2020 10:37
-
-
Save 0awawa0/36255d5b931439870d02ebfd5341c48f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import requests | |
import json | |
import curses | |
def main(stdscr): | |
curses.resize_term(100, 300) | |
stdscr.refresh() | |
curses.start_color() | |
curses.curs_set(0) | |
curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK) | |
curses.init_pair(2, curses.COLOR_GREEN, curses.COLOR_BLACK) | |
curses.init_pair(3, curses.COLOR_CYAN, curses.COLOR_BLACK) | |
stdscr.clear() | |
stdscr.addstr(0, 0, "***********************{ AES ECB CHOSEN PLAINTEXT ATTACK }***********************", curses.color_pair(2)) | |
# Базовый адрес для отправки запросов | |
base = "http://aes.cryptohack.org/ecb_oracle/encrypt/" | |
stdscr.addstr(1, 0, "Address to attack: " + base, curses.color_pair(3)) | |
stdscr.addstr(3, 0, "[*] Getting ciphertexts...", curses.color_pair(1)) | |
stdscr.refresh() | |
# Собираем шифротексты до начала перебора | |
block1 = [] | |
block2 = [] | |
for i in range(16, 32): | |
pad = "00" * i | |
response = requests.get(base + pad) | |
ciphertext = json.loads(response.content)["ciphertext"] | |
block1.append(ciphertext[32:64]) | |
block2.append(ciphertext[64:96]) | |
samples = block1 + block2 | |
stdscr.addstr(4, 0, "[!] Retrieved ciphertexts:", curses.color_pair(2)) | |
stdscr.addstr(5, 5, "Block 1:") | |
for i in range(16): | |
stdscr.addstr(6 + i, 10, samples[i]) | |
stdscr.addstr(7 + i, 5, "Block 2:") | |
for i in range(16, 32): | |
stdscr.addstr(7 + i, 10, samples[i]) | |
stdscr.addstr(40, 0, "[-] Attacking...", curses.color_pair(1)) | |
stdscr.refresh() | |
# Изначально известный текст пустой | |
known = "" | |
t = ["-", "\\", "|", "/", "-", "\\", "|", "/"] | |
for i in range(1, 33): | |
stdscr.addstr(41, 0, "Known text -> " + bytes.fromhex(known).decode(), curses.color_pair(3)) | |
if i <= 16: | |
rm = samples[-16 - i] # Берём шифротекст из первого блока | |
stdscr.addstr(6 + 16 - i, 10, rm + "<- attack", curses.color_pair(1)) | |
else: | |
rm = samples[16 - i] # Берём шифротекст из второго блока | |
stdscr.addstr(7 + 48 - i, 10, rm + "<- attack", curses.color_pair(1)) | |
# Перебираем не все 256 значений, а только печатные символы, таким образом снижая количество возможных запросов с 8192 до 3040. | |
for j in range(32, 127): | |
stdscr.addstr(40, 0, f"[{t[j % len(t)]}] Attacking...", curses.color_pair(1)) | |
# Подготавливаем payload | |
pad = "00" * (31 - len(known) // 2) | |
# Формируем запрос | |
request = base + pad + known + format(j, "02x") | |
# Получаем ответ | |
response = requests.get(request) | |
ciphertext = json.loads(response.content)["ciphertext"][32:64] | |
stdscr.addstr(42, 0, "Payload: 0x" + pad, curses.color_pair(3)) | |
stdscr.addstr(42, 11 + len(pad), known, curses.color_pair(2)) | |
stdscr.addstr(42, 11 + len(pad) + len(known), format(j, "02x"), curses.color_pair(1)) | |
stdscr.addstr(43, 0, "Current ciphertext: " + ciphertext, curses.color_pair(3)) | |
stdscr.refresh() | |
# Если шифротексты совпали, то переходим к следующему шагу | |
if ciphertext == rm: | |
known += hex(j)[2:] | |
if i <= 16: | |
stdscr.addstr(6 + 16 - i, 10, rm + "<- processed", curses.color_pair(2)) | |
else: | |
stdscr.addstr(7 + 48 - i, 10, rm + "<- processed", curses.color_pair(2)) | |
# Когда нашли закрывающую скобку, останавливаем перебор, потому что нам уже известен флаг | |
if chr(j) == "}": | |
stdscr.addstr(44, 0, "[2] Attack successful!", curses.color_pair(1)) | |
stdscr.addstr(45, 0, "[2] Flag retrieved: " + bytes.fromhex(known).decode(), curses.color_pair(2)) | |
stdscr.getkey() | |
return | |
break | |
stdscr.getkey() | |
curses.wrapper(main) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment