A file that is not what it says
A suspicious file is one that is in the wrong place, has the wrong owner, or is not the kind of file its name claims. A suspicious process is a running program that nobody can explain.
You find them by comparing what exists with what should exist. You also look at the first bytes of a file, instead of trusting its name.
By the end of this lesson
Note
I can find a suspicious file by its place, its owner and its first bytes.
Key words
| Word | What it means | Example |
|---|---|---|
| Process | a program that is running now | |
| File signature | the first bytes of a file, which show its type | |
| Hexadecimal | numbers written with 0 to 9 and a to f | 7f |
| Hex dump | the bytes of a file shown in hexadecimal | |
| Disguised file | a file whose name hides its real type | |
| Carving | finding files inside raw data by their signatures |
The cells students fill in are left blank in this preview.
A process list shows what is running now
Every running program is a process. It has a number, called its PID, an owner and a name. The command ps lists them.
A process list is a snapshot, so it is volatile. When you can, save it before you do anything else. Then ask of each process: whose is it, and do I know why it runs?
An example process list (invented)
USER PID COMMAND
root 1 systemd
root 612 sshd
www-data 845 nginx
sam 2301 bash
sam 2377 updater-helper
The first process on this machine
ps -p 1 -o comm=Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Check a file's place and its owner
System folders such as /usr/bin are filled by the system and owned by root. A new file there, owned by an ordinary user, is odd.
So you ask three questions of every file. Is its place sensible? Is its owner sensible? Is its time sensible?
Worked example: three questions about a file
| File | Place | Owner | Time | Verdict |
|---|---|---|---|---|
| /usr/bin/grep | System folder | root | With the install | Normal |
| /tmp/.cache-x | Temporary folder | sam | Last night | Look closer |
| /usr/bin/lsof2 | System folder | sam | Last night | Very odd |
The cells students fill in are left blank in this preview.
How many system programs does the list hold?
grep -c "/usr/bin/" case/mtimes.txtShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Any owned by someone other than root?
awk '$4 ~ "^/usr/bin/" && $3 != "root"' case/mtimes.txt | wc -lShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
First bytes show what a file is
Most file types begin with a fixed pattern of bytes, called a file signature. A program for Linux starts with 7f 45 4c 46. A PNG picture starts with 89 50 4e 47.
A name is only text, and anyone can change it. The signature is part of the content, so it is much harder to fake without breaking the file.
Some common file signatures
| Type | First bytes in hexadecimal | In letters |
|---|---|---|
| Linux program (ELF) | 7f 45 4c 46 | DEL E L F |
| PNG picture | 89 50 4e 47 | PNG after a marker byte |
| PDF document | 25 50 44 46 | |
| ZIP archive | 50 4b 03 04 | PK and two marks |
| Shell script | 23 21 | #! |
The cells students fill in are left blank in this preview.
The first four bytes of a real program
head -c 4 /bin/ls | od -An -tx1Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
The start of a picture, made by hand
printf '\x89PNG' | od -An -tx1Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
The first eight bytes of a text file
head -c 8 case/etc/passwd | od -An -tx1Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
A common mistake
Warning
Many people think the ending of a name, such as .png or .txt, tells them what a file is. It is only text, and anybody can rename a file. Read the first bytes and compare them with the signature table before you trust a name.
Carving finds files in raw data
Sometimes a file is deleted, or the file system is damaged, and only raw bytes are left. Carving scans those bytes for a signature and treats each match as the start of a file.
In a hex string every byte is two characters, so a match must start at an even position. Divide the position by two to get the byte number.
Find a signature in raw bytes
# Hexadecimal text: every two characters are one byte.
data = "000000504b0304aabb"
signature = "504b0304"
place = data.find(signature)
print("hex position", place)
print("byte number", place // 2)
# Change data so the signature starts later, then press Run.