# Raddest DB
There are two bugs we used
## Type confusionWhen a (key,value) is added to a db, the db checks if there exists a value with that key. If this is true, the db only changes the `value` field of the object and leaves the `vtable` field initialized. This leads to a type confusion bugs, giving us 3 primitvies:
```1. Type confusion from `string`->`int`: consider any string pointer as an int, giving us leaks2. Type confusion from `float`->`string`: consider any address as a string, which gives use an arbitrary read primitive```
With these two powerful infoleak bugs, we can get the libc base as well as the heap base.
## Fakeobj???We found a bug that wasn't found via analysis. It occurs if we do the following (One of my teammates found it and I still don't know how it was triggered, but we can make some guesses that it is a UAF)
```cmd("create db") 
cmd("store db int 1 1337")
cmd("getter db 1 2")p.sendline("echo {}".format("A"*0x10+p64(fakeobj_addr).strip("\x00")))p.sendline("empty")
cmd("print db")```
I made some speculations about how this happened: 1. Each entry (key,value) is stored as a 0x18 sized structure, which contains the pointer to the object. So in code it is like this:```struct entry {	char unknown[0x10];	struct object *obj;}```
```struct object {	funcptr_t *vtable;	union value {		unsigned long int_form;		char *string_form;		double float_form;	}}```
When we empty a db, the entry structure is free'd and the BUF in echo{BUF} takes that chunk if BUF is of appropriate size. Afterwards the reference is not removed and we have a `fakeobj` primitive, which gives us a single RIP control with no arguments controlled.In code, it is like this: `this->vtable->func1(this, aux);`
We have control to the entire `this` structure, so we can control `func1`. I changed `func1` to all one shot gadgets (found using david942j's `one_gadget`) but none of them popped a shell. 
I decided to expand this primitive to an arbitrary write primitive by changing `func1` to `gets`.
Before triggering the vtable function we free the chunk right under where the `this` object is located, turning it into a freed, size 0x20 tcache bin. Overflowing `this` enables us to overwrite a tcache bin, which gives use arbitrary allocation. So, I changed the `fd` field of the next tcache chunk entry to `__free_hook` and got `__free_hook` allocated and wrote `system` to it.
I tried some commands that would trigger `free('/bin.sh;'`. (The way was to enter /bin/sh;[LOTS OF SPACES] as the command because when the string is extended to some length its original buffer is freed (property of c++'s std::vector)
