Oletko koskaan tuntenut halua purkaa jotain mekanismia saadaksesi selville, miten se toimii? No, kukapa ei olisi. Tuo halu on käänteisen suunnittelun johtava voima. Tämä taito on hyödyllinen tuotteen tietoturvan analysoinnissa, epäilyttävän .exe-tiedoston tarkoituksen selvittämisessä ajamatta sitä, kadonneen dokumentaation palauttamisessa, uuden ratkaisun kehittämisessä vanhan ohjelmiston pohjalta jne.
Tässä artikkelissa käsittelemme käänteisen insinöörityön suorittamiseen tarvittavaa tietopohjaa, Windows-ohjelmiston käänteisen insinöörityön perusperiaatteita, purkuohjelmia ja työkaluja. Annamme myös vaiheittaisen esimerkin sovelluksen käänteisestä suunnittelusta.
Kirjoittaneet
Sergii Bratus,
Kehityskoordinaattori,
Verkkoturvaryhmä
ja
Anton Kukoba,
Turvallisuustutkimuksen johtaja
Sisältö
Mitä on ohjelmistojen kääntäminen?
Mitä tarvitsemme käänteissuunnitteluun?
Teoreettinen tieto. Ohjelmistojen käänteissuunnitteluprosessi
Käyttökelpoisia työkaluja Windows-ohjelmistojen käänteissuunnitteluun
Disassemblerit
Windows Sysinternals
Verkonvalvontatyökalut
Neuvontatyökalut
Neuvontatyökalut
Todellisessa-life software reverse engineering example
How to reverse engineering a driver
Conclusion
- What is software reversing?
- Mitä tarvitsemme käänteiseen suunnitteluun?
- Teoreettinen tieto. Ohjelmistojen käänteissuunnitteluprosessi
- Hyödyllisiä työkaluja Windows-ohjelmistojen reverse engineeringiin
- Disassemblerit
- Windows Sysinternals
- Verkonvalvontatyökalut
- Debuggerit
- Tosielämän esimerkki ohjelmistojen käänteisestä suunnittelusta
- Ajurin käänteinen suunnittelu
- Johtopäätös
What is software reversing?
Reverse engineering on prosessi, jossa paljastetaan laitteiston tai ohjelmiston taustalla olevat periaatteet, kuten sen arkkitehtuuri ja sisäinen rakenne. Kysymys, joka ohjaa käänteistä suunnittelua, on Miten se toimii?
On selvää, että jos sinulla on dokumentaatio, koko prosessi yksinkertaistuu huomattavasti. Usein käy kuitenkin niin, että dokumentaatiota ei ole, ja sinun on löydettävä jokin muu tapa oppia, miten ohjelmisto toimii.
Milloin saatat tarvita käänteissuunnittelua ohjelmistosta ja miten se voi auttaa sinua?
Käänteistä suunnittelua käytetään tietotekniikan alalla moniin eri tarkoituksiin, esimerkiksi:
- Verkkojen viestintäprotokollien tutkiminen
- Haittaohjelmissa, kuten tietokoneviruksissa, troijalaisissa, lunnasohjelmissa jne. käytettyjen algoritmien löytäminen.
- Tiedostomuodon tutkiminen, jota käytetään minkä tahansa tiedon tallentamiseen, esimerkiksi sähköpostitietokannat ja levykuvat
- Oman ohjelmiston kyvykkyyden tarkistaminen vastustaa käänteismuokkausta
- Ohjelmiston yhteensopivuuden parantaminen alustojen ja kolmansien osapuolten ohjelmistojen kanssa
- Dokumentoimattomien alustan ominaisuuksien käyttäminen
Käänteismuokkauksen laillisuus riippuu sen tarkoituksesta ja siitä, miten ohjelmistoa käytetään. Kaikki edellä mainitut tarkoitukset ovat täysin laillisia, olettaen, että olet hankkinut kopion ohjelmistosta laillisesti. Mutta jos aiot esimerkiksi käänteismallintaa suljetun sovelluksen tietyn ominaisuuden ja toteuttaa sen sitten toisessa sovelluksessa, joudut todennäköisesti vaikeuksiin.
Lainmukaisen dokumentaation osalta käänteismallinnus on usein kielletty loppukäyttäjän lisenssisopimuksissa (EULA). Yhdysvaltain Digital Millennium Copyright Act -laki kuitenkin täsmentää, että ohjelmiston käänteismuokkaus on laillista, jos se” tehdään yhteensopivuuden parantamiseksi muiden tuotteiden kanssa.
Lainsäädännölliset vaatimukset vaihtelevat maittain, joten tutustu niihin rauhassa ennen kuin aloitat.
Katsotaan nyt, miten käänteismuokkaus tehdään.
Mitä tarvitsemme käänteiseen suunnitteluun?
Aloittaaksesi ohjelmistojen käänteisen suunnittelun tarvitset:
- tietämystä alalta, jolla haluat soveltaa käänteistä suunnittelua
- työkaluja, joiden avulla voit soveltaa tietämystäsi yrittäessäsi purkaa ohjelmistoja.
Katsotaanpa yleistä esimerkkiä, joka ei liity ohjelmistoihin. Oletetaan, että sinulla on kello ja haluat selvittää, onko se mekaaninen, kvartsikello vai automaattikello.
Tietämyksesi alalta tarkoittaa, että sinun pitäisi tietää, että kelloja on kolmenlaisia. Lisäksi sinun pitäisi tietää, että jos kellossa on paristo, se sijaitsee kellon sisällä ja näet sen, jos avaat sen. Sinulla pitäisi myös olla perustiedot kellon sisäisestä rakenteesta, siitä, miltä paristo näyttää, ja siitä, mitä työkaluja tarvitset kellon kotelon avaamiseen. Työkalut, joilla voit soveltaa tietojasi, tarkoittavat sitä, että sinulla on oltava ruuvimeisseli tai muu siihen tarkoitettu työkalu, jonka avulla voit avata kellon.
Aivan kuten kellon käänteistekniikka vaatii erityisiä taitoja ja työkaluja, myös käänteistekniikkaohjelmistot vaativat oman alansa erikoisosaamista ja -työkaluja.
Teoreettinen tieto. Ohjelmistojen käänteissuunnitteluprosessi
Erilaisiin ohjelmistojen käänteissuunnittelutehtäviin tarvitaan erityyppistä tietoa. Tietenkin on olemassa yleistä tietämystä, joka auttaa sinua useimmissa käänteissuunnittelutehtävissä: tietämys yleisimmistä sovellusrakenteista, ohjelmointikielistä, kääntäjistä ja niin edelleen. Ilman teoreettista erikoisosaamista et kuitenkaan pysty ratkaisemaan erityisiä käänteiskehitystehtäviä.
Jos… |
Tarvitset tietoa… |
verkkosovellusten käänteentekevää suunnittelua |
prosessien välisen viestinnän periaatteita, verkkojen rakennetta, yhteyksiä, verkkopaketteja jne. |
kääntää salausalgoritmeja |
kryptografia ja alalla käytetyimmät algoritmit |
tutkimustiedosto. rakenteet |
perustiedostokäsitteet ja se, miten eri järjestelmät tai komponentit toimivat tiedostojen kanssa |
Erikoistekniikoilla voidaan säästää paljon aikaa erityyppisiä ohjelmistoja kääntäessä. Tiedostojen vuorovaikutuksen tapauksessa sellaisen testin tekeminen, joka kirjoittaa yksilöllisiä tyyppiarvoja tiedostoon ja kirjaa samalla offsetit ja datan koon varsinaiseen tallennustiedostoon, voi auttaa löytämään yhteisiä malleja offseteissa. Näin saat vihjeen näiden tiedostojen sisäisistä rakenteista.
Käänteistä suunnittelua aloittaessaan ohjelmistokehittäjät käyttävät yleensä disassembleria löytääkseen paikallaan olevat algoritmit ja ohjelmalogiikan. On olemassa monia erilaisia suoritettavia tiedostomuotoja, kääntäjiä (jotka antavat erilaisia tuotoksia) ja käyttöjärjestelmiä. Tämä tekniikoiden moninaisuus estää yhden ainoan tekniikan käytön kaikentyyppisten ohjelmistojen käänteismuokkaukseen.
Purkukoodin ymmärtämiseksi tarvitaan jonkin verran tietoa assembler-kielestä, funktiokutsukäytännöistä, pinorakenteesta, pinokehysten käsitteestä jne.
Erilaisten koodinäytteiden assembler-tulosteiden tunteminen voi auttaa alkuperäisen toiminnallisuuden paljastamisessa. Tarkastellaan joitakin esimerkkejä Windows x86 -alustalle.
Esitettäköön, että meillä on seuraava koodi:
Jos käännämme tämän koodin suoritettavaksi tiedostoksi, näemme disassemblerissä tämän:
Kuten näemme, tavallinen sykli muuttui assemblerikoodiksi, jossa on vertailuja ja hyppyjä. Huomaa, että assembly-koodi ei käytä tavallista assembly-silmukkaa, jossa laskuri on ecx-rekisterissä. Lisäksi paikallisiin muuttujiin viitataan tässä vastaavasti nimillä ja.
Katsotaanpa, mitä tapahtuu, jos käännämme tämän koodin käyttämällä release-buildia:
Tämä koodinpätkä ei näytä lainkaan edelliseltä. Tämä johtuu siitä, miten koodi on optimoitu. Teknisesti ottaen silmukka poistettiin, koska se ei tee mitään muuta arvokasta kuin kasvattaa count-muuttujan arvoksi 10. Niinpä optimoija päätti vain säilyttää count-muuttujan loppuarvon ja sijoittaa arvon suoraan count-ulostulooperaattorin argumentiksi.
Tänään käyttämämme kääntäjät ovat erittäin hyviä optimoimaan koodia. Siksi käänteisessä suunnittelussa on parempi ymmärtää koodin taustalla oleva idea (koodin periaatteet) kuin yrittää saada itse alkuperäistä koodia. Jos ymmärrät idean koodin takana, voit vain kirjoittaa oman prototyypin, joka sopii alkuperäiseen tehtävään.
On erittäin hyödyllistä tietää, mitä assembly-koodia saat, jos käännät erilaisia operaattoreita, rakenteita ja muita kielen rakenteita. Tuloksena syntyvän assembly-koodin ymmärtäminen on hyvä tapa aloittaa C++:n reverse engineering -prosessi, mutta emme mene tässä yhteydessä sen teknisiin yksityiskohtiin.
Hyödyllisiä työkaluja Windows-ohjelmistojen reverse engineeringiin
Sovellusarkkitehtuuritutkimuksessamme kuvasimme jo useita reverse engineering -työkaluja, muun muassa ProcessMonitor ja ProcessExplorer. Nämä työkalut ovat ehdottoman välttämättömiä käänteisessä suunnittelussa.
Tässä osiossa käymme läpi suosituimmat disassemblerit ja muutamat muut työkalut, joita käytämme käänteisessä suunnittelussa.
Lisätietoa ja käyttöesimerkkejä saat artikkelistamme Parhaat ohjelmistojen käänteisen suunnittelun työkalut.
Disassemblerit
Disassembleri eli purkulaite (disassembleriyksityiskohtainen purkulaite) on ohjelma, joka kääntää suoritettavan tiedoston assembler-kieleksi. Suosituin on IDA Pro
IDA Pro
IDA Pro
IDA Pro on kätevä ja tehokas työkalu purkamiseen. Siinä on valtava määrä välineitä, joiden avulla voit nopeasti purkaa ohjelmiston. Se voi näyttää funktiokutsupuun, jäsentää suoritettavan ohjelman tuonnin ja viennin ja näyttää tietoja niistä. Se voi jopa näyttää koodin C-kielellä. Lisäksi se tukee useita CPU-arkkitehtuureja, joten IDA Pro:n avulla on mahdollista purkaa koodia ARM:lle, AVR:lle, M68k:lle ja monille muille arkkitehtuureille.
Radare
Radare
Radare-disassembleri on vaihtoehto IDA:lle. Siinä on periaatteessa kaikki IDA:n ominaisuudet ilman, että se on yhtä vankka ja vakaa. Mutta se on ilmainen ja avoimen lähdekoodin. Radare itsessään on konsolityökalu, mutta siinä on Cutter-etuliite, mikä tekee siitä todellisen vaihtoehdon IDA:lle.
Windows Sysinternals
Windows Sysinternals -apuohjelmia käytetään yleensä Microsoft Windows -ympäristön hallintaan, diagnostiikkaan, vianmääritykseen ja valvontaan. Ne soveltuvat kuitenkin myös Windows-ohjelmistojen käänteiseen suunnitteluun.
TCPView on verkon haistelija, joka näyttää kaikki tiedot TCP/UDP-paketeista kaikista prosesseista. Tämä työkalu on hyödyllinen verkkoprotokollien kääntämiseen.
PortMon on fyysisen järjestelmän porttivalvoja. Se valvoo sarja- ja rinnakkaisportteja ja kaikkea niiden kautta kulkevaa liikennettä.
WinObj näyttää kaikki järjestelmän globaalit objektit hierarkkisessa rakenteessa. Tämä työkalu voi olla hyödyllinen, kun käännetään sovellusta, joka toimii synkronointiprimitiivien, kuten mutexien ja semafoorien, kanssa, ja myös kun käännetään kernel-moodin ajureita.
Verkonvalvontatyökalut
Wireshark
Wireshark
Wireshark on yksi tehokkaimmista verkonhaistelijoista. Sen avulla voit kaapata verkkoliikennettä, mutta se sisältää myös jäsentimet eri verkkoprotokollia varten, alkaen todella matalasta tasosta, kuten Ethernet, TCP ja IP, aina sovelluskohtaisiin protokolliin, kuten WebSockets ja XMPP.
Fiddler
Fiddler
Fiddler on web-välityspalvelin (web proxy), joka rekisteröi liikennettä selaimista ja jonka avulla voit analysoida HTTP/HTTPS-pyyntöjä. Toisin kuin Wireshark, se näyttää HTTP-istunnot erillisten verkkopakettien sijaan. Fiddlerin avulla voit myös analysoida HTTP:n kautta lähetettyä pakattua dataa ja analysoida JSON- ja XML-dataa seurattaessa SOAP-, REST- ja AJAX-pyyntöjä.
API Monitor
API Monitor
API Monitor on hyödyllinen työkalu, jonka avulla voit selvittää, mitä API:ita sovellus kutsuu ja minkälaista käyttäytymistä sovellus odottaa kyseisiltä API:ilta. Tässä työkalussa on tehokas tietokanta, ja sen avulla näet kutsut valtavaan määrään API-funktioita kernel32:n ja ntdll:n lisäksi myös COM:ista, hallitusta ympäristöstä ja muista. Lisäksi API Monitor tarjoaa käteviä suodatusmekanismeja.
Debuggerit
Debuggeri on korvaamaton jokaiselle kehittäjälle, joka haluaa nähdä, mitä ohjelma tekee juuri nyt. Debuggauksesta saa saman hyödyn sovelluksia kääntäessään kuin live-sovellusten debuggauksesta.
Suosituimmat debuggerit ovat OllyDbg, WinDbg ja Windbg Preview.
OllyDbg
OllyDBG
OllyDbg (ja sen seuraaja x64dbg) on luultavasti paras debuggeri ohjelmistojen käänteiskehityksessä. Se on kehitetty erityisesti käänteisohjelmoinnin tarpeisiin, ja siinä on kaikki siihen tarvittavat työkalut:
- sisäänrakennettu disassembleri, jolla on kyky analysoida ja tunnistaa keskeiset tietorakenteet
- tuonti- ja vientianalyysiominaisuus
- sisäänrakennettu kokoonpano- ja paikkausmoottori
Kyky jäsennellä ohjelmointirajapinnan (API) funktioita ja niiden parametreja helpottaa käänteisohjelmoinnin vuorovaikutusta järjestelmän kanssa. Pino-näkymä tarjoaa paljon tietoa kutsupinosta. Yksi tärkeä etu on myös se, että voit käyttää OllyDbg:tä debug-suojattujen sovellusten kanssa, kun tavalliset debuggerit eivät vain pysty tekemään mitään.
WinDbg
Windbg
Yksinkertaisesta käyttöliittymästä huolimatta WinDbg:ssä on tehokkaat työkalut debuggaukseen. Siinä on sisäänrakennettu disassembleri, erilaisia komentoja, joiden avulla voit tietää lähes kaiken debuggaamastasi prosessista/järjestelmästä, ja mahdollisuus tehdä kernel-mode debuggausta, joka on luultavasti arvokkain ominaisuus. Se on suuri etu ajureiden, erityisesti kernel-mode-ajureiden, kääntämisessä.
Windbg Preview
Windbg Preview
Windbg Preview on Microsoftin kehittämä Windbg:n uusi versio. Sitä jaetaan vain Windows Storen kautta. Siinä on kaikki klassisen Windbg:n ominaisuudet yhdistettynä uuteen käyttöliittymään ja useisiin uusiin ominaisuuksiin. Yksi näistä uusista ominaisuuksista on Time Travel Debugging, jonka avulla voit tallentaa jonkin ajanjakson ohjelman suorituksesta ja toistaa sen niin monta kertaa kuin haluat. Näin voit suorittaa koodin mielenkiintoiset osat askel askeleelta pelkäämättä, että suoritat jotakin koodia vahingossa ja menetät kontekstin tai kaikki tiedot.
Lue myös:
9 parasta Reverse Engineering -työkalua vuodelle 2018
Tosielämän esimerkki ohjelmistojen käänteisestä suunnittelusta
Katsomme nyt esimerkin siitä, miten käänteinen suunnittelu tehdään ohjelmistossa. Kuvitellaan, että sinulla on epäilyttävä suoritettava tiedosto. Sinun on selvitettävä, mitä tämä ohjelma tekee ja onko se turvallinen käyttäjille.
Skenaarion huomioon ottaen on hyvä ajatus olla ajamatta tätä suoritettavaa tiedostoa työkoneellasi vaan käyttää sen sijaan virtuaalikonetta. Käynnistetään sovellus virtuaalikoneessamme.
Prosessi luo palvelun
Kuten näemme, tämä tiedosto luo Windows-palvelun nimeltä TestDriver. Sen tyyppi on kernel, joten tiedämme sen olevan ajuri. Mutta mistä se ottaa ajuritiedoston toimiakseen? Voimme käyttää ProcessMonitoria Sysinternals Suite -ohjelmasta saadaksemme sen selville. Kun avaamme ProcessMonitorin, voimme asettaa suodattimia, jotka näyttävät meille vain sen prosessin tiedostoaktiviteetin, josta olemme kiinnostuneita. Sen toimintaloki näyttää tältä:
FileMon information
Ajuritiedoston luo prosessi, jonka käännämme, ja tämä prosessi sijoittaa tiedoston käyttäjän temp-hakemistoon. Tiedostoa ei tarvitse etsiä temp-kansiosta, koska näemme, että prosessi poistaa sen heti käytön jälkeen. Mitä prosessi tekee tälle tiedostolle? Jos se purkaa tiedoston, voimme yrittää etsiä sitä prosessin resurssiosiosta, koska se on yleinen paikka tällaisten tietojen tallentamiseen. Katsotaanpa sieltä. Käytämme toista työkalua – Resource Hacker – resurssien tutkimiseen. Käynnistetään se:
Examine resources with Resource Hacker
Bingo! Kuten löydetyn resurssin sisällöstä näemme, kyseessä on luultavasti Windowsin suoritettava tiedosto, sillä se alkaa MZ-allekirjoituksella ja siinä on merkkijono ”Tätä ohjelmaa ei voi ajaa DOS-tilassa”. Tarkistetaan, onko se ajuritiedostomme. Sitä varten puretaan resurssi Resource Hackerilla ja avataan se disassemblerilla.
Disassemblerin näyttö
Kuten tiedämme, DriverEntry on Windows-järjestelmissä kernel-moodin ajureiden sisäänmenopiste. Voimme jatkaa tutkimustamme, sillä näyttää siltä, että olemme löytäneet oikean ajurin.
Ajurin käänteinen suunnittelu
Aloittaaksemme ajurin käänteisen suunnittelun, tutkimme DriverEntrystä kutsuttuja funktioita yksi kerrallaan. Jos menemme sub_14005:een, emme löydä mitään mielenkiintoista, joten jatkamme sub_110F0:sta ja löydämme tämän koodin:
Koodinpätkä 1
Koodinpätkä 2
Koodinpätkä 3
Koodinpätkä 4
Joitain rivejä jätetään tässä pois yksinkertaisuuden vuoksi.
Ensimmäisessä listauksessa luodaan unicode-merkkijono, joka osoittaa polkuun C:\hello.txt. Tämän jälkeen rakenne OBJECT_ATTRIBUTES täytetään tavallisilla arvoilla; tiedämme, että tätä rakennetta tarvitaan usein kutsuttaessa funktioita, kuten ZwCreateFile.
Toisessa listauksessa näemme, että ZwCreateFileä tosiaan kutsutaan, mikä tekee meistä melko varmoja siitä, että ajuri luo tiedoston – ja tiedämme, missä tämä tiedosto sijaitsee sen luomisen jälkeen.
Kolmannesta ja neljännestä listauksesta näemme, että ajuri ottaa unicode-merkkijonon ja kirjoittaa sen puskuriin (tämä tapahtuu funktiossa sub_11150), ja puskuri kirjoitetaan tiedostoon funktiolla ZwWriteFile. Lopuksi ajuri sulkee tiedoston käyttämällä ZwClose API:ta.
Kerrataanpa yhteenveto. Saimme selville, että alkuperäinen ohjelma poimii ajuritiedoston resursseistaan, sijoittaa sen nykyisen käyttäjän temp-kansioon, luo Windows-palvelun tälle ajurille ja ajaa sen. Tämän jälkeen ohjelma pysähtyy ja poistaa palvelun ja alkuperäisen ajuritiedoston temp-hakemistosta. Tämän käyttäytymisen ja purkamisen analysoinnin perusteella näyttää siltä, että ajuri ei tee mitään muuta kuin luo C-asemaan tiedoston nimeltä hello.txt ja kirjoittaa siihen merkkijonon ”Hello from driver”.
Nyt on tarkistettava, että olemme oikeassa. Käynnistetään ohjelma ja tarkistetaan C-asema:
Sovelluksen näyttö
Hienoa! Olemme tehneet reverse engineeringin tästä yksinkertaisesta ohjelmasta ja nyt tiedämme, että sitä on turvallista käyttää.
Olisimme voineet saavuttaa tämän tuloksen monella eri tavalla – käyttämällä debuggausta tai API Monia, kirjoittamalla testejä jne. Voit keksiä omat, sinulle sopivat tavat ohjelmistojen käänteistekniikkaan.
Johtopäätös
Windows-ohjelmistojen käänteistekniikka vaatii vankan koulutustaustan ja ohjelmointikokemusta. Käänteissuunnittelun suorittamiseksi sinun on yhdistettävä purkamisen, verkonvalvonnan, virheenkorjauksen, API-integroinnin, useiden ohjelmakielten, kääntäjien jne. taidot. Sinun on myös oltava hyvin varovainen, kun käännät ohjelmistoja, jotta et rikkoisi tekijänoikeuslakeja tai vahingoittaisi järjestelmääsi.
Aprioritilla meillä on kokenut käänteisinsinööritiimi. Jos haluat soveltaa reverse engineering -taitoja projektissasi, ota rohkeasti yhteyttä meihin!