Pointer Redirecting

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

String pointers

If a function call is going to use an address of a string that is located in the stack, it’s possible to abuse the buffer overflow to overwrite this address and put an address to a different string inside the binary.

If for example a system function call is going to use the address of a string to execute a command, an attacker could place the address of a different string in the stack, export PATH=.:$PATH and create in the current directory an script with the name of the first letter of the new string as this will be executed by the binary.

Σε πραγματικούς στόχους, το repointing ενός stack string pointer είναι συνήθως πιο ενδιαφέρον από το να αλλάξεις απλά το εμφανιζόμενο κείμενο:

  • Redirect a later system/popen/execl* argument to an existing "/bin/sh" or attacker-controlled command string already present in memory.
  • Redirect a later read sink such as puts("%s", ptr) or write(fd, ptr, len) to leak stack, heap or binary data.
  • Redirect a later write sink such as strcpy(dst, ...), memcpy(dst, src, len), or a structure field assignment through ptr->field = value to turn the stack overflow into a second-stage arbitrary write.

Κατά το auditing, δώστε προτεραιότητα σε stack locals όπως char *cmd, char *path, char *buf, FILE *fp, ή δείκτες μέσα σε προσωρινές δομές request/response που χρησιμοποιούνται μετά το overflow αλλά πριν η συνάρτηση επιστρέψει. Αυτό είναι ιδιαίτερα χρήσιμο όταν το overflow δεν μπορεί με ασφάλεια να φτάσει το saved return address εξαιτίας ενός canary ή επειδή η διαφθορά ενός κοντινού pointer είναι αρκετή.

Αν η διαφθορά περιορίζεται σε ένα μερικό overwrite (π.χ. επειδή το bug προσθέτει ένα 0x00), δοκίμασε να ανακατευθύνεις τον pointer προς:

  • Μια κοντινή συμβολοσειρά στο ίδιο stack frame
  • Ένα άλλο αντικείμενο στο ίδιο module / non-PIE image
  • Μια ελεγχόμενη περιοχή της οποίας τα high bytes παραμένουν αμετάβλητα

Για την σχετική περίπτωση προσανατολισμένη σε ASLR όπου ένα trailing NUL τροποποιεί έναν existing stack pointer αντί για μια συγκεκριμένη local μεταβλητή, δες Ret2ret & Reo2pop.

You can find an example of this in:

Function pointers

Same as string pointer but applying to functions, if the stack contains the address of a function that will be called, it’s possible to change it (e.g. to call system).

Χρήσιμοι στόχοι δεν είναι μόνο ρητές callback μεταβλητές όπως void (*fp)(). Στην πράξη, ψάξε για:

  • Callbacks stored in local structs passed later to helper functions
  • Destructor / cleanup handlers invoked on error paths
  • Parser dispatch tables or state-machine handlers copied to the stack
  • Local structs / objects that later dispatch through an indirect call

In modern exploitation, pointer redirection is often the last primitive available before touching the canary. A 2024 exploitation writeup for CVE-2024-20017 shows the typical pattern: the overflow reaches several local variables before the stack canary, the attacker corrupts a stack pointer plus its associated length/value, and a later assignment through that pointer becomes an arbitrary write without ever needing to return through the corrupted frame.

Pointer corruption to second-stage primitives

If a nearby pointer is later dereferenced for a store, the goal is usually not to jump directly with the first overflow, but to upgrade the primitive:

  1. Overflow a local buffer and corrupt a pointer plus any associated length / integer / index.
  2. Wait for the function to perform a post-overflow dereference such as ptr->len = x, memcpy(ptr, src, n) or *ptr = value.
  3. Use that resulting write-what-where to overwrite a GOT slot, callback, config pointer, or another indirect callsite.

This is a good option when:

  • The bug stops at the canary
  • The function pointer itself is not directly reachable
  • A 4-byte or 8-byte data write is easier to get than an immediate control-flow hijack

The same idea also works for read primitives if the corrupted pointer is later passed to logging, printing, or network send helpers.

Modern AArch64 note: PAC / BTI

On current AArch64 targets, a classic saved return address overwrite may fail because the epilogue authenticates x30 with PAC. In those cases, non-return hijacks such as corrupted local function pointers or callback pointers become more attractive.

However, if BTI is enabled, the overwritten indirect-call target must still land on a valid landing pad (typically a function entry with bti c, or in PAC-enabled code a prologue starting with paciasp/pacibsp). Therefore, when redirecting a stack function pointer on AArch64, prefer:

  • Real function entries instead of mid-function gadgets
  • Targets whose prologue already satisfies BTI
  • Targets where the indirect-call pointer is not additionally authenticated before use

For a related AArch64 stack-overflow context, check ret2win-arm64.

You can find an example in:

References

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