The service fluxmail
is a binary service that works as a systemd socket, and thus, can be launched from a command line for testing. After the launch, the main process starts a child process and communicates with child via pipes. Parent process interprets commands from user, sends messages to the pipe, and then child process executes the commands and communicates the result back to parent, so parent would be able to print it. All required information is stored in a data
folder, so it can be reused later.
After reading the initial bits I realized:
- The bug is probably logical. It would be very hard exploit an overflow bug in the PIE binary.
- It is very strange that data processing is moved to a child process? Why? May be we could inject somehow in the protocol (didn't work out for me)
There are several files, which contain user information:
data/<username>
contains user password anduser_id
data/<user_id>
contains some is used for some magic explained later.hexdump
ing the file gives us some strange results I wasn't able to interpret by the time seeing them.data/inbox-<username>
anddata/outbox-<username>
are containing user to user messages
After reading through most of the code and reverse engineering most of the structures I observed few strange places:
- there is a special user
marty
. You can't login asmarty
. By looking at the traffic from the checksystem we can clearly see that checksystem sends some messages tomarty
. We should probably try to read his messages to grab flags. - the function, which sends command down a communication channel, requires confirmation from user before writing to the pipe. Maybe there is a some kind of racy bug in here.
A very obscure approach to transfer message during view inbox: 0. A special file was mmaped, which is shared between the processes
- A random was created and written to the user
username
was written toshared_file_location
+random_value
.send_command
function was then executed (it also had "side effect #2" that forced us to press enter before actually writing to pipe and sending "view inbox" cmd)
Due to the "side effect #2" and the fact that file is shared we would be able to overwrite username
and read messages of another user. In order to do it we have to do the following:
- Create two connections to the service
- In the first connection we create new user with name
XXXmarty
, whereXXX
are three random letters. Press view inbox ofXXXmarty
and observe thefirst_connection_random_number
that would be written to us in the stringThis request costs %d jigawatt!
. But we do not press enter in order to take our racy route. Remember: we have already written our login to the shared memory, but we still haven't sent the command to the child process. - In the second connection we use the same login and password, but now we wait unitl
second_connection_random_number
is equal tofirst_connection_random_number - 3
. This way we would be able to overwrite username in the shared memory. - So login
marty
would be sent by the first connection, when we press enter at last. As we remeber messages ofmarty
contain flags, so this is it.