Ghost in the Shellcode CTF 2014 (lugkist)

Решения

http://blog.zachorr.com/lugkist/ (Blogzor)
http://commandlinewani.blogspot.ru/2014/01/ghostintheshellcode-write-up-lugkist.html (Nehal J. Wani)
http://tasteless.se/2014/01/gits-2014-lugkist-trivia-150
https://systemoverlord.com/blog/2014/01/19/ghost-in-the-shellcode-2014-lugkist (David Tomaschik)
Назад к списку заданий

Задание (trivia)

Trivia "lugkist"
Find the key.

Подробное описание

Дан набор 6-символьных данных:
GVZSNG AXZIOG YNAISG ASAIUG IVPIOK AXPIVG PVZIUG AXLIEG YUPISK AXASEG GVZSSG AXZSKG PVPIXK ZNASKG LVPSOG PVZSVK IVASNG GVPIEK IVPSNK PNZIKK YNASSG TVPSSK LVZIVG PVLSKG PVLIVG TNLING ANLSUG PVPSEG AVASVK LNLSXG PVPSKK LVPSXK TNASXG AXPSVG GNLIUG LNLSNG TVLIOK AVZINK GNZSXG IVAIVG TVPIUK LVLSSG IVLSEG AVLISK YVAIKK ZKPING YVPIKG LNZSUG PVZSOG AXZISG YVASOK ZNAING AXPSUG IVLSVG AXLIKG GVZIXG IVASUG TXGIEK PNZIEK YVLIXK IVZSEG AXLSOG

Внешне всё выглядит как случайные данные. Но если посмотреть какие символы участвуют в кодировке, то окажется, что их всего 16:
AEGIKLNOPSTUVXYZ
Наличие только 16 символов напоминает 16-тиричную систему счисления:
0123456789ABCDEF

По ходу соревнований организаторы опубликовали подсказку. "Hints: lugkist: SLTIYG". Погуглив "SLTIYG", находим сайт, посвященный читам к играм. Дальнейший поиск привел к системе кодирования для Game Genie.
Game Genie — серия чит-устройств, разработанных Codemasters и продававшихся Camerica и Galoob для Nintendo Entertainment System, Super Nintendo Entertainment System, Game Boy, Mega Drive/Genesis и Sega Game Gear, который изменяет данные игры, позволяя игроку обманывать, управлять различными аспектами игр, и иногда просматривать неиспользованный контент и функции. Устройство известно как благоприятное для потребителя "улучшение игры" посредством (временно) прямого изменения двоичного кода игры.
Техническая справка по NES Game Genie (http://tuxnes.sourceforge.net/gamegenie.html) говорит, что существуют 6-тисимвольные и 8-символьные коды. Конечно, нас интересуют 6-тисимвольные варианты, которые кодировали в каждом конкретном случае 15-битный адрес плюс 8-битные данные.
Вот кодирующие символы:
A 0x0
P 0x1
Z 0x2
L 0x3
G 0x4
I 0x5
T 0x6
Y 0x7
E 0x8
O 0x9
X 0xA
U 0xB
K 0xC
S 0xD
V 0xE
N 0xF

Формат 6-тисимвольной последовательности:
[n0, n1, n2, n3, n4, n5]

Алгоритм получения 15-битного адреса:
address = 0x8000 + ((n3 & 7) « 12) | ((n5 & 7) « 8) | ((n4 & 8) « 8) | ((n2 & 7) « 4) | ((n1 & 8) « 4) | (n4 & 7) | (n3 & 8);

Алгоритм получения 8-битных данных:
data = ((n1 & 7) « 4) | ((n0 & 8) « 4) | (n0 & 7) | (n5 & 8);

Cкрипт на Питоне:

# -*- coding: cp1251 -*-
codes = "GVZSNG AXZIOG YNAISG ASAIUG IVPIOK AXPIVG PVZIUG AXLIEG YUPISK AXASEG \
GVZSSG AXZSKG PVPIXK ZNASKG LVPSOG PVZSVK IVASNG GVPIEK IVPSNK PNZIKK YNASSG \
TVPSSK LVZIVG PVLSKG PVLIVG TNLING ANLSUG PVPSEG AVASVK LNLSXG PVPSKK LVPSXK \
TNASXG AXPSVG GNLIUG LNLSNG TVLIOK AVZINK GNZSXG IVAIVG TVPIUK LVLSSG IVLSEG \
AVLISK YVAIKK ZKPING YVPIKG LNZSUG PVZSOG AXZISG YVASOK ZNAING AXPSUG IVLSVG \
AXLIKG GVZIXG IVASUG TXGIEK PNZIEK YVLIXK IVZSEG AXLSOG"
 
gameGenue = "APZLGITYEOXUKSVN"
 
def decode(n):
    address = 0x8000 + ((ord(n[3]) & 7) << 12) | ((ord(n[5]) & 7) << 8) | \
        ((ord(n[4]) & 8) << 8) | ((ord(n[2]) & 7) << 4) | ((ord(n[1]) & 8) << 4) | \
        (ord(n[4]) & 7) | (ord(n[3]) & 8)
    data = ((ord(n[1]) & 7) << 4) | ((ord(n[0]) & 8) << 4) | (ord(n[0]) & 7) | \
        (ord(n[5]) & 8)
    return address, data
 
ncodes = codes.split(" ")
 
res = []
key = ""
for i in range(len(ncodes)):
    temp = ["".join(chr(gameGenue.find(x))) for x in ncodes[i]]
    a, d = decode(temp)
    print "%0x %0x"%(a, d)
    key += chr(d)
    # Добавляем в список значение (адрес, данные)
    res.append((a, d))
print("[+]Flag: "+key)

…и смотрим результат:
dcaf 64
dca1 20
dc85 77
dc83 50
dc91 6d
dc96 20
dca3 61
dcb0 20

Все полученные данные - это читаемые символы (печатаемые ASCI-коды символов). Если собрать все данные в строку, то получим:
d wPm a ? d ircielmywncaavpahsikv tsnhtencehoBgsa or e de.yoe

Выглядит, как бред. Но! Адреса, скорее всего, приведены не случайно. Отсортируем символы в строке по возрастанию адресов (подправим скрипт):

key = ""
res.sort()
for i in range(len(res)):
    key += chr(res[i][1])
 
print("[+]Flag: "+key)

Power overwhelming? Back in my day cheats did not have spaces.

Флаг:
Power overwhelming? Back in my day cheats did not have spaces.

Пока не указано иное, содержимое этой страницы распространяется по лицензии Creative Commons Attribution-ShareAlike 3.0 License