Hacktricks-skills apparmor-security
How to analyze, create, and test AppArmor security profiles on Linux systems. Use this skill whenever the user mentions AppArmor, Linux security profiles, Docker container security, mandatory access control (MAC), or needs to audit/modify program confinement policies. Also trigger when investigating privilege escalation paths, container escapes, or security hardening on Linux systems.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/linux-hardening/privilege-escalation/docker-security/apparmor/SKILL.MDAppArmor Security Analysis
A skill for analyzing, creating, and testing AppArmor security profiles on Linux systems.
What is AppArmor
AppArmor is a kernel enhancement that restricts program resources through per-program profiles, implementing Mandatory Access Control (MAC) by tying access control attributes directly to programs instead of users.
Key concepts:
- Profiles are loaded into the kernel (usually at boot)
- Profiles dictate what resources a program can access (network, files, sockets)
- Two modes: Enforcement (blocks violations) and Complain (logs violations only)
Quick Status Check
Start by checking what's currently confined:
sudo aa-status
This shows:
- How many profiles are loaded
- Which are in enforce mode vs complain mode
- Which binaries are restricted
Profile naming convention: Replace
/ with . in the binary path to find the profile file.
- Binary:
→ Profile:/usr/bin/man/etc/apparmor.d/usr.bin.man
Core Commands
Status and Mode Management
aa-status # Check current status aa-enforce <profile> # Set profile to enforce mode aa-complain <profile> # Set profile to complain mode
Profile Management
apparmor_parser -a <profile> # Load profile in enforce mode apparmor_parser -C <profile> # Load profile in complain mode apparmor_parser -r <profile> # Replace existing profile apparmor_parser -R <profile> # Remove profile
Profile Creation Tools
aa-genprof <binary> # Interactive profile generation (inspect binary actions) aa-easyprof <binary> # Create template profile aa-logprof # Review logs and permit detected violations aa-mergeprof # Merge policies
Creating Profiles
Method 1: Interactive Generation (aa-genprof)
This is the most thorough approach - AppArmor inspects actual binary behavior:
-
Start the generator:
sudo aa-genprof /path/to/binary -
In a separate terminal, run the binary with typical operations:
/path/to/binary -a dosomething -
Return to the generator terminal:
- Press
to review recorded actionss - Use arrow keys to select: allow, deny, or ignore each action
- Press
when finished to create the profilef
- Press
The profile is saved to
/etc/apparmor.d/path.to.binary
Method 2: Template Creation (aa-easyprof)
Quick template generation:
sudo aa-easyprof /path/to/binary
This creates a basic profile structure. Important: By default, nothing is allowed - you must explicitly add permissions:
"/path/to/binary" { #include <abstractions/base> /etc/passwd r, # Allow reading /etc/passwd /var/log/myapp.log w, # Allow writing to log file /usr/bin/helper ix, # Allow executing helper program }
Access Control Modifiers
| Modifier | Meaning |
|---|---|
| Read |
| Write |
| Memory map as executable |
| File locking |
| Create hard links |
| Execute with policy inheritance |
| Execute under another profile (cleaned env) |
| Execute under child profile (cleaned env) |
| Execute unconfined (cleaned env) |
Profile Variables
Use variables for flexibility:
#include <tunables/global> "/path/to/binary" { @{HOME}/** r, # Read from user's home directory @{PROC}/** r, # Read from /proc }
Analyzing Logs
Audit Log Format
AppArmor violations appear in
/var/log/audit/audit.log:
type=AVC msg=audit(1610061880.392:287): apparmor="DENIED" \ operation="open" profile="/bin/rcat" name="/etc/hosts" \ pid=954 comm="service_bin" requested_mask="r" denied_mask="r"
Key fields:
: What action was attempted (open, getattr, etc.)operation
: Which AppArmor profile was activeprofile
: Resource that was accessedname
: What access was requested (r=read, w=write, etc.)requested_mask
: What was actually denieddenied_mask
Interactive Log Review
sudo aa-notify -s 1 -v
Shows recent denials in a readable format:
Profile: /bin/service_bin Operation: open Name: /etc/passwd Denied: r Logfile: /var/log/audit/audit.log
AppArmor in Docker
Default Docker Profile
Docker uses
docker-default profile by default. Key restrictions:
- ✅ Allowed: All networking access
- ❌ Denied: Writing to
files/proc - ❌ Denied: Access to
and/proc
subdirectories/sys - ❌ Denied: Mount operations
- ⚠️ Limited: Ptrace only on processes with same profile
Important: AppArmor blocks capabilities even if granted. Example:
# This fails - AppArmor blocks /proc write even with SYS_ADMIN docker run -it --cap-add SYS_ADMIN ubuntu /bin/bash echo "" > /proc/stat # sh: 1: cannot create /proc/stat: Permission denied
Running with Custom Profile
docker run --rm -it --security-opt apparmor:myprofile ubuntu /bin/bash
Disabling AppArmor
docker run --rm -it --security-opt apparmor=unconfined ubuntu /bin/bash
Finding Container's Profile
# Check which profile a container uses docker inspect <container_id> | grep AppArmorProfile # Find the profile file find /etc/apparmor.d/ -name "*<profile_name>*" -maxdepth 1 2>/dev/null
Security Testing Considerations
Common Bypass Patterns
1. Path-based bypass: AppArmor is path-based. If
/proc is protected but /host/proc is not:
# Mount host /proc to different path docker run -v /proc:/host/proc ubuntu /bin/bash # /host/proc may not be protected
2. Shebang bypass: Scripts with shebangs may execute under different profiles:
#!/usr/bin/perl use POSIX qw(setuid); POSIX::setuid(0); exec "/bin/sh"
If you execute this script directly, it may run under the shell's profile, not perl's.
3. Profile modification: If you can modify and reload a profile:
# Edit profile to remove restrictions sudo vim /etc/apparmor.d/docker-default # Reload the modified profile sudo apparmor_parser -r /etc/apparmor.d/docker-default
When Exploits Fail
If you have a privileged capability inside Docker but an exploit isn't working, AppArmor is likely blocking it. Check:
sudo aa-status | grep docker
Workflow Checklist
When analyzing AppArmor on a system:
- Check status:
sudo aa-status - Identify target binary's profile: Find in
/etc/apparmor.d/ - Review profile contents:
cat /etc/apparmor.d/<profile> - Check for denials:
sudo aa-notify -s 1 -v - Test in complain mode:
(if you have access)sudo aa-complain <profile> - Review audit logs:
grep apparmor /var/log/audit/audit.log
Troubleshooting
Profile not loading:
# Check for syntax errors sudo apparmor_parser -C /etc/apparmor.d/<profile>
Binary not confined:
# Verify profile is loaded sudo aa-status | grep <binary_name> # Check if profile is in complain mode (won't block)
Need to debug:
# Switch to complain mode to see what would be blocked sudo aa-complain <profile> # Run the binary # Check logs sudo aa-notify -s 1 -v # Switch back to enforce sudo aa-enforce <profile>