I sure miss radare2, it’s a fact! So, when I looked at the level13 code and realized that it hidden some token, radare2 was the first thing that came to my mind. But being honest, this will most likely be a trivial task using radare2, and I’m most interested in learning something new, getting out of my comfort zone. So I went to check what others did and I found something new and fun.
What you’ll need to know…
- My previous Radare2 teachings
- Dynamic linking
Level13
As Lua in the previous challenge, shared libraries on unix systems have been on my TODO list for some time now, although closer to the top :). This seems the perfect time to learn how to manipulate them.
The dynamic linker is what loads and links the shared libraries that some executable in runtime may need. This shared library can be manipulated through the environment variable LD_PRELOAD, which will force a specific .so file (shared library) to be loaded before every other. We can do plenty of tricks with this, including writing custom functions, as we’ll do.
Because the problem in level13 is the getuid function, let’s first create our own.
After this, we compile the library using the command gcc -shared -fPIC custom_getuid.c -o custom_getuid.so and then we create the environment variable LD_PRELOAD using the command export LD_PRELOAD=/home/level13/custom_getuid.so.
If we go ahead and try to run the flag13 we’ll still fail. One thing that the dynamic linker won’t do (for security reasons) is bind shared libraries to processes/programs with different user real IDs than ours.
So, because the token is hard coded in the flag13 we can copy the program to level13 folder in order it be owned by us, and enabling us to link it to our library.
Let’s try to run it again.
Now, it’s just a matter of login into the flag13 account using this token as a password.
Done!
Well, I can’t resist. Let’s use radare2!
We fire up radare2 and the first thing we need to check is the functions present.
After this, we seek to the main function and change to Visual mode. In here, we can see the getuid function being called. We can also see the eax register being compared to 1000. So let’s put a breakpoint there and force the result of the comparison yield true.
Now we put another breakpoint on the instruction before the print of the message “your token…” (0x080485d0) and run the dc command. In here, we can see eax has the string “your token…” so edx will have our token.
We can confirm this by reading the first 36 bytes of edx.
There we have it.
If we check all strings, we will notice this one 8mjomjh8wml;bwnh8jwbbnnwi;>;88?o;9ob, which has the same size as our token. Also, between the instructions 0x08048595 and 0x080485c1 we can see every byte being XORed with 0x5a (90 in decimal) in instruction 0x080485a2. So the hard coded token was “encrypted” by a XOR…
Challenges completed: 14/20
Mitigation
Use strong crypto libraries? Don’t hard code passwords?