0

I want to monitor/keep track of all the files uploaded using web server (mainly using PHP/Apache and NOT using FTP server).

I Googled and found that, only possible way could be writing a hook for move_uploaded_file in PHP.

If we can write a hook function for move_uploaded_file in PHP, then we can save the destination file path in one location. But, there is no solution I could find to achieve the same.

can someone suggest me a way to do it ?

Edit: The web server has 100s of hosting account and 1000s of website, so controlling them using web application is not possible, As we do not have control over the web application.

1
  • I am still trying to find a solution to this problem. I think, It can be done using the following example. <?php rename_function('strlen', 'new_strlen'); override_function('strlen', '$string', 'return override_strlen($string);'); function override_strlen($string) { echo "Inside function" ; return new_strlen($string); } echo "Length" . strlen ("Mani") ; ?>
    – Mani
    Nov 3, 2016 at 11:54

4 Answers 4

1

You can use the command inotifywatch (inside inotify-tools package on Debian) with the -r (recursive) parameter

e.g.:

inotifywatch -q -e moved_to,create -r /var/www/
1

I want to monitor/keep track of all the files uploaded using web server (mainly using PHP/Apache

There is no easy way. You can find all files using the move_uploaded_file function, but this will only intercept POST file uploads. AJAX uploads such as HTML5/PLupload will not be recognized.

The question is, why do you want to track "all uploaded files"? Since you don't even know what those files are nor where they are, there seems to be little point in knowing the file names, sizes, and ownerships - which is all you're going to be able to get.

If you're trying to intercept alterations to the system, e.g. web attacks, then you'd be much better served by tripwire, and/or some log scanning utility, or possibly Snort, or specialized security packages (e.g. for Wordpress). Or you might be interested in famd, or decide to be proactive and deploy (and configure, and maintain) AppArmor.

If it is accountability you're after, you will need to modify the upload scripts no matter what. And you'll need to do that on a script-by-script basis if you're running several different upload frameworks.

If you want to track traffic or quotas, there are much better ways.

But basically, you should not have to worry about files uploaded on your hosted web sites, unless you have other problems upstream. Worrying about file uploads makes me suspect yours, as stated, is a XY problem.

If you're still of the idea of monitoring files created (as stated before, uploaded is too restrictive), possibly the simplest way is to set up a strace process, but it depends now on how PHP is called - is it an Apache module, or CGI, or FPM? For the Apache module, assuming the binary is called httpd:

strace -f -p "$( pidof httpd )" -e open 2>&1 | grep -F -v ', O_RDONLY'

will get you something like,

[pid 28882] open("/var/lib/php5/sess_8v107eun48rj0u42uf9ncplrbobj4cqackscb2thx1138k78uk01", O_RDWR|O_CREAT, 0600) = 12
[pid 29739] open("/var/lib/php5/sess_8v107eun48rj0u42uf9ncplrbobj4cqackscb2thx1138k78uk01", O_RDWR|O_CREAT, 0600) = 12
[pid 28882] open("/srv/www/wiki.matrix.boa/data/boawiki.sqlite", O_RDWR|O_CREAT|O_CLOEXEC, 0644) = 13
[pid 29739] open("/srv/www/wiki.matrix.boa/data/boawiki.sqlite", O_RDWR|O_CREAT|O_CLOEXEC, 0644) = 13
0
1

Point checks

both snapshots and rsync --dry-run are incredibly fast because they only make / check inodes no actual data. Snapshots require a cow fs like zfs or btrfs.

btrfs subvolume snapshot -r / /snapshots/$(date +%Y%m%d)
rsync -ad --dry-run /var/www /snapshots/20161103/var/www

Instant events

strace

strace and grep can be used to log every file php changes;

strace -e open php_pid 2>&1 | grep open >> log.txt

inotify

inotify is nice but may be heavy because it adds a watch for each folder.

inotifywatch -v -e modify,moved_to,create -r /var/www/

PHP

The combination of php.ini, runkit, override and auto-prepend-file can be used to log file events but it can't stop people from intentionally avoiding the log. You would want to disable exec, and hope no one finds the renamed function;

php.ini:

disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source
runkit.internal_override = On
auto_prepend_file = /var/www/html/prepend.php

prepend.php

rename_function('move_uploaded_file', 'real_move_uploaded_file');
override_function('move_uploaded_file', '$filename,$destination', 'log ( $filename, $destination ) ; return real_move_uploaded_file ( $filename, $destination );');
rename_function("__overridden__", 'dummy_move_uploaded_file');

C

As php is FLOSS you could compile your own customized PHP but that's not advisable before making absolutely sure all other listed options are unsuitable.

8
  • +1 for mentioning inotify and rsync. :) Nov 3, 2016 at 14:35
  • This can not be accepted as a solution, Bcoz, I have around 2 TB of data in /var/www and more over, 1000s of files will be modified per second. So this does not help. but, Thank you for your help. :-)
    – Mani
    Nov 4, 2016 at 5:50
  • @user1133275, basically it is a shared hosting server, We have about 1000s of accounts and each account has avg 200K files. Apart from files uploaded via CGI(Web PHP), most of the files are uploaded using FTP and cPanel and additionally 1000s of files are created per minutes using web apps. So, picking up only the files uploaded via web is a tedious task in the above mentioned way. More over, We have to look for efficient way too, the above mentioned method will not be ok for production.
    – Mani
    Nov 5, 2016 at 5:06
  • 1
    @Mani, the fact of 2 TB of data and 1000s of modified files per second is very relevant and you should edit your question to include that info. What sort of "monitoring" do you want for that kind of volume? What's the purpose of monitoring the changes?
    – Wildcard
    Nov 5, 2016 at 16:14
  • @user1133275, thank you, let me try it.
    – Mani
    Nov 7, 2016 at 5:35
0

logstash / elk / kibabna...

I'm pretty sure you'd be able to magic up some regex out of the log files...

you'd be able to check for php uploads, webdav uploads, then combine this info with maps, times and so on...

elegance in simplicity... (there was no mention of a need for live processing in the question posted, so i'm assuming you don't need to run any scripts each time a file is uploaded? you just want to monitor and keep a log?)

if i assume wrong, then +1 on inotify

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .