rfxn / linux-malware-detect

Linux Malware Detection (LMD)
http://www.rfxn.com/projects/linux-malware-detect/
GNU General Public License v2.0
1.18k stars 228 forks source link

Maldet is unable to find files with newline characters in their filenames #301

Open sporks5000 opened 6 years ago

sporks5000 commented 6 years ago

Steps to reproduce the issue: Here's a directory that contains one file:

[root@host /home/sporks50/test]# ls -A /home/sporks50/test
r57.php

Let's scan that directory!

[root@host /home/sporks50/test]# maldet -a /home/sporks50/test | egrep "scan report saved"
maldet(32300): {scan} scan report saved, to view run: maldet --report 180902-0050.32300

And then view the results:

[root@host /home/sporks50/test]# cat /usr/local/maldetect/sess/session.hits.180902-0050.32300
{CAV}Legacy.Trojan.Agent-37006 : /home/sporks50/test/r57.php

It looks like the file is malicious!

Now let's make a copy of that file but with a newline character in the name:

[root@host /home/sporks50/test]# cp -av r57.php 'r57'$'\n''.php'
`r57.php' -> `r57\n.php'

Scan the directory and view the results again, but it still only finds the one file:

[root@host /home/sporks50/test]# maldet -a /home/sporks50/test | egrep "scan report saved"
maldet(38015): {scan} scan report saved, to view run: maldet --report 180902-0055.38015
[root@host /home/sporks50/test]# cat /usr/local/maldetect/sess/session.hits.180902-0055.38015
{CAV}Legacy.Trojan.Agent-37006 : /home/sporks50/test/r57.php

The reason for this appears to be because the "find" command represents the newline character as a question mark:

[root@host /home/sporks50/test]# find . -type f
./r57.php
./r57?.php

It seems to do this with a lot of special charaters:

[root@host /home/sporks50/test]# cp -av r57.php '123'$'\e'$'\b'$'\a''456.php'
`r57.php' -> `123\033\b\a456.php'
[root@host /home/sporks50/test]# find . -type f
./r57.php
./123???456.php
./r57?.php

And clamscan isn't compatible with the -print0 formatting from find:

[root@host /home/sporks50/test]# find . -type f -print0 > /home/sporks50/temp.txt
[root@host /home/sporks50/test]# clamscan -if /home/sporks50/temp.txt
./r57.php: Legacy.Trojan.Agent-37006 FOUND
.php: No such file or directory
WARNING: .php: Can't access file

Though if you tell it to scan the file directly, it detects the issue right away:

[root@host /home/sporks50/test]# clamscan -i 'r57'$'\n''.php'
r57
.php: Legacy.Trojan.Agent-37006 FOUND

Unfortunately I don't think that this is an issue that can be resolved without changing the functionality of either "clamscan" or "find".

That being said, it's almost unheard of to encounter any instances where a legitimate file contains one of those characters. Usually identifying the fact that they are present is enough. My solution has been something like this: https://sporks5000.com/scripts/find.pl

sporks5000 commented 6 years ago

Partial Solution:

Currently the find command is followed by this piping and redirection:

 2> /dev/null | grep -E -vf $ignore_paths > $find_results

We could change that to:

2> /dev/null | grep -E -vf $ignore_paths | trouble_characters > $find_results

and then create the following function

trouble_characters() {
    local line
    while read line; do
        if [[ -f "$line" ]]; then
            echo "$line"
        else
            local line2="${line// /\\ }"
            line2="${line2//\*/\\*}"
            line2="${line2//$( printf '\t' )/\\$( printf '\t' )}"
            local isfile="$( ls -1 $line2 | wc -l )"
            if [[ "$isfile" -gt 0 ]]; then
                echo "$line" >> $some_other_temporary_file
            fi
        fi
    done
}

In short - 1) If the line contains a file name, pass it on to be output to $find_results. If not... 2) escape out spaces, tabs, and asterisks, but leave question marks for globbing purposes. If that matches a file, print the line to... somewhere else.

Then at the end of the find, we have a list of the files with filenames that contain these characters. It won't represent the ACTUAL file names, but maybe we could figure out something to do with these from here?