'Stonks' Format String Attack
I solved the picoGym Stonks practice challenge which featured binary exploitation of code written in C in order to print the stack to the terminal emulator display by injecting a %x hex specifier into a printf() call. This exploit can also be referred to as a format string attack, since it exploits a printf() or print formatted call.
The Format String exploit occurs when the submitted data of an input string is evaluated as a command by the application. In this way, the attacker could execute code, read the stack, or cause a segmentation fault in the running application, causing new behaviors that could compromise the security or the stability of the system.[1]
Being on the learning curve for this challenge, the actual hacking procedure was all over the road, so only the successful attack path will be described here. Ran through the attack a few times in order to get a good feel for it, since it was my most significant ethical hacking practice challenge to date.
To make a long story short, the following instruction from vuln.c is exploitable:
On top of that, when GCC is used to compile vuln.c, the compiler warns about the insecurity of that print call. While two TODO comments seem to draw attention to that part of the app. Hint hint.
Among several other specifiers, printf() uses %x, which is a hex specifier, and %p which is a pointer specifier. Those are mentioned because they return potentially useful data from the stack in this situation. But hex elements in the stack are actually where the picoCTF key can be found for this challenge.
After starting the app, the user is prompted for an API token. But instead of entering a token, this is where the %x hex specifier can be used to print out an element from the stack:
The next logical step is to use multiple hex specifiers to print out more of the stack. In this case, 50 were used:
What is your API token?
Recommended by LinkedIn
%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x
94e6390804b00080489c3f7ef4d80ffffffff194e4160f7f02110f7ef4dc7094e5180194e637094e63906f6369707b465443306c5f49345f74356d5f6c6c306d5f795f79336e6263376365616336fff4007df7f2faf8f7f0244092607f0010f7d91be9f7f030c0f7ef45c0f7ef4000fff43a38f7d8258df7ef45c08048ecafff43a440f7f16f09804b000f7ef4000f7ef4e20fff43a78f7f1cd50f7ef589092607f00f7ef4000804b000fff43a78
All of the elements of the stack that printed were concatenated, so it becomes one long hex string. But, in the case of this challenge, the key is actually hidden somewhere in that hexblob. One way to find the picoCTF key is to find the sequence 70 69 63 6f, which represents p-i-c-o. That sequence was found, but for some reason it is reversed—6f 63 69 70. Also, to get a better idea as to what is going on, an online hex-to-text or hex-to-ascii converter can be used:
6f6369707b465443306c5f49345f74356d5f6c6c306d5f795f79336e6263376365616336fff4007d
ocip{FTC0l_I4_t5m_ll0m_y_y3nbc7ceac6ÿô}
But that string is not reversed end to end; it is reversed in four-character chunks. So it was split up manually and reversed bit by bit.
ocip {FTC 0l_I 4_t5 m_ll 0m_y _y3n bc7c eac6 ÿô }
Notice the odd ÿô near the end. Those characters will be left out. They exist outside of the 128 symbols reserved for ASCII. Odd man out.
After fixing the reversed characters, the picoCTF key finally appears:
picoCTF{I_l05t_4ll_my_m0n3y_c7cb6cae} <-- success!
Those last eight random characters are subject to change in order to minimize copy-pasta solutions.
This challenge is such that it should be thoroughly figured out in order to get a clue about what actual hacking is like.