A simple way to hack C/C++ application
Tags: c, rtldnext, vulnerability, cpp
Published: 2019-09-30 15:11:18

This is a cross-post from [my blog](http://www.vishalchovatiya.com/hack-c-cpp-application-using-rtld-next-with-an-easy-example/)

While I was working as a core C library developer with my previous employer. I came across this RTLD_NEXT flag in dynamic linking which has the amazing capability and can be easily exploited or used for the unethical purpose(Here I intend to educate the developer to don’t be victims). In this article, I will show you a simple way to hack C/C++ application using RTLD_NEXT with an easy example.

## Intro to RTLD_NEXT
- Library linking & symbol resolution i.e. extracting address(precisely offset here in dynamic linking case) of function is specified at compile time.
- For example, there are four shared libraries linked & loaded dynamically in order as A.so, B.so, C.so & D.so with the main application. And funcXYZ() is called from the main application which is defined in both the library C.so & D.so with the same prototype.
- Then funcXYZ() from C.so will be called first as it’s ahead of D.so in linking order.
- But what if you want to call funcXYZ() from D.so ? You can achieve this by RTLD_NEXT flag defined in <dlfcn.h>. What you have to do is define your funcXYZ() as below in C.so:

```
void funcXYZ()
{
  void (*fptr)(void) = NULL;
  if ((fptr = (void (*)(void))dlsym(RTLD_NEXT, "funcXYZ")) == NULL)
  {
    (void)printf("dlsym: %s\n", dlerror());
    exit(1);
  }
  return ((*fptr)());
}
```

- Now, whenever funcXYZ() called from main application it will come to C.so which simply search for the same symbol from next loaded libraries i.e. D.so .
- dlsym() search for symbol provided in argument from the memory and a returns function pointer to the same.
## Let’s hack C/C++ application using RTLD_NEXT

### malloc.c
```
#include <stdio.h>
#include <dlfcn.h>

void *malloc(size_t size)
{
  static void *(*fptr)(size_t) = NULL;

  /* look up of malloc, only the first time we are here */
  if (fptr == NULL)
  {
    fptr = (void *(*)(size_t))dlsym(RTLD_NEXT, "malloc");
    if (fptr == NULL)
    {
      printf("dlsym: %s\n", dlerror());
      return NULL;
    }
  }

  printf("Our Malloc\n");

  return (*fptr)(size); // Calling original malloc
}
```
### main.c
```
#include <stdio.h>
#include <stdlib.h>

int main()
{
  malloc(1);
  return 0;
}
```
### Creating a shared library
```
$ gcc -o malloc.so -shared -fPIC malloc.c -D_GNU_SOURCE
```
### Linking & executing the main application
```
$ gcc -o main main.c ./malloc.so -ldl
$ ./main
Our Malloc
```
Note: You can also use LD_PRELOAD as below, which loads the specified library first. No need to mention ./malloc.so explicitly in the compilation.
```
$ LD_PRELOAD=`pwd`/malloc.so ./main
```
## How it works
- When you compile `main.c` with `gcc -o main main.c ./malloc.so -ldl`, you specify malloc.so explicitly on first order. We can verify this by ldd command
```
$ ldd main
linux-vdso.so.1 => (0x00007fff37bf4000)
malloc.so (0x00007fc5df598000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007fc5df37d000)
libc.so.6 => /lib64/libc.so.6 (0x00007fc5defbb000)
/lib64/ld-linux-x86-64.so.2 (0x00007fc5df79b000)
```
- So when you call malloc it will refer the first occurrence of the symbol from the loaded library sequence which is in our malloc.so library.
- We now extract original malloc from next loaded shared library which is /lib64/libc.so.6.
Vulnerability & precautions you should consider

[[Click here to read more. . .]](http://www.vishalchovatiya.com/hack-c-cpp-application-using-rtld-next-with-an-easy-example/)