Skip to content

Instantly share code, notes, and snippets.

@PaulCher
Created July 20, 2022 00:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PaulCher/502b1fd2642b738f004c975dc8720e74 to your computer and use it in GitHub Desktop.
Save PaulCher/502b1fd2642b738f004c975dc8720e74 to your computer and use it in GitHub Desktop.

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.

Finding weird places of code

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 and user_id
  • data/<user_id> contains some is used for some magic explained later. hexdumping the file gives us some strange results I wasn't able to interpret by the time seeing them.
  • data/inbox-<username> and data/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 as marty. By looking at the traffic from the checksystem we can clearly see that checksystem sends some messages to marty. 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.

The bug

A very obscure approach to transfer message during view inbox: 0. A special file was mmaped, which is shared between the processes

  1. A random was created and written to the user
  2. username was written to shared_file_location + random_value.
  3. 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)

Exploit

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:

  1. Create two connections to the service
  2. In the first connection we create new user with name XXXmarty, where XXX are three random letters. Press view inbox of XXXmarty and observe the first_connection_random_number that would be written to us in the string This 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.
  3. In the second connection we use the same login and password, but now we wait unitl second_connection_random_number is equal to first_connection_random_number - 3. This way we would be able to overwrite username in the shared memory.
  4. So login marty would be sent by the first connection, when we press enter at last. As we remeber messages of marty contain flags, so this is it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment