23. 01. 2006 Python cracking a jak se proti němu bránit

Jelikož některé své programy distribuji formou .pyc (.pyo) souborů (bytecode jazyka Python), zajímal jsem se o to, jaké mají potencionální crackeři možnosti. Byl jsem překvapen, že moc nástrojů pro reverzní inženýrství Pythonu neexistuje, takže potencionální cracker musí bastlit nástroje vlastní - což je dobře.

Našel jsem jeden jediný nástroj pro disassembling, na druhou stranu je poměrně mocný. Jmenuje se decompyle, je to modul pro Python spolu s příkazem a manuálovou stránkou. Současná verze (nevypadá, že ji původní autor veřejně dál bude vyvíjet) funguje však jen s nejvyšší verzí Pythonu 2.3. Nevadí, v Gentoo mám Pythonů víc.

Vytvořil jsem testovací soubor a přeložil jej do souboru pyc pomocí příkazu python -c „import test“. Dále jsem si vytvořil pomocí programu decompyle nejprve zpětně kompletní zdrojový kód (decompilation), a pak také kompletní výpis opkódů (disassemblation).

Python VM je zásobníkový stroj (podobně jako Java), takže cracker to má poměrně snadné. Pokud se mu tedy podaří dostat k tomuto výpisu opkódů, má vyhráno. Kompletně zrekonstruovaný zdrojový kód je bonus, který mu jen usnadní práci. Tomuto se dá poměrně snadno zamezit pomocí obfuskace, ale rekonstruovat výpis opkódů může cracker vždy.

Nyní se stačí podívat do souboru opcode.h ze zdrojových kódů Pythonu. Jsou zde číselné kódy jednotlivých instrukcí VM. Asi nejzajímavější je pro hackera kombinace 6A 02 (instrukce 106 - skoč pokud podmínka platí, následovaná „podinstrukcí“ 02) a 6A 03 (pokud neplatí). Tím se dá tzv. obrátit IF, což je asi nepoužívanější crackerská technika. Najít tu instrukci ale nebude snadné, nástroj decompyle neukazuje, na jaké pozici se daná instrukce v souboru nachází. Na řadu přichází složité hledání (např. programem hexedit, ctrl+S).

V mém příkladě je tato instrukce jen jedna, stačí tedy přepsat opkód 6A 02 na 6A 03. Poté stačí spustit Python 2.3 a naimportovat modul test a spustit funkci test.test(). Nyní nevypíše na konzoli „Jedna“, ale „Dva“.

Hledání instrukce, která bude změněna, však není triviální záležistost. Moduly jsou objemné a obsahují tisíce instrukcí porovnání. Potencionální cracker si tedy bude muset napsat vlastní nástroj pro snadnou modifikaci .pyc souborů. Ačkoli existují různé balíky pro emisi opkódů, nenašel jsem žádný, který by byl schopen načíst modul ze souboru, modifikovat jej a zase zpět uložit. Hledání však dost usnadňují názvy funkncí, které jsou v konstantím poolu vždy za poolem instrukcí. Stačí tedy najít název funkce a hledání začít o pár obrazovek vzhůru.

Python je na tom tedy velmi dobře, lépe než například Java, kde tyto nástroje už existují. Navíc je zde stále šance použít obfuskátor (žádný neznám, ale napsat jej nebude zase tak náročné), případně upravit Python samotný (ačkoli GNU GPL licence by nám v tom trošku bránila), eventuelně zkompilovat program přes jazyk C do binárky.
21 April 2010 | oldblog
twitter.com linkedin.com
google.com/+ facebook.com
flickr.com youtube.com