--- nmap/nping/EchoClient.cc +++ nmap/nping/EchoClient.cc @@ -149,6 +149,7 @@ int EchoClient::start(NpingTarget *target, u16 port){ outError(QT_2, "Connection failed."); return OP_FAILURE; } + drop_priv(); /* Perform NEP authentication handshake */ if( this->nep_handshake() != OP_SUCCESS ){ --- nmap/nping/EchoServer.cc +++ nmap/nping/EchoServer.cc @@ -1398,6 +1398,7 @@ int EchoServer::start() { /* Get a socket suitable for an accept() call */ listen_sd=this->nep_listen_socket(); + drop_priv(); while(1){ /* If --once is enabled, just allow the first client */ --- nmap/nping/Makefile.in +++ nmap/nping/Makefile.in @@ -64,11 +64,11 @@ DESTDIR = TARGET = nping -export SRCS = ArgParser.cc NetworkLayerElement.cc PacketElement.cc common.cc common_modified.cc nping.cc RawData.cc UDPHeader.cc NpingOps.cc TCPHeader.cc utils.cc utils_net.cc IPv4Header.cc IPv6Header.cc ICMPv4Header.cc output.cc TransportLayerElement.cc stats.cc NpingTargets.cc NpingTarget.cc EthernetHeader.cc ARPHeader.cc EchoHeader.cc EchoServer.cc EchoClient.cc ProbeMode.cc NEPContext.cc Crypto.cc PacketDiff.cc @COMPAT_SRCS@ +export SRCS = ArgParser.cc NetworkLayerElement.cc PacketElement.cc common.cc common_modified.cc nping.cc RawData.cc UDPHeader.cc NpingOps.cc TCPHeader.cc utils.cc utils_net.cc IPv4Header.cc IPv6Header.cc ICMPv4Header.cc output.cc TransportLayerElement.cc stats.cc NpingTargets.cc NpingTarget.cc EthernetHeader.cc ARPHeader.cc EchoHeader.cc EchoServer.cc EchoClient.cc ProbeMode.cc NEPContext.cc Crypto.cc PacketDiff.cc droppriv.cc @COMPAT_SRCS@ -export HDRS = ApplicationLayerElement.h NetworkLayerElement.h TCPHeader.h ArgParser.h nping_config.h TransportLayerElement.h common.h common_modified.h nping.h NpingOps.h UDPHeader.h global_structures.h output.h utils.h utils_net.h IPv4Header.h IPv6Header.h ICMPv4Header.h PacketElement.h RawData.h stats.h NpingTargets.h NpingTarget.h DataLinkLayerElement.h EthernetHeader.h ARPHeader.h EchoHeader.h EchoServer.h EchoClient.h ProbeMode.h NEPContext.h Crypto.h PacketDiff.h +export HDRS = ApplicationLayerElement.h NetworkLayerElement.h TCPHeader.h ArgParser.h nping_config.h TransportLayerElement.h common.h common_modified.h nping.h NpingOps.h UDPHeader.h global_structures.h output.h utils.h utils_net.h IPv4Header.h IPv6Header.h ICMPv4Header.h PacketElement.h RawData.h stats.h NpingTargets.h NpingTarget.h DataLinkLayerElement.h EthernetHeader.h ARPHeader.h EchoHeader.h EchoServer.h EchoClient.h ProbeMode.h NEPContext.h Crypto.h PacketDiff.h droppriv.h -OBJS = ArgParser.o NetworkLayerElement.o PacketElement.o common.o common_modified.o nping.o RawData.o UDPHeader.o NpingOps.o TCPHeader.o utils.o utils_net.o IPv4Header.o ICMPv4Header.o IPv6Header.o output.o TransportLayerElement.o stats.o NpingTargets.o NpingTarget.o EthernetHeader.o ARPHeader.o EchoHeader.o EchoServer.o EchoClient.o ProbeMode.o NEPContext.o Crypto.o PacketDiff.o @COMPAT_OBJS@ +OBJS = ArgParser.o NetworkLayerElement.o PacketElement.o common.o common_modified.o nping.o RawData.o UDPHeader.o NpingOps.o TCPHeader.o utils.o utils_net.o IPv4Header.o ICMPv4Header.o IPv6Header.o output.o TransportLayerElement.o stats.o NpingTargets.o NpingTarget.o EthernetHeader.o ARPHeader.o EchoHeader.o EchoServer.o EchoClient.o ProbeMode.o NEPContext.o Crypto.o PacketDiff.o droppriv.o @COMPAT_OBJS@ export DOCS2DIST = leet-nping-ascii-art.txt nping.1 nping-man.html --- nmap/nping/ProbeMode.cc +++ nmap/nping/ProbeMode.cc @@ -216,6 +216,7 @@ int ProbeMode::start(){ /** TCP CONNECT MODE **/ /***************************************************************************/ case TCP_CONNECT: + drop_priv(); o.stats.startClocks(); for( c=0; c < o.getPacketCount(); c++){ /* Do requested times */ o.targets.rewind(); @@ -254,6 +255,7 @@ int ProbeMode::start(){ /** UDP UNPRIVILEGD MODE **/ /***************************************************************************/ case UDP_UNPRIV: + drop_priv(); o.stats.startClocks(); for( c=0; c < o.getPacketCount(); c++){ /* Do requested times */ o.targets.rewind(); @@ -342,6 +344,7 @@ int ProbeMode::start(){ outFatal(QT_3, "Error opening capture device %s --> %s\n", o.getDevice(), auxpnt); outPrint(DBG_2,"Pcap device %s open successfully", o.getDevice() ); } + drop_priv(); /* Ready? Go! */ o.stats.startClocks(); --- /dev/null +++ nmap/nping/droppriv.cc @@ -0,0 +1,81 @@ +#include "nping.h" +#include "output.h" +#ifndef NMAP_USER + +void drop_priv(void) {} + +#else + +#if HAVE_GRP_H +# include +#endif +#if HAVE_SYS_CAPABILITY_H +# include +#endif +#if HAVE_SYS_PRCTL_H +# include +#endif + +#ifndef NMAP_CHROOT_EMPTY +# ifdef NMAP_CHROOT_RESOLV +# define NMAP_CHROOT_EMPTY NMAP_CHROOT_RESOLV +# else +# define NMAP_CHROOT_EMPTY NULL +# endif +#endif + +#ifndef NMAP_CHROOT_RESOLV +# define NMAP_CHROOT_RESOLV NULL +#endif + +const char * +drop_priv_dir(void) +{ + return NMAP_CHROOT_EMPTY; +} + +void +drop_priv(void) +{ + const char *user = NMAP_USER; + const char *dir; + struct passwd *pw; + cap_t caps; + + if (geteuid()) + return; + + if (setgroups(0, 0) < 0) + fatal("setgroups failed"); + + if (prctl(PR_SET_KEEPCAPS, 1)) + fatal("prctl PR_SET_KEEPCAPS failed"); + + if (!(pw = getpwnam(user))) + fatal("lookup of user \"%s\" failed", user); + endpwent(); + + if (!pw->pw_uid) + fatal("user \"%s\" shouldn't be root", user); + + dir = drop_priv_dir(); + if (dir && (chroot(dir) || chdir("/"))) + fatal("chroot to \"%s\" failed", dir); + + if (setgid(pw->pw_gid) < 0) + fatal("setgid failed"); + + if (setreuid(pw->pw_uid, pw->pw_uid) < 0) + fatal("setreuid failed"); + + caps = cap_from_text("cap_net_raw=ep"); + if (!caps) + fatal("cap_from_text failed"); + + if (cap_set_proc(caps) < 0) + fatal("cap_set_proc failed"); + + cap_free(caps); +} + +#endif /* NMAP_USER */ --- /dev/null +++ nmap/nping/droppriv.h @@ -0,0 +1,7 @@ +#ifndef NMAP_DROPPRIV_H__ +#define NMAP_DROPPRIV_H__ + +extern const char *drop_priv_dir(void); +extern void drop_priv(void); + +#endif /* NMAP_DROPPRIV_H__ */ --- nmap/nping/nping.h +++ nmap/nping/nping.h @@ -101,6 +101,7 @@ #include #include #include +#include "droppriv.h" #include "../libnetutil/netutil.h"