NULL pointer dereference bug for dummies

Has been a while since this class of bug has emerged as a potential Linux kernel (and others) vulnerability. Actually it is still out there but since Brad Spengler (spender), of grsecurity, made public  a pretty cool exploit gaining local root, the guys from the Linux kernel paid attention and rushed out to provide a workaround fix in the kernel. Since then exploiting such vulnerability has become harder and harder.

Well, this is just a short story and the reader can Google around for it and learn more, it is pretty interesting, the whole story. Perhaps the best place to learn more about it is here.

Now let’s forget about Linux kernel current protections details and keep in mind only that there is a special proc file:


/proc/sys/vm/mmap_min_addr

The above file keeps a virtual memory address value, such value means that regular users are not able to write below the address, for example 4K, the first page which is 4096. Most systems have 4GiB of total virtual memory, 1GB for kernel only, privileged mode, and 3GB for user processes. High memory > 3Gib belongs to kernel and memory < 3Gib to users. The kernel, of course, can access the whole 4Gib.

NULL (void*)0 and 0 are not the same thing, but for practical purposes they are, because both point to address 0x00 in the virtual memory.

Long story made short tells that if the user can mmap()  an address range beginning at 0x00 (NULL) and then inside of kernel a sad programmer deference a pointer, before making sure it is valid or in other words, not NULL, then if virtual memory starting at 0x00 was previously mapped by the malicious user, things will get wild.

mmap() is usually used for mapping files in memory, but it is possible to map any kind of data, for example a shellcode or a local address (function) written inside of an exploit executable file, executing code in privileged mode.

Now, I wrote this whole text just to give an introduction for a simple piece of code that may exemplify the concept without having to delegate to a real kernel bug, making it simpler and userland only.

In the code there is a local funcion named exec() and a bytecode, which is an asm code like the one following:


$ cat addr.s
xor %eax , %eax # %eax := 0
call 0x000000000040062c # exec addr
ret

Line #3 is the address of my exec() function, in my ARCH Linux 64 bits, which may be different in your system. I got it from objdump:


$ objdump -d a.out |grep exec| awk '{print $1}' |head -1
000000000040062c

Then it was easy to write the following bytecode:


char loadexec[] = "\x31\xc0" // xor %eax, %eax

"\xe8\x25\x06\x40\x00" // call 0x80484b4 # exec()

"\xc3"; // ret

Now can “see” a NULL pointer dereference bug in action without having to mess around with the kernel.

To run the code you have either to write zero to /proc/sys/vm/mmap_min_addr, as ROOT:


# echo "0" > /proc/sys/vm/mmap_min_addr

or run the executable as root.

The output, if it works, would be like the following:


$ sudo ./a.out
+memcpy has successfully failed 🙂
+fp is NULL but it is supposed to execute data, let's try to call 0x40062c...
*** Yeah, it works ***

If you see “*** Yeah, it works ***” it is obvious.

The code is reasonably documented so I think the reader will get it.

https://gist.github.com/carloslack/4974945

Advertisements

Chained hash tables

People not much used with data structures does not know about the use of chaining when applying hash tables.

There are few types of hash tables out there and most of then does not implement dynamic size adjustment , for those types of hash tables a special technique can be put on the “table”.

Denominated by Chained Hash Tables, are very simple and useful. Consisting in the mix use of hash tables and single/double linked lists.

The theory is quite simple as well, when you run out of table entries you can fall down into a merged linked list, allowing the same key to have multiple entries in the hash table.

Hash tables are well known for fast access, can be very straightforward:

data = table[key]->data;

But because of its stack nature ( datatype table[CONSTANT_VALUE] ) hash table is “limited” (it can be adjusted in run-time but it is not our scope now) in size. So if someone makes use of linked lists it will be virtually unlimited (OK, let`s forget for an instant about RAM and virtual memory limitations) and will often be accessed immediately because in some cases hash collisions and/or same key usage will be much less frequent, reducing access time.

The hash key algorithm I use was written by Bernstein, there are many algorithms out there but this one is quite reasonable.
Below you can find an example code I wrote of hash chaining implementation. I took out other helper functions like delete() entries or find() specific entries because the reader will figure it out easily:

https://gist.github.com/carloslack/4957905

pthread: exiting from thread

Hi!  Programmers used with Posix threads (http://en.wikipedia.org/wiki/Pthread) mechanisms know pretty well about its auxiliary functions, pthread_cancel(), pthread_kill() and so on so one can make a thread that to perform some work inside of a loop to exit and release its resources, not a big deal.

However there is a dirty hack technique which may consist in the approaching explained below.

You make use of pthread_exit() in order to do it.

First create a function pointer to pthread_exit(), this way:

static void(*pexit)(void *) = NULL;

Then you’ll have your thread running in loop doing something and at some point you need to terminate the thread, but first a snip code of our thread:

void *our_thread(void *args) {

....

while(!pexit) {

//do something

}

.....

pexit(NULL);

}

Now somewhere else you just need to set pexit pointer:

pexit = pthread_exit;

Then your thread will terminate as expected.