Взлом хешей методом перебо­ра — одно из клю­чевых хакер­ских занятий. Глав­ное в этом деле — эффектив­ность, а что­бы ее добить­ся, нуж­но раз­бирать­ся в железе. Сегод­ня вспом­ним, как устро­ен CPU, как мож­но исполь­зовать GPU, с какой сто­роны под­сту­пить­ся к GPGPU, CUDA и OpenCL.

info

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

Хеш­кре­кинг (от англий­ско­го hash cracking — бук­валь­но «рас­калыва­ние хешей») — это область крип­тоана­лиза (или информа­цион­ной безопас­ности, смот­ря с какой сто­роны подой­ти), где цель — най­ти зна­чение сооб­щения, которое было про­пуще­но через хеш‑фун­кцию. Для нас хеш­кре­кинг акту­ален имен­но из‑за того, что самый рас­простра­нен­ный спо­соб хра­нения паролей имен­но в хешах. Поэто­му его час­то называ­ют вос­ста­нов­лени­ем паролей.

Сра­зу отме­тим, что хеш­кре­кинг — это тема стро­го офлай­новая, она никак не свя­зана со спре­ингом паролей (password spraying) или брут­форсом (brute force) при ата­ках на сис­темы аутен­тифика­ции.

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

На­ши шан­сы край­не малы, но есть методы, которые помогут начать сис­темати­чес­ки выиг­рывать в этом бою. Но, как ни кру­ти, нам при­дет­ся вычис­лять хеши, сот­ни или даже сот­ни тысяч хешей.

В девянос­тые и начале нулевых никому бы и в голову не приш­ло спо­рить о том, что явля­ется вычис­литель­ным сер­дцем компь­юте­ра, ответ был бы оче­виден — цен­траль­ный про­цес­сор (он же ЦП или CPU). Но сегод­ня все не так однознач­но: гра­фичес­кие про­цес­соры (ГП или GPU) ста­ли такими мощ­ными, что в некото­рых задачах ЦП уже слож­но кон­куриро­вать.

 

Как работает CPU?

Сов­ремен­ный ЦП — это крем­ниевая плас­тина, на которой в пер­вую оче­редь раз­меща­ются вычис­литель­ные ядра, а осталь­ное прос­транс­тво отда­но под мно­гоуров­невую кеш‑память, модули безопас­ности (они сле­дят, что­бы раз­ные ядра не занима­лись одним и тем же и не перег­ревались) и шины соеди­нения с перифе­рий­ными устрой­ства­ми.

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

Внут­ри ядра про­цес­сы под­чинены архи­тек­туре фон Ней­мана: извле­чение из памяти → декоди­рова­ние → выпол­нение → запись в память. За пер­вые два эта­па отве­чает фрон­тенд ядра (он, помимо про­чего, содер­жит еще и модули вет­вле­ния и парал­лелиза­ции команд) и модуль вне­оче­ред­ного выпол­нения команд.

Даль­ше в бой всту­пает ядер­ный бэкенд, где инс­трук­ции попада­ют в вычис­литель­ное сер­дце ЦП — ариф­метико‑логичес­кое устрой­ство (ALU). Одно ALU может выпол­нять одну или нес­коль­ко опе­раций сме­щения или перехо­да, ариф­метичес­ких или логичес­ких опе­раций, а иног­да и целые выраже­ния (FMA, DIV, MUL). Так­же ALU может работать с целыми чис­лами (прис­тавка INT), с десятич­ными (FPU или прис­тавка FP) и с чис­лами раз­ных раз­меров (FP32, FP64, ...).

Пред­став­ляешь, какое количес­тво раз­ношерс­тных ALU дол­жно умес­тить­ся в одно малень­кое ядро? Но в ядре есть еще и раз­ные уров­ни памяти, а так­же дорож­ки ком­муника­ции меж­ду всем этим доб­ром.

Пос­коль­ку ЦП дол­жен раз за разом выпол­нять любые инс­трук­ции, то его ядра боль­шие и уни­вер­саль­ные: с гро­моз­дким фрон­тендом и ALU всех типов. Пло­щадь на крис­талле огра­ниче­на, поэто­му чис­ло таких ядер тоже огра­ниче­но.

Почему не делают большие CPU

Ре­зон­ный воп­рос: почему бы не сде­лать CPU боль­шего раз­мера?

  • Во‑пер­вых, ЦП — это монолит­ный блок. Чипы про­изво­дят­ся на плас­тинах диамет­ром ~30 см, у которых всег­да есть дефек­ты. Цена ошиб­ки доволь­но высока: иног­да при­ходит­ся выб­расывать весь чип. Поэто­му чем боль­ше чипов мы смо­жем раз­местить на плас­тине, тем боль­ше у нас оста­нет­ся качес­твен­ных изде­лий. Ничего лич­ного, прос­то биз­нес.
  • Во‑вто­рых, обыч­ному поль­зовате­лю более чем дос­таточ­но текущих мощ­ностей, поэто­му смыс­ла вкла­дывать­ся в раз­работ­ку кар­диналь­но новой архи­тек­туры нет (для жела­ющих сущес­тву­ют ЦП более чем со 100 ядра­ми, но они, оче­вид­но, силь­но дороже).
  • На­конец, боль­ший чип озна­чает боль­шее рас­сто­яние и боль­шее соп­ротив­ление для сиг­нала, что вли­яет на ско­рость и огра­ничи­вает так­товую час­тоту, не говоря уже о теп­ле, которое нуж­но отво­дить.
Схема одного ядра CPU
Схе­ма одно­го ядра CPU
 

Великий и могучий GPU

Компь­юте­ры про­дол­жали бы весело молотить чис­ла на сво­их про­цес­сорах, но в семиде­сятые начали появ­лять­ся дис­плеи для вывода гра­фики. Прос­чет геомет­рии сна­чала выпол­няли пол­ностью на ЦП, но пос­тепен­но он ста­новил­ся узким гор­лышком при работе с гра­фикой. Поэто­му ста­ли появ­лять­ся отдель­ные чипы для уско­рения 2D- и 3D-гра­фики.

В 1984 году ком­пания IBM выпус­тила PGC, который сос­тоял из трех отдель­ных плат, каж­дая — со сво­им чипом и памятью. По сути, это был пер­вый GPU. А раз­работ­чики компь­юте­ра Amiga 1000 в 1985 году пол­ностью сня­ли с ЦП вычис­ление гра­фики. Впер­вые тер­мин GPU появил­ся толь­ко в 1994 году в докумен­тации к пер­вой PlayStation, а популя­ризи­рова­ла тер­мин Nvidia, выпус­тив GeForce 256, которая счи­тает­ся пер­вым GPU, каким мы его зна­ем сегод­ня. То есть сов­ремен­ный GPU — это доволь­но молодое изоб­ретение.

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

О GPU

Да­вай вне­сем ясность: гра­фичес­кий про­цес­сор (ГП или GPU) — не то же самое, что и виде­окар­та. Так же как ЦП — не то же самое, что и материн­ская пла­та. Поэто­му говорить мы будем имен­но о ГП, что­бы срав­нение с ЦП было кор­рек­тным.

ГП быва­ет ин­тегри­рован­ным (iGPU) и дис­крет­ным (dGPU). iGPU занима­ет при­мер­но 40% все­го чипа ЦП и делит с ядра­ми общие память, питание и охлажде­ние.

Все ЦП про­изводс­тва Intel без суф­фикса F име­ют iGPU, у AMD все более запутан­но, но это лиш­ний раз ука­зыва­ет нам на то, что боль­шая часть чипа ЦП занята сов­сем не ядра­ми. dGPU находит­ся на виде­окар­те, име­ет свою память, которая быс­трее, чем у ЦП, свое питание и охлажде­ние.

Важ­но понять, что GPU не выпол­няет работу CPU, а выс­тупа­ет соп­роцес­сором. При получе­нии задачи ЦП делеги­рует ее на внеш­ний для себя GPU, при этом про­дол­жая кон­тро­лиро­вать ее исполне­ние.

Продолжение доступно только участникам

Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».

Присоединяйся к сообществу «Xakep.ru»!

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии