Причуды «Фемиды». Пишем лоадер для программ, защищенных Themida

Причуды «Фемиды». Пишем лоадер для программ, защищенных Themida

the Matrix

Статья написа­на в иссле­дова­тель­ских целях, име­ет озна­коми­тель­ный харак­тер и пред­назна­чена для спе­циалис­тов по безопас­ности. Автор и редак­ция не несут ответс­твен­ности за любой вред, при­чинен­ный с при­мене­нием изло­жен­ной информа­ции. Исполь­зование или рас­простра­нение ПО без лицен­зии про­изво­дите­ля может прес­ледовать­ся по закону.

В прош­лый раз мы обсужда­ли прин­ципы внут­ренней орга­низа­ции вир­туаль­ной машины Themida. А теперь давай зак­репим получен­ные зна­ния на кон­крет­ном при­мере — поп­робу­ем оту­чить про­сить ключ пароч­ку популяр­ных при­ложе­ний фир­мы ConceptWorld. Эти при­ложе­ния пред­став­ляют собой набор мел­ких дешевых полез­няшек для работы с фай­лами, замет­ками и буфером обме­на.

Лич­но я не сов­сем понимаю при­чину популяр­ности этих ути­лит, более того, меня бесят их назой­ливые окош­ки, бол­тающиеся на экра­не и воз­ника­ющие в самый непод­ходящий момент. Но самое раз­дра­жающее зак­люча­ется в том, что на столь прос­тые и дешевые при­ложе­ния навеси­ли столь взрос­лую защиту, в чем мож­но убе­дить­ся при помощи детек­тора про­тек­торов DetectItEasy (Die). Этот стран­ный факт мы с тобой сей­час испра­вим.

При­ложе­ния ConceptWorld отлично подой­дут для демонс­тра­ции сла­бых мест защиты, которые мы с тобой изу­чим исклю­читель­но в ака­деми­чес­ких и иссле­дова­тель­ских целях. На вся­кий слу­чай еще раз напом­ню, что акту­аль­ная Themida не всег­да рас­позна­ется авто­мати­чес­ким ска­ниро­вани­ем, для подс­тра­хов­ки необ­ходимо под­клю­чать Nauz File Detector (NFD), который прак­тичес­ки всег­да опре­деля­ет ее пра­виль­но.

Итак, нач­нем с прог­раммы RecentX. Ради эко­номии мес­та я не буду занимать­ся рек­ламой, опи­сывая, для чего она слу­жит и что уме­ет делать (тем более, сам до кон­ца это­го не понимаю). Давай сра­зу перей­ду к сути защиты. При запус­ке при­ложе­ния (а так­же пос­ле переза­пус­ка сис­темы, пос­коль­ку эта ути­лита наг­ло про­писы­вает­ся в авто­заг­рузку), в вер­хней час­ти экра­на появ­ляет­ся пять вкла­док, которые поз­воля­ют выпол­нять раз­личные дей­ствия. Тул­за отлично работа­ет 30 дней, по про­шес­твии которых прев­раща­ется в тык­ву: нажатие на любой эле­мент интерфей­са при­водит к появ­лению нас­тырно­го окош­ка с тре­бова­нием зарегис­три­ровать прог­рамму.

В этот раз я нарушу собс­твен­ные же пра­вила и нач­ну с опи­сания прин­ципа сбро­са три­ала. Если ты уже читал мои статьи, то зна­ешь, что для начала нам понадо­бит­ся прог­рамма ProcessMonitor (ProcMon). Запус­каем ее, ста­вим филь­тр на имя про­цес­са RecentX.exe и для начала ана­лизи­руем фай­ловый ввод‑вывод это­го про­цес­са при его заг­рузке.

Это неп­росто, пос­коль­ку по сво­ей спе­цифи­ке прог­рамма обра­щает­ся чуть ли не ко всем фай­лам на жес­тком дис­ке. Одна­ко полис­тав спи­сок некото­рое вре­мя, мы натыка­емся на пос­ледова­тель­ные обра­щения к фай­лам со стран­ными неп­роиз­носимы­ми наз­вани­ями в катало­ге ProgramData.

Поп­робу­ем уда­лить, к при­меру, файл C:\ProgramData\xmvkknpt.yme. Ничего не про­исхо­дит, но при переза­пус­ке прог­раммы он вос­созда­ется на том же самом мес­те. Судя по всем приз­накам, это и есть файл три­ала.

Вни­матель­но про­ана­лизи­ровав лог ProcMon, мы обна­ружи­ваем пол­ный набор подоб­ных фай­лов. Все они находят­ся в катало­ге ProgramData: acqrldoh.otw, bgjxnlpy.hxt, lapoiwsc.hke, uhthdans.svu, vwnpbcnu.gon, xmvkknpt.yme и mntemp. При­чем вре­мя от вре­мени вмес­то фай­лов acqrldoh.otw и vwnpbcnu.gon прог­рамма ищет дру­гую пару — wspjaeoc.kjj и tvmnixvk.oib. Одна­ко даже уда­лив все фай­лы из катало­га ProgramData, удов­летво­рения мы не получим — прог­рамма упор­но про­дол­жает про­сить регис­тра­цию.

По сво­ему пре­дыду­щему опы­ту я пом­ню, что помимо фай­лов, информа­ция о три­але обыч­но дуб­лиру­ется в реес­тре, потому начина­ем рыть в этом нап­равле­нии. Вклю­чаем в ProcessMonitor режим Show Registry Activity и начина­ем тща­тель­но и кро­пот­ливо изу­чать обра­щения прог­раммы к сис­темно­му реес­тру.

По­хоже, мы в беде: зацепить­ся не за что: все клю­чи реес­тра, к которым идет обра­щение, на пер­вый взгляд, ни к "Фемиде", ни к три­алу никако­го отно­шения не име­ют — прог­рамма дела­ет что‑то свя­зан­ное с сер­тифик­тами. Что­бы раз­рулить тупико­вую ситу­ацию, нам явно пот­ребу­ются допол­нитель­ные инс­тру­мен­ты.

Поп­робу­ем ути­литу Registry Trash Keys Finder, которая пред­назна­чена для более интеллек­туаль­ной чис­тки реес­тра. Гру­бо говоря, при помощи этой прог­раммы мож­но получить при­мер­ное пред­став­ление, какие клю­чи в реес­тре не несут полез­ной наг­рузки и каково было их изна­чаль­ное пред­назна­чение. Мы не про­гада­ли: ключ HKCU\Software\Classes\CertificateAuthority.Request\CLSID\tkgiuafq яко­бы свя­зан­ный с сер­тифика­тами, ока­зыва­ется нап­рямую свя­зан с WinLicense. При­чем рядом рас­положе­но мно­жес­тво подоб­ных клю­чей, а мы бы на них никог­да и не подума­ли!

По­мимо это­го Registry Trash Keys Finder находит в реес­тре мно­жес­тво скры­тых три­аль­ных клю­чей от дру­гих про­тек­торов. Вни­матель­но прой­дясь по логу обра­щений к реес­тру в шаговой дос­тупнос­ти от это­го мес­та, кро­ме откро­вен­но фемидов­ских клю­чей находим спи­сок фик­тивных клю­чей, мар­киру­емых прог­раммой как «Невер­ное имя для CLSID». Что инте­рес­но, вре­мя их соз­дания соот­ветс­тву­ет нашему три­алу:

Уда­ляем эти клю­чи вмес­те с най­ден­ными фай­лами — бин­го, три­ал сбро­шен! Поп­робу­ем зак­репить успех для осталь­ных прог­рамм это­го про­изво­дите­ля. Что­бы не рас­текать­ся мыслью по дре­ву, при­веду в качес­тве при­мера толь­ко пор­табель­ные 32-бит­ные вер­сии. Возь­мем Notezilla. Соот­ветс­тву­ющие фай­лы три­ала для нее тоже живут в катало­ге ProgramData, хоть и называ­ются по‑дру­гому: blejnwva.rcm, bueobidn.ojo, cyslknnt.dlv, dyjcmtbi.sxr, fqnyawif.yei, htisjfog.xco, uqvsamsm.gdq, xmvnjmsu.toe. Отве­чающие за три­ал клю­чи реес­тра для этой прог­раммы выг­лядят так:

Уда­ление соот­ветс­тву­ющих фай­лов и клю­чей так­же при­водит к обну­лению три­ала Notezilla.

На­конец раз­берем­ся с треть­ей прог­раммой, Copywhiz. С ней дело обсто­ит чуть слож­нее, пос­коль­ку «Фемида» навеше­на не на основном исполня­емом фай­ле Copywhiz.exe, а на вспо­мога­тель­ном, CopywhizCopy.exe (который запус­кает­ся из основно­го при выпол­нении какого‑либо дей­ствия), а так­же на соот­ветс­тву­ющих прог­рамме пун­ктах кон­текс­тно­го меню. Итак, перечис­лим три­аль­ные фай­лы для нее из того же катало­га ProgramData: mntemp, uiqgndne.cop, lnaychdo.pku, ldrbrntx.mrr, nylnduck.ivy, cougyhgc.fqc, vtoynwkm.ggb. А вот клю­чи реес­тра:

На при­мере этих трех прог­рамм мы уже можем вырабо­тать общую стра­тегию борь­бы с фемидов­ски­ми три­ала­ми. Судя по все­му, все фай­лы три­ала рас­полага­ются в катало­ге ProgramData. Хотя наз­вания у них и фор­миру­ются слу­чай­ным обра­зом, одна­ко они всег­да оди­нако­вые для кон­крет­ной прог­раммы, и спи­сок рас­ширений у них тоже всег­да стан­дар­тный. Веро­ятно, воз­можны и дру­гие рас­ширения, отличные от вышепе­речис­ленных, одна­ко это лег­ко вычис­ляет­ся при помощи ProcessMonitor.

Ког­да мы зна­ем, что имен­но искать, эти фай­лы прос­то бро­сают­ся в гла­за. Более того, они име­ют еще и оди­нако­вые раз­меры — всег­да 8 или 12 байт (mntemp — 16 байт). Поэто­му уда­лив их, а заод­но — все три­аль­ные клю­чи в реес­тре, помечен­ные Registry Trash Keys Finder как WinLicense 1.x и «Невер­ное имя для CLSID», мы прак­тичес­ки с пол­ной уве­рен­ностью можем сбро­сить фемидов­ский три­ал для любой прог­раммы.

Од­нако давай все‑таки поп­робу­ем отвя­зать подопыт­ные прог­раммы от три­ала пол­ностью. Общие прин­ципы иссле­дова­ния и взло­ма защищен­ных Themida при­ложе­ний мы рас­смат­ривали в пре­дыду­щей статье, поп­робу­ем при­менить эти зна­ния на прак­тике.

Для начала сдам­пим прог­раммы для иссле­дова­ния, заг­рузив их в отладчик x64dbg. Анти­отладку обхо­дим при помощи пла­гинов ScyllaHide и Themidie, хотя в дан­ном кон­крет­ном слу­чае дос­таточ­но и прос­того ScyllaHide с кон­фигура­цией Themida — прог­раммы прек­расно заг­ружа­ются и трас­сиру­ются без каких‑либо проб­лем. Дам­пим по стан­дар­тной схе­ме при помощи пла­гина Scylla. Не будем замора­чивать­ся с пол­ной отвязкой и вос­ста­нов­лени­ем импорта, прос­то заг­рузим дам­пы в IDA для иссле­дова­ния.

Что может быть обще­го у столь раз­ных прог­рамм? Пра­виль­но — диалог регис­тра­ции, выс­какива­ющий при про­туха­нии три­ала. Мес­та заг­рузки это­го диало­га одно­тип­ные и лег­ко находят­ся во всех трех прог­раммах.

Notezilla:

RecentX:

Copywhiz:

Ты, навер­ное, заметил, что пер­вый слу­чай самый нехоро­ший: в прог­раммах RecentX и Copywhiz код вызова диало­га регис­тра­ции офор­млен в нор­маль­ные про­цеду­ры, вызыва­емые из нор­маль­ного кода, а в Notezilla дан­ный фраг­мент прос­то висит в воз­духе, что быва­ет при вызове из вир­туали­зиро­ван­ного кода. Если ты читал мою пре­дыду­щую статью про «Фемиду», то навер­няка пом­нишь, как неп­росто копать­ся в ее вир­туаль­ной машине.

По­это­му исполь­зуем спо­соб полег­че. Пос­коль­ку у нас работа­ет трас­сиров­ка, поп­робу­ем по сте­ку вызовов отсле­дить точ­ку вхо­да в вир­туали­зиро­ван­ный фраг­мент кода, из которо­го вызыва­ется это окно. Вот она:

Сде­лаем сме­лое пред­положе­ние, что помимо про­вер­ки экспи­рации три­ала вир­туали­зован­ный фраг­мент кода не несет в себе никаких жиз­ненно важ­ных для прог­раммы дей­ствий. Про­верить эту гипоте­зу очень прос­то — пря­мо в отладчи­ке меня­ем переход по адре­су 45698C с 15A834A на конец про­цеду­ры 456A7C, пос­ле чего запус­каем прог­рамму.

И бин­го! Прог­рамма запус­кает­ся как ни в чем не бывало безо вся­кого регис­тра­цион­ного окна! Теперь надо при­думать, как офор­мить этот алго­ритм в виде кря­ка. Пря­мой патч EXE здесь, по понят­ным при­чинам, не годит­ся: код запако­ван и зашиф­рован, да еще и с парано­идаль­ным кон­тро­лем целос­тнос­ти, то есть, самое быс­трое и прос­тое решение — патч пря­мо в памяти.

В моей прош­лой статье, пос­вящен­ной Themida, я при­водил при­мер это­го метода, опи­рающе­гося на вызыва­емую из основно­го про­цес­са откры­тую DLL. Забегая чуть впе­ред, ска­жу, что на этот раз мы поп­робу­ем такой спо­соб при­мени­тель­но к дру­гой прог­рамме — RecentX, но сна­чала пой­дем от прос­того к слож­ному. Поэто­му для зат­равки рас­смот­рим еще более прос­той спо­соб пат­ча — через лоадер. При­чем лоадер даже не обя­затель­но писать самому, доб­рые и умные люди написа­ли мно­жес­тво раз­нооб­разных лоаде­ров на любой вкус, выб­рать под­ходящий мож­но на этой стра­нице.

К сожале­нию, дру­гие доб­рые люди тоже сле­дят за прог­рессом в этой области и, что­бы помешать рас­простра­нению сво­бод­ного прог­рам­мно­го обес­печения, упор­но вно­сят лоаде­ры в анти­вирус­ные базы. При­ходит­ся мирить­ся с тем, что све­жес­качан­ный лоадер может быть с виз­гом убит встро­енным анти­виру­сом. Я выб­рал для при­мера более‑менее без­различ­ный анти­виру­сам Abel Loader Generator, хотя, как показа­ла прак­тика, и его самого, и про­изве­ден­ные им лоаде­ры на мно­гих сис­темах тоже при­дет­ся извле­кать из каран­тинов и вно­сить в исклю­чения защит­ного ПО.

Поль­зовать­ся этим генера­тором не прос­то, а очень прос­то — нуж­но выб­рать запус­каемую прог­рамму, подоб­рать вре­мя задер­жки и, собс­твен­но, патч. В нашем слу­чае патч сос­тоит в том, что пос­ле рас­паков­ки прог­раммы по адре­су 45698C нуж­но поменять безус­ловный переход jmp 15A834A (пос­ледова­тель­ность байт E9 B9 19 15 01) на дру­гой безус­ловный переход jmp 456A7C (пос­ледова­тель­ность байт E9 EB 00 00 00). Выг­лядит это так.

На­жима­ем кноп­ку Generate! — и лоадер для прог­раммы Notezilla готов. Помеща­ем его в рабочий каталог при­ложе­ния и переве­шива­ем на него шот­кат. Мож­но поль­зовать­ся.

Од­нако ты сам понима­ешь, что лоадер, тем более чужой — это спо­соб для сов­сем ленивых. Глав­ный недос­таток опи­сан­ного метода ты уже, навер­ное, понял: анти­виру­сы такие лоаде­ры чер­тов­ски не любят. Мож­но, конеч­но, написать свой собс­твен­ный уни­каль­ный лоадер, воз­можно, я ког­да‑нибудь оста­нов­люсь на этом более под­робно, но сей­час у нас мало вре­мени.

По­это­му в зак­лючение пос­тро­им для прог­раммы RecentX патч моим любимым спо­собом — на осно­ве зависи­мой биб­лиоте­ки mfc140u.dll. Для начала я опи­шу суть пат­ча. Выше я при­водил код про­цеду­ры вызова окна лицен­зии по адре­су 480E60. Рас­смот­рим ссыл­ки на эту про­цеду­ру:

Вид­но, что вез­де фигури­рует гло­баль­ная перемен­ная 56A018, при ненуле­вом зна­чении которой выб­ранное дей­ствие отра­баты­вает нор­маль­но без вызова окош­ка акти­вации прог­раммы. То есть, в сущ­ности, для акти­вации при­ложе­ния дос­таточ­но прис­воить этой перемен­ной ненуле­вое зна­чение.

Но как отсле­дить этот момент и как прис­воить нуж­ное зна­чение? Про­ана­лизи­ровав сдам­плен­ный код в IDA, мы обна­ружи­ваем, что прог­рамма написа­на на май­кро­соф­тов­ском C и активно юза­ет MFC-шные фун­кции из биб­лиоте­ки mfc140u.dll. Ста­вя бря­ки на раз­личные фун­кции экспор­та этой биб­лиоте­ки и запус­кая прог­рамму, мы при­ходим к выводу, что боль­ше все­го нам под­ходит фун­кция __thiscall ATL::CSimpleStringT<wchar_t,1>::CSimpleStringT<wchar_t,1>(wchar_t const *,int,struct ATL::IAtlStringMgr *)> (поряд­ковый номер 270). Она вызыва­ется прак­тичес­ки сра­зу пос­ле того, как код прог­раммы рас­пакован в память и перемен­ная 56A018 про­ини­циали­зиро­вана.

Нам нуж­но все­го‑нав­сего поп­равить дан­ную фун­кцию так, что­бы она перед сво­им выпол­нени­ем записы­вала в перемен­ную 56A018 зна­чение 1. Не буду под­робно опи­сывать про­цесс пос­тро­ения пат­ча, пос­коль­ку неод­нократ­но делал это в сво­их пре­дыду­щих стать­ях. Оста­нов­люсь толь­ко на спо­собе получе­ния реаль­ного адре­са перемен­ной 56A018 из кода пат­ча. Итак, рас­смот­рим стек про­цес­са в момент вызова фун­кции 270.

Об­рати вни­мание: адрес воз­вра­та в про­цесс RecentX (44F985) лежит в сте­ке по адре­су [esp+0xC]. Отло­жив от это­го адре­са сме­щение 11A693, получа­ем адрес нуж­ной нам перемен­ной 56A018. Резуль­тиру­ющий код пат­ча mfc140u.dll выг­лядит так:

За­меня­ем в рабочем катало­ге прог­раммы биб­лиоте­ку mfc140u.dll — и мож­но забыть о три­але.

Я думаю, мы разоб­рали дос­таточ­но при­ложе­ний для того, что­бы поль­зуясь получен­ным опы­том, ты понимал устрой­ство одно­тип­ных защит. Как видишь, нес­мотря на всю кру­тиз­ну про­тек­тора, дос­таточ­но все­го лишь най­ти пра­виль­ный под­ход, и тог­да задача взло­ма Themida впол­не посиль­на, и даже мес­тами рутин­на. Конеч­но, всег­да воз­можны нюан­сы, к раз­бору которых мы еще обя­затель­но ког­да‑нибудь вер­немся.


Источник

Наши проекты:

- Кибер новости: the Matrix
- Хакинг: /me Hacker
- Кодинг: Minor Code

Report Page