| Linux hosting5.siteguarding.com 3.10.0-962.3.2.lve1.5.88.el7.x86_64 #1 SMP Fri Sep 26 14:06:42 UTC 2025 x86_64 Path : /home/devsafetybis/backups.dev.safetybis.com/ |
| Current File : /home/devsafetybis/backups.dev.safetybis.com/ftp_download.php |
<?php
/** 33F190D04D71-0B067FFC03A6-1810FA8DBECA
*
* FTP downloader (.php, .js and etc)
* Version: 1.9
* Date: 24 Nov 2017
*/
$ftp_host = 'sl158.web.hostpoint.ch';
$ftp_username = 'siteguarding@schwarz-architekten.com';
$ftp_password = 'GJBgL8YbuGfLZc7dBZZx';
$ftp_folder = 'Hostpoint Quarantined Files/www_infected-2023-10-09T16:11:22.573829/schwarz-architekten.com'; // DONT need / in the beginning and in the end, sample: public_html or public_html/somefolder
$exclude_folders = array(); // array('/folder_1/', '/folder_2/')
?>
<style>
.err,.error{color:red}
.info{color:blue}
.ok{color:green}
.b{font-weight: bold;}
</style>
<?php
define('SCAN_LEVEL', 3);
ini_set('memory_limit', '256M');
$tmp_result = set_time_limit ( 7200 );
ignore_user_abort(true);
date_default_timezone_set('Europe/London');
$flag_pack = intval($_GET['pack']);
if ($flag_pack == 1)
{
$scan_path = dirname(__FILE__)."/downloaded/";
$cmd = 'cd '.$scan_path.''."\n".'tar -czf '.$scan_path.'file.tar *';
$output = array();
$result = exec($cmd, $output);
if (file_exists($scan_path.'file.tar') === false)
{
echo '<p class="err b">File '.$scan_path.'file.tar is absent</p>';
}
else {
echo '<p class="ok">File '.$scan_path.'file.tar (size: '.filesize($scan_path.'file.tar').' bytes)</p>';
$link_dl = 'http://'.$_SERVER['HTTP_HOST'].'/downloaded/file.tar';
echo '<p>Download link: <a href="'.$link_dl.'">'.$link_dl.'</a></p>';
}
exit;
}
$flag_download = intval($_GET['download']);
if ($flag_download == 0)
{
echo '<p class="err">!!!!! Only shows the list of the files. Add ?download=1 to start download process !!!</p>';
}
$link_download = 'http://'.$_SERVER['HTTP_HOST'].'/ftp_download.php?download=1';
$link_pack = 'http://'.$_SERVER['HTTP_HOST'].'/ftp_download.php?pack=1';
echo '<p>Commands: <br><br>
Download: <a href="'.$link_download.'">'.$link_download.'</a> <br>
Pack (file.tar): <a href="'.$link_pack.'">'.$link_pack.'</a>
</p>';
if (count($exclude_folders))
{
foreach ($exclude_folders as $k => $v)
{
$exclude_folders[$k] = "/".$ftp_folder.$v;
}
}
$scanner = new SiteGuarding_ftp();
$scanner->exclude_folders = $exclude_folders;
$scanner->filter_ext = true; // only php, js and etc
$time_start = time();
echo "Start Collect file list: ".date("Y-m-d H:i:s")."<br><br>";
$files = $scanner->GetFileList($ftp_host, $ftp_username, $ftp_password, $ftp_folder);
echo "File list collected: ".date("Y-m-d H:i:s")."<br><br>";
echo "Total files: ".count($files)."<br><br>";
if ($files === false)
{
echo '<span class="err b">Error cant connect to FTP or cant get the file list</span>'."</br>";
exit;
}
if ($files !== false && $flag_download == 0)
{
if (count($exclude_folders))
{
echo "Excluded folders:"."<br><br>";
echo "<pre>";
echo print_r($exclude_folders, true);
echo "</pre>";
}
echo "List of the files (in tmp/cache folders) review these files, maybe it's possible to exclude or remove them directly from the server:"."<br><br>";
$i = 0;
foreach ($files as $file => $filesize)
{
if (stripos($file, "/tmp/") !== false || stripos($file, "/cache/") !== false)
{
echo '<span class="err">'.$file.'</span>'."<br>";
$i++;
}
}
echo "<br>".'Total: '.$i.'</span>'."<br>";
echo "<hr>";
echo "List of the files (all files for download):"."<br><br>";
foreach ($files as $file => $filesize)
{
echo $file."<br>";
}
echo "<br><br>"."Finished, total: ".count($files)."<br><br>";
exit;
}
if ($files !== false && $flag_download == 1)
{
echo "Download Start: ".date("Y-m-d H:i:s")."<br><br>";
if (SiteGuarding_ftp::$debug) SiteGuarding_ftp::SaveLog('Download Start');
$result = $scanner->DownloadFiles($ftp_host, $ftp_username, $ftp_password, $files);
echo "<br><br>"."Finish: ".date("Y-m-d H:i:s")."<br><br>";
echo "Spent: ".round( (time() - $time_start)/60, 2).' mins'."<br><br>";
if (SiteGuarding_ftp::$debug) SiteGuarding_ftp::SaveLog('Download Finish');
}
//print_r($files);
class SiteGuarding_ftp
{
public static $result_filelist_json = 'ftp_filelist.json';
public static $result_latest_file = 'ftp_latest_file.log';
public static $result_local_folder = '/downloaded';
public static $debug = true;
public static $debug_lof_file = 'ftp_debug.log';
var $filter_ext = false; // true - .php, js and etc
var $show_output = false;
var $exclude_folders = array(); // array('/folder_1/', '/folder_2/')
var $filter_filesize = array();
public function DownloadFiles($ftp_host, $ftp_username, $ftp_password, $files)
{
$time_start = time();
if (self::$debug) ob_start();
$conn_id = ftp_connect($ftp_host, 21);
if ($conn_id === false) return false;
else {
// Check the ftp password
if (!@ftp_login($conn_id, $ftp_username, $ftp_password)) {
return false;
}
}
ftp_pasv($conn_id, true);
$i = 0;
$local_folder = dirname(__FILE__).self::$result_local_folder;
if (!file_exists($local_folder)) mkdir($local_folder);
$total_files = count($files);
$error_files_array = array();
foreach ($files as $file => $filesize)
{
$i++;
/*if ($i == 30) exit();*/
$time_left = round( ( (time() - $time_start) / $i * ($total_files - $i) ) / 60, 2 );
$time_past = round( (time() - $time_start) / 60, 2 );
$tmp_fp = fopen(dirname(__FILE__).'/'.self::$result_latest_file, 'w');
$proc = round( (100 * $i) / $total_files , 2);
$i_timer = 'Current: '.$i.' ('.$proc.'%) Total: '.$total_files.' [time left aprox.: '.$time_left.' mins | time past: '.$time_past.' mins] ';
fwrite($tmp_fp, $i_timer.$file);
fclose($tmp_fp);
$i_timer = $i.' ('.$proc.'%) of '.$total_files.' [time left: '.$time_left.' mins] ';
//if ($i / 10 == intval($i / 10)) // show every 10th
//{
if (self::$debug) echo $i_timer.$file;
//}
$local_file = $local_folder.$file;
if (file_exists($local_file) && filesize($local_file) == $filesize)
{
if (self::$debug)
{
echo ' - <span class="info b">exists</span>'."</br>";
self::SaveLog($file.' - exists');
}
}
else {
$tmp_path = dirname($file);
$tmp_path_array = explode("/", $tmp_path);
$tmp_full_path = $local_folder;
foreach ($tmp_path_array as $tmp_folder)
{
$tmp_full_path = $tmp_full_path."/".$tmp_folder;
if (!file_exists($tmp_full_path))
{
$status = mkdir($tmp_full_path);
if ($status === false && self::$debug)
{
echo ' - <span class="err b">Error cant create folder '.$local_file_folder.'</span>'."</br>";
self::SaveLog($file.' - Error cant create folder '.$local_file_folder, true);
}
}
}
$local_file_folder = dirname($local_file);
$handle = fopen($local_file, 'w');
if (ftp_fget($conn_id, $handle, $file, FTP_BINARY, 0))
{
if (self::$debug)
{
echo ' - <span class="ok b">downloaded</span>'."</br>";
self::SaveLog($file.' - downloaded');
}
}
else {
if (self::$debug)
{
echo ' - <span class="err b">Error downloading '.$file.'</span>'."</br>";
self::SaveLog($file.' - Error downloading '.$file, true);
// Try to reconntect
$conn_id = ftp_connect($ftp_host, 21);
if ($conn_id === false) return false;
else {
// Check the ftp password
if (!@ftp_login($conn_id, $ftp_username, $ftp_password)) {
return false;
}
ftp_pasv($conn_id, true);
}
if (ftp_fget($conn_id, $handle, $file, FTP_BINARY, 0))
{
if (self::$debug)
{
echo ' - <span class="ok b">downloaded</span>'."</br>";
self::SaveLog($file.' - downloaded');
}
}
else {
echo ' - <span class="err b">Error downloading '.$file.'</span>'."</br>";
self::SaveLog($file.' - Error downloading '.$file, true);
$error_files_array[] = $file;
}
}
}
fclose($handle);
}
if (self::$debug) echo "</br>";
// Flush output
if (self::$debug)
{
ob_flush();
flush();
}
}
if (count($error_files_array))
{
echo '<br><p class="err b"><b>NOT DOWNLOADED FILE (check manually) [total: '.count($error_files_array).']</b></p>';
foreach ($error_files_array as $file)
{
echo $file."<br>";
}
echo '</p>';
}
}
public function MergeFolders($to_list, $from_list )
{
foreach ($from_list as $path)
{
if (!in_array($path, $to_list))
{
$to_list[] = $path;
}
}
//sort($to_list);
return $to_list;
}
public function GetFileList($ftp_host, $ftp_username, $ftp_password, $ftp_folder)
{
$conn_id = ftp_connect($ftp_host, 21);
if ($conn_id === false) return false;
else {
// Check the ftp password
if (!@ftp_login($conn_id, $ftp_username, $ftp_password)) {
return false;
}
}
ftp_pasv($conn_id, true);
self::SaveLog('Logged');
$files_list = array();
if (file_exists(dirname(__FILE__).'/'.self::$result_filelist_json))
{
self::SaveLog('Use JSON list');
$filename = dirname(__FILE__).'/'.self::$result_filelist_json;
$handle = fopen($filename, "rb");
$files_list = fread($handle, filesize($filename));
$files_list = (array)json_decode($files_list, true);
fclose($handle);
}
else {
self::SaveLog('Start to collect files from FTP');
$ftp_folder_tmp = $ftp_folder;
$dirs = array();
$a = ftp_rawlist($conn_id, $ftp_folder_tmp);
//print_r($a);
$dirs = $dirs_tmp_array = self::ParseFolders($a, $ftp_folder_tmp);
//print_r($dirs_tmp_array);
self::SaveLog('Scanned '.$ftp_folder_tmp.' got folders: '.count($dirs_tmp_array));
if (count($dirs_tmp_array))
{
for ($i = 1; $i <= SCAN_LEVEL; $i++) // How deep to scan the folders
{
self::SaveLog('Step i='.$i);
$dirs_tmp_array_level = array();
foreach ($dirs_tmp_array as $ftp_folder_tmp)
{
self::SaveLog('Get info from '.$ftp_folder_tmp);
$a = ftp_rawlist($conn_id, $ftp_folder_tmp);
$tmp = self::ParseFolders($a, $ftp_folder_tmp);
//print_r($tmp);
$dirs_tmp_array_level = self::MergeFolders($dirs_tmp_array_level, $tmp);
}
$dirs_tmp_array = $dirs_tmp_array_level;
$dirs = self::MergeFolders($dirs, $dirs_tmp_array);
}
}
//print_r($dirs);
//exit;
$a = ftp_rawlist($conn_id, $ftp_folder);
// Process list
$files = self::ParseFiles($a, $ftp_folder);
self::SaveLog('Collect files in '.$ftp_folder);
if (count($files))
{
foreach ($files as $file => $filesize)
{
$files_list[$file] = $filesize;
}
}
self::SaveLog('Found in '.$ftp_folder.' '.count($files_list).' files');
self::SaveLog('Start to collect the files in '.count($dirs).' folders');
if (count($dirs))
{
foreach ($dirs as $k => $ftp_folder)
{
$k++;
self::SaveLog('Get files from [#'.$k.'] '.$ftp_folder);
$a = ftp_rawlist($conn_id, $ftp_folder, true);
$files = self::ParseFiles($a, $ftp_folder);
self::SaveLog('Found '.count($files).' files in '.$ftp_folder);
foreach ($files as $file => $filesize)
{
$files_list[$file] = $filesize;
}
}
}
$fp = fopen(dirname(__FILE__).'/'.self::$result_filelist_json, 'w');
fwrite($fp, json_encode($files_list));
fclose($fp);
self::SaveLog('Finish and save JSON with the files');
}
//print_r($a);
//print_r($files_list);
return $files_list;
}
public function ParseFolders($a, $ftp_folder)
{
$dirs = array();
//print_r($a);
foreach ($a as $child)
{
if (trim($child) == '') continue;
$chunks = preg_split("/\s+/", $child);
//print_r($chunks);
if (isset($chunks[4]))
{
if ($chunks[0]{0} === 'd')
{
array_splice($chunks, 0, 8);
$remote_filename = implode(" ", $chunks);
if ($remote_filename != '.' && $remote_filename != '..') $dirs[] = $ftp_folder."/".$remote_filename;
}
}
}
//print_r($dirs);
//exit;
return $dirs;
}
public function ParseFiles($a, $ftp_folder)
{
foreach ($a as $child)
{
if (trim($child) == '') continue;
$chunks = preg_split("/\s+/", $child);
if (isset($chunks[4]))
{
if ($chunks[0]{0} === 'd') continue;
$file_size = intval($chunks[4]);
if ($file_size == 0) continue;
array_splice($chunks, 0, 8);
$remote_filename = implode(" ", $chunks);
if ($this->filter_ext === true)
{
$file_ext = strtolower( substr( $remote_filename, strrpos($remote_filename, ".") ) );
if (strpos($remote_filename, '.php.') || strpos($remote_filename, '.phtml.') || strpos($remote_filename, '.php3.') || strpos($remote_filename, '.php4.') || strpos($remote_filename, '.php5.'))
{
$remote_file = '/'.$ftp_folder.'/'.$remote_filename;
$files_list[$remote_file] = $file_size;
}
else {
switch ($file_ext)
{
case '.inc':
case '.php':
case '.php4':
case '.php5':
case '.phtml':
case '.js':
case '.html':
case '.htm':
case '.cgi':
case '.pl':
case '.so':
case '.sh':
case '.htaccess':
case '.pl':
case '.cgi':
case '.suspected':
case '.ico':
$remote_file = '/'.$ftp_folder.'/'.$remote_filename;
$remote_file = str_replace("//", "/", $remote_file);
$files_list[$remote_file] = $file_size;
}
}
}
else {
$remote_file = '/'.$ftp_folder.'/'.$remote_filename;
$remote_file = str_replace("//", "/", $remote_file);
$files_list[$remote_file] = $file_size;
}
}
else {
if (substr($child, -1) == ":")
{
$ftp_folder = substr($child, 0, -1);
}
else {
echo 'Error row: '.$child."<br>";
}
}
}
// Remove excluded files
if ( count($this->exclude_folders))
{
foreach ($files_list as $file => $filesize)
{
foreach ($this->exclude_folders as $excluded_folder)
{
if (strpos($file, $excluded_folder) == 0 && strpos($file, $excluded_folder) !== false)
{
unset($files_list[$file]);
}
}
}
}
return $files_list;
}
public function SaveLog($txt, $flag = false)
{
$filename = self::$debug_lof_file;
$log = @fopen($filename, 'a');
$line = date("Y-m-d H:i:s").' '.$txt."\n";
if ($flag) $line = "! ERROR ! ".$line;
if ($log) {
fputs($log, $line);
fclose($log);
}
}
}
?>