The Design and Implementation of Userland Exec (2014)
grugq.github.io
grugq.github.io
I wrote the code because someone asked how to do this and it was easier to implement it than to explain it in detail. The whole thing is based on what I learned from “Linkers & Loaders,” a great book. (I still have my copy)
Later that year I wrote a wrapper around ul_exec() that used an automated interactive session with gdb to load a process, replace it with another binary (delivered over STDIN) and then execute that. This would prevent the binary ever being written to disk.
Remote exec was documented in phrack 62, along with the more advanced theory of counter forensics. Interestingly, the techniques I discussed in rexec() are now common APT tradecraft. Using common tools to limit the chance of detection and reduce evidence, aka living off the land, is now standard practice. I explained why about 20 years ago :)
http://phrack.org/issues/62/8.html
It seems easier to load the whole issue from here: https://www.exploit-db.com/exploits/42873
The boot loader loaded an image into memory which contained the kernel, a utility process called "proc", and whatever else needed to be available at startup. For an embedded application, that might be the entire program. For a standard desktop environment, it would include a disk driver, a network driver, and a startup program.
Shared object files could also be loaded as part of the initial image. One of them was the program loader. The C library for QNX had calls for the various 'exec' functions, but they were just passed to the program loader shared object. With no special privileges, it allocated the memory for the new program, read in the program image, set up the Unix-type args, and transferred control to the newly loaded program.
Interesting idea, it shows that Linux execute(2) system call doesn't do any magic, except look at setuid bits.
Also, isn't this pretty much what Windows people call "process hollowing" or some such?
I’m not sure what the terminology is these days, but I called it userland exec() because it was an implementation of execve in userland…
I wrote it in, 2003 or 2004? I can’t find an original link anymore, but I posted it to bugtraq the week after I finished it.
By 2008, your original code didn't seem to work: https://lkml.indiana.edu/hypermail/linux/kernel/0803.3/1215....