Deobfuscation of obfuscated software. Kurucsai István

Hasonló dokumentumok
Szoftverek obfuszkációja

Fordító részei. Fordító részei. Kód visszafejtés. Izsó Tamás szeptember 29. Izsó Tamás Fordító részei / 1

Szoftver-modellellenőrzés absztrakciós módszerekkel

Fordító Optimalizálás

A fordítóprogramok szerkezete. Kódoptimalizálás. A kódoptimalizálás célja. A szintézis menete valójában. Kódoptimalizálási lépések osztályozása

GPU Lab. 4. fejezet. Fordítók felépítése. Grafikus Processzorok Tudományos Célú Programozása. Berényi Dániel Nagy-Egri Máté Ferenc

sallang avagy Fordítótervezés dióhéjban Sallai Gyula

Miért van szükség fordítóprogramokra? Fordítóprogramok célja és szerkezete. Miért van szükség fordítóprogramokra?

Digitális rendszerek. Utasításarchitektúra szintje

Mintavételes szabályozás mikrovezérlő segítségével

Programozási nyelvek (ADA)

1. Bevezetés szeptember 9. BME Fizika Intézet. Szám. szim. labor ea. Tőke Csaba. Tudnivalók. feladat. Tematika. Moodle Házi feladatok

Szekvenciális hálózatok és automaták

Programozási nyelvek 6. előadás

KOMPUTER-ALGEBRA RENDSZEREK VERIFIKÁCIÓJA

A szemantikus elemzés helye. A szemantikus elemzés feladatai. A szemantikus elemzés feladatai. Deklarációk és láthatósági szabályok

Clang Static Analyzer belülről

Programozási nyelvek a közoktatásban alapfogalmak I. előadás

Kifejezések. Kozsik Tamás. December 11, 2016

Adatok ábrázolása, adattípusok

Megoldások a mintavizsga kérdések a VIMIAC04 tárgy ellenőrzési technikák részéhez kapcsolódóan (2017. május)

5. KOMBINÁCIÓS HÁLÓZATOK LEÍRÁSÁNAK SZABÁLYAI

Aritmetikai kifejezések lengyelformára hozása

Fordító Optimalizálás

Korlátos modellellenőrzés. dr. Majzik István BME Méréstechnika és Információs Rendszerek Tanszék

4. Programozási nyelvek osztályozása. Amatőr és professzionális

Programok értelmezése

Dinamikus modellek szerkezete, SDG modellek

Apple Swift kurzus 3. gyakorlat

2. Fejezet : Számrendszerek

Programozás I. Sergyán Szabolcs Óbudai Egyetem Neumann János Informatikai Kar szeptember 10.

Programzás I gyakorlat

Szoftvertechnológia alapjai Java előadások

Operációs rendszerek. 11. gyakorlat. AWK - szintaxis, vezérlési szerkezetek UNIVERSITAS SCIENTIARUM SZEGEDIENSIS UNIVERSITY OF SZEGED

Kifejezések. Kozsik Tamás. December 11, 2016

Algoritmuselmélet. Katona Gyula Y. Számítástudományi és Információelméleti Tanszék Budapesti Műszaki és Gazdaságtudományi Egyetem. 13.

A programozás alapjai előadás. Amiről szólesz: A tárgy címe: A programozás alapjai

BASH script programozás II. Vezérlési szerkezetek

GPU Lab. 5. fejezet. A C++ fordítási modellje. Grafikus Processzorok Tudományos Célú Programozása. Berényi Dániel Nagy-Egri Máté Ferenc

Fordítás Kódoptimalizálás

Python tanfolyam Python bevezető I. rész

15. Programok fordítása és végrehajtása

A 32 bites x86-os architektúra regiszterei

A kódgenerálás helye a fordítási folyamatban. Kódgenerálás I. (kifejezések és vezérlési szerkezetek) A kódgenerálás feladata. Ebben az előadásban...

Objektum Vezérelt Szoftverek Analízise

Fordítóprogramok. Aszalós László szeptember 7.

Bánsághi Anna 2014 Bánsághi Anna 1 of 68

PHP. Telepítése: Indítás/újraindítás/leállítás: Beállítások: A PHP nyelv

A programozás alapjai

Szoftvertervezés és -fejlesztés I.

Bevezetés az informatikába

Kriptográfia 0. A biztonság alapja. Számítás-komplexitási kérdések

Hatékony technikák modellellenőrzéshez: Korlátos modellellenőrzés. dr. Majzik István BME Méréstechnika és Információs Rendszerek Tanszék

Haladó Fordítóprogramok

Kinek szól a könyv? A könyv témája A könyv felépítése Mire van szükség a könyv használatához? A könyvben használt jelölések. 1. Mi a programozás?

Bonyolultságelmélet. Monday 26 th September, 2016, 18:50

Bonyolultságelmélet. Thursday 1 st December, 2016, 22:21

Kiterjesztések sek szemantikája

A szerzõrõl... xi Bevezetés... xiii

Programozás I. Sergyán Szabolcs Óbudai Egyetem Neumann János Informatikai Kar szeptember 10.

Hardver leíró nyelvek (HDL)

Laborgyakorlat Logikai áramkörök számítógéppel segített tervezése (CAD)

Java programozási nyelv

Mechatronika és mikroszámítógépek 2017/2018 I. félév. Bevezetés a C nyelvbe

Metamodellezés. Simon Balázs BME IIT, 2011.

1. Melyik szabvány foglalkozik dokumentumok tulajdonságainak megfogalmazásával? a. RDFS b. FOAF c. Dublin Core d. DBPedia

A Feldspar fordító, illetve Feldspar programok tesztelése

A CMMI alapú szoftverfejlesztési folyamat

C programozás. 1 óra Bevezetés

Kriptográfia I. Kriptorendszerek

Szkriptnyelvek. 1. UNIX shell

4. Fejezet : Az egész számok (integer) ábrázolása

Formális szemantika. Kifejezések szemantikája. Horpácsi Dániel ELTE Informatikai Kar

Ismeretanyag Záróvizsgára való felkészüléshez

Funkcionális és logikai programozás. { Márton Gyöngyvér, 2012} { Sapientia, Erdélyi Magyar Tudományegyetem }

Memóriagazdálkodás. Kódgenerálás. Kódoptimalizálás

Operációs rendszerek gyak.

Emlékeztető: a fordítás lépései. Szimbólumtábla-kezelés. Információáramlás. Információáramlás. Információáramlás.

Szoftver karbantartási lépések ellenőrzése

Adatelérés és memóriakezelés

1. Mi a fejállományok szerepe C és C++ nyelvben és hogyan használjuk őket? 2. Milyen alapvető változókat használhatunk a C és C++ nyelvben?

Számítógépes Hálózatok. 7. gyakorlat

Máté: Számítógép architektúrák

Algoritmizálás, adatmodellezés tanítása 6. előadás

Programozási nyelvek JAVA EA+GY 1. gyakolat

(11) Lajstromszám: E (13) T2 EURÓPAI SZABADALOM SZÖVEGÉNEK FORDÍTÁSA

Digitális technika VIMIAA01 9. hét Fehér Béla BME MIT

Digitális technika VIMIAA01 9. hét

Programozás BMEKOKAA146. Dr. Bécsi Tamás 2. előadás

Komputeralgebra rendszerek

Programozás I. 1. előadás: Algoritmusok alapjai. Sergyán Szabolcs

Digitális technika II. (vimia111) 5. gyakorlat: Tervezés adatstruktúra-vezérlés szétválasztással, vezérlőegység generációk

Stack Vezérlés szerkezet Adat 2.

C programozási nyelv

találhatók. A memória-szervezési modell mondja meg azt, hogy miként

Komputeralgebra rendszerek

Informatika tanítási módszerek

Programozás. (GKxB_INTM021) Dr. Hatwágner F. Miklós február 18. Széchenyi István Egyetem, Gy r

Programozás alapjai C nyelv 4. gyakorlat. Mit tudunk már? Feltételes operátor (?:) Típus fogalma char, int, float, double

Programozás I. 3. gyakorlat. Szegedi Tudományegyetem Természettudományi és Informatikai Kar

Átírás:

Deobfuscation of obfuscated software Kurucsai István

Tartalom Bevezetés Obfuszkáció típusai Mit és hol? Deobfuszkáció Szintaxis alapú módszerek Szemantikus módszerek Összefoglalás

Bevezetés Anti-reversing: programok visszafejtésének megnehezítése Az előadás keretében: natív Windows alkalmazások Motivációk: Illegális szoftvermásolás akadályozása Kritikus/értékes algoritmusok védelme Kártékony kódok elrejtése Csak nehezítés, a visszafejtés időigényét és költségét növelhetjük Tökéletes védelem nem megvalósítható

Anti-reversing ~ ára Kódméret növekedése Teljesítmény csökkenése Kompatibilitási kérdések SecuROM Hatékonyság nehezen mérhető: mennyivel nehezebb visszafejteni a kódot? Embernek Automatikus eszközöknek

Anti-reversing módszerek Szimbólumok/debug információk eltávolítása Natív alkalmazások esetén szinte mindig megtörténik Bytecode alapú nyelveknél fontos Packerek/wrapperek (csomagolás) Virtualizáció Anti-debugging/disassembly/VM/dumping trükkök Obfuszkáció Gyakran együtt jelennek meg

Refused és Stubborn Önálló laboratórium keretében készített programok Refused: source-to-source transformer Különböző obfuszkációs módszerek Stubborn: Windows PE packer

Kártékony kódok elrejtése (packerek)

Obfuszkáció A funkcionalitás megőrzése mellett a kód összezavarása, az olvashatóság csökkentése Layout obfuscations: szimbólumok és kommentek eltávolítása, formázás megváltoztatása Natív bináris készítésekor a fordító elvégzi Preventív transzformációk: a deobfuszkálásnál felhasznált eszközök esetleges gyengeségeinek kihasználása

Adat obfuszkáció A program által használt adatok struktúrája és a konstansok nagyban segítik a visszafejtést

Adat obfuszkáció Számos módszer Tárolás és kódolás transzformációja Tömbök átszervezése (tömbök összevonása és szétválasztása, dimenziók számának növelése/csökkentése, elemek permutációja) A hatékonyság és általánosság hiánya illetve költségeik gyakran kérdésessé teszi az alkalmazhatóságukat

Konstansok védelme A konstansok védelme azonban egyszerű és hatásos lehet Hashelés Amennyiben a konstanst csak egyenlőség jellegű vizsgálatoknál használja a program és nincs szükség a konkrét értékére (==,!=,!strcmp, stb...) if (a == 24) helyett if (hash(a) == 356725135) A megfelelő hash kiválasztása Ütközésmentesség: a program helyes műküdése Egyirányúság: visszafejtés nehézsége

Konstansok védelme II Ha a konstans eredeti értékére is szükség van Titkosítás majd futásidőben a használat előtt ideiglenes dekódolás Stringek egyszerű (XOR, SUB) rejtjelezése Bonyolultabb algoritmusok, például blokkrejtjelezők alkalmazása nem jelent különösebb nehézséget, mert futásidőben úgyis megjelenik a konstans eredeti értéke és a kulcs is

Adat obfuszkáció Összességében A konstansok védelme alapfunkciónak számít Az általánosabb adat obfuszkációs megoldások viszont kevésbé elterjedtek Nehéz az általános megvalósítás Nagy overhead Gyenge védelem

Control-flow obfuscation A program vezérlési struktúrájának összezavarása Sokat kutatott terület A legtöbb obfuszkátor alapja

Opaque predicates (átlátszatlan feltételek) Olyan elágazás-feltételek, melyek mindig igazra vagy hamisra értékelődnek ki, de ezt nehéz belátni a visszafejtett programot vizsgálva Egyszerű példa: (x + x^2) % 2 == 0 A hatásosság nagyban függ a predikátumok változatosságától és bonyolultságától Ilyen elágazásokat elhelyezve a programban annak vezérlésfolyama bonyolítható

Példa feltételek

Opaque predicates példa I (Refused)

Opaque predicates példa II

Opaque predicates példa III

Opaque predicates Platformfüggő feltételek Kihasználva egyes operációs rendszerek vagy API-k sajátosságait Regiszter értéke a program indulásakor vagy valamelyik API visszatérése után Erős feltételek hozhatóak létre Kompatibilitás hiánya Összességében: Hatásos és egyszerű Jól kombinálható más módszerekkel

CFG flattening (vezérlési gráf kilapítása) Célja a vezérlésfolyam elrejtése Függvény basic blockokra osztása Eredetileg más mélységben lévő blokkok egy szintre hozása switch kifejezésben (kiválasztás) A blokkok végén a switch-et vezérlő változó megfelelő beállítása A kiválasztás ciklusba ágyazása

CFG flattening példa

CFG flattening példa II

Diablo CFG flattening

Apple FairPlay CFG flattening

Junk code insertion (szemét kód beszúrása) Do-nothing vagy do-little Az ember számára olvashatatlan és értelmezhetetlen kód automatizált eszközökkel gyakran hatékonyan kezelhető

Junk code példa

További vezérlésfolyam obfuszkációk CFG arches meshing Inlining/outlining Cloning of functions Combined functions

Mit és hol? A cél a kimeneti bináris obfuszkációja De az egyes módszerek alkalmazhatóak a fordítás különböző lépéseiben (forráskód, köztes reprezentáció, tárgykód) kész binárison is

Mit és hol? II Célszerű a legmegfelelőbb helyet kiválasztani minden transzformációhoz Packelés csak a kész binárison CFG kilapítása bármelyik lépésben Szemét kód Ha a forrásba illesztjük, a fordító kioptimalizálhatja Ha a kész binárisba, ügyelni kell a mellékhatásokra (regiszterek, különösen EFLAGS)

Opaque predicates példa I

Refused Source-to-source transformation C/C++ kódok támogatása Funkciók: Opaque predicates Szemét kód (félkész) CFG flattening (félkész)

Clang/LLVM C nehezen parse-olható, a C++ még nehezebben Az LLVM frontendjének felhasználása (Clang) Transzformációk az abstract syntax tree-n (AST)

Morpher Morpher is a versatile and flexible automatic software transformation toolkit focused on protection of software algorithms. Despite of other software protection solutions on the market which operate only on the final binary Morpher is tightly coupled with the industry-standard C/C+ + compiler and thus can exploit much more information about sources to be protected. Note that such information is normally lost during compilation and codegeneration. Functions interleaving and merging; Opaque predicates insertion; Opaque variables insertion (generic framework used by other transformation passes); Automatic constants (e.g. string literals) protection and encryption; Code flow graph altering; LLVM optimalizációs lépésekként implementált obfuscating compiler

Deobfuszkáció szintaktikus vs. szemantikus módszerek Szintaxis-alapú: csak az objektumok formátumát figyelembe vevő módszerek Gépi kód / assembly utasítások bájtjainak sorozata, esetleges wildcardok Szemantikus: az objektumok jelentését is számításba vevő módszerek Az utasítások hatásai/mellékhatásai

Szintaxis-alapú módszerek Pro Gyors (gyakorlatilag mintaillesztés) Néhány problémára remek megoldást jelentenek Con Sok probléma egyáltalán nem oldható meg így Tipikus felhasználás: Signatures: packer entrypoint, FLIRT, anti-virus Egyszerű deobfuszkáció

Szintaxis-alapú deobfuszkáció Amennyiben a transzformáció valamilyen felismerhető mintázatot tartalmaz Emulált jmp és call: push/ret

Szintaxis-alapú deobfuszkáció II A korábbi szemét kód példa:

Korlátok Mi történne, ha az előző példa tartalmazna egy aritmetikai utasítást amire nem készültünk fel? egy feltételes ugrást? egy átlátszatlan feltételt? A szintaxis-alapú módszerek hatékonyak bizonyos esetekben, de gyorsan korlátokba ütközünk

Szemantikus módszerek Az objektumok jelentését is számításba vevő módszerek Számos felhasználás a reverse engineering területén Automatikus kulcsgenerátor generálás :) Automatikus hibafelderítés (részben) generikus deobfuszkáció A program analízis akadémiai eredményeinek gyakorlatba való átültetése népszerű téma

Egy utasítás szemantikája... Az and (x86) utasítás köztes reprezentációja (IR - Intermediate Language translation)

Absztrakt interpretáció A program analízis klasszikus technikája Bonyolult módszer, de alapja egyszerű Absztrakt állapot a konkrét helyett Absztrakt szemantika a konkrét helyett Egyszerű példa: váltózok előjelének meghatározása A változók konkrét értéke helyett csak előjelüket tartjuk nyilván Ennek megfelelően definiáljuk az egyes műveletek szemantikáját is

Absztrakt interpretáció példa Minden más információt figyelmen kívül hagyunk

Absztrakt interpretáció Gyakran arra vagyunk kíváncsiak, hogy egy adott pont a programban egy adott változó milyen értékeinél érhető el Erre a kérdésre ad választ a szimbolikus végrehajtás, Az absztrakt interpretáció speciális esete

Szimbolikus végrehajtás Minden elágazás korlátozza az értékkészletet valamilyen módon

SMT (Satisfiability Modulo Theories) solving Alapötlet: alakítsuk a kódot logikai formulákká, amelyeken aztán különböző tulajdonságokat bizonyíthatunk be illetve egyszerűsíthetjük Felhasználás: input generálás (input crafting) Milyen értéket kell az eax regiszternek tartalmaznia kezdetben, hogy a kód lefutása után értéke 0x12345678 legyen?

SMT solving A köztes reprezentációból készített SMT formula (Z3)

SMT solving II assert(t175d == 0x12345678); T175d eax végső értéke Sat => a formula kielégíthető A kimenet egy model, ami kielégíti a formulát Az utolsó sorban eax értéke

LLVM IR obfuszkátor Kryptonite Az összeadás utasítást lecseréli egy assemblyben megvalósított bitenkénti összeadóra Egy összeadásból 2000 sor assembly kód lesz Junk code insertion extrém esete Deobfuszkáció egy lehetséges megoldása: Szimbolikus végrehajtással meghatározzuk, hogy a függvény kimenete hogy függ a bemenetektől (a két összeadandó szám) Egy SMT megoldóval megpróbáljuk egyszerűsíteni az előző lépés végén kapott formulát Ha minden jól megy megkapjuk, hogy a kimenet minden esetben a két bement összege

Kryptonite I (szimbolikus végrehajtás) A szimbolikus végrehajtó motor működése: Szimbolikus változók tárolása (gyk. ha inicializálatlan területről találunk olvasást, akkor létrehozunk egy változót). Ezek a változók lesznek a bemenetek. Az egyes utasítások emulálása, az állapotok frissítése Az obfuszkátor sajátosságai miatt viszonylag egyszerű

Kryptonite II (SMT solving) A függvény végén kapott formula még az SMT solverrel való egyszerűsítés után sem túl barátságos

Kryptonite II (SMT solving) Miért? Azonban Az SMT solver simplify funkciója többnyire szintaktikus szabályok alapján dolgozik, túl bonyolult a kifejezés prove(eax == Sum(sym.sym_variables)) True Azaz: valóban összeadást végez a függvény De: ha ezt nem tudtuk volna előre, hogy jöttünk volna rá hogy mit kérdezzünk a solvertől? Nyitott kérdés

OptiCode Deobfuszkációs megoldás Opaque predicates Junk code LLVM köztes reprezentáció Z3 SMT solver Részben manuális megoldás

OptiCode (junk code) A különböző fordítók optimalizáló és kódgeneráló részei folyamatosan fejlődnek. Kiválóan alkalmasak redundáns kódok eltávolítására Szintaktikus és szemantikus módszerek Az obfuszkált kódot a fordító köztes reprezentációjára konvertálva lefuttathatjuk rajta az optimalizációs lépéseket A kimenetet újra lefordítva tisztább kódot kapunk

OptiCode (opaque predicates) Dinamikus analízis Átlátszatlan feltételek kiszűrése Részben automatizált megoldás Az analízist végző plusz információkkal segíti az eszköz működését, illetve ellenőrzi a feltételek kiválasztását LLVM IR-ből az egyes feltételek SMT formuláinak meghatározása Z3 SMT solverrel a formulák vizsgálata Amennyiben a feltétel mindig igaz vagy hamis, csak a megfelelő ág követése

Összefoglalás - deobfuszkáció A szemantikus módszerek egyre nagyobb teret nyernek Aktív kutatási terület (illetve a kutatási eredmények gyakorlati felhasználása lendületesen halad) Tökéletes védelem nem létezik De reális cél a visszafejtés költségeit jelentősen növelni Kevés a jól használható és ingyenes eszköz Sok nyitott kérdés

Kérdések? Köszönöm a figyelmet!

Felhasznált források http://www.wtbw.co.uk/semantics-based-methods.pdf http://doar-e.github.io/blog/2013/09/16/breaking-kryptonites-obfuscation-with-symbolic-exec Binary-Code Obfuscations in Prevalent Packer Tools by KEVIN A. ROUNDY and BARTON P. MILLER http://www.inf.u-szeged.hu/~akiss/pub/pdf/laszlo_obfuscating.pdf http://blog.sei.cmu.edu/post.cfm/semantic-code-analysis-for-malware-code-deobfuscation http://www.data.proidea.org.pl/confidence/11edycja/nguyen_anh_quynh.pdf