socket_server useless?
Posted:
Tue Dec 23, 2003 10:37 pm
by grebneke
kernel 2.4.23 + grsec 1.9.13
I'm trying to use socket_server and socket_server_gid to stop group "nogroup" from starting listening daemons. The point is to prevent exploits with Apache/PHP that install a small telnet-daemon running as "nobody", letting anyone telnet straight into the server w/o password
Tests show that enabling socket_server block the bind() call, but it doesn't seem to matter - the daemon can still accept connections on the port. Look at these straces:
## Without socket_server
## echo 0 >| /proc/sys/kernel/grsecurity/socket_server
[pid 4717] socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
[pid 4717] bind(3, {sin_family=AF_INET, sin_port=htons(14589), sin_addr=inet_addr("0.0.0.0")}}, 16) = 0
[pid 4717] listen(3, 5) = 0
[pid 4717] accept(3, <unfinished ...>
## With socket_server enabled
## echo 1 >| /proc/sys/kernel/grsecurity/socket_server
[pid 984] socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
[pid 984] bind(3, {sin_family=AF_INET, sin_port=htons(14589), sin_addr=inet_addr("0.0.0.0")}}, 16) = -1 EACCES (Permission denied)
[pid 984] listen(3, 5) = 0
[pid 984] accept(3, <unfinished ...>
In the second example, bind() returns EACCES, but the daemon still accepts on the port (14589). When telneting to port 14589 you get access to a login shell running as the Apache user (nobody/nogroup).
What's wrong here?
Am I missing something obvious?
How can I prevent Apache/PHP from opening listening sockets?
Blocking bind() seems totally useless?
Grateful for any help.
Posted:
Wed Dec 24, 2003 6:27 am
by Sleight of Mind
do you use CONFIG_GRKERNSEC_SOCKET_SERVER_GID?
and if so, to what value is it set? and is apache in this group?
after setting socket_server to 1 and socket_server_gid to a certain value i tested logging in as this user(with [primary group $socket_server_gid) and running `nc -l -p 12345`:
- Code: Select all
....
bind(3, {sa_family=AF_INET, sin_port=htons(12345), sin_addr=inet_addr("0.0.0.0")}, 16) = -1 EACCES (Permission denied)
write(2, "Can\'t grab 0.0.0.0:12345 with bi"..., 34Can't grab 0.0.0.0:12345 with bind) = 34
write(2, " : Permission denied\n", 21 : Permission denied
) = 21
close(-1) = -1 EBADF (Bad file descriptor)
_exit(1) = ?
As you can see it works perfectly for me.
Posted:
Wed Dec 24, 2003 7:42 am
by grebneke
I'm using the sysctl interface. Apache runs as nobody.nogroup. nogroup has id 65534:
# id -g nobody
65534
echo "65534" >| /proc/sys/kernel/grsecurity/socket_server_gid
As you can see from the straces I posted, bind() returns EACCESS just as in your case, indicating that I configured the socket_server_gid correctly. Your code seems to do error checking and bail out on the error, but the program I tried doesn't care about bind() returning -1 and so continues to accept() successfully which is the real problem here.
I don't have the src for the program but I believe it's fairly obvious from the straces what's going on
Posted:
Wed Dec 24, 2003 1:46 pm
by Sleight of Mind
well, if this is true i don't think its a grsecurity bug, since it does what it is supposed to (return -EACCES). The operating system (kernel) should take care about it from here afaik.
- Code: Select all
int
gr_handle_sock_server(const struct sockaddr *sck)
{
#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
if (grsec_enable_socket_server &&
in_group_p(grsec_socket_server_gid) &&
sck && (sck->sa_family != AF_UNIX) &&
(sck->sa_family != AF_LOCAL)) {
security_alert(GR_BIND_MSG, DEFAULTSECARGS);
return -EACCES;
}
#endif
return 0;
}
I don't think anything _can_ be wrong about this code, since it's all pretty clear. So my guess would be some config error, and if not, maybe a kernel bug. Could you make the application you're using to test available somewhere?
Posted:
Wed Dec 24, 2003 9:15 pm
by grebneke
The code
is clear and as you can see from the strace, the application gets EACCES like it should, but it can still accept() on the port like nothing happened.
The program I've been tested with can be found here:
http://www12.aname.net/~johan/telnetd
Grateful for any help - if this isn't an error on my part it's an extremely serious security problem
Posted:
Thu Dec 25, 2003 7:35 am
by Sleight of Mind
i tried to test this application to see if i could reproduce the error, but this program segfaults on any machine i try it on. Do you have it's source code somewhere? Or is this just a distro's telnetd?
Posted:
Thu Dec 25, 2003 7:55 am
by grebneke
Please download it again. I stripped the binary before posting it on the URL and that seems to have broken it (segfaults here as well). I've restored the original without any modifications and it should work
http://www12.aname.net/~johan/telnetd
Posted:
Thu Dec 25, 2003 8:24 am
by Sleight of Mind
with this program i was able to reproduce: (using strace & strace -f)
- Code: Select all
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
bind(3, {sa_family=AF_INET, sin_port=htons(14589), sin_addr=inet_addr("0.0.0.0")}, 16) = -1 EACCES (Permission denied)
listen(3, 5) = 0
accept(3,
But when trying nmap or telnet on this port it seems to be closed. When doing the same thing as a user that is not in the group it works just fine and a shell is spawned when i telnet to the port.
So this problem seems to occur on your box only. Do you use any other patches on your kernel? or just plain 2.4.23 with grsec?
Posted:
Mon Dec 29, 2003 6:46 am
by grebneke
This is vanilla 2.4.23 + grsec, no other related patches applied. (The only other patches are a few small adjustments for using quota with reiserfs)
This is the relevant config from /proc:
- Code: Select all
# cat /proc/sys/kernel/grsecurity/socket_server
1
# cat /proc/sys/kernel/grsecurity/socket_server_gid
65534
I tried this again by adding my own user "johan" to group 65534 and starting the telnetd program.
dmesg said:
- Code: Select all
grsec: From ...: attempted bind() by (telnetd:25326) UID(4501) EUID(4501), parent (telnetd:25324) UID(4501)
EUID(4501)
netstat -telp said:
- Code: Select all
tcp 0 0 *:33193 *:* LISTEN johan 24547948 26953/getty
Telnetting to the machine from another location:
- Code: Select all
other-machine# telnet ... 33193
Connected to ...
Escape character is '^]'.
Linux 2.4.23-grsec (...) (pts/1)
~$ whoami
johan
I really don't know what to do now...