private function setNewPassword($password) { if (!file_exists($this->passwordHashFilepath)) { $passwordHash = hash('sha256', $password); file_put_contents2($this->passwordHashFilepath, "<?php die('Forbidden'); ?>\n" . $passwordHash); $this->setPasswordHashCookie($passwordHash); } }
public function start() { global $projectTmpDir, $php_errormsg; $authenticator = new Auth(); if ($authenticator->auth()) { ob_start(); if (!empty($_GET['a'])) { $action = $_GET['a']; $interval = empty($_GET['delay']) ? 5 : (int) $_GET['delay']; $fileScanner = new FileList(); $fileScanner->setInterval($interval); if ($action === 'cleanUp') { $this->removeTempFiles(); print json_encode(array('type' => 'cleanUp', 'status' => 'ok', 'phpError' => $php_errormsg)); } else { if ($action === 'getFileList') { echo $fileScanner->performScanning(); } else { if ($action === 'getSignatureScanResult') { $this->detector = new MalwareDetector(); $this->detector->setRequestDelay($interval); print $this->detector->malwareScanRound(); } else { if ($action === 'getWebsiteLog') { //REPORTING $xmlLog = $this->getXMLReport(); $logFilename = $projectTmpDir . '/scan_log.xml'; file_put_contents2($logFilename, $xmlLog); print json_encode(array('type' => 'getWebsiteLog', 'status' => 'ok', 'phpError' => $php_errormsg)); } } } } } else { //GENERATE INTERFACE $fileScanner = new FileList(); define('PS_ARCHIVE_DOWNLOAD_URL', $_SERVER['PHP_SELF'] . '?controller=download&f=report'); $this->templateOutput($fileScanner->getInterval()); } } }
public function executeXmlRecipe($deleteFiles, $quarantineFiles, &$numQuarantined) { //Put suspicious file in quarantine archive $this->archiver = new Archiver($this->quarantineFilepath, 'a'); $numQuarantined = 0; foreach ($quarantineFiles as $filename) { $absolutePath = $this->webRootDir . substr($filename, 1); if ($this->quarantineFile($absolutePath)) { $this->log .= sprintf(PS_WAS_QUARANTINED, $filename) . '<br/>'; $numQuarantined++; } } $this->archiver->close(); //Put malicious files to backup archive and delete them foreach ($deleteFiles as $filename) { $this->archiver = new Archiver($this->backupFilepath, 'a'); $absolutePath = $this->webRootDir . substr($filename, 1); $this->quarantineFile($absolutePath); $this->archiver->close(); if ($this->deleteFile($absolutePath)) { $this->log .= sprintf(PS_WAS_DELETED, $filename) . '<br/>'; } } if (file_exists($this->quarantineFilepath)) { file_put_contents2($this->quarantineFilepathFilepath, $this->quarantineFilepath); } return $this->log; }
function malwareScanRound() { global $php_errormsg; $startTime = time(); if (!is_file($this->QUEUE_FILENAME)) { die(basename(__FILE__) . ': cannot open ' . $this->QUEUE_FILENAME . ' on scan round'); } $fh = fopen($this->QUEUE_FILENAME, 'r'); $offset = 0; if (file_exists($this->QUEUE_OFFSET_FILENAME)) { $offset = (int) file_get_contents($this->QUEUE_OFFSET_FILENAME); fseek($fh, $offset); } if (filesize($this->QUEUE_FILENAME) - $offset <= 0) { fclose($fh); return $this->finishMalwareScan(); } $queueText = fread($fh, filesize($this->QUEUE_FILENAME) - $offset); $queueLines = explode("\n", $queueText); $numFilesScanned = 0; if (count($queueLines) < 1) { fclose($fh); return $this->finishMalwareScan(); } foreach ($queueLines as $line) { $executionTime = time() - $startTime; if ($executionTime >= round($this->MAX_EXECUTION_DURATION * 0.8)) { break; } else { if (empty($line)) { continue; } } $offset += strlen($line) + 1; $fileinfo = explode(' ', $line); $filePath = $fileinfo[0]; $fileHash = $fileinfo[1]; $snippet = ''; $fileExtension = pathinfo(basename($filePath), PATHINFO_EXTENSION); $res = $this->detectMalware($filePath, $snippet, $pos, $this->SCRIPT_START, $this->MAX_EXECUTION_DURATION, $fileExtension); switch ($res) { case 'no_need_to_check': break; case 'no_read': break; case 'skipped': break; case 'timeout': file_put_contents2($this->QUEUE_OFFSET_FILENAME, $offset); $this->throwTimeout($filePath); break; default: $numFilesScanned++; $content = $filePath . ';detected=' . $res . ';pos=' . $pos . ';snippet=' . base64_encode($snippet) . PHP_EOL; file_put_contents2($this->MALWARE_LOG_FILENAME, $content, 'a'); if ($res) { $this->queueQuarantine($filePath); } } } file_put_contents2($this->QUEUE_OFFSET_FILENAME, $offset); fclose($fh); if (count($queueLines) <= 1) { return $this->finishMalwareScan(); } $data = array('filesScannedThisTime' => $numFilesScanned, 'filesLeft' => count($queueLines), 'lastFile' => $filePath); $result = json_encode(array('type' => 'getSignatureScanResult', 'status' => 'inProcess', 'data' => $data, 'phpError' => $php_errormsg)); return $result; }
function content_do_export_data() { global $cur_mysql_table; // just a quick error message function for the export routine function draw_errmsg($msg, $qry, $msg2) { echo "<p><span style=\"font-size:110%;\"><b>{$msg}</b></span> -- <br />\n <i>{$qry}</i><br /><b>{$msg2}</b></p>\n"; } // see if they want MySQL to do the export, rather than Sqlicity: if ($_POST['useSELECTINTOOUTFILE']) { $sqlicity_exportfile = trim($_POST['sqlicity_exportfile']); // make sure they requested a file! if (!$sqlicity_exportfile) { draw_errmsg('You need to specify a file location for the export to be saved!', '', ''); return; } // export location can be relative or absolute if ($_POST['exportfile_absolutepath']) { $thefile = $sqlicity_exportfile; } else { $thefile = getcwd() . '/' . $sqlicity_exportfile; } // do the export mysql_query($query = "SELECT * INTO OUTFILE '{$thefile}'\n\t\t FIELDS\n\t\t TERMINATED BY '{$_POST['fields_terminatedby']}'\n\t\t " . (trim($_POST['fields_optionally_enclosed']) ? ' OPTIONALLY' : '') . "\n\t\t ENCLOSED BY '{$_POST['fields_enclosedby']}'\n\t\t ESCAPED BY '{$_POST['fields_escapedby']}'\n\t\t LINES\n\t\t TERMINATED BY '{$_POST['lines_terminatedby']}'\n\t\t STARTING BY '{$_POST['lines_startingby']}'\n\t\t FROM `{$cur_mysql_table}`\n\t\t;"); // see if they have an error trying this query if (mysql_error()) { draw_errmsg('Your SELECT INTO OUTFILE failed', nl2br($query), mysql_error()); return; } // ASSERT: it worked, give the user the file as well header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="' . basename($thefile) . '"'); // read and output the file in chunks, // this allows us to handle much bigger files here $export_filehandle = fopen($thefile, 'rb'); while (!feof($export_filehandle)) { echo fread($export_filehandle, 8192); } fclose($export_filehandle); // quit now, the rest is for sqlicity's export functionality return; } // FIRST, make sure the submitted stuff makes sense as a SELECT // get the select conditions from submitted form $select_where = $_POST['select_where']; $select_columns = $_POST['select_columns']; // store all column names, and enclosed columns+BLOB columns // SEE THE COMMENTS WITH THE SELECT PAGE CONTENTS $all_columns = array(); // store all column names (only the names) $enclosed_cols = array(); // track enclosed string columns $blob_cols = array(); // track BLOB columns $result_cols = mysql_query("SHOW COLUMNS FROM `{$cur_mysql_table}`"); // make sure table still exists if (!$result_cols) { echo "<p><b>Table <i>`{$cur_mysql_table}`</i> no longer exists!</b></p>\n"; return; } // store all the columns and flag important ones while ($column = mysql_fetch_assoc($result_cols)) { // find out if this column should be enclosed on output if (isEnclosedColumn($column['Type'])) { $enclosed_cols[$column['Field']] = TRUE; } // handle BLOB type columns specially if (strtolower(substr($column['Type'], 0, 4)) == 'blob') { $blob_cols[$column['Field']] = TRUE; } // store all column names in case no explicit select_columns was given $all_columns[] = $column['Field']; } // check for columns to select if (!$select_columns) { $select_columns = implode(', ', array_map(create_function('$c', 'return "`$c`";'), $all_columns)); } // select_where MUST start with either: WHERE, ORDER, or LIMIT $select_where2 = strtoupper(substr(trim($select_where), 0, 5)); if ($select_where2 !== NULL && $select_where2 !== '' && strpos($select_where2, 'WHERE') !== 0 && strpos($select_where2, 'ORDER') !== 0 && strpos($select_where2, 'LIMIT') !== 0) { draw_errmsg('Invalid WHERE/etc clause!', $select_where, ''); return; } // try the SELECT now so that we can verify it will actuall work! $export_data = mysql_query($query_temp = "SELECT {$select_columns} FROM `{$cur_mysql_table}` {$select_where}"); // make sure their query was valid... if (mysql_error()) { draw_errmsg('ERROR in query', $query_temp, mysql_error()); return; } // make sure there is data to export! if (mysql_num_rows($export_data) < 1) { draw_errmsg('NO data in this SELECT to export!', $query_temp, $cur_mysql_table); return; } // ASSERT: now we have valid data for export selected already // get the actually displayed columns, for building the list with INSERT or column header list // we just do the exact same export query, and pull off the first entry to get the column names from it // I'd like to do a LIMIT 1 in here, but there might already be a LIMIT in $select_where... $display_columns = mysql_query("SELECT {$select_columns} FROM `{$cur_mysql_table}` {$select_where}"); $display_columns = mysql_fetch_assoc($display_columns); $display_columns = array_keys($display_columns); // are we doing SQL INSERTs or delimited output? $exportSQLinsert = $_POST['export_sqlinserts'] ? TRUE : FALSE; // are we trying to save this to the server? $thefile = NULL; if ($_POST['sqlicity_export_saveonserver']) { // make sure they requested a file! if (!$_POST['sqlicity_exportfile2']) { draw_errmsg('You need to specify a file location for the export to be saved!', '', ''); return; } // export location can be relative or absolute if ($_POST['exportfile_absolutepath2']) { $thefile = $_POST['sqlicity_exportfile2']; } else { $thefile = getcwd() . '/' . $_POST['sqlicity_exportfile2']; } // we will NOT overwrite existing files with this! if (@file_exists($thefile)) { draw_errmsg('That file already exists -- you cannot overwrite existing files!', $thefile, ''); return; } // name the file we send to the user after the export filename $export_filename = basename($thefile); } else { // name the file we send to the user after the table being exported $export_filename = $cur_mysql_table . '.'; // if no compression requested, file extension is .txt or .sql if (!$_POST['export_file_compression']) { // if we are outputing sql, name it .sql if ($exportSQLinsert) { $export_filename .= 'sql'; } else { $export_filename .= 'txt'; } } else { $export_filename .= $_POST['export_file_compression']; } } // identify this as a zip file being transferred // or just generic binary data: application/octet-stream // http://www.graphcomp.com/info/specs/mime.html header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="' . $export_filename . '"'); // if this is going to be compressed or written to the server, save it all // otherwise it's plaintext and I can just put it out as I go along if ($fileextension || $thefile) { ob_start(); } // if we're outputing SQL, we do that special -- same func as with db sql export if ($exportSQLinsert) { output_sql_insert_values($export_data, $display_columns, $enclosed_cols); } else { // get field/line terminator/encloser/escape chars and optionally, etc // these get overwritten if we're exporting sql inserts // the eval()s are needed to handle escaped chars like \n, etc properly $optionally_enclosed = $_POST['fields_optionally_enclosed'] ? TRUE : FALSE; $field_enclose_char = unescape_mysql_chars($_POST['fields_enclosedby']); $field_enclose_char = $field_enclose_char[0]; // force only one char $field_escape_char = unescape_mysql_chars($_POST['fields_escapedby']); $field_escape_char = $field_escape_char[0]; // force only one char $field_terminatedby = unescape_mysql_chars($_POST['fields_terminatedby']); $line_terminatedby = unescape_mysql_chars($_POST['lines_terminatedby']); $line_startingby = unescape_mysql_chars($_POST['lines_startingby']); // this one picks which string to use in place of enclosers in data $encloser_in_data = $_POST['double_fields_encloser'] ? $field_enclose_char . $field_enclose_char : $field_escape_char . $field_enclose_char; // these are used only for escaping fields/lines terminated by sequence // FIXME FIX ME -- have to test this properly: // is this only inside enclosed data? // what about newline chars when terminator is newline???? $field_terminated_firstchar = $field_terminatedby[0]; $line_terminated_firstchar = $line_terminatedby[0]; // the list of chars that need to be escaped on output // this is for the loop over all the field data in every row // AND also for the column header list, if that is output $output_escaped_chars = array(chr(0) => $field_escape_char . '0', $fields_escape_char => $field_escape_char . $fields_escape_char, $field_enclose_char => $encloser_in_data, $field_terminated_firstchar => $field_escape_char . $field_terminated_firstchar, $line_terminated_firstchar => $field_escape_char . $line_terminated_firstchar); // just in case any empties (e.g. enclose_char) come in // such empty keys can seriously break str_replace unset($output_escaped_chars['']); // remove line/field terminator escaped chars if requested if ($_POST['noescape_lf_terminator']) { unset($output_escaped_chars[$field_terminated_firstchar]); unset($output_escaped_chars[$line_terminated_firstchar]); } // add newline escape chars if requested if ($_POST['escape_all_newlines']) { $output_escaped_chars["\n"] = '\\n'; $output_escaped_chars["\r"] = '\\r'; } // when not outputting sql, we might want a header line if ($_POST['addfirstlineheaders']) { // we need to handle escaped chars in the column names! foreach ($display_columns as $k => $col) { // if there is escaping going on, we do some here if ($field_escape_char) { // we do not handle enclosers here, that is outside this escaping // so we TEMPORARILY turn this off unset($output_escaped_chars[$field_enclose_char]); // do the escaping needed for this identifier $col = str_replace(array_keys($output_escaped_chars), array_values($output_escaped_chars), $col); // return this to original, IF there is an encloser at all! if ($field_enclose_char) { $output_escaped_chars[$field_enclose_char] = $encloser_in_data; } } // even if there is no official escaping going on, we double enclosers anyway $col = str_replace($field_enclose_char, $field_enclose_char . $field_enclose_char, $col); // use the original or escaped identifier name (as it is now) // and ALL identifiers get enclosed, whether an encloser exists or not $display_columns[$k] = $field_enclose_char . $col . $field_enclose_char; } // now that we've fixed encloser chars, echo it joinned // make sure to include startingby and terminatedby strings // -- this is a real line like the rest, and will be imported as such echo $line_startingby . implode($field_terminatedby, $display_columns) . $line_terminatedby; } // handle each row one at a time -- using the select we did above while ($exportrow = mysql_fetch_assoc($export_data)) { // start the row's "line" properly echo $line_startingby; // now handle every field in the row $firstcol = TRUE; // to do separating on fields foreach ($exportrow as $name => $value) { // after first col, start with field terminator if (!$firstcol) { echo $field_terminatedby; } else { $firstcol = FALSE; } // handle NULLs specially if ($value !== NULL) { // enclosed data on _export_ (different when importing) will always need escaping // while uneclosed data will never need escaping, almost by definition if ($enclosed_cols[$name] || !$optionally_enclosed) { // open enclosed data echo $field_enclose_char; // are we actually escaping chars? if ($field_escape_char) { echo str_replace(array_keys($output_escaped_chars), array_values($output_escaped_chars), $value); } else { echo $value; } // close enclosed data echo $field_enclose_char; } else { echo $value; } } else { echo $field_escape_char ? $field_escape_char . 'N' : 'NULL'; } } // end the row's "line" properly echo $line_terminatedby; } } // end non sql insert export version // do the compression, if requested $compressed_export_file = ''; // default to empty if ($fileextension) { // get all the content of the file to be compressed $export_file_contents = ob_get_contents(); ob_end_clean(); // need to end before we try to echo the content! // have to do different compressions differently switch ($fileextension) { case 'zip': $compressed_export_file = 'zip'; break; case 'gz': $compressed_export_file = 'gz'; break; case 'bz2': $compressed_export_file = 'bz2'; break; } // php does NOT write zip?!?! // http://www.smiledsoft.com/demos/phpzip/index.shtml // consider alternative (open-source) compression: // http://www.php.net/manual/en/wrappers.compression.php // this will not be written to the server, so just send it now if (!$thefile) { echo $compressed_export_file; } } // end do compression conditional // allow for sqlicity exporting into a file on the server: if ($thefile) { // simluates a PHP 5 function -- named 2 to not conflict function file_put_contents2($filename, $data) { $retval = FALSE; if ($file_res = fopen($filename, 'wb')) { $retval = fwrite($file_res, $data); fclose($file_res); } return $retval; } // did we compress the export file? // NOTE: I made a choice, better to be told that the file // was NOT saved on the server, than to download the file // thinking that it did in fact happen if ($fileextension) { // write it to the server, then echo it for the user to download if (@file_put_contents2($thefile, $compressed_export_file) === FALSE) { echo "\nFile NOT successfully saved on server at\n {$_POST['sqlicity_exportfile2']}\n-- are you sure your permissions are high enough?\n\nYou must redo the export WITHOUT trying to save to the server\n in order to download the export file.\n"; return; } echo $compressed_export_file; } else { // write it to the server, then echo it for the user to download $export_file_contents = ob_get_contents(); ob_end_clean(); // need to end before we try to echo the content! if (@file_put_contents2($thefile, $export_file_contents) === FALSE) { echo "\nFile NOT successfully saved on server at\n {$_POST['sqlicity_exportfile2']}\n-- are you sure your permissions are high enough?\n\nYou must redo the export WITHOUT trying to save to the server\n in order to download the export file.\n"; return; } echo $export_file_contents; } } // end writing to server }
function cache_changed($file, $data, $func = 'seri') { $file = cache_getfilename($file, $func); $backup = @file_get_contents($file); if ($func == 'md5') { if ($backup != md5(json_encode($data))) { file_put_contents2($file, md5(json_encode($data))); return true; } } elseif ($func == 'json') { if ($backup != json_encode($data)) { file_put_contents2($file, json_encode($data)); return true; } } elseif ($func == 'seri') { if ($backup != serialize($data)) { file_put_contents2($file, serialize($data)); return true; } } return false; }
public function performScanning() { global $php_errormsg; $dirs = '.'; if (file_exists($this->DIRLIST_TMP_FILENAME)) { $dirs = file_get_contents($this->DIRLIST_TMP_FILENAME); } $dirList = explode("\n", $dirs); $startTime = time(); while (true) { $dirList = array_merge($this->folderWalker(array_shift($dirList), $this->filesFound), $dirList); $currentTime = time(); if ($currentTime - $startTime >= $this->MAX_EXECUTION_DURATION || count($dirList) < 1) { break; } } $result = $this->finalizeRound(); if (!$this->filesFound) { $response['meta'] = array('type' => 'getFileList', 'status' => 'finished', 'phpError' => $php_errormsg); $response['data'] = array(); $report = json_encode($response); return $report; } file_put_contents2($this->DIRLIST_TMP_FILENAME, implode("\n", $dirList)); return $result; }