strace is your forensic microscope for Linux, revealing the syscalls a process makes. The surprising truth is that strace itself is often part of the malware’s toolkit, used to analyze other malware.

Let’s see it in action. Imagine you’ve got a suspicious process, evil_daemon (PID 12345), running. You want to know what it’s up to.

strace -p 12345 -s 1024 -f -o /tmp/evil_daemon.strace

This command attaches strace to the running process 12345, captures up to 1024 bytes for each string argument (-s 1024), follows any child processes (-f), and dumps the entire trace to /tmp/evil_daemon.strace.

Now, let’s analyze the output. A typical strace output looks like this:

...
openat(AT_FDCWD, "/etc/passwd", O_RDONLY) = 3
read(3, "root:x:0:0:root:/root:/bin/bash\n"..., 4096) = 1234
close(3)                                  = 0
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) = 4
connect(4, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("192.168.1.100")}, 16) = 0
write(4, "GET / HTTP/1.1\r\nHost: 192.168.1.100\r\nUser-Agent: evil_agent\r\n\r\n", 78) = 78
...

Here’s what’s happening:

  • openat(AT_FDCWD, "/etc/passwd", O_RDONLY) = 3: The process is opening the /etc/passwd file for reading. File descriptor 3 is assigned to it. This is common for many legitimate processes, but malware might be looking for user credentials.
  • read(3, "root:x:0:0:root:/root:/bin/bash\n"..., 4096) = 1234: It’s reading data from the file descriptor 3 (which we know is /etc/passwd). The 1234 indicates the number of bytes read.
  • close(3) = 0: The file descriptor is closed.
  • socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) = 4: A new TCP socket is created, assigned file descriptor 4. This is the first step in network communication.
  • connect(4, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("192.168.1.100")}, 16) = 0: The process is attempting to connect to IP address 192.168.1.100 on port 80 (HTTP). A successful connection returns 0.
  • write(4, "GET / HTTP/1.1\r\nHost: 192.168.1.100\r\nUser-Agent: evil_agent\r\n\r\n", 78) = 78: The process sends an HTTP GET request over the socket. The User-Agent: evil_agent is a potential indicator of malicious activity.

The Mental Model:

strace works by leveraging the ptrace system call. When you use strace, it intercepts the target process’s execution at the kernel level. Before any syscall the target process intends to make is executed, the kernel notifies strace. strace then has a chance to examine the syscall arguments, modify them, or even prevent the syscall from running. After the syscall completes, strace can examine its return value. This allows strace to effectively "watch" every interaction the process has with the operating system.

The problem strace solves is visibility. When a process is a black box, you don’t know if it’s reading sensitive files, making outbound network connections to suspicious IPs, or executing other commands. strace lifts the lid.

The levers you control are primarily the options passed to strace:

  • -p PID: Attach to a specific process ID. Essential for live analysis.
  • -o filename: Redirect output to a file. Crucial for long-running processes or when you need to analyze the trace later.
  • -s size: Control the maximum string length to display. Default is often too short for URLs or file paths.
  • -f: Follow child processes. Malware often forks or execs other malicious binaries.
  • -e trace=syscall_set: Filter by specific syscalls. For example, -e trace=network to see only network-related calls, or -e trace=open,read,write to focus on file I/O. This is powerful for narrowing down noisy output.
  • -e signal=signal_set: Trace specific signals.
  • -t, -tt, -ttt: Add timestamps to the output. -ttt provides microsecond precision, invaluable for correlating events.

A common trap is assuming that a syscall appearing in strace output is directly executed by the process. In reality, strace might be tracing a library call that internally makes one or more syscalls. For instance, a printf call might trigger write syscalls to output to stdout or a terminal. You’re seeing the syscalls, but the intent of the process is often at a higher level of abstraction.

The next concept you’ll run into is understanding how to interpret the absence of certain syscalls. If a process is supposed to be performing a specific network operation but you don’t see any socket, connect, or sendto calls in its strace output, that’s a significant anomaly.

Want structured learning?

Take the full Strace course →