Now Reading
Bugtraq: Saying Userland Exec

Bugtraq: Saying Userland Exec

2024-01-02 05:41:27



Bugtraq
mailing record archives






From: the grugq <grugq () hcunix web>
Date: Thu, 01 Jan 2004 19:02:26 +0000



Hey,


That is an implementation of userland exec, that's, code which replaces
the present course of picture with a brand new one. The accompaning paper explains
the design and implementation of this code. The complete src code can also be
included.




peace,

--gq
        The Design and Implementation of Userland Exec

                        by the grugq

Summary:

This paper examines a mechanism to execute a binary with out using the
syscall execve(). The design for this mechanism is easy: clear up the
handle house; examine for, and cargo, the dynamic linker; load the binary; set
up the stack; find the entry level, and switch management of execution. One
implemenation of this mechanism is used for example this design.

Introduction:

Userland exec replaces the present course of picture inside the present handle
house with a brand new one. On this, userland exec mimics the habits of the
system name execve()*. Nevertheless, as a result of it operates in userland, the kernel
course of constructions which describe the method picture stay unchanged. This
signifies that the method identify reported by system utilities would be the previous
course of identify, and so on.

The power to load a brand new course of picture with out the direct assist of the kernel
is necessary in lots of situations. For instance: a program (e.g. shellcode) might
load a binary off the wire and execute it with out first creating a duplicate on
disk; or, a program might extract a binary from an encrypted knowledge retailer and
execute it with out making a plain textual content picture on the disk. Userland exec is
helpful for any state of affairs the place it's preferable to not create a file on the
disk when executing a program.

This paper will describe the design and implementation of the userland exec
code. First it should talk about how execve() creates a brand new course of picture, and what
this course of picture appears like (together with the stack structure). Based mostly on this
data the design of the userland exec code might be examined, utilizing the
userland exec implementation for example ideas.

*) This implementation of userland exec is restricted to ELF binaries on i386
Linux programs, nonetheless the methodology outlined is common throughout Unix-like
programs.

Background:

When a Unix program needs to execute one other program it should use the execve()
system name to load the brand new program as a course of picture (creating the brand new
course of by way of fork() is ignored right here). The person web page for the exec household of
perform calls (execl() and the opposite wrappers for execve()) describes what
occurs: "[t]he exec household of features replaces the present  course of picture
with a brand new course of picture." A extra full image of what occurs when a
course of picture is changed might be discovered within the execve() man web page:

       execve() doesn't return on success, and the  textual content,  knowledge,
       bss,  and  stack of the calling course of are overwritten by
       that [sic] of this system loaded. 

Clearly, this system which calls execve() is taken out of reminiscence and the brand new
program loaded. When this occurs, the .textual content and .knowledge segments in addition to the
heap and the stack are changed. Any implementation of userland exec would
must take away the previous course of' textual content, knowledge and heap, and reset the stack.

To design a userland exec implementation, a extra detailed description of how
execve() operates is required. This extra detailed description of how a brand new
course of picture is created from an ELF binary could be: 

First, execve() cleans the handle house of the present course of by unmapping
the entire pages of reminiscence which kind the present picture. If the executable is
dynamically linked -- that's, if it makes use of run time libraries supplied by the
system -- the dynamic linker is loaded into reminiscence. The primary ELF executable is
then mapped into the method handle house. The stack is initialized with the
environmental variables and the opposite parameters to foremost(). The stack can also be
initialized with arguments for the dynamic linker to permit it to find the
binary in reminiscence. Lastly, the kernel determines the proper entry level:
both the dynamic linker, whether it is loaded, or the primary binary, whether it is
not.The kernel then transfers execution to this entry level.

This extra detailed description gives a blueprint for the userland exec
implementation. Nevertheless, some particular particulars nonetheless should be clarified:
specifically the precise structure of the stack simply after the picture is created.
The diagram beneath roughly illustrates this stack structure.

          -----------------------------------------
                        [ 0 ]  <-- prime of the stack
                        [ envp strings ]
                        [ 0 ]
                        [ argv strings ]
                        [ 0 ]
                        [ auxv ]
                        [ 0 ]
                        [ envp ]
                        [ 0 ]
                        [ argv ]
                        [ argc ] <-- stack pointer
          -----------------------------------------

On the prime of the stack are the environmental and argument strings. The underside
of the stack begins with the argument depend, then come the argument
pointerarray and the environmental pointer array.  Within the center is the
Elf_aux vector. This array of information constructions gives data to the
dynamic linker concerning the course of picture, e.g. the situation of this system
header desk.

The dynamic linker is accountable for relocating the ELF binary, if required,
in addition to loading all the required libraries and performing run time image
decision. For extra data on dynamic linkers see [Levine 1999],
[grugq 2001] and [grugq & scut 2001].

Design:

With a transparent understanding of how execve() creates a brand new course of picture, it's
doable to enumerate a listing of steps {that a} userland implementation should
observe. That record is:

1. Clear out the handle house
2. If the binary is dynamically linked, load the dynamic linker
3. Load the binary
4. Initialize the stack
5. Decide the entry level (i.e. the dynamic linker or the primary executable)
6. Switch execution to the entry level

Notice: the second and third step are literally interchangeable.

Implementation:

Step 0, preserving arguments to foremost()

When userland exec is invoked, it accepts arguments to the primary() perform of
the brand new program. Whereas constructing the brand new course of picture, userland exec will
reset the stack and doubtlessly harm these parameters. Because of this, the
very first thing that userland exec should do is protect these arguments for later
use. On this implementation, the arguments are saved in tables allotted with
mmap(). The contents of those tables can then be copied again into the stack
when it's being initialized for the brand new course of picture.

Step 1, clear out the handle house

To organize the handle house for a brand new course of picture userland exec must
clear out solely sure handle ranges, not all the previous picture. The handle
vary of major significance is the one to which the brand new program binary has
been relocated. On i386 Linux programs, this handle is normally 0x08048000. The
.textual content section, and the .knowledge section, of the present course of's binary might be
mapped to this location. Following the .knowledge section would be the .bss, and
following that, the heap. Userland exec should subsequently map the previous executable
down, along with mapping down the previous heap. Relying on the state of the
program, the heap might be of various dimension.

The userland exec implementation should decide the place the reminiscence vary which
includes the .textual content, .knowledge and heap, begins and ends in order that it might probably map the
vary down. There are a number of other ways of figuring out this vary. In
some situations, for a particular goal, it's doable to hard-code the values.
For a extra generic strategy, one strategy could be to register a sign
handler and begin probing the handle house, e.g. to find out the top of the
heap. Utilizing the exhausting coded begin handle of 0x08048000 and the probed heap
dimension, userland exec might map down this vary.

On this implementation, userland exec makes use of the method maps file maintained by
the kernel to find out the situation and dimension of the method' .textual content and .knowledge
segments and the heap. Convieniently, beneath Linux, the primary three traces of
the /proc/self/maps file comprise the .textual content section, the .knowledge section and the
heap. By mapping down the primary three reminiscence segments listed within the maps file
userland exec can clear the vary required for the brand new .textual content and .knowledge
segments, and the brand new heap.

Step 2, examine for, and cargo, the dynamic linker

Figuring out whether or not a given ELF binary requires a dynamic linker, or not, is
extremely easy. The execve() man pages describe the precise technique
utilized by the kernel (and by userland exec) to examine for a dynamic linker.

       If the executable is a dynamically-linked ELF  executable,
       the  interpreter named within the PT_INTERP section is used to
       load the wanted shared  libraries.

The dynamic linker is barely required for these processes which make the most of shared
libraries from the system. If a binary requires dynamic linking, the trail
to the specified dynamic linker might be saved in a particular program header
section: PT_INTERP. By looking out this system header desk of the brand new ELF
picture, userland exec can decide whether or not a dynamic linker is required, and,
concurrently, which dynamic linker to load. Loading the linker after that is
trivial, requiring solely an understanding of how ELF binaries are loaded into
reminiscence. The following part will talk about how that is completed.

Step 3, load the primary binary

The precept for loading an ELF binary is identical no matter whether or not the
binary is loaded from a reminiscence buffer or off the disk. For every PT_LOAD
section in this system header desk, the loader ensures that the ELF picture
from p_offset for p_filesz bytes is copied right into a reminiscence buffer (with p_flags
permissions) at p_vaddr of p_memsz (aligned to p_align) bytes. That's, every
PT_LOAD section primarily says "this a part of the ELF goes into this a part of
the reminiscence picture".

The userland exec implementation scans this system header desk and determines
the full quantity of reminiscence the loaded ELF will occupy. This merely means
aligning the p_memsz values of all of the PT_LOAD segments utilizing p_align, then
including them collectively. The userland exec code then allocates a reminiscence vary
ranging from the primary PT_LOAD section's p_vaddr for the full size
beforehand calculated. With the reminiscence now reserved, all that continues to be is to
copy the PT_LOAD segments into their applicable ranges after which set the
section permissions primarily based on their p_flags.

Step 4, initialize the stack

With the primary binary, and any dynamic linker, loaded into reminiscence, the final
main activity which nonetheless stays is establishing the stack. The stack, at program
begin up, has a strict format examined briefly above. To initialize the
stack, userland exec should reset the stack pointer. Performing that is merely
a matter of calculating the dimensions of the stack contents (the argv strings,
environmental strings, auxv, and so on. and so on.) and subtracting this worth from the
stack base. With the house allotted for the brand new parameters, userland exec can
start creating the stack structure.

To create the stack structure the userland exec implementation should extract the
saved parameters for the primary() perform (argc, argv and envp) and replica them
to the stack. This will trivially be achieved utilizing the saved parameters
from step 0 and a few easy pointer arithmetic. The Elf_Aux vector is the one
knowledge construction which requires some rationalization. This vector accommodates knowledge
which the dynamic linker wants as a way to combine with the method picture
appropriately. There are only some key items of data required by the
dynamic linker to carry out its activity. These are: its personal load handle (AT_BASE);
the situation of this system header desk (AT_PHDR), in addition to the variety of
program headers (AT_PHNUM); the dimensions of a web page of reminiscence (AT_PAGESZ); any
flags to change its run time habits (AT_FLAGS), and the entry level for the
foremost executable (AT_ENTRY).

Step 5, decide entry level

Finding the proper entry level for the brand new course of picture could be very straight
ahead. If a dynamic linker was loaded, then the entry level is the load
handle of the linker plus the e_entry worth, in any other case it's the foremost ELF's
e_entry.

Step 6, switch management of execution

The ultimate step is to start out the brand new course of picture operating by transferring
management of execution to the entry level positioned throughout step 5.

These six steps are all which might be required to load an arbitrary ELF binary into
an handle house and execute it.

Conclusion:

It has been proven that the execve() system name might be mimicked in userland 
with a minimal of problem. Creating a brand new course of picture is a straightforward matter
of: cleansing out the handle house; checking for, and loading, the dynamic
linker; loading the binary; initializing the stack; figuring out the entry
level and, transferring management of execution.  By following these six steps,a
new course of picture might be created and run. Utilizing this implementation as a begin
level, it's doable to create each smaller, and likewise extra elaborate,userland
exec implementations.

Historical past of userland exec:

The writer first developed a userland exec implementation in early 2002. The
preliminary proof of idea implementation demonstrated that it was certainly
doable to imitate execve() in userland. Nevertheless, a number of limitations within the
implementation made it unfit for public launch. Just lately, some individuals have
posted extremely crude mechanisms for executing a brand new binary in an handle
house occupied by one other course of picture. Given the extreme limitations of this
method, and the request of a buddy for the previous proof of idea
implementation, the writer felt compelled to implement a totally useful
model of userland exec.  Design and implementation took lower than 48 hours
to finish.

Acknowledgments:

As all the time, the creation of any work will not be doable with out the assistance of different
people. Right here, then, is a listing of those that've been concerned in some
capability or one other in making userland exec: mammon_; gera; duke, and Grendel,
PhD.  Moreover because of these ppl who made .sg so fulfilling Halvar &
Evelyn, SK, Saumil, Charl and Dave Aitel. And all of the ppl who got here to my speak.

Bibliography:

http://www.phrack.org/phrack/58/p58-0x05 grugq & scut, 2001
http://downloads.securityfocus.com/library/subversiveld.pdf  grugq, 2001
http://www.iecc.com/linker/ levine, 1999

Attachment:
ul_exec-1.1.tar.gz

Description:







Present thread:

  • Saying Userland Exec the grugq (Jan 01)



Source Link

What's Your Reaction?
Excited
0
Happy
0
In Love
0
Not Sure
0
Silly
0
View Comments (0)

Leave a Reply

Your email address will not be published.

2022 Blinking Robots.
WordPress by Doejo

Scroll To Top