Проверка на CVE: когато версията в банера подвежда
Резултат от скенер, който свързва версия на услуга с CVE, е основание за проверка, а не доказателство за използваема уязвимост. Приложимостта зависи от реалната версия, наличните поправки и конфигурацията. Потвърждаването или отхвърлянето на този резултат е важна част от теста. В първата част обясняваме защо банерите могат да заблуждават, какви са последствията и как безопасно да проверите предполагаема уязвимост.
Банерът е твърдение, не диагноза
Механизмът зад версийна CVE е по-прост, отколкото представянето му подсказва. Скенерът се свързва, чете каквото услугата доброволно предоставя — поздрав на протокола, хедър на отговора, страница за грешка, идентификатор на компилацията на статичен ресурс, субект на сертификат — и го нормализира в продукт и версия. Търси тази двойка в таблица с бюлетини и излъчва всеки бюлетин, чийто диапазон на засегнати версии съдържа парснатата стойност. Никоя заявка не упражни уязвимия код. Нищо не беше доказано. Изходът е свързване между парснат низ и база данни, пременено в цветовете на критичност на това, с което е съвпаднало.
Този извод се чупи по няколко обикновени начина.
- Backport-нати поправки, оставящи версията непроменена. Дистрибуциите с дългосрочна поддръжка съществуват, за да могат операторите да приемат поправки за сигурност, без да приемат промяна в поведението. Поддържащите вземат поправката нагоре по веригата във версията, която вече доставят, и повишават само ревизията на пакетирането. Низът нагоре по веригата — онзи в банера, и онзи, който скенерът парсва — остава точно където беше. Компилациите с и без поправката са неразличими от мрежата, а скенерът ще настоява за бюлетина безкрайно.
- Компилации на доставчици и фърмуер на устройства. Посочената версия на компонент невинаги съответства на публично издание на оригиналния проект. Доставчикът може да поддържа собствен вариант, да е премахнал функционалности или да е приложил избрани корекции. Номерът на версията показва произхода, но не доказва съдържанието на кода.
- Функции, изключени при компилация или така и невключени. Много бюлетини живеят в опционален код: парсър за разширение на протокол, модул за удостоверяване, скриптов интерпретатор, обработчик за съвместимост с наследени системи. Ако този код е изключен при билда, или е наличен, но недостижим, защото функцията е изключена, диапазонът на версията е удовлетворен, а уязвимостта все още не съществува.
- Компенсираща конфигурация. Уязвимият път може да се нуждае от опция, която е изключена, роля, която анонимният извикващ не държи, слушател, свързан само с loopback, или компонент нагоре по веригата, който премахва входа, който бъгът изисква. Кодът е там; маршрутът до него — не.
- Умишлено фалшиви банери. Оператори, на които е казано да „поправят разкриването на версия“, понякога правят това чрез лъжа: прокси пренаписва хедъра, или директива фиксира измислен низ. Банерите подценяват версии толкова често, колкото и ги надценяват, а случаят на подценяване е опасният — той фабрикува констатации, които карат екипите да закърпват вече закърпеното.
Какво струва да вярвате на скенера
Погрешно отчетена критична уязвимост често се защитава като благоразумен — по-добре да се докладва прекомерно, отколкото да се пропусне нещо. Той не е безплатен, а разходите падат върху хората, най-малко способни да ги поемат.
Първият разход е непланирана промяна. Critical на устройство, изложено към интернет, задейства спешния път: прозорец извън работно време, надстройка на устройство, което прекратява отдалечен достъп или поток на поща, план за връщане назад, хора в конферентен разговор. Спешната промяна е там, откъдето идват прекъсванията. Ако констатацията никога не е била истинска, организацията е приела истински риск за достъпността и истинска умора, без да отстрани реален проблем.
Вторият разход е погрешно разпределено отстраняване. Екипите имат фиксиран брой прозорци за промяна и фиксирано количество капацитет на инженерите на тримесечие. Харченето им за недостижим бюлетин означава да не ги харчите за пропуска в удостоверяването, остарелия административен акаунт или записа за удостоверяване на поща, с който действително се злоупотребява. Прекомерното докладване не добавя капацитет; то го преназначава, обикновено далеч от това, което има значение.
Третият разход се натрупва и е онзи, който си заслужава да бъде назован пред борд: ерозия на доверието. Екип, който е закърпвал устройство два пъти при спешни условия и два пъти не е намерил нищо нередно, научава правило — че докладите от този източник са раздути — и го прилага и към следващия доклад, включително онзи, който беше истински. Викането „вълк“ не е неутрална свръхпредпазливост; то е унищожаването на сигнал, който ще ви потрябва по-късно. Доклад, чиито Critical-и винаги са истински, може да изисква действие. Такъв, чиито Critical-и са изход от скенер, не може, и в крайна сметка няма да го получи.
Документираната отрицателна оценка е полезен резултат, когато посочва какво е изключено и при какви условия. Тя подпомага приоритизирането и може да предотврати ненужна спешна промяна, но не закрива автоматично задълженията за обновяване и не доказва липса на всички пътища за експлоатация.
Проверка на механизма за експлоатация, вместо само на версията
За всяко предположение прочетете advisory и определете необходимите функция, вход и права. Използвайте най-слабо въздействащата разрешена проверка, която дава информация, и я съчетайте с build и конфигурационни доказателства, когато са налични. Самата версия в банера не е достатъчна; неуспешна проба също може да остави несигурност.
Четири опростени примера от външен ангажимент показват как да се проучват предположения по версия. Пробите не възпроизвеждат предполагаемите проблеми през тестваните интерфейси. Изводите трябва да останат свързани с проверените предпоставки, build версия, път на заявката и мрежова позиция.
Периметрово VPN устройство, клас разкриване на памет. Този клас зависи от заявка, чиято обявена дължина надхвърля предоставените данни, карайки услугата да върне байтове, които не е възнамерявала да изпрати. Това е примитив, който можете да поискате пряко и да наблюдавате, без да променяте нищо.
проба: pre-auth заявка, обявена дължина > изпратено тяло
наблюдение: върнати спрямо изпратени байтове
резултат: върната дължина == изпратена дължина
без допълнителни heap данни при повторните опити
извод: не е наблюдаван over-read при тези проби;
patch статусът и другите пътища изискват отделни доказателства
Сравнението на дължините може да разкрие over-read, когато се връща допълнителна памет. Отрицателният резултат се отнася само за проверените проби: той не доказва налична проверка на границите, поправена build версия или липса на друг вход към уязвимото условие. Записвайте предпоставките от конкретното advisory и проверявайте build или кодови доказателства, когато са налични.
Агент за трансфер на поща, клас chunking за отдалечено изпълнение на код. Този клас изисква конкретно разширение за трансфер; дефектният парсър е достижим само през командата на това разширение. Въпросът не е „коя версия е това“, а „ще приеме ли тази услуга тази команда изобщо“.
> EHLO probe
< 250-SIZE …
< 250-STARTTLS
< 250 HELP
# разширението не е рекламирано
> <chunked-transfer verb> 4
< 500 unrecognised command
урежда го: уязвимият парсър е недостижим — глаголът нито
рекламиран, нито приет, преди и след TLS
Забележете двете стъпки. Отсъствието от рекламирания списък с разширения е подсказващо, но някои услуги приемат необявени команди. Изпращането на командата и получаването на твърд отказ — проверено и преди, и след TLS надстройката, тъй като наборите от способности се различават — е това, което го затваря.
Уеб приложение, клас неудостоверено извличане на код. Този клас зависи от обработчик, който връща изходния код на приложението на извикващ без сесия. Поискахме го със зададен параметър за извличане и погледнахме тялото, не само кода на състоянието.
проба: неавтентикирана заявка към засегнатия handler
с параметъра за извличане на код
наблюдение: тялото на отговора
резултат: 404, общ документ за грешка, без изходен код;
еднакво със и без сесия
извод: тази заявка не разкрива код; само 404 не доказва
patch статус или липсващ handler
Интерфейс на шлюз, клас отразено cross-site scripting. Тук примитивът е изпълнение на скрипт в браузъра на жертвата. Инжектирахме канонична сонда за отражение и инспектирахме както отразените байтове, така и хедърите на отговора.
наблюдение 1: отразената стойност е HTML entity-encoded
(< > " ' са екранирани в тялото)
наблюдение 2: има Content-Security-Policy без разрешено inline
изпълнение и без wildcard script source
извод: оценете действителния контекст и ефективната CSP;
наблюденията сами не изключват всеки XSS път
Екранирането трябва да съответства на контекста: HTML текст, атрибути, URL и JavaScript имат различни изисквания. Ограничителната ефективна CSP е полезна допълнителна защита, но наличието ѝ и липсата на wildcard източници не доказват блокиране на всеки път за изпълнение. Опишете тестваното отражение и наблюдаваното поведение, без да ги превръщате в универсално опровержение на XSS.
Останалите докладвани находки засягат имейл удостоверяване, разкриване на информация и анонимен file-transfer достъп. Документирайте ги отделно от невъзпроизведените предположения, с тежест според показаната изложеност и употреба.
Как да укрепите защитата
- Записвайте ревизията на пакетирането, не само версията на оригиналния проект. Инвентаризирайте от мениджъра на пакети и идентификаторите на билда на фърмуера, а не от мрежови банери, така че backport-натите поправки да са видими за вас дори когато скенер не може да ги види.
- Поддържайте манифест на функциите за всяка услуга. Кои опционални модули, разширения на протоколи и интерпретатори са включени? Повечето версийни бюлетини се проверяват и приоритизират за минути спрямо точен манифест.
- Изисквайте твърдение за примитива, преди да отворите спешна промяна. Ако никой не може да каже от коя конкретна способност се нуждае експлойтът, никой още не е проверил и приоритизирал кандидата.
- Не отстранявайте разкриването на версия чрез фалшифициране на версии. Потиснете банера, ако трябва; фалшив низ покварява собствения ви триаж, както и разузнаването на нападател. Използвайте допълващи се контроли и проверявайте обхвата им. Подходящото за контекста екраниране, ефективната CSP и изключените протоколни функции могат да ограничат конкретни атаки. Документирайте провереното, без да приемате броя на контролите за доказателство, че всички варианти са изключени.
- Поискайте от тестерите си наблюдаемото. Констатациите и опроверженията еднакво трябва да заявяват какво е било измерено. „Версия в диапазона“ не е наблюдаемо.
Безопасно опровержение
Опровержението трябва да е по-евтино и по-безопасно от експлоатацията, или то няма да се случи на продукционни системи — където е най-нужно. Няколко правила носят по-голямата част от тежестта.
Предпочитайте наблюдението пред експлоатацията. Повечето примитиви се обявяват, преди да бъдат използвани: списък със способности, дължина на отговор, хедър, код на състояние, формата на грешка. Наблюдавайте първо; ескалирайте само ако наблюдението е двусмислено.
Използвайте най-малкия примитив, който разграничава двата случая. Тестът трябва да е минималното взаимодействие, чийто резултат се различава между уязвим и закърпен хост. Декларация на chunk от четири байта установява дали командата се приема; няма причина да движите пълна верига, за да разберете.
Избягвайте разрушителни и променящи състояние доказателства. Никакви опити за повреда на паметта срещу работещи услуги, никакви записи, никаква мутация на данни за достъп или сесии, никакви рестарти, никакви умишлено изчерпващи ресурси заявки. Опровержение, което поваля пощенски шлюз, е струвало повече от констатацията, която е отменило.
Съгласувайте подхода, където продукционната среда е в обхвата. Кажете предварително кои примитиви възнамерявате да сондирате, как изглежда всеки по мрежата, най-лошия реалистичен изход и кога ще го направите. Операторите рядко пречат, щом видят, че планът е сравнение на дължина, а не опит с shellcode — а журналите им ще покажат трафика, затова би трябвало да го разпознаят.
Знайте кога честният отговор е „нетестваемо оттук“. Това е дисциплината, която държи останалото достоверно. Ако примитивът изисква сесия, която не ви е дадена, сертификат, който не държите, мрежова позиция извън обхвата или състояние, което не бива да създавате, не сте опровергали нищо — не успяхте да го достигнете. „Неуязвим“ означава, че сте тествали примитива и той е отсъствал. „Недостижим от тестваната позиция“ означава, че кандидатът остава отворен и се нуждае от потвърждение на ниво хост за състоянието на актуализациите за сигурност или конфигурацията. Да сгънеш второто в първото е грешката на скенера, направена от някой, който би трябвало да знае повече.
Как записвате всяко от тях, така че читател шест месеца по-късно да може да каже кое сте имали предвид — и какъв остатъчен риск оцелява след опровержение — има също толкова значение, колкото самата сонда.
Документирайте доказателствата, че уязвимостта не е приложима
Опровержение, което живее само в главата на тестера, не струва нищо. Не за инженера, който наследява системата следващото тримесечие, не за одитора, който изпълнява отново същия скенер и вижда същия червен ред, и не за тестера шест месеца по-късно, който вече не може да си спомни кой от кандидат-проблемите на този хост действително е преследвал. Работата беше истинска; отсъствието на запис я прави невъзстановима.
Режимът на провал е предсказуем. При следващата оценка някой изважда предишния доклад, не вижда запис за маркиран базиран на версия проблем, и има две хипотези: той беше тестван и отхвърлен, или той никога не беше погледнат. Нищо не разграничава двете. Затова те или повтарят цялото разследване на пълна цена, или — по-често, под натиск от времето — копират твърдението на скенера напред като непроверен Critical, и организацията харчи още цикъл в спорове за нещо, което беше уредено преди година. Недокументирано опровержение е операционно идентично с нетествана точка. Третирайте го като такова.
Това, което прави един запис дълготраен, е, че записва разсъждението, не само присъдата. „Неизползваемо“ е заключение без носеща структура. Шест неща трябва да са на страницата:
- Кандидат-проблемът и неговият клас. Не идентификатор сам по себе си — механизмът. Дефект в десериализацията в управляващ интерфейс, преминаване на път в обработчик на статични файлове, заобикаляне на удостоверяването в ръкостискане на протокол. Класът е това, с което бъдещ читател разсъждава; идентификаторът е просто търсене.
- Примитивът, от който зависи. Какво трябва да е вярно, за да работи публикуваният експлойт: зареден модул, включен функционален флаг, договорима версия на протокол, парсър, извикан върху контролиран от нападателя вход. Това е пантата на записа.
- Точната извършена сонда. Достатъчно, че някой друг да може да я повтори дословно: какво е изпратено, към кой интерфейс, с кои параметри, от коя позиция в мрежата.
- Наблюдаемият отговор. Какво се върна — състоянието, грешката, отсъстващият хедър, отхвърленото ръкостискане, тишината. Наблюдения, не интерпретация.
- Заключението, с неговия обхват. Какво наблюдението изключва, и само това. „Уязвимият път на парсване не е достижим през изложения интерфейс“ е заключение. „Хостът е сигурен“ не е.
- Условията, при които то престава да важи. Клаузата за изтичане: ако този флаг бъде включен, ако този модул бъде зареден, ако това обратно прокси бъде премахнато, опровержението е невалидно и точката се връща в опашката.
За описаните предположения запазете пробите, build и конфигурационните доказателства, позициите и условията, ограничаващи извода. Разграничавайте независимо проверена липсваща предпоставка от заявка, която просто не възпроизвежда проблема. Така бъдещият читател няма да приема двата резултата за равностойни.
Формата, която издържа, е скучна и фиксирана. Скучното е целта — фиксираната форма е прегледаема под натиск и трудна за наполовина попълване:
кандидат : отдалечено изпълнение на код в <клас компонент>, докладван от банер за версия
клас : небезопасна десериализация на параметър в тялото на заявката
примитив : опционален модул за сериализация трябва да е зареден И
засегнатата крайна точка трябва да е достижима от тестовия източник
сонда : изработена заявка към засегнатата крайна точка, носеща
безвреден типизиран обектен маркер, от <тестова наблюдателна точка>
наблюдавано : 404 на крайната точка; крайната точка за списък с модули връща набор,
който не включва модула за сериализация; никаква
грешка в десериализацията не изплува при неправилно оформен вход
заключение : примитивът отсъства — уязвимият път на кода не е достижим
през изложената услуга. Неизползваемо както е внедрено.
изтича ако : модулът за сериализация бъде включен; засегнатата крайна точка
бъде повторно изложена; услугата бъде обратно проксирана различно
остатъчно : компонентът остава извън прозореца на поддръжка — проследяван като
хигиена на управлението на закърпвания
проверено : <референция на ангажимента>, проверете повторно при следваща промяна на инфраструктурата
„Неексплоатируемо днес“ не означава „уязвимостта липсва“
Втората дисциплина е да устоите на облекчението. След като сте доказали, че Critical на скенер не се задейства, има силно изкушение да изтриете реда и да продължите. Това е погрешното решение, по причини, които са напълно банални.
Отрицателният резултат не решава въпроса за състоянието на компонента. Внедреният build може да е поправен, незасегнат или защитен само при определена конфигурация; проверете кой извод се подкрепя от доказателствата. Следете нужните обновявания и условията за компенсиращия контрол, защото rebuild или промяна на функция може да промени изложеността.
Затова честното третиране е понижаване, не изтриване. Докладвайте остатъка като това, което е: хигиена или констатация за управление на актуализациите за сигурност, обикновено Low, от време на време Medium, където защитното условие е крехко или компонентът е много отвъд края на поддръжката. Заявете ясно, че използваемият път е тестван и не е намерен, и че оценката отразява оставащата изложеност — неподдържан софтуер, свойство за безопасност, почиващо на конфигурация, а не на фиксиран код. Тази рамка е защитима пред одитор и полезна за екипа, който притежава цикъла на актуализациите за сигурност.
Описаният ангажимент не възпроизвежда предполагаемите RCE проблеми през проверените външни пътища. Остават находки за имейл удостоверяване, разкриване на информация и анонимна услуга за прехвърляне на файлове. Те изискват собствен контекст и оценка на тежестта; неуспешна RCE проба не прави автоматично всички останали проблеми нискорискови.
Как да укрепите защитата
- Записвайте защитното условие като твърдение за конфигурация, не като памет — поставете списъка с модули, адреса за свързване или функционалния флаг под управление на конфигурации и сигнализирайте при отклонение.
- Дръжте остарелия компонент в списъка с чакащи актуализации с истинската му възраст, независимо от текущата използваемост.
- Където безопасността зависи от прокси, правило на защитна стена или контрол на достъпа пред компонента, документирайте тази зависимост в записа за контрол на промените за самия контрол, така че премахването му да задейства преглед.
- Премахвайте функции и модули, които не използвате, вместо да разчитате, че са изключени; отсъстващ код не може да бъде повторно включен по случайност.
- Третирайте датите на край на поддръжката като твърди крайни срокове с определени отговорни лица, не като незадължителни бележки.
Неудобният разговор за покритието
Понякога механизмът за експлоатация не може да бъде проверен, защото достъпът е ограничен. Услугата филтрира IP адреса на тестера, ограниченията на честотата възпрепятстват проверката, липсват необходимите данни за удостоверяване или определеният период за тестване е изтекъл. Това не доказва, че уязвимостта липсва.
В такава ситуация докладът трябва изрично да описва ограничението на покритието: кой актив не е проверен, коя проверка не е изпълнена, защо и какво е необходимо за повторно тестване. Признатият пропуск е по-полезен от неподкрепено заключение, че няма проблеми. За него може да се планира допълнителна проверка.
Научихме цената на това на отделен ангажимент. Цял адресен блок в обхвата не върна нищо на приложния слой — никакви отговори, никакви грешки, никакви банери. Изкушаващият прочит беше, че диапазонът е неизползван или защитен така, че да не връща отговори. Той не беше нито едното: блокът филтрираше на приложния слой според адреса ни на източник, а втора наблюдателна точка го съживи. Ако не бяхме сменили позицията, докладът щеше да запише чист диапазон, който всъщност никога не беше изследван.
Какво един доклад, пълен с опровержения, всъщност ви казва
Клиентите понякога възприемат такъв доклад като недостатъчно задълбочен: скенерът е посочил четиринадесет критични проблема, а докладът съдържа два доказани проблема, седем документирани отхвърляния и няколко констатации с ниска критичност. Това може погрешно да изглежда като снизходителна оценка.
Обратното е вярно. Преобразуването на дълъг списък хипотези в къс списък доказани факти плюс защитим запис за това, което е изключено, е най-скъпата и най-полезна работа в ангажимента. Възпроизвеждането на известен експлойт е работа за една сутрин; установяването, че уязвим път на кода не може да бъде достигнат, и записването на доказателството, така че заключението да преживее следващото изграждане наново, изисква тестерът действително да разбере внедряването.
Четете такъв доклад, като проверявате дали всяко отхвърляне е опровержимо. Достоверно опровержение назовава примитива и показва сондата; тънък тест казва „не можа да бъде потвърдено“ и продължава. Въпросите, които си струва да зададете на доставчик, са прями: за всяка точка, която отхвърлихте, какво трябваше да е вярно, за да работи експлойтът, и как установихте, че не е? Кои заключения зависят от конфигурация, която би могла да се промени? Какво не достигнахте, и откъде опитахте? Конкретни отговори означават, че сте купили проверка. Отговори в страдателен залог означават, че сте купили сканиране с корица.
Как да направите това рутинно
Вътрешните екипи могат да прилагат същия подход към резултатите от собствените си скенери. Систематичната проверка намалява времето, прекарано в спорове за оценки на критичността.
Започнете, като проверявате и приоритизирате по примитив, а не по критичност. Групирайте опашката по условието, от което всеки проблем зависи — този модул зареден, тази крайна точка изложена, тази версия на протокол договорима — и дълъг списък се свива до шепа въпроси за собственото ви внедряване, няколко от които изчистват цели клъстери наведнъж. Триажът първо по критичност ви принуждава да извеждате същия въпрос за достижимост отново и отново, в низходящ ред на паниката.
После поддържайте регистъра. Един ред за опровергана точка, във формата по-горе, с попълнено условие за загуба на валидност, защото условието за изтичане е частта, която си струва. Проверявайте повторно след промени в инфраструктурата — миграция на платформа, замяна на прокси, обновяване на базов образ, промяна във входния път — и третирайте промяна, докосваща записано защитно условие, като автоматичен повод за повторна проверка, а не като нещо, което да забележите по-късно.
Следете отделни състояния като потвърдено, доказано незасегнато, ограничено при определени условия, невъзпроизведено и непроверено. Пазете доказателствата и основанията за нов преглед. Отрицателна проба не трябва да става доказано незасегнато без допълнителни данни; наличен софтуер не изисква едно и също състояние във всеки работен процес.
Как да укрепите защитата
- Добавете състояние „проверено като неексплоатируемо (условно)“ в проследяващата система, със задължителни полета за примитив, сонда, наблюдение и условие за загуба на валидност.
- Проверявайте и приоритизирайте изхода от скенера в групи по примитив; отговорете на въпроса за достижимост веднъж на група, не веднъж на констатация.
- Закачете повторната проверка за управлението на промените: всяка промяна, докосваща записано защитно условие, преотваря свързаните записи.
- Направете ограниченията на покритието първокласен раздел във вътрешните записи на тестовете, така че недостижим актив да бъде планиран, а не приет за здрав.
- Тествайте от повече от една мрежова позиция навсякъде, където филтрирането по източник е правдоподобно, и записвайте наблюдателната точка с всяка сонда.
- Преглеждайте регистъра на фиксирана честота и промотирайте всичко, чието условие за загуба на валидност тихомълком е станало истина.
Колко от вашите критични констатации са действително доказани?
Валидирана оценка на уязвимостите разделя доказуемото от просто докладваното, така че екипът ви да поправя това, което има значение.
Заявете оценка