If you develop software in C (or any other language), you should know that using the strcmp function (or the equivalent in other languages) for password validation leaves the password and the program open to compromise. For those unfamiliar with this function, strcmp takes two parameters that contain a string and compares the two to see if they are the same. When used to validate a password, it exposes both the password and the program to compromise. If the source string is hard-coded in the program, it is viewable in plain text by opening it in any text editor. Sure, the password is wrapped in lots of unreadable code, and the average person wouldn’t know what they are looking at if they were staring right at it. However, it is not likely an average user that will attempt to hack a program. Here are four ways that the password could be hacked using tools readily available on Linux-based systems. The example program was written in C and compiled using gcc.
Strings is a Linux-based tool that writes every string of printable text from within a binary file to the standard output.
Remember how I said the password was wrapped in unreadable code? Strings will strip all of that out leaving you with just the plain text data from the file. If that is too much data, use option d on strings to filter down to just the initialized, loaded data. which reduces 93 options for the stored password down to 24. From there a simple bash for loop can brute force the program to determine the password. Just like that the program is hacked in under two seconds. To try this out for yourself, grab the bash script from my Github and the a.out file from the Holberton School Github.
Linux’s objdump tool displays information from an object or program including functions and read-only data.
Using a list of strings from the code is a pretty rudimentary method to hacking a C program, and simply locking access for too many incorrect passwords would delay getting hacked a bit. The objdump allows access to track down what strings are actually being used in the strcmp function. There are two flags that simplify the data in a C program. Option d disassembles the data to make it more accessible. Option j enables selection of specific data for review. The first command I ran was “objdump -d -j.text a.out”. It displays the actual functions occurring including the main function. The yellow highlighted text shows the strcmp function being called twice in main. Two lines above the call is where the program moves the password string from memory into the register %esi. This register is used as a function parameter in strcmp. So to find the actual strings I move to .rodata, or read only data noting the memory locations where the parameter is sourced for each call.
The command to access the read-only data is very similar, “objdump -d -j.rodata a.out”. This displays memory locations with data showing in hexadecimal format. The ASCII characters are displayed to the right. Each piece of data is separated by a ’00’ null value. The needed data begins at the memory location listed in the main function and ends at the next null value. I’ve highlighted the test strings in the image above. Using the objdump tool I have now limited the number of test strings down to two. A lockout feature would no longer prevent the hacking of the program as the hacker would have a 50/50 chance of getting it right on the first try.
The ltrace tool in Linux runs the program and listens for library function calls including strcmp and outputs the information to the standard output.
Perhaps the objdump tool is too complex. Another tool gives the same data as objdump with much easier access. The ltrace tool filters out all the data and isolates library function calls such as the strcmp function. The ‘e’ optional argument can filter down to a specific library function call. One run through ltrace and the program spills all the beans. Why bother hacking when the program will do it for you? The command used in this example is “ltrace -e strcmp ./a.out 1234”. The key difference here is that even if the password is not hard-coded it can still be obtained when strcmp uses it as a parameter.
Gdb, a debugging tool in Linux, is used by developers to stop a program in process and obtain troubleshooting information including data and functions called.
If the first three tools were not enough reason to not use strcmp for password validation, gdb, a common debugging tool, can be used to to find passwords validated with strcmp as well. The command used in this example is “gdb –args a.out 1234”. Once gdb is launched, “disass main” will breakdown the main function. The output is similar to what objdump displays after disassembly. The information needed is the memory location of each function call. This is used to create breakpoints to stop the program for review of data and processes in use. At each breakpoint, print the data stored in the register %esi using x/s. As mentioned earlier this is the register used by the strcmp function as a parameter. It holds the data that the entered password is compared against to gain access.
Once you have the data needed, you can quit the process to prevent the program from completing any other functions. The example program deletes itself if the wrong password is entered. Quitting gdb in this case prevents the remove command from running, and allows a hacker to proceed with accessing the program unhindered.
In summary, the use of strcmp to compare two strings for password validation is not a safe way to protect a program within C. The stored password is accessible in plain text within the compiled program. Accessing the stored password is made even easier when using tools such as strings, objdump, ltrace, and gdb. If you are aware of C programs currently using the strcmp function for password validation, share this post with the software engineer responsible for its development.
About Rick Harris
Rick Harris is a student at Holberton School, a project-based, peer-learning school developing full-stack software engineers. He has been involved in the IT industry for 6+ years most recently as a part of the Office of Information Technologies at the University of Notre Dame. Follow him on Twitter or LinkedIn.