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


Linux kernel setgid implementation flaw


<< Previous INDEX Search src Set bookmark Go to bookmark Next >>
Date: Fri, 19 Jul 2002 04:54:18 +0200
From: FozZy <fozzy@dmpfrance.com>
To: bugtraq@securityfocus.com
Subject: Linux kernel setgid implementation flaw

--Multipart_Fri__19_Jul_2002_04:54:18_+0200_00261000
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit

Hi,

I believe the following to be accurate and of some interest to bugtraq 
readers, although i did not have time to extensively test it, nor did i 
warn the vendor, since 1) this is at most a undirect risk - IMHO - and 2) i am 
going on holidays so i had to balance betweeen disclosing now and letting 
people think about it and patch it OR delaying publication and forgetting it 
for some months as usual ;) But as i said, it is only a subtle local flaw 
that, i think, do not have direct security consequences in most linux 
distributions. Unless someone see something i missed. Also, I apologise if
i am totally wrong here, no time to cross check it. 


OVERVIEW

On current stable linux systems the setgid system call does not behave 
correctly in certain conditions:
- Setgid-only programs cannot fully drop privileges.
- Programs with both setuid and setgid flags which call setuid(getuid) before 
setgid(getgid) do not fully drop privileges.

"priviledges are not fully dropped" means that the saved gid remains 0, 
although both gid, egid, fsgid, uid, euid, suid, and fsuid are set to 
the unprivileged user id.


CONSEQUENCES

A setuid or setgid program can wish to give up its privileges as soon as it 
does not need them anymore, if the program is written to minimise the 
impact of a vulnerability in the now unprivileged part of the code. Note that 
most linux set[ug]id progs seems to don't care too much about it. Surely in 
owl linux and such they care more (and in openbsd for sure, but...).
The problem is, if a vulnerability (like a buffer overflow) appears in an 
unprivileged part of the code, with current linux kernels the cracker will 
still be able to get group id 0 (from the saved gid) ! That is a good launch 
pad for gaining full root privileges.

Don't panic, the impact of this vulnerability is LOW in most (all ?) linux 
distributions:
- it is local only (well, unless you wrote a daemon that thinks it can drop
group privileges *after* doing the setuid(userid) ! And unless you have a
setgid daemon or network client program).
- it needs for a setgid or setuid program to have an exploitable 
vulnerability.
- it could be a serious vulnerability if security was not so low in current 
linux systems. Most set[ug]id programs do not even bother to give up their 
privileges, so locally exploiting them gives instant root.
- Programs which drop privileges before calling execve are not vulnerable 
since exceve reset the saved uid (at least it should: not tested).

However, if you can find on your system a program that relies too much on the
setgid behavior and gives full control to the user on the process, this problem
would become a very serious vulnerability. I did not find any program of this
type on my Mandrake systems.


DETAILS

I tested this with a 2.4.3 kernel, and the latest 2.4.18 with the (excellent) 
grsecurity patch. 

>From the setgid manpage (conforming to most unix systems if not all):

"If  the  user  is root or the program is setgid root, special care must be 
taken. The setgid function checks the effective gid of the caller  and  if
it is the superuser, all process related group ID's are set to gid.  After  
this has occurred, it is impossible for the program to regain root  privi╜
leges."

However: 

[fozzy@defcon10 fozzy]$ uname -a
Linux 2.4.18-grsec-1.9.4 #5 (...)
[fozzy@defcon10 fozzy]$ ls -l dg
-r-xr-sr-x    1 root     root        15525 jui 19 04:18 dg*
[fozzy@defcon10 fozzy]$ ./dg
uid=501, euid=501, gid=501, egid=0
--> suid=501 and sgid=0
Dropping privileges...
Privileges dropped : uid=501, euid=501, gid=501, egid=501
--> suid=501 and sgid=0
After trying to recover here is what we've got: uid=501, euid=501, gid=501, 
egid=0
/\/\/\/\

See the attached source code of the program.


IN-DEPTH DETAILS

Here is the interesting part of the advisory: WHY ?
Well, easy. Let's take a look at the main part of the setgid syscall:

------------------------
if (capable(CAP_SETGID))
        {
                if(old_egid != gid)
                        current->dumpable=0;
                current->gid = current->egid = current->sgid = current->fsgid 
= gid;
        }
else if ((gid == current->gid) || (gid == current->sgid))
        {
                if(old_egid != gid)
                        current->dumpable=0;
                current->egid = current->fsgid = gid;
        }
-----------------------

If the process do not have the CAP_SETGID capability, current->sgid  is 
never modified ! It will remain 0 no matter what you do (well, actually, a 
setregid will change the sgid, and a setresgid also, but everybody call the 
standard setgid).
This capability is set only if you are the superuser (unless you 
have set up a real capability-aware system of course). So it is not set when 
running setgid programs, and in setuid programs it is unset when you do a 
setuid(user).

As an untested 30 seconds-reflexion patch I would suggest editing the setgid 
syscall in kernel/sys.c like this (last line in the above source code):
 
439c439
<               current->egid = current->fsgid = gid;
---
>               current->egid = current->fsgid = current->sgid = gid;


CONCLUSION

See you in Marocco :)


FozZy
Hackademy & Hackerz Voice Director


--Multipart_Fri__19_Jul_2002_04:54:18_+0200_00261000
Content-Type: application/octet-stream;
 name="drop_gid.c"
Content-Disposition: attachment;
 filename="drop_gid.c"
Content-Transfer-Encoding: base64

LyogZHJvcF9naWQuYyAtIHNjYWxlZCBkb3duIHZlcnNpb24gb2YgbXkgW2V8ZnN8c3xdW3VnXWlk
IGJlaGF2aW9yIGNoZWNrZXIgKi8KLyogc3UgOyBnY2MgLW8gZGcgZHJvcF9naWQuYyA7IGNobW9k
IDI1NTUgZGcgOyBzdSB1c2VyIDsgLi9kZyAqLwovKiBUaGUgdGVzdCBpczogY2FuIHdlIHJlY292
ZXIgc29tZSBwcml2aWxlZ2VzIGFmdGVyIHNldGdpZCgpID8gKi8KIAojaW5jbHVkZSA8c3RkaW8u
aD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNkZWZpbmUgTElO
VVgKIAppbnQKbWFpbiAodm9pZCkgewogIHVpZF90IHVpZCwgZXVpZCwgc3VpZCwgVEFSR0VUSUQ7
CiAgZ2lkX3QgZ2lkLCBlZ2lkLCBzZ2lkOwogIFRBUkdFVElEPWdldGdpZCgpOwoJCQkJIAogIHBy
aW50ZigidWlkPSVkLCBldWlkPSVkLCBnaWQ9JWQsIGVnaWQ9JWRcbiIsIGdldHVpZCgpLCBnZXRl
dWlkKCksIGdldGdpZCgpLCBnZXRlZ2lkKCkpOwojaWZkZWYgTElOVVgKICBnZXRyZXN1aWQoJnVp
ZCwgJmV1aWQsICZzdWlkKTsKICBnZXRyZXNnaWQoJmdpZCwgJmVnaWQsICZzZ2lkKTsKICBwcmlu
dGYoIi0tPiBzdWlkPSVkIGFuZCBzZ2lkPSVkXG4iLCBzdWlkLCBzZ2lkKTsKI2VuZGlmCiAgcHJp
bnRmKCJEcm9wcGluZyBwcml2aWxlZ2VzLi4uXG4iKTsKICBpZiAoc2V0Z2lkKFRBUkdFVElEKSkK
ICAgIHBlcnJvcigic2V0Z2lkIik7CiAgaWYgKHNldHVpZChUQVJHRVRJRCkpCiAgICBwZXJyb3Io
InNldHVpZCIpOwogIHByaW50ZigiUHJpdmlsZWdlcyBkcm9wcGVkIDogdWlkPSVkLCBldWlkPSVk
LCBnaWQ9JWQsIGVnaWQ9JWRcbiIsIGdldHVpZCgpLCBnZXRldWlkKCksIGdldGdpZCgpLCBnZXRl
Z2lkKCkpOwojaWZkZWYgTElOVVgKICBpZiAoZ2V0cmVzdWlkKCZ1aWQsICZldWlkLCAmc3VpZCkp
CiAgICBwZXJyb3IoImdldHJlc3VpZCIpOwogIGlmIChnZXRyZXNnaWQoJmdpZCwgJmVnaWQsICZz
Z2lkKSkKICAgIHBlcnJvcigiZ2V0cmVzZ2lkIik7CiAgcHJpbnRmKCItLT4gc3VpZD0lZCBhbmQg
c2dpZD0lZFxuIiwgc3VpZCwgc2dpZCk7CiNlbmRpZgogIGlmIChzZXRlZ2lkKDApKQogICAgcGVy
cm9yKCJzZXRlZ2lkIik7CiAgaWYgKHNldGZzZ2lkKDApKQogICAgcGVycm9yKCJzZXRmc2dpZCIp
OwogIGlmIChzZXRnaWQoMCkpCiAgICBwZXJyb3IoInNldGdpZCIpOwoJCQkJCQkJCQkJCQkJCQkJ
CQkgCiAgcHJpbnRmKCJBZnRlciB0cnlpbmcgdG8gcmVjb3ZlciBoZXJlIGlzIHdoYXQgd2UndmUg
Z290OiB1aWQ9JWQsIGV1aWQ9JWQsIGdpZD0lZCwgZWdpZD0lZFxuIiwgZ2V0dWlkKCksIGdldGV1
aWQoKSwgZ2V0Z2lkKCksIGdldGVnaWQoKSk7CiAgcmV0dXJuIDA7Cn0KCg==

--Multipart_Fri__19_Jul_2002_04:54:18_+0200_00261000--

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



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

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