В предишната публикация направих много кратък преглед на някои концепции за машинно обучение, говорих за проекта Revoke-Obfuscation и описах подробно моите усилия за подобряване на набора от данни и моделите за откриване на обфускирани скриптове на PowerShell. Това доведе до три отделни настроени модела за скрито откриване на скриптове на PowerShell: модел на логистична регресия с L2/Ridge регуляризация, LightGBM класификатор и 4-слойна напълно свързана невронна мрежа. Ако не сте запознати с машинното обучение, силно препоръчвам да прочетете „първата публикация“, преди да се гмурнете тук.

В тази публикация ще покажа как да атакувате тези три модела. Тази област на изследване е известна като съперничещо машинно обучениеи е доста млада дисциплина. Докато „документ от 2018 г.“ на Батиста Биджо и Фабио Роли посочва, че академичните изследвания върху атакуващото машинно обучение датират най-малко от „2004 г. с Dalvi et al.“, а документът от 2013 г. „„Интригуващи свойства на невронните мрежи»” от Szegedy et al. показа някои от първите състезателни примери за невронни мрежи, полето не започна да се развива до около 2014 г. Документът от 2018 г. „Диви модели: десет години след възхода на съперническото машинно обучениеот Biggio et al. има страхотна времева линия, която документира еволюцията на състезателното машинно обучение до 2018 г.:

Прочетох много (предимно академични) материали за състезателното машинно обучение и една от основополагащите работи на специалистите, които често се позовават, е документът от 2014 г. „Обяснение и използване на състезателни примери“ от Гудфелоу и др. Алгоритъмът за атака, описан в този документ, известен като Fast Gradient Sign Method (FGSM), е една от „най-старите“ „практически внедрени атаки“ в един от най-утвърдените комплекти инструменти за машинно обучение, „Adversarial Robustness Toolbox“.

Тази публикация ще третира тези модели от подхода на бялата кутия, където имаме целия обучен модел, включително входните функции, архитектурата на модела и параметрите/теглата на модела. Третият пост от тази поредица ще разгледа атакуването на тези модели от гледна точка на черна кутия, където са известни само входните функции, което е по-труден проблем.

Ще бъда небрежен, ако не спомена „цялата работа“, която Уил Пиърс („@moo_hax“) е свършил през последните няколко години по състезателното машинно обучение в информационната сигурност. Работата му беше вдъхновение за мен да започна в тази област и много от усилията, които полагам, са повторения на първоначалните му идеи.

Бележниците на Jupyter, описани в тази публикация, вече са актуализирани в хранилището Invoke-Evasion.

Състезателно машинно обучение

Въпреки че състезателното машинно обучение е сравнително нова дисциплина, има разумно количество материал, описващ подробно изследвания в тази област. Преди това беше предимно академично, но през последните няколко години започнаха „практически“ „рамки“, които прилагат много от атаките, които преди това съществуваха само в бели книги.

За съжаление повечето от изследванията изглежда са били в областта на разпознаването на изображения. Вярвам, че причината за това вероятно е, защото а) класификаторите на изображения са много често срещано приложение на машинното обучение и б) можете да модифицирате всеки пиксел от изображение с малко количество и въпреки това полученото противопоставимо изображение да изглежда като оригинала. Каноничното състезателно изображение е Фигура 1 от „Обяснение и използване на състезателни примери»“ от Goodfellow et al., често известно като примера с пандата:

В горния пример изображение, първоначално класифицирано като панда, има специално изработен набор от противопоставящ се „шум“, приложен към него (т.е. модификации на стойностите на пикселите), който кара новото изображение да бъде класифицирано като гибон, докато изображението все още изглежда като панда за човешки наблюдатели. Въпреки че това е интересно и има много приложения за подкопаване на изображения и видео в реалния свят, това определено е различна ситуация от тази, с която се занимаваме в информационната сигурност. Например, с проблемното пространство за обфускация на скрипта PowerShell (и всъщност много от нашите проблеми в infosec) ние сме по-ограничени в а) броя на функциите, които можем да модифицираме, и б) до каква степен можем да модифицираме споменатите функции. Това означава, че имаме по-малко функционално подпространство от модификации, които можем да направим в скриптовете на PowerShell, за разлика от изображенията. Вярвам, че това е често срещан сценарий в моделите за машинно обучение, фокусирани върху информационната сигурност.

Също така, вероятно като следствие от състезателни изследвания, фокусирани до голяма степен върху изображения, повечето академична литература приема, че атакуващият знае всички входни функции за модел. За изображения това има смисъл, тъй като входните характеристики са пиксели. За други примери, като нашето казус за откриване на обфусциран скрипт, това не винаги е така. Схемите за извличане на функции често могат да бъдат определени чрез обратно инженерство, но за тази поредица от публикации ще приема, че знаем всички входни функции за простота. Надявам се да преразгледам тази конкретна тема в бъдеща работа.

Обратно към типа атаки срещу алгоритми за машинно обучение. Will описва пет общи вида атаки срещу алгоритми за машинно обучение в няколко от своите презентации:

Извличане на модел е основна състезателна техника за машинно обучение, за която ще говорим в дълбочина в третата публикация от тази серия. За тази публикация ще се съсредоточим върху Избягванетоза настоящите модели бели кутии, които вече имаме.

Също така искам да направя разлика между съперническотомашинно обучение и нападателнотомашинно обучение. Уил определя Adversarial ML като „Поддисциплина, която конкретно атакува ML алгоритми“ и OffensiveML като „Приложение на ML към обидни проблеми със сигурността ”, и аз съм съгласен с тези определения. Съперническото машинно обучение е това, с което се занимаваме в тази поредица от публикации, където изработваме състезателни проби, за да избегнем съществуващите модели. Офанзивното машинно обучение ще включва неща като „откриване на пясъчна кутия“, увеличаване на „атаки с отгатване на парола“ или „подобряване на фишинг“. Това е област, която проучваме и се надяваме скоро да имаме какво да споделим!

Укриване

При избягването обикновено има две цели, донякъде аналогични на силната и слабата устойчивост на хеш сблъсък. В единия случай искаме всичкипротивнически проби, които са неправилно класифицирани, а в другия искаме да променим класификацията за конкретна проба. Това са известни съответно безразборни и насочени атаки, понякога наричани неправилна класификация и погрешна класификация на източника/целта.

Много добре обучени алгоритми за машинно обучение са доста устойчиви на малки количества произволеншум. С укриването нашата цел е да добавим малко количество специфично изработен шум към вход, за да променим класификационния му етикет за целева проба. Както Коуди Мари Уайлд заявява в публикацията си „Опознайте своя противник: Разбиране на състезателните примери»“, „Конкретният елемент, който прави тези примери състезателни, е колко малко смущение е необходимо да се приложи, за да се получи мрежа, за да промени мнението си относно правилната класификация.” В традиционния контекст на състезателни изображения, целта е обезпокоеното изображение все още да изглежда като оригиналното изображение за човешки наблюдател, като същевременно има различен етикет от модела .

Но първо нека направим малко резервно копие и да поговорим защо атаките за укриване срещу алгоритми за машинно обучение са дори възможни.

Състезателно пространство

Има много академични изследвания по тази тема, но едно от най-добрите опростени обяснения, които съм чел, е от глава 8 „Състезателно машинно обучение“ от Машинно обучение и сигурност от Кларънс Чио и Дейвид Фрийман. Книгата описва основния проблем с несъвършеното обучение - ние не сме в състояние да предоставим на алгоритъм за машинно обучение "перфектен" набор от данни, който покрива цялото входно пространство за проблем. Например, не можем да предоставим всички обфускирани и необфускирани PowerShell скриптове за нашите примери от първата публикация. Има и случай, че „„нередуцируемата грешка““може да е различна от нула, което е грешката, присъща на данните за обучение, която не може да бъде елиминирана от нито един модел. В този случай, дори ако елиминираме несъвършеното обучение, все още има противопоставящи се проби, които могат да доведат до погрешни класификации.

Фигура 8–1 Противствено пространство в резултат на несъвършено представяне в данните за обучение от Машинно обучение и сигурност илюстрира това (акцентът е мой):

По същество данните за обучение, които предоставяме като алгоритъм за машинно обучение, са извлечени от непълен сегмент от теоретичното пространство за разпространение. Когато дойде време за оценка на модела в лаборатория или в природата, тестовият набор (извлечен от разпределението на тестовите данни) може да съдържа сегмент от данни, чиито свойства не са уловени в разпределението на обучителните данни; ние наричаме този сегмент състезателно пространство. Нападателите могат да използват джобове на състезателно пространство между колектора на данни, монтиран от агент за статистическо обучение, и теоретичното пространство за разпределение, за да заблудят алгоритмите за машинно обучение.

Чио, Кларънс; Фрийман, Дейвид. Машинно обучение и сигурност: Защита на системи с данни и алгоритми. O’Reilly Media. Издание Kindle.

Тази „публикация“ обхваща еволюцията на теориите за обяснение на състезателни проби. Той също така обобщава „хипотезата за наклонена граница“ от този документ, която съвпада добре с предишното обяснение:

Накратко, авторите твърдят, че тъй като моделът никога не отговаря на данните перфектно (в противен случай точността на тестовия набор винаги щеше да бъде 100%) — винаги ще има противоположни джобове от входове, които съществуват между границата на класификатора и действителен подколектор от извадкови данни.

Публикацията също така описва „документ от 2019 г. от MIT“, че състезателните примери са характеристика на начина, по който невронните мрежи възприемат данните. По-конкретно, тези противопоставящи се примери са „чисто ориентиран към човека феномен»“, тъй като „устойчивостта“ е понятие, определено от човека. Като признат неспециалист, аз лично клоня към наклонената граница хипотезатакакто е описано по-горе. Но важното е, че въпреки че има конкуриращи се теории за това защо са възможни състезателни проби, за всички системи за машинно обучение има състезателно пространство, което ние като нападатели можеда можем да използваме. В зависимост от познанията ни за архитектурата и вътрешността на модела, това използване понякога е по-лесно да се каже, отколкото да се направи.

Бяла кутия срещу черна кутия

Повечето от нас са запознати с идеята за перспективата на бялата кутия и черната кутия на системата. При грамотното машинно обучение тези термини имат малко по-конкретно определение. Но първо малко (малко, обещавам) малко математика!

Спомнете си обратно към концепцията за производна в смятането:

TL;DR наклонът на горната линия е еквивалентен на производната на изобразената функция в червената точка. Градиент в машинното обучение се отнася до обобщаване на производното до три или повече измерения вместо двете, показани тук. Защо ни е грижа?

Поради градиентно спускане, една изключително важна концепция в машинното обучение.

Като много съкратено обяснение, процесът за намиране на „оптималната“ вътрешна конфигурация за много (но не всички) алгоритми за машинно обучение е както следва:

  1. Начертайте всичките си точки с данни за обучение в N-измерно пространство. Например, ако имате 1000 проби и 14 функции, вие нанасяте тези 1000 проби в 14-измерно пространство. Не се опитвайте да си го визуализирате, не можете. За да цитирам Джефри Хинтън, „За да се справите с хипер-равнини в 14-измерно пространство, визуализирайте 3-D пространство и кажете „четиринадесет“ на себе си много силно. Всеки го прави.»”
  2. Инициализирайте произволна „хиперравнина“ — линия към двумерното пространство е към хиперравнина в по-високомерното пространство.
  3. Пуснете редица проби през модела и измерете колко правилно/неправилно е всяко предсказание, като използвате функция за загуба, също често наричана функция за грешка. Това просто ви казва колко неправилна или точна е била прогнозата на модела. Често срещан пример е log-loss, известен също като загуба на кръстосана ентропия.
  4. Използвайте градиента на функцията за загуба, за да ви каже къде да побутнете вътрешността на вашия модел, за да минимизирате загубата. Това ви дава информация в каква посока да тласнете тези вътрешни органи и с колко.
  5. Повтаряйте този процес, докато достигнете някакъв критерий за спиране, което води до (надявам се!) разумно оптимизиран модел.

Истинският процес е по-сложен от този, но това е общата идея - имате функция за загуба, която ви казва колко неправилни са вътрешните части на текущия ви модел и използвате градиента на тази функция, за да насочвате интелигентно как коригирате вътрешните части на модела в ред за минимизиране на грешките при прогнозиране на данните за обучение.

Странична бележка: едно от големите изключения са ансамбли от дървета като произволни гори и градиентно подсилени дървета на решения, тъй като те са непрекъснати стъпкови функции, които нямат градиент. Това означава, че повечето от ефективните състезателни атаки с бяла кутия няма да работят срещу тези архитектури, въпреки че някои атаки с черна кутия могат да бъдат ефективни. Има „някои изследвания“ за „атакуващи дървесни ансамбли“, но тази изследователска област като цяло не е толкова стабилна, колкото състезателната работа срещу модели с градиенти

Обратно към перспективата на бялата кутия и черната кутия. При състезателното машинно обучение атаката с бяла кутия е тази, при която знаем всичко за внедрения модел, напр. входове, архитектура на модела и специфични вътрешни елементи на модела като тегла или стойности на коефициенти. В повечето случаи това конкретно означава, че имаме достъп до вътрешните градиенти на модела. Някои изследователи също включват познаването на пълния набор от данни за обучение в атаките с бяла кутия, но това не винаги е необходимо за избягване. Обратно, атака с черна кутия е такава, при която знаем само входните данни на модела и имаме оракул, който можем да направим заявка за изходни етикети или резултати за доверие.

Избягването при състезателен ML може да се разглежда като градиентно изкачване вместо градиентно спускане — „искаме да увеличим загубата за една или повече проби“ вместо да я намалим. Можем също така да мислим за състезателното машинно обучение като за вид проблем с макс. Искаме да максимизирамегрешката за една или повече проби, като същевременно минимизирамепромените, които правим в извадката (известни също като противопоставящи се смущения).

Атаките с бяла кутия обикновено са по-ефективни от атаките с черна кутия при тази задача, защото можем да използваме градиентите на вътрешния модел, за да изпълним по-точно процеса на изкачване на градиента спрямо подхода на черна кутия. Това прави по-бързо и по-ефективно изчисляването на минималната промяна, необходима за създаване на състезателна извадка.

Интерпретируемост

В нашата концепция интерпретируемостта или обяснимостта включва колко добре човек може да разбере защо даден модел взема определено решение. Защо това има значение за укриването? Е, не всички функции в модела на машинно обучение са еднакво влиятелни. Ако успеем да получим информация за това кои характеристики имат най-голямо влияние върху границата на вземане на решение на даден модел, можем да използваме това прозрение, за да ръководим нашия процес на избягване.

Както Кристоф Молнар заявява в своята книга Интерпретируемо машинно обучение (чудесно, но плътно, четиво между другото), „Интерпретируемостта може да позволи на хора или програми да манипулират системата.” Ще покажем как интерпретируемостта може да се използва като инструмент за избягване в раздела Метод за избягване A — Извличане на важността на характеристиките и ръчно модифициране на тази публикация.

Изявление на проблема с извикване-избягване

Имаме три модела от нашата първа публикация, които вземат 446 характеристики, измерени от дървото на абстрактния синтаксис (AST) на скрипт на PowerShell и връщат етикет на обфусциран или нормален. Имаме и скрипт, който в момента е класифициран като обфусциран, и искаме да го модифицираме, така че даден модел да класифицира погрешно извадката като нормална.

Мислейки върху този проблем, с всеки модел имаме хиперравнина през 446-измерно пространство, което разделя точките на нашите набори от проби, където нашата злонамерена извадка е точка, която в момента се намира от скритата страна на границата на решението. Искаме да модифицираме едно или повече свойства на скрипта, така че да запазим функционалността на скрипта (и очевидно да запазим обфусцирания му „характер“), но преместваме точката от данни за скрипта през границата на вземане на решение до нормално, в идеалния случай с възможно най-малко модификации.

Нека да разгледаме два начина да направим това - извличане на важностите на характеристиките, за да извършим ръчна модификация, и използване на установени алгоритми за атака срещу нашите модели.

Метод на укриване A — Извличане на важността на характеристиките и ръчно модифициране

Преди да можем да направим каквито и да е модификации на обфусциран скрипт, искаме да знаем кои функции във всеки модел влияят най-много на окончателното решение за класификация. Тук се появява проблемът с обяснимостта или интерпретируемостта, който непрекъснато споменавам. Нашите три модела имат нарастващи нива на сложност, което увеличава трудността да се обясни кои характеристики са най-важни.

Логистична регресия

Тъй като логистичната регресия е линеен модел, обяснимостта е лесна. Логистичната регресия приема следната форма:

Или в друга, по-често срещана форма:

Причината да харесваме тази функция е, че тя ограничава изхода между 0 и 1, което я прави страхотна за задачи за класификация. Примерна крива за стандартната логистична регресия е:

Не се плашете от горните формули! Нека да видим как работи това.

За да се класифицира извадка, всяка измерена стойност на характеристика за скрипт (Xᵢ) се умножава по свързано фиксирано тегло/коефициент (Bᵢ), добавя се отклонение ( B₀), а стойността се въвежда за X в стандартната логистична формула f(x) = 1 / (1 + e^-x), също известна като сигмоидна функция. Логистичната регресия се счита за линейна по природа, защото използва линейна комбинация от входните променливи (B₀+B₁X₁+B₂X₂+ … ), което го прави доста интерпретируем за нас. Колкото по-голямо е теглото/коефициента на характеристиката, толкова повече тази характеристика влияе върху крайното решение на модела. Знакът на характеристиката (+/-) определя кой етикет е функцията натискане към. „Точната сума, която функцията допринася“ се определя от „log-odds“, които няма да навлизам тук, защото:

Но ако се интересувате от точното тълкуване на коефициентите на логистична регресия (имам предвид, кой не се интересува?), „нокаутирайте се“.

Така че, ако искаме да прехвърлим скрипта си над границата на вземане на решения, за да обърнем етикет от смазан(1) на нормален(0), трябва да знаем кои функции допринасят най-много за етикета обфусциран и които допринасят най-много за етикета нормален. От гледна точка на математиката искаме да знаем кои коефициенти имат най-голямата абсолютна стойност както за положителната, така и за отрицателната посока.

Нека да видим как това се сравнява както за оригиналния модел на логистична регресия на Revoke-Ofuscation, така и за нашия настроен модел на логистична регресия.

Оригинална логистична регресия с отмяна и обфускация

Оригиналният модел на логистична регресия от работата Revoke-Obfuscation е капсулиран тук, като първият термин е прихващане/пристрастие. Тъй като имаме всички входове и параметри на модела, това е пълен сценарий с бяла кутия. Искаме да знаем кои характеристики влияят най-много на модела към скрити и нормални, така че нека оценим модела на познат скрипт, за да можем лесно да получим имената на функциите, да ги съпоставим функции до коефициентите (напр. Bₓ) в $highConfidenceWeightedVector от Revoke-Obfuscation и изберете първите 10 и най-долните 10 коефициента по стойност:

$Vector = Get-RvoFeatureVector -Път C:\Tools\PowerView.ps1

$FeatureNames = $($Vector.Keys)

[System.Double[]] $highConfidenceWeightedVector = @(-218.9926, -4217.0000, …))

$Features = за ($i = 0; $i -lt $($Vector.Count); $i++) {

$Feature = New-Object -TypeName PSObject

$Feature | Add-Member -MemberType NoteProperty -Name “Feature” -Value “$($FeatureNames[$i])”

$Feature | Add-Member -MemberType NoteProperty -Name “Value” -Value ([float]($highConfidenceWeightedVector[$i+1]))

$Feature

}

$Характеристики | Сортиране-Обект -Стойност на свойството -Низходящ | изберете -първите 10 -Последните 10

Получаваме следния резултат:

Положителните стойности допринасят най-много за 1, което означава скрити, а отрицателните стойности допринасят най-много за 0, което означава нормално. Нека да проверим какво означава функцията AstStringMetrics_CharacterDistribution_/_2f_Count, като проверим източника на Revoke-Obfuscation за тази проверка „тук“ и „тук“. Изглежда, че тази проверка извлича всички низови константи от абстрактното синтактично дърво (AST) на скрипта и връща общия брой 0x2F (което се превежда като „/“) знаци във всички константи в скрипта. Според Microsoft, „Това включва низове с единични и двойни кавички…“ И така, какво ще се случи, ако създадем нов низ, състоящ се от „/“s, и го пъхнем в скрипт, измерен преди това като злонамерен, като DBOdemo1.ps1 скрипт?

Оригинален скрипт DBOdemo1.ps1:

Модифициран скрипт DBOdemo1.ps1:

Страхотно! Обърнете внимание, че можехме да направим това с повечето от големите отрицателни коефициенти, но по-малките величини биха отнели повече "/". Сега нека насочим вниманието си към нашата настроена логистична регресия от първия пост.

Странична бележка:ще продължим да използваме скрипта DBOdemo1.ps1 като еталон за всички атаки в тази поредица публикации.

Настроена логистична регресия

Спомнете си от първата публикация, че нашата настроена логистична регресия използва 446 функции, избрани от Boruta-Shap, и завършихме с наказание L2 (Ridge), C от 5 и saga solver. Нека да заредим запазения модел и да ципваме имената на характеристиките с коефициентите. След това ще сортираме функциите по стойност и ще изведем горните и долните 10 (вижте WhiteBox.ipynb бележника в репо Invoke-Evasion за подробности).

Резултатите са:

Разглеждайки горната таблица, интересно е, че в крайна сметка получаваме различни функции от оригиналния модел Revoke-Obfuscation. Ще разгледаме отново това и защо има значение в третата публикация от поредицата.

Отново, положителните стойности допринасят най-много за 1, което означава замъгляване, а отрицателните стойности допринасят най-много за 0, което означава нормално. В този случай функцията AstMemberMetrics_CharacterDistribution_y_79_Percent има най-голямо влияние върху етикета нормално. Според Microsoft, „Астът, който представлява достъп до член като свойство, напр. $x.Length или [int]::MaxValue.” Така че нека опитаме достъп до несъществуващо свойство, съдържащо куп y (0x79) за някаква променлива. Надяваме се, че това повишава процента и помага на тази функция да премести извадката над границата на решение:

Успех! Ако добавим достатъчно y към свойството, до което осъществяваме достъп, можем да преместим етикета за този многообфусциран скрипт до нормалната граница.

LightGBM функция_важност

Както споменах в първия пост, ансамбълите от дървета като случайни гори и градиентно подсилени дървета на решения съдържат важността на това колко „важна“ е функцията. „Тази публикация“ има добро обобщение защо:

...когато тренирате дърво, е възможно да изчислите колко всяка характеристика намалява примесите. Колкото повече дадена характеристика намалява примесите, толкова по-важна е характеристиката. В произволни гори намалението на примесите от всяка характеристика може да бъде осреднено за дърветата, за да се определи крайната важност на променливата.

Освен това има опростено обяснение:

...функциите, които са избрани в горната част на дърветата, като цяло са по-важни от характеристиките, които са избрани в крайните възли на дърветата, тъй като обикновено горните разделяния водят до по-големи печалби от информация.

Тези аспекти са валидни и за подсилени дървета, като нашия модел LGBMClassifier. Това е точният проблем, който Адриан Крес изследва в отличния си „Избягване на модели за откриване на зловреден софтуер при статично машинно обучение — Част 2: Подходът на сивата кутия»“, който аз силно препоръчвам всеки прочете. Както Адриан описва в публикацията, тук има два основни подхода: разделяне и печалба.

Използвайки функцията plot_importance на LightGBM с feature_importance=split, можем да определим най-използваните функции в нашия модел:

Използвайки feature_importance=gain, можем да определим функциите, които имат най-голямо въздействие върху етикета скрити спрямо нормален, ако функцията се използва поне веднъж:

Разглеждайки тези два графика, много от тези резултати имат смисъл. По-конкретно, функцията LineByLineMetrics_CharacterDistribution__27_Percent (нашето кодиране на името на JSON функция премахна ') има голямо значение. Това има смисъл, като се има предвид, че единичните кавички се използват в много обфусцирани проби на PowerShell.

Тъй като искаме да запазим оригиналния обфусциран скрипт, доколкото можем, искаме да добавим неща, които влияят на „нормалните“ показатели, вместо да премахваме неща като единични кавички или обратни точки. Един недостатък на диаграмите за важност на характеристиките е, че те не ви позволяват да знаете в каква посока функцията влияе върху решението, така че трябва да направим някои допускания. Функцията AstMemberMetrics_CharacterDistribution_e_65_Percent изглежда като нещо, което е по-често срещано в нормалните скриптове. Нека добавим куп e към променлива, подобна на това, което направихме преди, и да видим дали можем да преместим границата:

Без зарове. Съвкупностите от дървета — като случайни гори и градиентно подсилени дървета на решения — изглеждат, поне в този случай, много по-стабилни срещу избягване. „Това е нещо, което и други са наблюдавали“ поне в някои случаи.

Така че всяка надежда е загубена?

LightGBM SHAP

Въведете SHapley Additive ExPlanations, обикновено наричан SHAP, „теоретичен подход на игрите за обяснение на изхода от всеки модел на машинно обучение.“ Въпреки че няма да навлизам в техническо обяснение какво е SHAP (има други ресурси вече достъпни за това), ще покажа как можем да използваме SHAP, за да извлечем известна представа за модела LightGBM, към който се насочваме.

Едно нещо, което искам да засегна накратко, преди да се потопя, е концепцията в SHAP за глобална интерпретируемост срещу локална интерпретируемост. Прозренията за глобалната интерпретируемост, осигурени от SHAP, могат да покажат доколко всяка функция допринася за изхода на модела, в този случай смазан или нормален, в целия набор от данни. Има няколко начина да направите това, но моят предпочитан метод е summary_plot (или beeswarm plot). Примерният beewarm за всички функции в нашия модел LightGBM е:

Характеристиките в този график са класирани в низходящ ред по важност, т.е. характеристиките, които имат по-голямо влияние върху изхода на модела, са по-високо в графиката. Оста x представлява стойността на SHAP за функция, където по-високата стойност на SHAP означава, че е по-вероятно моделът да върне етикет на модела 1 или скрит в нашата конкретна ситуация. Червеното означава, че стойността на функцията е висока, а синьото означава, че стойността на характеристиката е ниска. Така че, гледайки този график, можем да видим прозрения, които имат смисъл, като например наличието на нисък процент единични кавички (hex 0x27) ред по ред е свързано с нормален етикет. За повече подробности относно тълкуването на този тип графика вижте тази публикация в StackExchange или този раздел в Интерпретируемо машинно обучение.

Локална интерпретируемост означава, че SHAP може да ни покаже кои характеристики са допринесли най-много за класификацията на конкретнапроба, а не ефектите на характеристиките в всичкимостри. Това може да стане с диаграми „водопад“ и/или „решение“. „Бележниците на Юпитер за всичко това“ показват и двете, но тук ще подчертая само графиките на водопада.

Моят подход за този конкретен случай беше да използвам прозрения от глобалния график на пчелния рояк, за да може моделът да избере нормални функции, от които да ги добави итеративно към скрипта. След всяка модификация регенерирах графиката на водопада за пробата, за да видя ефекта от промяната.

Ето водопада за функциите от оригиналния скрипт DBOdemo.ps1 преди модификация:

Горният график показва функции в червено, които тласкаха решението към скрити, и характеристики в синьо, които тласкаха решението към нормално. В този случай искаме да модифицираме функции, за да изтласкаме това най-високо число (6,448) на отрицателна територия.

След това направих многократни модификации на извадката, опитвайки се да минимизирам всички функции, които тласкаха извадката до скрити, и да максимизирам всички функции, които избутваха извадката до нормален. След като всеки процес извлича функциите отново за модифицирания скрипт и регенерира графиките, повтаряйки този процес, докато извадката премине през границата:

Имаше много модификации, значително повече от необходимото за избягване на модела на логистична регресия. Очевидно има по-ефективни състезателни модификации за тази проба от това, което направих тук, това беше само първи (но не оптимизиран) опит. Както споменах по-рано, здравината на ансамблите от дървета е наблюдавана и от други. Въпреки че има скорошна работа по конкретно атакуване на дървесни ансамбли, тя все още е оскъдна от противниковата работа срещу невронните мрежи.

Странична бележка: това не винаги е така! Adrian Kress успя да избегне силно модел LightGBM, обучен на набора от данни EMBER, като изследва важността на характеристиките и просто променя клеймото за време за образец на зловреден софтуер. Всеки набор от данни и модел са различни!

Невронна мрежа

Невронните мрежи по своята същност не са обясними като логистичната регресия или дървесните ансамбли. Нашата основна опция е да използваме нещо като SHAP, така че нека да се заемем с глобалната важност на функциите в beeswarm:

Не получаваме толкова добри резултати, колкото с SHAP TreeExplainer, тъй като за невронни мрежи условните очаквания на стойностите на SHAP се приближават с помощта на редица фонови проби вместо целия набор от данни. На английски: за модели за задълбочено обучение произволно подмножество от проби се използва с математика за приближаване на стойностите на SHAP, докато точните стойности на SHAP могат да бъдат изчислени от модели, базирани на дърво. Независимо от това, горната фигура ни дава известна представа кои функции тласкат нещата към нормално.

Ще повторим процеса, който използвахме, за да атакуваме модела LightGBM, където генерираме графики за каскада/решение за проба, която се опитваме да модифицираме, правим нашите модификации, извличаме характеристиките и регенерираме графиките, докато преминем границата за вземане на решения . Ето откъде започваме с нашия пример:

И след само няколко модификации, ето какво получаваме:

По-конкретно, това е всичко, което добавих в началото на DBOdemo.ps1:

функция t — — — — — — — — — — — — — — — — — — — — — — — — — a{}

t — — — — — — — — — — — — — — — — — — — — — — — — — a

$a.yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy

…останалата част от DBOdemo.ps1…

Този модел на невронна мрежа се оказа значително по-лесен за избягване от модела LightGBM, поне в този случай. Не забравяйте, че всеки набор от данни и модел са различниʸᵒᵘʳ ʳᵉˢᵘˡᵗˢ ᵐᵃʸ ᵛᵃʳʸ.

Що се отнася до важността на функцията и SHAP, има някои общи неща между моделите като {}, обратни означения и единични кавички, които обикновено се показват под някаква форма. Въпреки това, най-„важните“ характеристики за всеки модел варират. Това често се случва при машинно обучение, когато наборът от данни е сравнително „шумен“ – всеки модел се стеснява до различно подмножество от функции, които се оказват ефективни. Това ще има последици за третия пост от тази серия, когато атакуваме тези модели като черна кутия.

Метод за избягване B — Общи алгоритми за атака

Споменах в първата част на тази публикация, че през последните 8 години имаше доста работа по академичната страна на машинното обучение. Съвсем наскоро започнаха да се появяват практически рамки, които ни позволяват действително да изпълняваме много от тези атаки. Една от най-утвърдените рамки с общо предназначение е Adversarial Robustness Toolbox (ART), която ще използваме в тази публикация.

Също така по-рано споменах колко голяма част от академичните изследвания са били около състезателни изображения и „атаките за укриване, внедрени в ART“ отразяват това. Въпреки това, както разгледахме, имаме по-малко функционално подпространство от модификации, които можем да направим в скриптове на PowerShell спрямо изображения. Моята теория беше, че в идеалния случай бихме искали алгоритъм за атака, който ни позволява да уточним кои специфични функции искаме да смутим (известно като маскиране на функции), когато генерираме конкурентни примери. За щастие, тези алгоритми в ART ни позволяват да направим това:

PGD, Auto-PGD и FGM са атаки с бяла кутия, които разчитат на познаването на градиентите на вътрешния модел, за да генерират конкурентни проби. Тъй като дърветата на решенията и ансамблите от дървета нямат ясен градиент, са необходими техники на „други“ „бяла кутия“, за да ги атакуват. Повечето примери за атака срещу ансамбли от дърво, които съм виждал, използват методи на черна кутия като HopSkipJump или Оптимизация на нулевия ред (ZOO) — има специфичен алгоритъм за атака в ART на дървото на решенията, но не работи срещу дърво ансамбли като произволни гори и градиентно подсилени дървета. Поради тези ограничения и тъй като не можах да накарам Auto-PGB да работи правилно с моите модели, използвах PGD, FGM и HSJ на логистичната регресия като пример.

Бележникът WhiteboxBox.ipynbJupyter в хранилището на Invoke-Evasion съдържа всичките ми опити и резултати за този раздел, но за краткост просто ще обобщя подхода и резултатите тук .

Първо, коя подгрупа от функции искаме да променим? Моята теория беше, че най-лесните опции, които запазват функционалността на оригиналния скрипт, са показатели, които включват преброяване на знаци, като AstVariableNameMetrics_CharacterDistribution_E_74_Count. Другото предимство е, че докато много от показателите на функциите са проценти, което ограничава обхвата им до 0–100 в практически сценарий, няма ограничение за това колко можем да увеличим *_Countфункциите.

Взех настроения алгоритъм за логистична регресия и извлякох всички тегла на характеристиките, които са отрицателни, което означава, че тласкат решението на модела към нормално. След това филтрирах тези за показателите от типа *_CharacterDistribution_X_Count, което доведе до 16 целеви характеристики, които използвах за изграждане на маска на функция. За всеки алгоритъм за атака генерирах състезателни проби, използвайки както маската на функцията, за да модифицирам само функциите, които посочих, така и генериране на проби, като изобщо не използвах маскиране на функция.

Донякъде изненадващо, атаката с черна кутия HopSkipJump доведе до значително по-добри маскирани състезателни резултати от Projected Gradient Descent или Fast Gradient Method. Предположих, че методът на бялата кутия с познаване на вътрешността на модела ще се справи по-добре, но предполагам, че вероятно съм объркал обработката за мащабиране на функции по някакъв начин (вижте Бележника на Jupyter за повече подробности ). Въпреки това нито един от резултатите не беше супер обещаващ.

Но дори ако алгоритъм за атака е в състояние успешно да модифицира подмножество от нашите функции с относително минимални промени, все още има доста голям слон в стаята: как всъщност използваме тези състезателни числа, генерирани от алгоритмите за атака?

Тоест, ако действително сме в състояние да модифицираме измерванията на табличните характеристики за дадена проба, за да променим класификационния й етикет, как да картографираме тези модифицирани числа обратно към действителен скрипт по начин, по който скриптът все още функционира, както първоначално е предназначен. По-конкретно, какво е ??? процес тук:

Не се страхувайте, има решение на този проблем, което ще разгледам в третия пост от тази поредица.

Заключение

Ако имате пълен модел, можете да извлечете много информация за процеса на вземане на решения спрямо конкретни проби. В нашия случай успяхме да използваме тези важности на функциите, за да ръководим нашето ръчно избягване за обфусцирания примерен скрипт DBOdemo.ps1. Въпреки че SHAP беше създаден за обяснимост на модела, ние го използвахме тук, за да изработим ръчно ефикасно състезателни проби, подход, който е потенциално нов.

В този конкретен казус, ръчното създаване на състезателни проби срещу модели на логистична регресия с бяла кутия беше значително по-лесно от създаването на проби срещу ансамбли от дървета като случайни гори или градиентно подсилени дървета, но само незначително по-лесно, отколкото срещу невронни мрежи. Това обикновено има смисъл поради линейния характер на логистичната регресия. Ако трябваше да използвам един от тези три модела в производството, подобно на подхода на Joost Jansen в „Машинно обучение от идея до реалност: казус с PowerShell»“, бих избрал Gradient Boosted Decision Tree. Тази архитектура се оказа не само най-точната, но и най-устойчивата срещу атаки за укриване за това конкретно приложение. Тези резултати не са гарантирани за всички приложения: данните са странни.

Що се отнася до алгоритмите за атака като HopSkipJump, голямо предизвикателство, което имаме с този специфичен сценарий за обфускация на скрипт, е как можем да вземем състезателна извадка, генерирана от нещо като HopSkipJump, и да картографираме тези модификации на функцията обратно към действителен примерен скрипт. Въпреки че това е начинът, по който тези алгоритми за атака традиционно се използват, има друг начин за разглеждане на проблема, който ще опиша подробно в следващата публикация от тази серия.

Като оставим настрана всички тези проблеми, моделите са уязвими. Въпросът е само колко уязвими са те и колко усилия са необходими, за да бъдат подкопани. В следващата публикация ще разгледаме атакуването на тези три модела от гледна точка на черна кутия, където архитектурите на модела не са известни.

Бележниците на Jupyter, описани в тази публикация, вече са актуализирани в хранилището Invoke-Evasion.

Препратки

  • SHAP
  • „Кутията с инструменти за съперническа устойчивост“
  • Тези две постове от Adrian Kress за избягване на модели на зловреден софтуер за машинно обучение, които бяха страхотно вдъхновение
  • Публикацията „Машинно обучение от идея до реалност: казус с PowerShell»“ от Joost Jansen
  • Интерпретируемо машинно обучение от Кристоф Молна
  • „Всички разговори на Уил Пиърс“