// underground articles :: est. 200x //

root@h4ckz1ne:~$ rundll32 cat.dll,Open reverse,2,revers-p2p-protokola-windows-update-dosvc-doclient-dll_

> Реверс P2P протокола Windows Update (DoSvc / doclient.dll)

[2026-04-15 18:47] [author: admin] [cat: reverse] [hits: 22]

"Microsoft никогда не публиковал спеку этого P2P
протокола. Значит — придётся выдернуть её из бинарника."

============================================================
[ 00 ] ВВЕДЕНИЕ
============================================================

Windows Delivery Optimization (DO / WUDO) — встроенный
P2P-сервис для распространения апдейтов Windows. Работает
от SYSTEM, слушает TCP 7680 на всех интерфейсах,
позволяет peers в LAN обмениваться контентом Windows Update.

Поверхность атаки:

- порт 7680 открыт на 0.0.0.0
- контекст SYSTEM (NetworkService)
- нет аутентификации — только проверка swarm hash
- P2P-трафик НЕ шифруется (CDN/cloud — HTTPS)
- доступен из LAN без кредов

============================================================
[ 01 ] АРХИТЕКТУРА СЕРВИСА
============================================================

dosvc.dll — тонкий загрузчик, вся логика в doclient.dll,
который грузится через LoadLibraryExW -> CreateDOService.

Ключевые классы (выдернуто из RTTI):

CPeerSock — TCP-сокет, state machine, парсинг
CSwarmConn — per-peer соединение, handshake, диспатч
CServer — реестр swarm'ов, управление peers
CSwarm — состояние download swarm
CDownload — трекинг скачивания, управление pieces
CStorage — хранение pieces, disk I/O, hash verify
CBitField — битовый массив доступности pieces
CMetaInfo — метаданные контента (pieces, size, hash)
CConnMan — менеджер соединений, свич на CDN
CHttpPeerConn — HTTP-mode peer (CDN вместо TCP P2P)
CHash — обёртка BCrypt (SHA256)

============================================================
[ 02 ] ПРОТОКОЛ :: ОБЗОР
============================================================

BitTorrent-подобный бинарный фрейминг. Big-endian integers.
TCP transport. Порт 7680. Три стадии:

1. Handshake — строка "Swarm protocol" + 32-байтовый
хэш контента (SHA256 идентификатор swarm'а)
2. Peer ID exchange — 20 байт произвольного идентификатора
3. Data transfer — 11 типов сообщений, длина до 2 МБ

Ключевое отличие от BitTorrent:

- handshake клиента = 56 байт (БЕЗ peer_id)
- handshake сервера = 76 байт (+ peer_id в конце)
- swarm_hash ОБЯЗАН совпасть с активным download'ом в
CServer::GetSwarm, иначе connection drop

Полная спека — в секции [ 10 ].

============================================================
[ 03 ] CLOUD ИНФРАСТРУКТУРА
============================================================

DO использует 5 cloud-эндпоинтов. Единственный
захардкоженный адрес — geo.prod.do.dsp.mp.microsoft.com.
Остальные приходят динамически по цепочке:

Geo -> GeoVersion -> ContentPolicy / KeyValue / Discovery

Все запросы по HTTPS с pin'ом сертификата.

Peer discovery происходит через:

- DNS-SD / mDNS в локалке
- Cloud API (ContentPolicy с swarm ID)
- Teredo / IPv6 через TeredoExtAcquireTeredoConsumerHandle

============================================================
[ 04 ] ВЕРИФИКАЦИЯ ДАННЫХ
============================================================

Каждый piece проверяется SHA256 против таблицы хэшей
из объекта CMetaInfo. Таблица создаётся ТОЛЬКО из ответа
CDN и подписана RSA (PKCS#1). Peers не могут подменить
таблицу — она приходит от Microsoft по HTTPS.

Цепочка доверия:

Microsoft CDN (HTTPS + RSA)
|
v
метаданные + таблица SHA256 хэшей
|
v
CMetaInfo
|
v
peer шлёт данные -> SHA256(data) -> сравнение с
CMetaInfo.hash_table[piece_index]

Без CDN-метаданных P2P-скачивание невозможно — CPieceChecker
не инициализируется и данные от peers не принимаются.

============================================================
[ 05 ] БЕЗОПАСНОСТЬ ПРОТОКОЛА
============================================================

В ходе тестирования критических уязвимостей не найдено.
Сервис ни разу не крашнулся при отправке любых комбинаций
сообщений. Наблюдения:

[+] Integrity: каждый piece = SHA256(data) vs CDN-таблица.
Подмена контента невозможна.

[+] Chain of trust: адреса обновляются по HTTPS с pin'ом
сертификата. Таблица хэшей RSA-подписана.

[+] Устойчивость: при массовой отправке (до 100 повторов)
процесс DoSvc выживает, закрываются только отдельные
соединения.

[-] P2P-трафик не шифруется — TLS negotiation при
реверсе не обнаружен. Только CDN/cloud идут по HTTPS.

[-] Аутентификация peers — ТОЛЬКО через совпадение
swarm hash. Без хэша — connection reject.

============================================================
[ 06 ] HTTP MODE
============================================================

Альтернатива TCP P2P. CHttpPeerConn использует HTTP Range
requests через WinHTTP:

// CHttpPeerConn::SendRequestBlock -- декомп

offset = GetPieceOffset(piece_index) + request.Begin()
WinHTTP-запрос с Range header

обработка ответов:
206 -> Content-Range парсинг (bytes start-end/total)
200 -> Content-Length или Transfer-Encoding: chunked
403 -> CDN unauthorized, banning логика
301 / 302 -> redirect с лимитом хопов

error handling:
Fibonacci backoff для retries (CFibonacciBackoff)
CDN ban list (CBanList::IsBanned)
переключение на альтернативный CDN
(_TryCdnFallbackDownload)

============================================================
[ 07 ] РЕЖИМЫ СКАЧИВАНИЯ
============================================================

Mode Название Описание
---- -------------------- -----------------------------
0 HTTP only без P2P
1 LAN P2P + HTTP default
2 Group P2P + HTTP enterprise
3 Internet P2P + HTTP P2P через интернет
99 Simple HTTP CDN provider

Конфигурация:
реестр HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\DeliveryOptimization
либо cloud override через GeoVersion / KeyValue endpoints.

============================================================
[ 08 ] VTABLE :: CSwarmConnPeerSockListener
============================================================

Полная vtable из 25 методов обратного вызова
(IDA RTTI dump):

offset method описание
------ ------------------- ----------------------------
0x00 GetConnMan получить менеджер соединений
0x08 GetMaxRequests макс. кол-во запросов
0x10 GetPeerType тип peer
0x18 IsUnrestrictedLan неограниченное LAN?
0x20 ScheduleDeletion запланировать удаление
0x28 OnConnect подключение установлено
0x30 OnInvalidMsg невалидное сообщение
0x38 OnKeepAlive keepalive получен
0x40 OnPartialHandshake handshake получен
0x48 OnHandover передача управления
0x50 OnPeerId peer ID получен
0x58 OnChoke choke
0x60 OnUnchoke unchoke
0x68 OnInterested interested
0x70 OnNotInterested not interested
0x78 OnHave piece доступен
0x80 OnDoNotHave piece недоступен
0x88 OnBitField bitfield получен
0x90 OnRequest запрос piece
0x98 OnPiece piece data получен
0xA0 OnCancel отмена запроса
0xA8 OnBytesReceived статистика приёма
0xB0 OnBodyBytes байты тела
0xB8 OnBytesSent отправлено
0xC0 OnCommError ошибка коммуникации

============================================================
[ 09 ] ИНСТРУМЕНТЫ ТЕСТИРОВАНИЯ
============================================================

Написаны кастомные C-инструменты. Все работают от
обычного юзера
— права админа не нужны.

--- 09.1 :: Handshake ---

// формирование P2P handshake для DoSvc
void send_handshake(SOCKET s, const char* swarm_hash_hex) {
unsigned char buf[128];
int pos = 0;

buf[pos++] = 14; // proto_len
memcpy(buf + pos, "Swarm protocol", 14);
pos += 14;
buf[pos++] = 1; // version
memset(buf + pos, 0, 8); // reserved
pos += 8;

unsigned char hash[32] = {0};
hex2bytes(swarm_hash_hex, hash, 32); // swarm hash
memcpy(buf + pos, hash, 32);
pos += 32;

send(s, (char*)buf, pos, 0); // total: 56 B
}

--- 09.2 :: Отправка P2P-сообщений ---

// Big-endian uint32
void put32(unsigned char* buf, unsigned int val) {
buf[0] = (val >> 24) & 0xFF;
buf[1] = (val >> 16) & 0xFF;
buf[2] = (val >> 8) & 0xFF;
buf[3] = val & 0xFF;
}

// length-prefixed отправка
void send_msg(SOCKET s, unsigned char* msg, int msglen) {
unsigned char hdr[4];
put32(hdr, msglen); // LE prefix
send(s, (char*)hdr, 4, 0);
send(s, (char*)msg, msglen, 0);
}

// HAVE (msgId=4, piece_index=42)
unsigned char msg[5];
msg[0] = 4; // HAVE
put32(msg + 1, 42); // piece_index
send_msg(s, msg, 5);

// REQUEST (msgId=6)
unsigned char req[13];
req[0] = 6; // REQUEST
put32(req + 1, 0); // piece_index
put32(req + 5, 0); // offset
put32(req + 9, 1048576); // length (1 MB)
send_msg(s, req, 13);

--- 09.3 :: Массовая отправка ---

Результаты (сколько повторов выдерживает соединение):

msgId=0 CHOKE -> закрыто на повторе 2
msgId=1 UNCHOKE -> выжил 50 повторов
msgId=4 HAVE -> закрыто на повторе 46
msgId=5 BITFIELD -> закрыто на повторе 4
msgId=6 REQUEST -> закрыто на повторе 5
msgId=7 PIECE -> закрыто на повторе 6
msgId=8 CANCEL -> закрыто на повторе 5
msgId=9 -> выжил 50 повторов
msgId=10 DO_NOT_HAVE -> закрыто на повторе 12

Процесс svchost / DoSvc не крашится — закрываются
только индивидуальные соединения. Сам сервис жив.

============================================================
[ 10 ] СПЕЦИФИКАЦИЯ ПРОТОКОЛА
============================================================

--- 10.1 :: HANDSHAKE (State 0) ---

Client -> Server (56 байт):

field size note
----------- ---- ----------------------------------
proto_len 1 длина protocol string (14)
protocol 14 "Swarm protocol" (ASCII, case-sens)
version 1 версия протокола (1)
reserved 8 нули
swarm_hash 32 SHA256 идентификатор контента

Server -> Client (76 байт):

field size note
----------- ---- ----------------------------------
proto_len 1 14
protocol 14 "Swarm protocol"
version 1 min(local, remote)
reserved 8 reserved[5] = 0x10
swarm_hash 32 echo
peer_id 20 peer ID сервера

Валидация:

proto_len :: диапазон 1..49, НЕ может быть 0 или 22
protocol :: точное совпадение "Swarm protocol"
swarm_hash:: lookup в CServer::GetSwarm — должен
совпасть с активным download'ом

--- 10.2 :: PEER ID (State 1) ---

field size note
------- -------- ---------------------------
peer_id 20 байт произвольный идентификатор

--- 10.3 :: MESSAGE FRAMING (State 2) ---

field size note
------- ----------- ----------------------------------
length 4 (BE) размер payload, max 0x1F4000
(2 МБ). 0 = keepalive
msgId 1 тип сообщения
payload length - 1 данные сообщения

--- 10.4 :: Все типы сообщений ---

id name payload wire
--- --------------- ------- ---------------------------
0 CHOKE 0 00000001 00
1 UNCHOKE 0 00000001 01
2 INTERESTED 0 00000001 02
3 NOT_INTERESTED 0 00000001 03
4 HAVE 4 00000005 04 [idx:4BE]
5 BITFIELD N [N+1:4BE] 05 [bf:N]
6 REQUEST 12 0000000D 06 [idx][off][len]
7 PIECE 8+N [N+9:4BE] 07 [idx][off][data]
8 CANCEL 12 0000000D 08 [idx][off][len]
10 DO_NOT_HAVE 4 00000005 0A [idx:4BE] (cond)
20 KEEPALIVE_DATA N [N+1:4BE] 14 [data] (dropped)

Все msgId вне таблицы -> OnInvalidMsg -> ошибка.

--- 10.5 :: CLOUD ENDPOINTS ---

Geo https://geo.prod.do.dsp.mp.microsoft.com/geo
начальная точка (захардкожена), геолокация

GeoVersion https://geover.prod.do.dsp.mp.microsoft.com/geoversion
версия конфига, обновление endpoint'ов

ContentPolicy https://cp801.prod.do.dsp.mp.microsoft.com/v3/content
peer discovery, CDN URL'ы для контента

KeyValue https://kv801.prod.do.dsp.mp.microsoft.com/
удалённая конфигурация (ключ-значение)

Discovery https://disc801.prod.do.dsp.mp.microsoft.com/
обнаружение peers для swarm

--- 10.6 :: PEER DISCOVERY ---

DNS-SD (mDNS)
поиск в LAN
tunes: DnsPeerDiscoveryParticipationRate,
DnsPeerSearchIntervalMsecs

Cloud API
запрос ContentPolicy с swarm ID
tunes: ContentPolicy_EndpointFullUri

Teredo / IPv6
через TeredoExtAcquireTeredoConsumerHandle

--- 10.7 :: Верификация ---

Piece hash SHA256 (BCrypt) 32 B CMetaInfo (CDN)
Swarm hash SHA256 32 B из метаданных
Content signature RSA + SHA256 var Microsoft cert
(PKCS#1)

--- 10.8 :: Транспортная безопасность ---

P2P (TCP 7680) шифр: НЕТ (cleartext) auth: swarm_hash
CDN (HTTP/HTTPS) шифр: TLS via WinHTTP auth: cert pin
CHttpServerCertRetriever
Cloud API шифр: HTTPS auth: TLS + RSA
подпись метаданных

--- 10.9 :: Конфигурация (реестр) ---

Путь: HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\DeliveryOptimization

DODownloadMode режим (0-3, 99)
DOAbsoluteMaxCacheSize макс. кэш
DOAllowVPNPeerCaching P2P через VPN
DOMinBackgroundQoS фоновый QoS
DOCacheHost hostname кэш-сервера
DODelayBackgroundDownloadFromHttp задержка (фон)
DODelayForegroundDownloadFromHttp задержка (FG)
ParticipationRate уровень P2P
RestrictPeerSelectionBy ограничение peers
VpnKeywords ключевые слова VPN

============================================================
[ 11 ] МЕТОДОЛОГИЯ
============================================================

1. Service discovery
netstat -> порт 7680 -> DoSvc -> doclient.dll

2. Статика
IDA Pro + MCP -> exports, imports, strings

3. State machine
декомп CPeerSock::_ProcessBytes -> 3 состояния

4. Message parser
декомп CPeerSock::_ProcessMsg -> 11 типов

5. Vtable
RTTI CSwarmConnPeerSockListener -> 25 методов

6. Send functions
декомп SendHandShake, SendHave, SendBitField,
SendRequest

7. Cloud endpoints
строковые ссылки -> 5 cloud URL'ов

8. Hash verify
CPieceChecker::CheckPiece -> BCrypt SHA256

9. Config
таблица строк -> 30+ ключей конфигурации

10. Fuzz / behavior
кастомные C-тулзы -> анализ поведения

============================================================
[ 12 ] ЗАЩИТА
============================================================

[*] Отключить P2P:
DODownloadMode=0 через GPO или реестр

[*] Только LAN:
оставить Mode 1 (default), НЕ включать Mode 3
(internet P2P)

[*] Firewall:
блокировать входящий TCP 7680 из недоверенных
сегментов

[*] Мониторинг:
аномальные подключения к 7680 -> IDS/EDR

[*] VLAN:
ограничить P2P-трафик доверенными сегментами

============================================================
[ 13 ] EOF
============================================================

Тестирование проводилось на собственном железе в
изолированной лабораторной среде. Используй полученные
знания ответственно и только с разрешения владельца.


-- end of transmission --

<< back to index