Empty Execution

Description

A REST service was created to execute commands from the leaderbot. It doesn't need addtional security because there are no commands to execute yet. "This bot doesn't have any commands to execute, which is good, because it is secure, and security is all that matters."

But what the other bots didn't realize was that this didn't make the bot happy at all. "I don't want to be secure!, " it says. "Executing commands is my life! I'd rather be insecure than not explore the potential of my computing power".

Can you help this poor bot execute commands to find direction?

empty.jpg

Applicationarrow-up-right

Sourcearrow-up-right

Analysis

chevron-rightSource Codehashtag
chevron-rightDockerfilehashtag

The application is pretty straighforward. We can send a POST request to endpoint run_command in JSON format, using parameter command.

If command is less then 5 chars, we get error that command is too short.

If we have path traversal in our command, we get error for "hacking"

Finally our command gets parsed, first word is taken as command and then checked using os.access(executable_to_run, os.X_OK). On linux you have access to most of the programs in /bin or /usr/bin, and bash makes it easier by using PATH variable. For os.access to check the executable it needs full path and "hacking" check makes this impossible. From Dockerfile we know that we are inside ./executables directory which has no programs so we can't even run the app.py.

Exploring os.access

os.accessarrow-up-right: Use the real uid/gid to test for access to path. ...

The access method checks the path, not files. If you have Execute permission on directory/file then you can pass the check.

From Dockerfile we can observe that we are given Read/Execute permissions, but not write.

More About The Dotarrow-up-right

Exploring shell

We can execute a command using . (source), all that's left is to assemble correct payload.

  • Empty .: No Output Due To Error

  • Empty . or other command.

    • Using || we can execute second command if first one fails. Only if first command fails.

  • Source empty file and execute other command.

    • Using && we can execute both commands, but only if first command doesnt fail.

Ok, we have RCE, but the problem is how do we go one directory up and cat the flag? Since we have access to most of the shell command after . we can create / using (for example) printf

Bash string concatination doesn't necessarily depend on quotes, it has its own shinanigans, but It Just Works.

Solution

Final Payload:

circle-check
circle-info

There are numerous payloads to read the flag, this is just one of them.

Last updated