3

I've script which is connecting to remote host via SSH, creates temporary file and executing the following command:

Calling system(mysql --database=information_schema --host=localhost < /tmp/drush_1JAjtt)

Each time it's creating different file (pattern: drush_xxxxxx).

I've tried couple of times manually running on the remote:

tail -f /tmp/drush_*

but my connection is too slow and most of the time I've end up with the error:

tail: cannot open `/tmp/drush_*' for reading: No such file or directory

Is there any trick accessing such file straight after it's being created to show it's content?

1

5 Answers 5

5

I've ran into this problem when examining behavior of a particular application I didn't trust. The application would create and later delete its temp files. kenorb's solution is good, however using cat can lead to race condition( that is a file may be removed while cat is working, so partial data only is retrieved).

A lower chance of race condition can be done with creating a hard-link to the file itself. greping and creating hard link can be combined via awk. Thus what I've came up with is the following;

inotifywait -e create -m --format "%w/%f" /tmp/suspicious_dir/ 2>&1 | 
awk 'NR>2{n=split($0,a,"/");system("ln "$0" /tmp/hardlink_to_"a[n]);}'

Since we're using -e create flag , we're only interested in temporary files that are going to be immediately created, and the output format gives us the full path to created temp file. Ignoring first two lines of output via NR>2. For every reported file, there will be created a hard link in form /tmp/hardlink_to_<original filename>

3
  • 1
    I love this idea! Especially since it preserves all data written to the file prior to deletion. (Unfortunately that means that if the program actually is malicious/dysfunctional and clears the contents of the file before deleting it, then you won't be able to retrieve the file contents very easily. Commented Sep 11, 2018 at 2:01
  • @NonnyMoose Very true. Well, this is the best I can come up with so far. Ideally, when you have access to the program you could either reverse engineer it, decompile, or run with debugger to see what actual data is being written, even strace. But for a non-security expert type of user this may be sufficient ( and for focus on attackers who assume file is gone after deleting original filename ) Commented Sep 11, 2018 at 3:39
  • On Unix if you have started cat on any file (temp or not) subsequently 'removing' it (really unlinking it) has no effect on the cat which still reads all the data -- unless some other process that (still) has it open does a truncate,. and in that case having a hardlink to it won't fare any better. Also awk system runs a fully-parsing shell so using possibly-malicious input allows unrestricted command injection under your id, even if you have otherwise restricted the suspect program. Commented May 14 at 2:48
2

You could set up a script that uses inotify (inotify-tools on Debian) and have it scan any changes of files in a particular directory. Then filter out the filename and cat it to a log file.

2

drush is likely using that temp file in one of two ways:

  1. It's creating the file; using it; and then leaving it around.
  2. It's creating the file; using it; and then cleaning it up.

My guess is that you wouldn't be asking the question in case (1) because you could just inspect the file manually after the fact. So then the problem is that you want to inspect that temporary file during its momentary lifespan.

Using an external process to monitor for temp files may have a good probability of working -- though it depends on how long the temp files endure (5ms? 500ms? 5s? 5min?) and how quick your monitoring system responds.

Another approach is to instrument the "mysql" command to log the data you're interested in. For example, if "mysql" is in "/usr/bin/mysql", then you might create a file "/usr/local/bin/mysql" with:

#!/bin/bash
LOG=/tmp/mysql-commands
REALCMD=/usr/bin/mysql

NOW=$(date)
echo "[[$NOW: Running: $REALCMD $@]]" >> "$LOG"
tee -a "$LOG" | "$REALCMD" "$@"
exit $?
2

If the file is created for enough short amount of time, you can run the following command on separate terminal before running the script:

while true; do cat /tmp/drush_* 2>/dev/null && break; done

Where /tmp/drush_* is your pattern. The advantage is that it's quick and you don't have to install any external tools (if you don't have e.g. admin/root permissions).

Please note that using inotifywatch (from inotify-tools) tool won't work in this particular case, because the file is created after the watches have been placed and the change will not be detected. Read more: Why inotify doesn't print list of changed files?

But still you can use inotifywait tool which efficiently waits for changes to files using Linux's inotify interface.

Here is the simple example:

inotifywait -m --format "%e %f" /tmp

And example to show the content of newly created files in /tmp:

inotifywait -m --format "%f" /tmp | grep --line-buffered ^drush | xargs -L1 -I% cat /tmp/% 2> /dev/null

Add sudo before cat if necessary. Change /tmp and drush to your suitable values.

0

You can hijack unlink system call with LD_PRELOAD.

// https://serverfault.com/questions/75927/blocking-rm-rf-for-application
// gcc unlink.c --shared -o unlink.so
//
// LD_PRELOAD=./unlink.so rm foo
int unlink(const char *pathname) {
     return 0;
}

int unlinkat(int dirfd, const char *pathname, int flags) {
     return 0;
}

You must log in to answer this question.

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