1

I'm looking at a CVE for an old thrift shop router that amounts to a stack based buffer overflow with no NULL characters allowed. I can control the instruction pointer register as well as a few less useful registers. My goal is to perform a stack pivot to something I control. The router runs on MIPS big endian architecture so I can't leave the last 8 bits of a payload empty to get a leading NULL in an address. e.g. 0x00XXXXXX. I'm left to look for gadgets in shared objects (or the stack if cache flushed). I find that shared objects are generally loaded at higher addresses that make use of all 32 bits of the address. I cannot use gadgets from the vulnerable process because it was not compiled with -fpie and it loads at the same address with a leading NULL every time.

If I consistently want to be able to use gadgets in a shared object, it will need to be loaded with the same base address most of the time. Assuming no ASLR (not enabled on my router), what determines where a shared object will be loaded?

If I run ldd on the target binary, I get this:

$ mips-linux-ldd squashfs-root/sbin/my_binary
    /lib/ld-uClibc.so.0 => /lib/ld-uClibc.so.0 (0x00000000)

Not super useful. I know that ld-uClibc.so.0 doesn't get loaded at 0x00000000 and that there are several other libraries that get loaded for this process (not dlopen'ed) which are not listed. Perhaps the non-useful output is a toolchain thing or due to the fact that I'm not running on the target architecture.

Under the hood, I'd think we're looking at mmap logic.

I found this in an article from Oracle:

An executable or shared object file's base address is calculated during execution from three values: the memory load address, the maximum page size, and the lowest virtual address of a program's loadable segment

To me it seems like these things would never change when working with a specific firmware version where the binaries can always be expected to be the same.

My questions are:

  • Will shared objects get loaded in the same place every time on a Linux system with ASLR disabled?
    • Is the mapping deterministic?
  • What factors, if any will make the shared object map to a different address?
    • Perhaps 2 libraries conflict in a preferred address
  • Iff library loading is deterministic, can I assume the shared object will always be at the same address after checking once? The word deterministic answers my own question, but I want to be clear.

0

Browse other questions tagged or ask your own question.