Up ../

Unprivileged Bind(2) Linux

Another way to bind a reserved port (<1024) from an unprivileged process is to spawn a privileged binary to do the binding for you.

I first saw this in:

Firewalls and Internet Security: Repelling the Wily Hacker First Edition
William R. Cheswick and Steven M. Bellovin
Chap 4, p103. (In reference to port 20 for ftp.)

bind_port.c is the privileged executable installed suid-root. If you have a kernel > 2.6.25 you can just use setcap to give the program or a wrapper CAP_NET_BIND_SERVICE without all the privilege/chroot/capabilities fiddling in bind_port.c.

bind.c contains the bind(2) replacement intercept_bind(). intercept_bind() just calls bind(2) if no privilege is needed or the socket being bound isn't AF_INET. (AF_INET6 would follow pretty much the same logic.) If the port number requires privilege the code clears the close-on-exec flags of the socket descriptor, forks:

a) The child closes all inherited descriptors except the one we are binding and execs the privileged wrapper passing the descriptor number, port, and local address on the command line.

b) The parent waits for the child to complete and retrieves the exit code and restores the close-on-exec flags on the socket descriptor. (The close-on-exec flag on apache 1.3.X is set for the socket descriptor hence this rigamarole.)

The common header constants.h

To use you can either overide the weak symbol bind in libc with the one defined in bind.c or alter any calls to bind in your source to call intercept_bind and add libbind.o to the link line.

	cc -o bind_port bind_port.c -lcap
	sudo install -o root -o root -m 4511 bind_port /sbin/opt

	cc -c -DREPLACE_BIND_SYMBOL libbind.c
	cp libbind.o /tmp

	cd $APACHE_1.3.41_SOURCE
	env EXTRA_LDFLAGS="/tmp/bind.o -lcap" ./configure --prefix=/tmp/apache
	make install
	/tmp/apache/bin/apactl start

The REPLACE_BIND_SYMBOL preprocessor symbol controls this in libbind.c

Another option for unmodified binaries is to interpolate a shared library containing the modified bind routine using the LD_PRELOAD environment variable. The make target libbind.so will build libbind.so from libbind.c eg

	cc -fPIC -o libbind.o -DREPLACE_BIND_SYMBOL bind.c
	cc -shared -o libbind.so -Wl,-soname,libbind.so libbind.o
	cp bind.so	/tmp

	env LD_PRELOAD=/tmp/libbind.so /usr/sbin/apactl start

Source files are in "files"