linux-malware-detect
linux-malware-detect copied to clipboard
Maldet is unable to find files with newline characters in their filenames
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
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 -
- If the line contains a file name, pass it on to be output to $find_results. If not...
- 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?