macOS .Net Applications Injection

Support HackTricks

Αυτή είναι μια περίληψη της ανάρτησης https://blog.xpnsec.com/macos-injection-via-third-party-frameworks/. Ελέγξτε την για περισσότερες λεπτομέρειες!

.NET Core Debugging

Establishing a Debugging Session

Η διαχείριση της επικοινωνίας μεταξύ του debugger και του debuggee στο .NET γίνεται από το dbgtransportsession.cpp. Αυτό το συστατικό ρυθμίζει δύο ονομαστικούς σωλήνες ανά διαδικασία .NET όπως φαίνεται στο dbgtransportsession.cpp#L127, οι οποίοι ξεκινούν μέσω του twowaypipe.cpp#L27. Αυτοί οι σωλήνες έχουν το επίθημα -in και -out.

Επισκεπτόμενος το $TMPDIR του χρήστη, μπορεί κανείς να βρει διαθέσιμα FIFOs αποσφαλμάτωσης για εφαρμογές .Net.

DbgTransportSession::TransportWorker είναι υπεύθυνος για τη διαχείριση της επικοινωνίας από έναν debugger. Για να ξεκινήσει μια νέα συνεδρία αποσφαλμάτωσης, ένας debugger πρέπει να στείλει ένα μήνυμα μέσω του σωλήνα out που ξεκινά με μια δομή MessageHeader, λεπτομερώς στον πηγαίο κώδικα .NET:

struct MessageHeader {
MessageType   m_eType;        // Message type
DWORD         m_cbDataBlock;  // Size of following data block (can be zero)
DWORD         m_dwId;         // Message ID from sender
DWORD         m_dwReplyId;    // Reply-to Message ID
DWORD         m_dwLastSeenId; // Last seen Message ID by sender
DWORD         m_dwReserved;   // Reserved for future (initialize to zero)
union {
struct {
DWORD         m_dwMajorVersion;   // Requested/accepted protocol version
DWORD         m_dwMinorVersion;
} VersionInfo;
...
} TypeSpecificData;
BYTE          m_sMustBeZero[8];
}

Για να ζητήσετε μια νέα συνεδρία, αυτή η δομή συμπληρώνεται ως εξής, ορίζοντας τον τύπο μηνύματος σε MT_SessionRequest και την έκδοση πρωτοκόλλου στην τρέχουσα έκδοση:

static const DWORD kCurrentMajorVersion = 2;
static const DWORD kCurrentMinorVersion = 0;

// Configure the message type and version
sSendHeader.m_eType = MT_SessionRequest;
sSendHeader.TypeSpecificData.VersionInfo.m_dwMajorVersion = kCurrentMajorVersion;
sSendHeader.TypeSpecificData.VersionInfo.m_dwMinorVersion = kCurrentMinorVersion;
sSendHeader.m_cbDataBlock = sizeof(SessionRequestData);

Αυτή η κεφαλίδα αποστέλλεται στη συνέχεια στον στόχο χρησιμοποιώντας την κλήση συστήματος write, ακολουθούμενη από τη δομή sessionRequestData που περιέχει ένα GUID για τη συνεδρία:

write(wr, &sSendHeader, sizeof(MessageHeader));
memset(&sDataBlock.m_sSessionID, 9, sizeof(SessionRequestData));
write(wr, &sDataBlock, sizeof(SessionRequestData));

Μια λειτουργία ανάγνωσης στον σωλήνα out επιβεβαιώνει την επιτυχία ή αποτυχία της εγκατάστασης της συνεδρίας αποσφαλμάτωσης:

read(rd, &sReceiveHeader, sizeof(MessageHeader));

Reading Memory

Μόλις καθοριστεί μια συνεδρία αποσφαλμάτωσης, η μνήμη μπορεί να διαβαστεί χρησιμοποιώντας τον τύπο μηνύματος MT_ReadMemory. Η συνάρτηση readMemory είναι λεπτομερής, εκτελώντας τα απαραίτητα βήματα για να στείλει ένα αίτημα ανάγνωσης και να ανακτήσει την απάντηση:

bool readMemory(void *addr, int len, unsigned char **output) {
// Allocation and initialization
...
// Write header and read response
...
// Read the memory from the debuggee
...
return true;
}

The complete proof of concept (POC) is available here.

Writing Memory

Ομοίως, η μνήμη μπορεί να γραφτεί χρησιμοποιώντας τη συνάρτηση writeMemory. Η διαδικασία περιλαμβάνει την ρύθμιση του τύπου μηνύματος σε MT_WriteMemory, καθορίζοντας τη διεύθυνση και το μήκος των δεδομένων, και στη συνέχεια στέλνοντας τα δεδομένα:

bool writeMemory(void *addr, int len, unsigned char *input) {
// Increment IDs, set message type, and specify memory location
...
// Write header and data, then read the response
...
// Confirm memory write was successful
...
return true;
}

Η σχετική POC είναι διαθέσιμη εδώ.

.NET Core Εκτέλεση Κώδικα

Για να εκτελέσετε κώδικα, πρέπει να εντοπίσετε μια περιοχή μνήμης με άδειες rwx, κάτι που μπορεί να γίνει χρησιμοποιώντας vmmap -pages:

vmmap -pages [pid]
vmmap -pages 35829 | grep "rwx/rwx"

Είναι απαραίτητο να εντοπιστεί μια τοποθεσία για να αντικατασταθεί ένας δείκτης συνάρτησης και στο .NET Core, αυτό μπορεί να γίνει στοχεύοντας τον Dynamic Function Table (DFT). Αυτός ο πίνακας, που περιγράφεται στο jithelpers.h, χρησιμοποιείται από το runtime για τις βοηθητικές συναρτήσεις JIT compilation.

Για συστήματα x64, η αναζήτηση υπογραφών μπορεί να χρησιμοποιηθεί για να βρεθεί μια αναφορά στο σύμβολο _hlpDynamicFuncTable στο libcorclr.dll.

Η συνάρτηση debugger MT_GetDCB παρέχει χρήσιμες πληροφορίες, συμπεριλαμβανομένης της διεύθυνσης μιας βοηθητικής συνάρτησης, m_helperRemoteStartAddr, που υποδεικνύει την τοποθεσία του libcorclr.dll στη μνήμη της διαδικασίας. Αυτή η διεύθυνση χρησιμοποιείται στη συνέχεια για να ξεκινήσει μια αναζήτηση για τον DFT και να αντικατασταθεί ένας δείκτης συνάρτησης με τη διεύθυνση του shellcode.

Ο πλήρης κωδικός POC για την ένεση στο PowerShell είναι προσβάσιμος εδώ.

Αναφορές

Support HackTricks

Last updated