Skip to content

Instantly share code, notes, and snippets.

@0awawa0
Created September 1, 2020 10:37
Show Gist options
  • Save 0awawa0/36255d5b931439870d02ebfd5341c48f to your computer and use it in GitHub Desktop.
Save 0awawa0/36255d5b931439870d02ebfd5341c48f to your computer and use it in GitHub Desktop.
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