Эксплойтов в интернете не найдено. Объяснений почему так случилось тоже. Все ссылки на коммиты и исправления подобраны исходят из дат и типов внесенных изменений, а также патч-версий и обсуждений в соответсвующем ишью. Официальных комментариев о связи изменений, причин и данной CVE нет. Более того, комментарий об открытии изменений в самом ишью проигнорен разработчиками :)
Злоумышленник без прохождения авторизации может сформировать запрос, который вызовет отказ в обслуживании веб-приложения развернутом на IIS-сервере.
About Product
ASP.NET Core —- это кроссплатформенный, высокопроизводительный,открытый фреймворк для создания веб-приложений. Веб-приложение может быть развернут на большей части популярных веб-серверов, таких как Nginx. Apache. В том числе и Windows IIS (Internet Information Services (IIS)).
Affected Versions
Вы подвержены DDOS, если используете AspNetCoreModuleV2 версии не выше 12.2.19024.2, то есть ваш конфигурационный файл сервера выглядит как
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\\myapp.dll" stdoutLogEnabled="false" stdoutLogFile=".\\logs\\stdout" hostingModel="inprocess" />
</system.webServer>
</location>
</configuration>
Проверить версию используемой библиотеки можно с помощью команды
(Get-Item "$env:ProgramFiles\\IIS\\Asp.Net Core Module\\V2\\aspnetcorev2.dll").VersionInfo
Reasons
[Вероятно] К отказу в обслуживании, а именно (как указано в announcments) к аварийному завершению работы сервера приводит неправильная работа с указателями. [Возможно] это связано с повторному обращению к ранее обнуленному указателю.
Fix
В коммитах от соответствующих дат исправления добавлен дополнительный код, добавляющий блокировку DisconnectHandler объекта при его удалении.
<...>
class DisconnectHandler final: public IHttpConnectionStoredContext
{
public:
DisconnectHandler(IHttpConnection* pHttpConnection)
: m_pHandler(nullptr), m_pHttpConnection(pHttpConnection), m_disconnectFired(false)
{
InitializeSRWLock(&m_handlerLock);
}
virtual
~DisconnectHandler()
{
RemoveHandler();
}
void
NotifyDisconnect() override;
void
CleanupStoredContext() noexcept override;
void
SetHandler(std::unique_ptr<IREQUEST_HANDLER, IREQUEST_HANDLER_DELETER> handler);
void RemoveHandler() noexcept;
private:
SRWLOCK m_handlerLock {};
std::unique_ptr<IREQUEST_HANDLER, IREQUEST_HANDLER_DELETER> m_pHandler;
IHttpConnection* m_pHttpConnection;
bool m_disconnectFired;
};
В части кода выше мы видим деструктор, который вызывает следующую функцию.
#include "DisconnectHandler.h"
#include "exceptions.h"
#include "proxymodule.h"
#include "SRWExclusiveLock.h"
void DisconnectHandler::NotifyDisconnect()
{
try
{
std::unique_ptr<IREQUEST_HANDLER, IREQUEST_HANDLER_DELETER> pHandler;
{
SRWExclusiveLock lock(m_handlerLock);
m_pHandler.swap(pHandler);
m_disconnectFired = true;
}
if (pHandler != nullptr)
{
pHandler->NotifyDisconnect();
}
}
catch (...)
{
OBSERVE_CAUGHT_EXCEPTION()
}
}
void DisconnectHandler::CleanupStoredContext() noexcept
{
delete this;
}
void DisconnectHandler::SetHandler(std::unique_ptr<IREQUEST_HANDLER, IREQUEST_HANDLER_DELETER> handler)
{
IREQUEST_HANDLER* pHandler = nullptr;
{
SRWExclusiveLock lock(m_handlerLock);
handler.swap(m_pHandler);
pHandler = m_pHandler.get();
}
assert(pHandler != nullptr);
if (pHandler != nullptr && (m_disconnectFired || m_pHttpConnection != nullptr && !m_pHttpConnection->IsConnected()))
{
pHandler->NotifyDisconnect();
}
}
void DisconnectHandler::RemoveHandler() noexcept
{
**SRWExclusiveLock lock(m_handlerLock);**
m_pHandler = nullptr;
}
Сам объект типа SRWExclusiveLock описан в следующих файлах
#pragma once
#include <synchapi.h>
class SRWExclusiveLock
{
public:
SRWExclusiveLock(const SRWLOCK& lock) noexcept;
~SRWExclusiveLock();
private:
const SRWLOCK& m_lock;
};