Upload and Run (or Proglet Server)

Syscall Proxies

As noted in the introduction to this chapter, if you take a look at most shellcode archives, you see a number of different shellcode snippets drawn from a fairly small set and doing mostly similar things.

When you use shellcode as an attacker, you often find situations in which the code inexplicably refuses to work. The solution in these situations is normally to make an intelligent guess at what might be happening and then try to work around the problem. For instance, if your repeated attempts to spawn cmd.exe fail, you might want to try copying your own version of cmd.exe to the target host and trying to run that instead. Or, possibly you're trying to write to a file that (it turns out) you don't have permissions for; therefore, you might want to try and elevate privileges first. Or, maybe your break chroot code simply failed for some reason. Whatever the problem, the solution is almost always a painful period of piecing together scraps of assembler into another exploit or of simply finding some other way into the box.

There is, however, a solution that is generic, elegant, and efficient in terms of shellcode size the syscall proxy.

Introduced by Tim Newsham and Oliver Friedrichs and then developed further in an excellent paper by Maximiliano Caceres of Core -SDI (which can be found at www.coresecurity.com/files/files/11/SyscallProxying.pdf ), syscall proxying is an exploit technique in which the exploit payload sits in a loop, calling system calls on behalf of the attacker and returning the results. Table 20.1 shows what this looks like.

Table 20.1: How a Syscall Proxy Works

Time T =

Client Host

Syscall Stub

Network

Syscall Proxy

Calls syscall stub

     

1

 

Packages parameters into buffer for transportation over network

   

2

   

Transports data

 

3

     

Unpackages parameters

4

     

Makes syscall

5

     

Packages results for transportation over network

6

   

Transports data

 

7

 

Unpackages results into syscall return parameters

   

8

Returns from syscall stub

     

9

Interprets results

     

10

Makes another syscall . . .

     

While syscall proxies are not always possible (because of the network location of the target host), this approach is exceptionally powerful, because it allows the attacker to dynamically determine what action to take given the prevailing conditions upon the host. Looking at our examples above, say we are attacking a Windows system, and we can't edit a given file. We look at our current username and find that we are running as a low-privileged user . We determine that the host is vulnerable to a named pipe-based privilege escalation exploit, then we perform the function calls required to activate the privilege elevation, and bingowe have system privileges.

More generally , we can proxy the actions of any process running on our machine, redirecting the syscalls (or Win32 API calls on Windows) to execute on the target machine. That means that we can effectively run any tools we have through our proxy, and the relevant parts of the code will run on the target host.

Any readers familiar with RPC will have noticed similarities between the syscall proxy mechanism and the (more generic) RPC mechanismsthis is no coincidence , because what we're doing with a syscall proxy involves the same challenges. In fact, the major challenge is the same marshalling , or packaging up the syscall parameter data in a form in which it can be represented easily in a flat stream of data. What we're effectively doing is implementing a very small RPC server in a small fragment of assembler.

There are a couple of different approaches to the implementation of the proxy itself:

  • Transfer the stack, call the function, and then transfer the stack back.

  • Transfer the input parameters into a contiguous block of memory, call the function, and then transfer the output parameters back.

The first technique is a simple method and is therefore small and easy to code, but can take up quite a bit of bandwidth (data for output parameters is transferred unnecessarily from client to server) and doesn't cope well with returned values that aren't passed on the stack (for example Windows GetLastError ).

The second method is a little more complex but copes better with awkward return types. The big disadvantage of this technique is that you must specify the prototypes of the functions that you're calling on the remote host in some form so that the client knows what data to send. The proxy itself must also have some means of distinguishing between in and out parameters, pointer types, literals, and so on. For those familiar with RPC, this will probably end up looking a lot like IDL .



The Shellcoder's Handbook. Discovering and Exploiting Security
Hacking Ubuntu: Serious Hacks Mods and Customizations (ExtremeTech)
ISBN: N/A
EAN: 2147483647
Year: 2003
Pages: 198
Authors: Neal Krawetz

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net