Connect to below address to spawn your team dedicated instance of the task.
You can find your team token in “edit profile”.
Warning! Connections to the spawned instance will be limited to the IP address which connected to the launcher (below address) and spawned the instance. There is a limit of one instance per team.
Hint: flag is in “/flag.txt”.
This challenge is running on Ubuntu 20.04.
Clarification: “/proc” is not mounted in the challenge setup.
Dragonbox was kind of a file download service. It spawns a server process, to which we can connect and request a file. It would then spawn a daemon, which communicates to the service via a socket. The server process would send our request to the daemon, which then checks, if the user is allowed to access the file and answers the server with either yes or no.
Skimming through the provided source code, a buffer overflow on bss can be spotted.
So, we can send 0x200 bytes as “authentication token” and the get_user function will take the string at the beginning of our token as username, then searches for : and takes everything after as password and then strcpy it into g_username and g_password.
If we provide a token like A:B*0x140, this will overflow g_password and overwrite g_flags.
As this was the only obvious bug, I found on first glance, I checked, where g_flags is used.
First usage was in the connection handling for new clients.
Though, when I corrupted g_flags and tried to connect another client to the server afterwards, connection mostly failed, so we have to keep this in mind, that we’ll need a clean g_flags, if we want to connect to the server.
When we request a file for the first time, the server will check, if a permission daemon is already running (by checking g_daemon_fds != -1).
If it’s not up, it will create a socket and pipe fds to communicate with it and fork.
This means, if we overwrite g_flags before requesting a file, we could maybe influence the socket creation of the daemon.
Played around with different flags to see, what will happen when the server tries to create the daemon and something interesting occured :)
This will now try to call socketpair(AF_UNIX, SOCK_DGRAM|SOCK_SEQPACKET, 0, &g_daemon_fds), which seems to be an invalid type combination and will fail to create a socket.
The manpacke of socketpairs tells us
But checking g_daemon_fds shows something different.
So, no socket was created, since socketpair failed, but g_daemon_fds was set nevertheless to fd 6 and 7.
We can abuse the fact, that those fds are still free by connecting more clients to the server and with enough connections, one of the new clients will overtake fd 6 and 7. By this we can impersonate the permission daemon itself.
But since we have overwritten g_flags, we cannot connect to the server anymore, because accept4 will fail.
Though, we can overcome this by connecting a second client directly at the start, before overwriting g_flags with our first client. After letting the daemon spawn fail, we can use the second client authentication to fix g_flags again, enabling us to connect more clients again.
g_flags will contain 0 again and we’re ablet to connect to the server without any issue again.
After connecting more clients, r4 will now have the same fd as the (not existing) permission daemon socket.
Thus, we can now request the file again via our first connection, but this time, it will send its request to our connection r4, so we can just simply answer with a yes.
This will let the server think, that we’re indeed allowed to read the flag: