🐻
CTF Notes
  • Home
  • General
    • Hints
    • Formats
    • Links
    • Reversing
  • Binary
    • Basics
    • Vectors
    • Evasion
    • Payloads
    • Heap
    • Tools
  • Web
    • Web
    • Javascript
    • PHP
  • System
    • Escape
    • Escalation
    • Shells
  • Crypto
    • Hints
Powered by GitBook
On this page
  • Function pointers used by _call_tls_dtors
  • .fini ELF termination function table
  • glibc exit handlers
  • Hijack the stack of a created pthread
  • Overwrite a function pointer in .got.plt
  • Threads have their own .got.plt, it seems.
  • Overwrite __malloc_hook and friends
  • Loader hooks
  • Overwrite a return address on the stack
  • Overwrite a SIGRETURN frame
  • Overwrite some application function pointer
  • Pivot the stack
  • vtable techniques
  • Forged C++ object
  • vtables of FILE* objects
  • Function pointers in __IO_STR_FIELDS
  1. Binary

Vectors

These are various ways to gain control of the instruction pointer.

PreviousBasicsNextEvasion

Last updated 3 years ago

Function pointers used by _call_tls_dtors

Called as a part of __run_exit_handlers as described above, has a list of destructors to invoke. The function pointers are mangled using (see link above for evasion technique)

.fini ELF termination function table

This table contains function pointers which are called after main() returns. Many challenges disable this by NOPing out the function responsible for calling. Check for xrefs.

glibc exit handlers

if exit() is ever called, glibc invokes a set of functions called exit handlers. Check out the implementation of exit() for a pointer to __run_exit_handlers and the function list it uses.

Hijack the stack of a created pthread

The system allocates stack memory for new pthreads using mmap. It has a somewhat predictable behavior, so you may be able to double-free so that the same memory gets allocated both as a stack space and as user data space. Write whatever you want on that stack and run free!

Overwrite a function pointer in .got.plt

If the binary lacks FULL RELRO, .got.plt is writable. It's only used on the very first call to a library function, so the sploit needs to overwrite an unused call and trigger it later. You may only need to overwrite the least-significant bytes, depending on where you want to go.

Threads have their own .got.plt, it seems.

Overwrite __malloc_hook and friends

If you know you're running glibc and know where glibc is and have a write primitive, you can overwrite one of the hooks

__malloc_hook
__realloc_hook
__memalign_hook
__free_hook

They're just global variables with function pointers in them.

Loader hooks

The _rtld_global._dl_load_lock and _rtld_global._dl_rtld_lock_recursive function pointers are called by dl_fini. The recursive member is at offset 0xf08 in glibc 2.31.

Overwrite a return address on the stack

If you can write to the stack, overwrite the return address. "Return" to wherever you please. Not much else to say about that.

Overwrite a SIGRETURN frame

If you find a stack overflow in a signal handler, you can even control registers by hijacking the data stored for sys_sigrt!

Overwrite some application function pointer

If the code itself using func pointers, nuke them.

Pivot the stack

If you can overwrite a stored rbp to point to a buffer you control, you own the stack.

vtable techniques

Forged C++ object

C++ objects with inheritances start with a vtable pointer. If you can control the vtable pointer, you can run whatever function you want.

  • Corrupt an object pointer to point to your vtable pointer.

  • Corrupt an object in memory to overwrite the vtable pointer itself.

vtables of FILE* objects

Function pointers in FILE* objects

These techniques are designed to bypass the vtable validation introduced in glibc 2.24. Supposedly, they give control of rip, rdi, rsi, and rdx.

Function pointers in __IO_STR_FIELDS

glibc before 2.28 had some function pointers which were called by various file handling functions (see patch above) and printf derivates. They were never anything other than malloc and free or NULL, so the devs removed the pointer magic.

shows how a Use-After-Free bug can be exploited this way.

The opaque FILE* type points to an internal object which has a vtable-ish thing. The simplest form of this attack is as of libc 2.24.

from GSEC 2018 () ()

Tell me more
Pointer Guard
Tell me more
Tell me more
A writeup
Tell me more
Tell me more
Tell me more
This writeup
Documentation
Tell me more
A writeup
A broken writeup
obsolete
Whitepaper
Presentation
slides
Tell me more
And more
Tell me more
Patch