OpenSSH RSA Authentication Patch

Other Runtime Patching Ideas

The runtime patching technique has barely been addressed in the security literature, mainly because root shells are generally so much more effective and possibly because the process of developing a runtime patching exploit is a little more tricky (or at least, less known).

One exploit that included a simple aspect of runtime patching was the Code Red wormwhich (intermittently) remapped the import table entry in IIS for the TcpSockSend function to be an address within the worm payload itself that returned the string "Hacked by Chinese!" rather than the desired content. This was a more elegant way of defacing infected IIS servers than overwriting files, because the logic involved in determining which files to overwrite would be complex, and it is by no means certain that the account that IIS is running under even has permission to write to these files. Another interesting property of the Code Red technique (shared by most runtime patching exploits) was that the damage vanished without a trace as soon as the process was stopped and restarted.

When runtime patches disappear in volatile memory, it is both a blessing and a curse for the attacker. On the various UNIX platforms, it is common to have a pool of worker processes that handle a number of requests from clients and then terminate. This is the case with Apache, for example. Runtime patching exploits have a slightly modified behavior in this scenario, because the server instance whose code you patched may not be around for very long.

The worst case for the attacker occurs if every server instance handles exactly one client request; this means that the runtime patch cannot be used in subsequent requests. The upside from the attacker's point of view to having a pool of worker processes is that evidence of the attacker's misdeeds is almost immediately removed.

Apart from modifying the authentication/authorization structure of the application, there are other, rather more insidious approaches to runtime modification.

Almost every secure application relies to some extent on cryptography, and almost every cryptographic mechanism relies to some extent on good randomness. Patching a random number generator may not seem to be an earth-shattering way in which to exploit something, but the consequences are really quite severe.

The poor-randomness patch technique applies to any target where it would be useful for you to degrade its encryption. Occasionally, a poor-randomness patch will allow you to defeat authentication protocols as well as encryptionin some systems that use a random challenge (a nonce ), users are authenticated if they are able to determine the value of the nonce. If you already know the value of the nonce, you can easily cheat the authentication system. For instance, in the OpenSSH RSA example given previously, note the line:

 /* The response is MD5 of decrypted challenge plus session id. */ 

If we know in advance what the challenge will be, we do not need knowledge of the private key in order to provide the correct response. Whether this defeats the authentication mechanism or not depends on the protocol, but it certainly gives us a big head start.

Other good examples can be found in more traditional encryption products. For instance, if you were to patch someone's instance of GPG or PGP in such a manner that the message session keys were always constant, you would then easily be able to decrypt any e-mail that person sent. Of course, you'd have to be able to intercept the e-mail, but still, we just negated the protection offered by an entire encryption mechanism by making a minor change to one routine.

As a quick example of this, let's take a look at patching GPG 1.2.2 to weaken the randomness.

GPG 1.2.2 Randomness Patch

Having downloaded the source, we start by looking for session key . That leads us to the make_session_key function. This calls the randomize_buffer function to set the key bits. randomize_buffer calls the get_random_bits function, which in turn calls the read_pool function ( read_pool is only ever called by get_random_bits , so we don't need to worry about messing up any other parts of the program). Examining read_pool , we find the section that reads the random data from the pool into the destination buffer.

 /* read the required data       * we use a readpointer to read from a different position each       * time */      while( length-- ) {          *buffer++ = keypool[pool_readpos++];          if( pool_readpos >= POOLSIZE )           pool_readpos = 0;          pool_balance--;      } 

Since pool_readpos is a static variable, we probably want to maintain its state, so we patch as follows :

 /* read the required data       * we use a readpointer to read from a different position each       * time */      while( length-- ) {          *buffer++ = 0xc0; pool_readpos++;          if( pool_readpos >= POOLSIZE )           pool_readpos = 0;          pool_balance--;      } 

Every GPG message encrypted using that binary has a constant session key (whichever algorithm it uses).



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