albadi132 / PCPAPP

Demo website: https://pcpplatform.com
https://github.com/albadi132/PCPAPP/wiki
6 stars 1 forks source link

Remote code execution through user-supplied code #2

Open omr00t opened 2 years ago

omr00t commented 2 years ago

Based on the following presentation I have given previously, I explained how the code executed by PCPAPP can be used to execute any malicious code supplied by the user.

The idea basically here can be seen in this chunk of code:

...
$process = new Process(['python3', $path, 'memory_limit=10M']);
$process->setTimeout($testcase->timelimit / 60);
$process->setInput($testcase->input);
$process->run();

We can see that the file submitted by the user gets renamed and then placed in a specific directory. Once that's done, the file gets executed directly in the system without a sandbox.

To fix this issue, I'd suggest adding a sandbox that the code gets executed in. The sandbox should both deny network traffic and code execution in general. It also should limit CPU/memory resources for each submission to prevent possible DOS attacks.

albadi132 commented 2 years ago

Thank you for clarifying!

I have seen your proposal for the solution, and we have already set restrictions for CPU/memory resources that can be used to prevent a DOS attacks. We also released a patch for the vulnerability that causes RCE to prevent use network for all solutions submitted by the contestants.

...
$process = new Process(['unshare','-r', '-n','python3', $path, 'memory_limit=10M']);
$process->setTimeout($testcase->timelimit / 60);
$process->setInput($testcase->input);
$process->run();

unshare -n program ... This creates an empty network namespace for the process. See unshare for details.

if it possible, can you verify the effectiveness of the solution?

omr00t commented 2 years ago

I'm not sure why you're supplying the option -r to unshare. It doesn't seem to be relevant in this case. However, the unshare with -n will only prevent a possible attacker from creating a network socket remotely. It will not prevent him/her from executing operating system commands (i.e echo 'mywebshell' > app_root/hax.php). That said, I don't think that this is sufficient.

If you're looking at sandboxing Python code, you might want to look for PyPy, which is another implementation of Python that has a builtin sandbox. You can look at this.

However, since you might have several possible programming languages, and looking for a way to sandbox each one on its own might be a headache, you might want to create a securely sandboxed environment for all of them, and run all the untrusted code within that environment. Check out this blog for more details. I know this won't be so easy, but it is for sure worth it in the long run.

As a temporary solution, I would suggest creating a docker container, preventing all network traffic from it, and running all the code inside it. That is, untrusted code won't affect the host file system, and no network traffic will be allowed to get outside the dockerized environment.

Good luck!