Sunday, August 27, 2017

Elsa David you want the code of Cheery Blossom ??? NSA - National Security Agency ??? I know you want

Dynamic linker tricks: Using LD_PRELOAD to cheat, inject features and investigate programs


This post assumes some basic C skills.
Linux puts you in full control. This is not always seen from everyone’s perspective, but a power user loves to be in control. I’m going to show you a basic trick that lets you heavily influence the behavior of most applications, which is not only fun, but also, at times, useful.

A motivational example

Let us begin with a simple example. Fun first, science later.
random_num.c:
1
2
3
4
5
6
7
8
9
10
#include
#include
#include
 
int main(){
  srand(time(NULL));
  int i = 10;
  while(i--) printf("%d\n",rand()%100);
  return 0;
}
Simple enough, I believe. I compiled it with no special flags, just
gcc random_num.c -o random_num
I hope the resulting output is obvious – ten randomly selected numbers 0-99, hopefully different each time you run this program.
Now let’s pretend we don’t really have the source of this executable. Either delete the source file, or move it somewhere – we won’t need it. We will significantly modify this programs behavior, yet without touching it’s source code nor recompiling it.
For this, lets create another simple C file:
unrandom.c:
1
2
3
int rand(){
    return 42; //the most random number in the universe
}
We’ll compile it into a shared library.
gcc -shared -fPIC unrandom.c -o unrandom.so
So what we have now is an application that outputs some random data, and a custom library, which implements the rand() function as a constant value of 42.  Now… just run random_num this way, and watch the result:
LD_PRELOAD=$PWD/unrandom.so ./random_nums
If you are lazy and did not do it yourself (and somehow fail to guess what might have happened), I’ll let you know – the output consists of ten 42’s.
This may be even more impressive it you first:
export LD_PRELOAD=$PWD/unrandom.so
and then run the program normally. An unchanged app run in an apparently usual manner seems to be affected by what we did in our tiny library…
Wait, what? What did just happen?
Yup, you are right, our program failed to generate random numbers, because it did not use the “real” rand(), but the one we provided – which returns 42 every time.
But we *told* it to use the real one. We programmed it to use the real one. Besides, at the time we created that program, the fake rand() did not even exist!
This is not entirely true. We did not choose which rand() we want our program to use. We told it just to use rand().
When our program is started, certain libraries (that provide functionality needed by the program) are loaded. We can learn which are these using ldd:
$ ldd random_nums
linux-vdso.so.1 => (0x00007fff4bdfe000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f48c03ec000)
/lib64/ld-linux-x86-64.so.2 (0x00007f48c07e3000)
What you see as the output is the list of libs that are needed by random_nums. This list is built into the executable, and is determined compile time. The exact output might slightly differ on your machine, but a libc.so must be there – this is the file which provides core C functionality. That includes the “real” rand().
We can have a peek at what functions does libc provide. I used the following to get a full list:
nm -D /lib/libc.so.6
The nm command lists symbols found in a binary file. The -D flag tells it to look for dynamic symbols, which makes sense, as libc.so.6 is a dynamic library. The output is very long, but it indeed lists rand() among many other standard functions.
Now what happens when we set up the environmental variable LD_PRELOAD? This variable forces some libraries to be loaded for a program. In our case, it loads unrandom.so for random_num, even though the program itself does not ask for it. The following command may be interesting:
$ LD_PRELOAD=$PWD/unrandom.so ldd random_nums
linux-vdso.so.1 =>  (0x00007fff369dc000)
/some/path/to/unrandom.so (0x00007f262b439000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f262b044000)
/lib64/ld-linux-x86-64.so.2 (0x00007f262b63d000)
Note that it lists our custom library. And indeed this is the reason why it’s code get’s executed: random_num calls rand(), but if unrandom.so is loaded it is our library that provides implementation for rand(). Neat, isn’t it?

Being transparent

This is not enough. I’d like to be able to inject some code into an application in a similar manner, but in such way that it will be able to function normally. It’s clear if we implemented open() with a simple “return 0;“, the application we would like to hack should malfunction. The point is to be transparent, and to actually call the original open:
inspect_open.c:
1
2
3
4
int open(const char *pathname, int flags){
  /* Some evil injected code goes here. */
  return open(pathname,flags); // Here we call the "real" open function, that is provided to us by libc.so
}
Hm. Not really. This won’t call the “original” open(…). Obviously, this is an endless recursive call.
How do we access the “real” open function? It is needed to use the programming interface to the dynamic linker. It’s simpler than it sounds. Have a look at this complete example, and then I’ll explain what happens there:
inspect_open.c:
1
2
3
4
5
6
7
8
9
10
11
12
13
#define _GNU_SOURCE
#include
 
typedef int (*orig_open_f_type)(const char *pathname, int flags);
 
int open(const char *pathname, int flags, ...)
{
    /* Some evil injected code goes here. */
 
    orig_open_f_type orig_open;
    orig_open = (orig_open_f_type)dlsym(RTLD_NEXT,"open");
    return orig_open(pathname,flags);
}
The dlfcn.h is needed for dlsym function we use later. That strange #define directive instructs the compiler to enable some non-standard stuff, we need it to enable RTLD_NEXT in dlfcn.h. That typedef is just creating an alias to a complicated pointer-to-function type, with arguments just as the original open – the alias name is orig_open_f_type, which we’ll use later.
The body of our custom open(…) consists of some custom code. The last part of it creates a new function pointer orig_open which will point to the original open(…) function. In order to get the address of that function, we ask dlsym to find for us the next “open” function on dynamic libraries stack. Finally, we call that function (passing the same arguments as were passed to our fake “open”), and return it’s return value as ours.
As the “evil injected code” I simply used:
inspect_open.c (fragment):
1
printf("The victim used open(...) to access '%s'!!!\n",pathname); //remember to include stdio.h!
To compile it, I needed to slightly adjust compiler flags:
gcc -shared -fPIC  inspect_open.c -o inspect_open.so -ldl
I had to append -ldl, so that this shared library is linked to libdl, which provides the dlsym function. (Nah, I am not going to create a fake version of dlsym, though this might be fun.)
So what do I have in result? A shared library, which implements the open(…) function so that it behaves exactly as the real open(…)… except it has a side effect of printfing the file path :-)
If you are not convinced this is a powerful trick, it’s the time you tried the following:
LD_PRELOAD=$PWD/inspect_open.so gnome-calculator
I encourage you to see the result yourself, but basically it lists every file this application accesses. In real time.
I believe it’s not that hard to imagine why this might be useful for debugging or investigating unknown applications. Please note, however, that this particular trick is not quite complete, because open() is not the only function that opens files… For example, there is also open64() in the standard library, and for full investigation you would need to create a fake one too.

Possible uses

If you are still with me and enjoyed the above, let me suggest a bunch of ideas of what can be achieved using this trick. Keep in mind that you can do all the above without to source of the affected app!
  1. Gain root privileges. Not really, don’t even bother, you won’t bypass any security this way. (A quick explanation for pros: no libraries will be preloaded this way if ruid != euid)
  2. Cheat games: Unrandomize. This is what I did in the first example. For a fully working case you would need also to implement a custom random()rand_r(), random_r(). Also some apps may be reading from /dev/urandom or so, you might redirect them to /dev/null by running the original open() with a modified file path. Furthermore, some apps may have their own random number generation algorithm, there is little you can do about that (unless: point 10 below). But this looks like an easy exercise for beginners.
  3. Cheat games: Bullet time. Implement all standard time-related functions pretend the time flows two times slower. Or ten times slower. If you correctly calculate new values for time measurement, timed sleep functions, and others, the affected application will believe the time runs slower (or faster, if you wish), and you can experience awesome bullet-time action.
    Or go even one step further and let your shared library also be a DBus client, so that you can communicate with it real time. Bind some shortcuts to custom commands, and with some additional calculations in your fake timing functions you will be able to enable&disable the slow-mo or fast-forward anytime you wish.
  4. Investigate apps: List accessed files. That’s what my second example does, but this could be also pushed further, by recording and monitoring all app’s file I/O.
  5. Investigate apps: Monitor internet access. You might do this with Wireshark or similar software, but with this trick you could actually gain control of what an app sends over the web, and not just look, but also affect the exchanged data. Lots of possibilities here, from detecting spyware, to cheating in multiplayer games, or analyzing & reverse-engineering protocols of closed-source applications.
  6. Investigate apps: Inspect GTK structures. Why just limit ourselves to standard library? Let’s inject code in all GTK calls, so that we can learn what widgets does an app use, and how are they structured. This might be then rendered either to an image or even to a gtkbuilder file! Super useful if you want to learn how does some app manage its interface!
  7. Sandbox unsafe applications. If you don’t trust some app and are afraid that it may wish to rm -rf / or do some other unwanted file activities, you might potentially redirect all it’s file IO to e.g. /tmp by appropriately modifying the arguments it passes to all file-related functions (not just open, but also e.g. removing directories etc.). It’s more difficult trick that a chroot, but it gives you more control. It would be only as safe as complete your “wrapper” was, and unless you really know what you’re doing, don’t actually run any malicious software this way.
  8. Implement features. zlibc is an actual library which is run this precise way; it uncompresses files on the go as they are accessed, so that any application can work on compressed data without even realizing it.
  9. Fix bugs. Another real-life example: some time ago (I am not sure this is still the case) Skype – which is closed-source – had problems capturing video from some certain webcams. Because the source could not be modified as Skype is not free software, this was fixed by preloading a library that would correct these problems with video.
  10. Manually access application’s own memory. Do note that you can access all app data this way. This may be not impressive if you are familiar with software like CheatEngine/scanmem/GameConqueror, but they all require root privileges to work. LD_PRELOAD does not. In fact, with a number of clever tricks your injected code might access all app memory, because, in fact, it gets executed by that application itself. You might modify everything this application can. You can probably imagine this allows a lot of low-level hacks… but I’ll post an article about it another time.
These are only the ideas I came up with. I bet you can find some too, if you do – share them by commenting!


   54 # grab the gtk configuration flags from pkg-config
   55 import shell
   56 import string
   57 
   58 pkg_modules = "gtk+-2.0"
   59 
   60 # see if we're using the target gtk version (triggers setting of the
   61 # DISABLE_DEPRECATED flag)
   62 
   63 (exitstatus, gtk_mod_version) = shell.run("pkg-config --modversion gtk+-2.0")
   64 if exitstatus != 0:
   65     e = err.Error()
   66     e.Set("pkg-config failed")
   67     raise err.error, e
   68 
   69 if string.find(gtk_mod_version, "2.0") == 0:
   70     project.AddDefines('G_DISABLE_DEPRECATED',
   71                        'GDK_DISABLE_DEPRECATED',
   72                        'GTK_DISABLE_DEPRECATED')
   73 
   74 # on gcc we want to turn on all warnings
   75 extra_cflags = ""
   76 if platform.cc.cmd == 'gcc':
   77  extra_cflags = "-Wall"
   78 
   79 (exitstatus, gtk_config_output_cflags) = shell.run("pkg-config --cflags " + pkg_modules)
   80 (exitstatus, gtk_config_output_ldflags) = shell.run("pkg-config --libs " + pkg_modules)
   81 
   82 gtk_cflags = string.split(gtk_config_output_cflags)
   83 gtk_ldflags = string.split(gtk_config_output_ldflags)
   84 
   85 gtk_ld_paths = []
   86 gtk_libs = []
   87 gtk_includes = []
   88 gtk_defines = []
   89 gtk_other_cflags = ""
   90 gtk_other_ldflags = ""
   91 
   92 for x in gtk_cflags:
   93         if x[0:2] == '-I':
   94                 gtk_includes[-1:-1] = [ x[2:] ]
   95         elif x[0:2] == '-D':
   96                 gtk_defines[-1:-1] = [ x[2:] ]
   97         else:
   98                 gtk_other_cflags = gtk_other_cflags + " " + x
   99 
  100 for x in gtk_ldflags:
  101         if x[0:2] == '-l':
  102                 gtk_libs[-1:-1] = [ x[2:] ] 
  103         elif x[0:2] == '-L':
  104                 gtk_ld_paths[-1:-1] = [ x ]
  105         else:
  106                 gtk_other_ldflags = gtk_other_ldflags + " " + x
  107         
  108 
  109 # add the flags
  110 project.AddSystemLibraries(gtk_libs)
  111 project.AddIncludes(gtk_includes)
  112 project.AddSystemPaths(gtk_ld_paths)
  113 project.AddDefines(gtk_defines)
  114 
  115 platform.cc.args["default"] = platform.cc.args["default"] + " " + gtk_other_cflags + " " + extra_cflags
  116 platform.cxx.args["default"] = platform.cxx.args["default"] + " " + gtk_other_cflags + " " + extra_cflags
  117 # platform.link.args["default"] = platform.link.args["default"] + " " + gtk_other_ldflags
  118 # XXXRGG: This is a hack
  119 project.AddDynamicLibraries(gtk_other_ldflags)
  120 
  121 project.AddSystemLibraries('pthread')

https://fossies.org/linux/misc//old/hxplay-11.0.0.tar.gz/player/common/gtk/unix.pcf

Friday, August 25, 2017

Nek - Notte di febbraio (Official Video)

TPM Reset Attack

Welcome to the TPM Reset Attack page. Here you can find information about a novel new attack against TPMs and the TCG architecture, in addition to a video demo of the attack in action. This attack was first performed by Bernhard Kauer, but we at the Dartmouth College PKI/Trust Lab have been exploring the same kind of attack, and thought it would be interesting to demonstrate and document it here. Please read this entire document before jumping to conclusions about what this attack can and cannot do. For instance, this attack cannot get an endorsement (or any other) kind of key out of a TPM and thus does not enable a random remote party to masquerade as a trusted platform, only a remote party with physical access to the TPM with the endorsment key of the trusted system in question. Also, while the basis of this attack is very simple and interesting, building on this attack to do interesting things might require both basic and sophisticated specialized hardware. Consider yourself warned.

Background

Trusted Platform Module (TPM) is an embedded cryptographic device, whose spec was designed by the Trusted Computing Group (TCG). These devices are implemented by various vendors. They are meant to be cheap, commodity devices included on new PC motherboards and are designed to enable trusted computing.
One key facility that TPMs provide to enable trusted computing is the ability to securely store a series of measurements. To do this, the TPM employs a set of registers called Platform Configuration Registers (PCRs). A TPM equipped PC with a trusted BIOS can boot up, and take a series of measurements of the hardware and software of the running machine, and store them in the PCRs. The TPM can cryptographically sign these PCRs and send them to a remote party. This party can then verify that the platform equipped with that TPM has been booted up and measured in that specific manner. TPMs also use these PCRs for the purposes of binding wrapped keys to a platform in a particular state. That is, the TPM may not allow a platform in a different state than it was when the key was created to have access to the key.
PCRs work as secure measurement storage because they support only one operation: Extend(). At initialization, all PCRs are filled with 20 NULL bytes (0x00). Normally only the BIOS sees them in this state. The BIOS will then take some measurement, and Extend() it into a specified PCR. Extend is defined as follows.

Extend(PCR#, newval) {

val[PCR#] = SHA1(val[PCR#] . newval)
}

Where '.' is the concatenation operator.
Because of SHA1 pre-image resistance, it is very difficult to come up with a 'newval' which will get val[PCR#] into a desired state given an arbitrary old val[PCR#]. Thus, it is difficult to fake that an arbitrary series of measurements has taken place.
It is worth noting that some PCRs do support a reset operation (beginning with version 1.2 TPMs), but the PCRs most commonly used to store the trusted boot sequence (the ones we are interested in attacking) do not.

The Attack

So, given everything we've seen above, it should be very difficult to fake a trusted boot process, as long as the BIOS takes the first few measurements. The critical assumption here is that the PCRs cannot be easily reset without restarting the whole platform that the TPM resides on. If an attacker is capable of monitoring the measurements sent to the PCRs by the BIOS (with, for instance a logic analyzer, see this paper), and capable of zeroing out the PCRs without restarting the machine, then she could take a platform in any configuration and put it into a 'trusted' state. So, the difficult part is getting the TPM to reset without bringing down the whole machine. It is worth mentioning that we've also looked at interposing memory and other such things to change the running system after its been measured, but due to the speed of the busses that memory and hard drives sit on, this is a tricky endeavor. Attacking a slower bus is much easier.
TPMs typically reside on the Low Pin Count (LPC) bus. The LPC bus supports a ground driven reset line. This means that when this particular line on the bus is driven to ground every device on this bus is supposed to reset. Other devices attached to this bus include the BIOS, and legacy keyboard and mouse controllers. The video below demonstrates that driving this line is indeed possible, and fairly easy to do. Please note that in the video, we are accessing the computer in question via a remote ssh session. This is because the keyboard and mouse controller get reset when we drive the reset pin, but the network card does not. More details of this attack (and others!) can be seen in my senior honors thesis: A Security Assessment of Trusted Platform Modules, Dartmouth College Computer Science Technical Report TR2007-597.

The Video!

We attack a v1.1b TPM on an IBM NetVista PC. We chose this particular TPM as a target because it resides on a daughterboard and is thus easier to access physically.

Implications

This demonstration shows that we can drive this line without significantly disturbing the running system. If an attacker really wanted to keep from disturbing the rest of the platform, they could physically isolate the TPM from the platform and drive the reset line only on the TPM . Either way, we could ultimately take a platform in an untrusted configuration and put it into a trusted one.
An attacker with a v1.1b TPM and monitored measurements in hand could easily redrive these using the TPM_Extend() command using a standard TPM driver. Note that on a v1.2 TPM, if the BIOS locality is different from the host's (in terms of LPC locality), then some hardware attached to the bus which communicates using the BIOS's locality will be needed to redrive these measurements. However, since there is no authentication mechanism on the LPC bus itself, any rogue device could do this.

New work

Bernhard Kauer has created the OSLO Bootloader to defend against these types of attacks. It employs AMD's new sk_init instruction to use a dynamic root of trust, as opposed to a static root with the BIOS. This new type of protection relies on the LPC locality features incorporated into v1.2 TPMs.
However, an attacker with physical access to the LPC bus could circumvent these protections by communicating measurements to the TPM which claim to be from the CPU in sk_init mode. 

NATO Intel virtual airforce pilots op flights

                                         https://virtualnato.org/home/pilots