ARM64 Linux Security Toolkit

Auris

Auris (Latin for "ear") is a security toolkit that intercepts every system call a process makes on ARM64 Linux. It uses the kernel's ptrace interface to attach to processes, monitor their behavior, and optionally modify their execution.

Version 2.0 introduces dual-purpose capabilities: defensive operations for behavioral analysis and policy enforcement, plus offensive operations for penetration testing and security research.

Blue Team

Defensive Operations

Trace syscalls, build behavioral profiles, detect anomalies, enforce security policies. Understand what normal looks like, then catch deviations.

learn · profile · compare · policy · enforce
Red Team

Offensive Operations

Inject shellcode, find ROP gadgets, manipulate process memory. The same ptrace infrastructure that enables monitoring also enables exploitation.

inject list · shellcode · gadgets · dump

How It Works

The ptrace System Call

Auris is built on ptrace(), a Linux system call that allows one process (the tracer) to observe and control another process (the tracee). This is the same mechanism used by debuggers like GDB. When Auris attaches to a process, the kernel stops the tracee before and after every system call, allowing Auris to inspect registers, read memory, and even modify the process state.

ARM64 Register Convention

On ARM64 (AArch64) Linux, system calls follow a specific register convention:

  • x8 contains the syscall number (e.g., 221 for execve)
  • x0-x5 contain up to 6 arguments
  • x0 contains the return value after the syscall completes
// Core tracing loop in Auris
while (1) {
    // Wait for tracee to stop at syscall entry/exit
    waitpid(pid, &status, 0);
    
    // Read all registers using GETREGSET
    struct iovec iov = { .iov_base = &regs, .iov_len = sizeof(regs) };
    ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &iov);
    
    // Extract syscall information
    uint64_t syscall_nr = regs.regs[8];   // x8 = syscall number
    uint64_t arg0 = regs.regs[0];         // x0 = first argument
    uint64_t arg1 = regs.regs[1];         // x1 = second argument
    
    // Record, analyze, block, or inject...
    
    // Continue to next syscall
    ptrace(PTRACE_SYSCALL, pid, NULL, NULL);
}

Capabilities Required

To use ptrace, you need appropriate permissions. The Linux kernel's Yama security module controls ptrace access through /proc/sys/kernel/yama/ptrace_scope:

  • 0: Any process can ptrace any other process owned by the same user
  • 1: Only parent processes can ptrace their children (default on most systems)
  • 2: Only processes with CAP_SYS_PTRACE can use ptrace
  • 3: No process can use ptrace

Auris typically requires running as root or with CAP_SYS_PTRACE capability. In Docker, use --cap-add=SYS_PTRACE.

Defense

Command: learn

The learn command traces a program's execution and records every system call it makes. This creates a trace file containing the complete syscall history, including syscall numbers, arguments, return values, and timing information.

Usage: auris learn [options] -- program [args...]

What it captures:

  • Every syscall number and its human-readable name (e.g., openat, read, write, mmap)
  • All syscall arguments, with special handling for file paths, flags, and pointers
  • Return values and error codes
  • Timestamps for performance analysis
  • Process metadata: PID, binary path, SHA256 hash of the executable
behavioral profiling
$

Command: profile

The profile command analyzes a trace and builds a statistical behavioral profile. This profile captures the "fingerprint" of normal program behavior.

Usage: auris profile -t trace-id

Profile contents:

  • Syscall histogram: Which syscalls were used and how often
  • Shannon entropy: A measure of behavioral diversity (higher = more varied behavior)
  • File access patterns: Which files were opened, read, or written
  • Network behavior: Whether the program used sockets, connected to networks
  • Process spawning: Whether the program created child processes
  • Sensitive file access: Access to credentials, keys, or config files

Command: compare

The compare command runs a program while comparing its behavior against a baseline profile. It calculates a similarity score and flags any deviations.

Usage: auris compare -p profile-id -- program [args...]

What it detects:

  • New syscalls: Syscalls that were never seen in the baseline
  • Missing syscalls: Expected syscalls that did not occur
  • Frequency anomalies: Syscalls occurring much more or less than expected
  • New file access: Files accessed that were not in the baseline
  • Network activity: Network operations when baseline had none
anomaly detection
$

Commands: policy and enforce

The policy command generates a security policy from a behavioral profile. The enforce command then runs a program under that policy, blocking or alerting on violations.

Usage:

  • auris policy -p profile-id - Generate policy from profile
  • auris enforce -P policy-id -m alert -- program - Log violations
  • auris enforce -P policy-id -m block -- program - Block and terminate on violation

Enforcement modes:

  • alert: Log violations but allow the program to continue. Useful for testing policies before enforcement.
  • block: When a violation occurs, the syscall is blocked (by setting x8 to -1) and the process is terminated with SIGKILL.
policy enforcement
$
Offense

Process Injection Framework

Warning: For authorized security research and penetration testing only. Unauthorized use against systems you do not own or have explicit permission to test is illegal and may result in criminal prosecution.

The same ptrace mechanism that allows Auris to observe syscalls also enables it to modify process state. By writing to process memory and changing register values, Auris can inject and execute arbitrary code in a running process.

How injection works:

  1. Attach to the target process using PTRACE_ATTACH
  2. Wait for the process to stop (it receives SIGSTOP)
  3. Save the current register state using PTRACE_GETREGSET
  4. Save the original code at the injection point using PTRACE_PEEKDATA
  5. Write shellcode to executable memory using PTRACE_POKEDATA
  6. Set the program counter (PC) to point to the shellcode
  7. Continue execution with PTRACE_CONT
  8. Optionally restore original state after shellcode completes
target discovery
$

Command: inject shellcode

The inject shellcode command injects pre-built ARM64 shellcode into a target process and executes it.

Usage: auris inject shellcode -p PID -t TYPE [options]

Available shellcode types:

  • exec_sh - Execute /bin/sh, spawning a shell in the target process context
  • reverse -i IP -P PORT - Connect back to attacker machine and spawn shell
  • bind -P PORT - Listen on a port and spawn shell when connection received
  • exec_cmd -c "command" - Execute an arbitrary command
shellcode injection
$

Command: inject gadgets

The inject gadgets command scans ELF binaries to find ROP (Return-Oriented Programming) gadgets. ROP is a technique used when DEP/NX prevents direct code injection by chaining together existing code snippets that end in RET instructions.

Usage: auris inject gadgets -b /path/to/binary

Gadget types found:

  • RET gadgets: Simple return instructions for chaining
  • Load gadgets: Instructions that load registers from the stack (e.g., ldr x0, [sp, #8])
  • Syscall gadgets: Instructions containing svc #0 for making system calls
  • Stack pivot gadgets: Instructions that modify SP for stack manipulation

On ARM64, a typical ROP chain to call execve("/bin/sh", NULL, NULL) would: load x0 with pointer to "/bin/sh", set x1 and x2 to NULL, set x8 to 221 (execve syscall number), then execute svc #0.

rop gadgets
$

Command: inject dump

The inject dump command reads memory from a target process and displays it in hexdump format.

Usage: auris inject dump -p PID -a ADDRESS -n LENGTH

Use cases:

  • Analyze memory layout before injection to find suitable injection points
  • Extract runtime data, secrets, or encryption keys from process memory
  • Verify shellcode was written correctly
  • Forensic analysis of running processes
  • Debugging and reverse engineering
memory dump
$

Installation and Setup

System Requirements

  • Architecture: ARM64 (AArch64) only. Auris uses ARM64-specific register layouts and syscall conventions.
  • Operating System: Linux kernel 4.8 or later (for PTRACE_GETREGSET support)
  • Permissions: Root access or CAP_SYS_PTRACE capability
  • Dependencies: libcurl, openssl, json-c (for AI integration features)

Option 1: Docker (Recommended)

Docker is the easiest way to run Auris, especially on machines that are not natively ARM64. Docker Desktop on Apple Silicon Macs or any ARM64 Linux host works out of the box.

# Clone the repository
git clone https://github.com/kuladeepmantri/Auris.git
cd Auris

# Build the Docker image
docker build --platform linux/arm64 -t auris .

# Run with required capabilities
docker run --platform linux/arm64 \
  --cap-add=SYS_PTRACE \
  --security-opt seccomp=unconfined \
  -it auris

# You are now inside the container
./build/auris version
./build/auris help

Important Docker flags explained:

  • --platform linux/arm64 - Ensures ARM64 emulation if not on native ARM64
  • --cap-add=SYS_PTRACE - Grants the ptrace capability required for tracing
  • --security-opt seccomp=unconfined - Disables seccomp filtering that would block ptrace

Option 2: Native Build on ARM64 Linux

For native ARM64 Linux systems (Raspberry Pi 4/5, AWS Graviton, Apple Silicon with Linux VM, etc.):

# Install build dependencies (Debian/Ubuntu)
sudo apt update
sudo apt install -y build-essential cmake pkg-config \
  libcurl4-openssl-dev libssl-dev libjson-c-dev

# Clone and build
git clone https://github.com/kuladeepmantri/Auris.git
cd Auris
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make -j$(nproc)

# Verify the build
./auris version

# Run with sudo (or set CAP_SYS_PTRACE)
sudo ./auris learn -- /bin/ls -la

Data Directory

Auris stores traces, profiles, and policies in a data directory. By default, this is /data/auris in Docker or ~/.auris on native installs. You can override this with the -d flag:

# Use custom data directory
auris -d /path/to/data learn -- /bin/ls

# Directory structure
/data/auris/
  traces/      # JSON trace files
  profiles/    # Behavioral profiles
  policies/    # Security policies

Quick Start Examples

Example 1: Trace a program and build a profile

# Step 1: Learn the program's behavior
auris learn -- /usr/bin/curl https://example.com
# Output: Trace ID: abc123

# Step 2: Build a behavioral profile
auris profile -t abc123
# Output: Profile ID: def456

# Step 3: Compare future executions
auris compare -p def456 -- /usr/bin/curl https://example.com

Example 2: Create and enforce a security policy

# Generate policy from profile
auris policy -p def456
# Output: Policy ID: ghi789

# Test policy in alert mode (logs violations but allows execution)
auris enforce -P ghi789 -m alert -- ./my_program

# Enforce policy in block mode (terminates on violation)
auris enforce -P ghi789 -m block -- ./untrusted_program

Example 3: Offensive operations (authorized testing only)

# List injectable processes
auris inject list

# Get info about a specific process
auris inject info -p 1234

# View process memory maps
auris inject maps -p 1234

# Inject shellcode (spawns /bin/sh in target)
auris inject shellcode -p 1234 -t exec_sh

# Find ROP gadgets in libc
auris inject gadgets -b /lib/aarch64-linux-gnu/libc.so.6

# Dump process memory
auris inject dump -p 1234 -a 0x400000 -n 256

Command Reference

auris <command> [options] [-- program [args...]]

Commands:
  learn       Trace a program and record all syscalls
  profile     Build behavioral profile from a trace
  compare     Compare execution against baseline profile
  policy      Generate security policy from profile
  enforce     Run program under policy enforcement
  analyze     Send profile to AI for analysis
  inject      Process injection framework (offensive)
  help        Show help message
  version     Show version information

Global Options:
  -h, --help            Show help
  -V, --version         Show version
  -v, --verbose         Verbose output
  -q, --quiet           Quiet mode
  -j, --json            JSON output format
  -d, --data-dir DIR    Data directory path
  -t, --trace-id ID     Trace ID to use
  -p, --profile-id ID   Profile ID to use
  -P, --policy-id ID    Policy ID to use

Inject Subcommands:
  inject list           List injectable processes
  inject info -p PID    Show process information
  inject maps -p PID    Show memory maps
  inject shellcode      Inject and execute shellcode
  inject gadgets        Find ROP gadgets in binary
  inject dump           Dump process memory