Resources

People often ask me "How did you learn how to hack?" The answer: by reading. This page is a collection of the blog posts and other articles that I have accumulated over the years of my journey. Enjoy!

Four Bytes of Power: exploiting CVE-2021-26708 in the Linux kernel - 461

Alexander Popov - Positive TechnologiesPosted 4 Years Ago
  • While fuzzing the Linux kernel with syskaller, the author of this post got a suspicious kernel crash within some socket handling code. Unable to reproduce the crash, the author read some source code until they found a strange code pattern.
  • The consistent pattern was an issue with locking. Prior to a socket lock a heap pointer was dereferenced and put into a variable. The code is shown below:
        struct sock *sk;
        struct vsock_sock *vsk;
        const struct vsock_transport *transport;
        /* ... */
        sk = sock->sk;
        vsk = vsock_sk(sk);
        transport = vsk->transport;
        lock_sock(sk);
    
  • Notice that the transport variable is dereferenced from vsk then the lock occurs on this. If the value of transport were to change prior to the lock, then we have a race condition!
  • To trigger the race condition two threads are required. First, one thread (thread #1) should try to set socket options. The second thread (thread #2) needs to connect with a virtual socket. When thread #1 attempts to access the virtual socket, thread #2 has already taken the lock. However, the transport
  • Now that thread #2 has the lock, it can force the altering of the transport struct. The transport constructor can be called, which frees the object and creates a UAF. This UAF is a 4 byte user controlled write at offset 40. Does not seem that deadly but itself!
  • This same pattern for the handling of sockets was found in a total of 5 places. Although the bugs were not there to begin with, they were created by misunderstanding the original intention of the code.
  • With a 4 byte UAF, the next step is to fill this freed memory with something important to corrupt. Finding a candidate object to fill required a significant amount of effort. Eventually, this led the author to corrupting an SELinux security pointer to allow for an arbitrary free primitive.
  • When the initial race condition succeeds, it creates a warning message because of a value being NULL that is unexpected. This error message is dumped to /dev/kmsg which leaks kernel memory. So, now, we know if the race was won and have a memory leak!
  • With the arbitrary free and the memory leak, the next step is to create an arbitrary read primitive. This was done by altering the msg_msg struct in order to map to kernel data to be read. This required some crazy feng shui for this code to not crash however. All of the necessary pointers are not acquired!
  • The arbitrary write is done by altering a network related buffer called sk_buff. First, hit the arbitrary free on the sk_buff kernel address. Then, when a user controlled object slips into there a function pointer is overwritten!
  • With code execution, one would think this would be easy... but, the author could not find a proper pivoting gadget for the system. So, they created a single WRITE that would overwrite the location of uid and guid to be 0s. With this, privileges of the current process are escalated to root!
  • The author adds some tips for how this cold have been mitigated:
    • SLAB_QUARANTINE would have made this impossible to get the same piece of memory back from the race condition. Hence, the UAF is not possible to exploit.
    • The Dmesg having a stricter log would have prevented the kernel leak.
    • MODHarden by grsecurity prevent kernel module autoloading by lower privileged users.
    • Binary protections: Control Flow Integrity (CFI) would have prevented the the ROP gadget. Then, Memory Tagging would have prevented the UAF altogether.
  • I'm not too deep into the Linux kernel exploitation scene. However, this article has several tricks (and references to others) that could be used in future exploits. I personally enjoyed the bug explanation and the general plan of exploitation a lot.