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!

Heap-based Buffer Overflow in Sudo (CVE-2021-3156)- 376

Qualys - Baron SameditPosted 5 Years Ago
  • Sudo is a setuid program that allows a user to execute commands as another user (impersonation feature). Because of this, finding a vulnerability in sudo is an important privilege escalation.
  • When running sudo with the -s or -i flag, turns on functionality that rewrites argv by concatenating all command-line arguments and by escaping all meta-characters with backslashes. Parsing is really hard!
  • When this transferring and escaping happens, is where the parsing issues occur. If a command line input ends with a single backslash, then issues happen with the copying functionality. It causes the while loop to over deviate because of an unexpected increase in the buffer. In other words, set_cmnd() is vulnerable to a heap-based buffer overflow, because the out-of-bounds characters that are copied to the "user_args" buffer were not included in its size.
  • Here is the problem though: it is not possible to call this function with a single backslash, by default. By calling sudoedit, the escape code can be skipped, causing the vulnerable path to hit. An example crashing exploit looks like the sudoedit -s '\' `perl -e 'print "A" x 65536'`. This hits iterates once too many, then copies extra data from the heap.
  • To an attacker, this buffer overflow is awesome because
    • The size of the "user_args" buffer that we overflow, which is just the size of our concatenated command line arguments.
    • Independently control the size and contents of the overflow itself. Our last command-line argument is conveniently followed by our first environment variables.
    • Even write null bytes to the buffer that we overflow (every command-line argument or environment variable that ends with a single backslash writes a null byte to user_args.
  • The original idea for exploitation was to corrupt locale strings in order to turn this into a format string exploit. This is a common exploitation for sudo and other binaries with locales used. However, this technique did not produce any good results.
  • After setting up a fuzzer to find different exploitation primitives, a few ways were found that caused crashes with the proper heap grooming.
  • The first interesting crash was a direct overwrite of a function pointer within process_hooks_getenv . The main thing to note was that the function pointer could be partially overwritten in order to bypass ASLR.
  • The second exploitation method was found by a crash in nss_load_library. Using this crash, it was possible to overwrite the file path of the library being loaded to load an arbitrary library.
  • The final way they found to exploit this was different than all of the others. From the fuzzing, they noticed that a bunch of directories were created with root privileges by overwriting the location of the def_timestampdir. Using this, we can overwrite this directory then we can race against Sudo's ts_mkdirs(), create a symlink to an arbitrary file and (or create) this arbitrary file as root, and write a struct timestamp_entry to it.
  • Using this timestamp writing functionality, we can open /etc/passwd and write a user into this. Now, we can use sudo and become root.