Group :: Monitoramento
RPM: nmap
Main Changelog Spec Patches Sources Download Gear Bugs e FR Repocop
Patch: nmap-5.51-alt-owl-drop-priv.patch
Download
Download
--- nmap/MACLookup.cc
+++ nmap/MACLookup.cc
@@ -100,6 +100,7 @@
#include "NmapOps.h"
#include "nmap_error.h"
#include "charpool.h"
+#include "droppriv.h"
extern NmapOps o;
@@ -109,7 +110,7 @@ static inline int MacCharPrefix2Key(const u8 *prefix) {
return (prefix[0] << 16) + (prefix[1] << 8) + prefix[2];
}
-static void mac_prefix_init() {
+void mac_prefix_init() {
static int initialized = 0;
if (initialized) return;
initialized = 1;
--- nmap/Makefile.in
+++ nmap/Makefile.in
@@ -93,11 +93,11 @@ NSE_OBJS+=nse_openssl.o nse_ssl_cert.o
endif
endif
-export SRCS = main.cc nmap.cc targets.cc tcpip.cc nmap_error.cc utils.cc idle_scan.cc osscan.cc osscan2.cc output.cc payload.cc scan_engine.cc timing.cc charpool.cc services.cc protocols.cc nmap_rpc.cc portlist.cc NmapOps.cc TargetGroup.cc Target.cc FingerPrintResults.cc service_scan.cc NmapOutputTable.cc MACLookup.cc nmap_tty.cc nmap_dns.cc traceroute.cc portreasons.cc xml.cc $(NSE_SRC) @COMPAT_SRCS@
+export SRCS = main.cc nmap.cc targets.cc tcpip.cc nmap_error.cc utils.cc idle_scan.cc osscan.cc osscan2.cc output.cc payload.cc scan_engine.cc timing.cc charpool.cc services.cc protocols.cc nmap_rpc.cc portlist.cc NmapOps.cc TargetGroup.cc Target.cc FingerPrintResults.cc service_scan.cc NmapOutputTable.cc MACLookup.cc nmap_tty.cc nmap_dns.cc traceroute.cc portreasons.cc xml.cc droppriv.cc $(NSE_SRC) @COMPAT_SRCS@
-export HDRS = charpool.h FingerPrintResults.h global_structures.h idle_scan.h MACLookup.h nmap_amigaos.h nmap_dns.h nmap_error.h nmap.h NmapOps.h NmapOutputTable.h nmap_rpc.h nmap_tty.h nmap_winconfig.h osscan.h osscan2.h output.h payload.h portlist.h protocols.h scan_engine.h service_scan.h services.h TargetGroup.h Target.h targets.h tcpip.h timing.h utils.h traceroute.h portreasons.h xml.h $(NSE_HDRS)
+export HDRS = charpool.h FingerPrintResults.h global_structures.h idle_scan.h MACLookup.h nmap_amigaos.h nmap_dns.h nmap_error.h nmap.h NmapOps.h NmapOutputTable.h nmap_rpc.h nmap_tty.h nmap_winconfig.h osscan.h osscan2.h output.h payload.h portlist.h protocols.h scan_engine.h service_scan.h services.h TargetGroup.h Target.h targets.h tcpip.h timing.h utils.h traceroute.h portreasons.h xml.h droppriv.h $(NSE_HDRS)
-OBJS = main.o nmap.o targets.o tcpip.o nmap_error.o utils.o idle_scan.o osscan.o osscan2.o output.o payload.o scan_engine.o timing.o charpool.o services.o protocols.o nmap_rpc.o portlist.o NmapOps.o TargetGroup.o Target.o FingerPrintResults.o service_scan.o NmapOutputTable.o MACLookup.o nmap_tty.o nmap_dns.o traceroute.o portreasons.o xml.o $(NSE_OBJS) @COMPAT_OBJS@
+OBJS = main.o nmap.o targets.o tcpip.o nmap_error.o utils.o idle_scan.o osscan.o osscan2.o output.o payload.o scan_engine.o timing.o charpool.o services.o protocols.o nmap_rpc.o portlist.o NmapOps.o TargetGroup.o Target.o FingerPrintResults.o service_scan.o NmapOutputTable.o MACLookup.o nmap_tty.o nmap_dns.o traceroute.o portreasons.o xml.o droppriv.o $(NSE_OBJS) @COMPAT_OBJS@
# %.o : %.cc -- nope this is a GNU extension
.cc.o:
--- nmap/configure.ac
+++ nmap/configure.ac
@@ -745,6 +745,50 @@ if test $ac_cv_ip_has_ip_sum = yes ; then
AC_DEFINE(HAVE_IP_IP_SUM, 1, [Define to 1 for ip_sum member])
fi
+try_drop_priv=no
+AC_CHECK_HEADERS(grp.h sys/capability.h sys/prctl.h)
+AC_CHECK_FUNC(chroot)
+AC_CHECK_FUNC(prctl,
+ [AC_CHECK_FUNC(setgid,
+ [AC_CHECK_FUNC(setgroups,
+ [AC_CHECK_FUNC(setreuid,
+ [try_drop_priv=yes
+ AC_CHECK_LIB(cap, cap_from_text, , [try_drop_priv=no])]
+ )]
+ )]
+ )]
+)
+
+AC_ARG_WITH(user,
+ [ --with-user=USERNAME Lower root privileges by switching to user USERNAME])
+AC_MSG_CHECKING([whether to lower root privileges by default])
+if test -z "$with_user" -o "$try_drop_priv" = "no"; then
+ AC_MSG_RESULT(no)
+else
+ AC_DEFINE_UNQUOTED(NMAP_USER, "$withval", [Define user to switch during lowering privileges])
+ AC_MSG_RESULT(to \"$withval\")
+fi
+
+AC_ARG_WITH(chroot-empty,
+ [ --with-chroot-empty=DIRECTORY When lowering privileges and -n option is given, chroot to empty DIRECTORY])
+AC_MSG_CHECKING([whether to chroot when -n option is given])
+if test -z "$with_chroot_empty" -o "$try_drop_priv" = "no" -o "$ac_cv_func_chroot" = no; then
+ AC_MSG_RESULT(no)
+else
+ AC_DEFINE_UNQUOTED(NMAP_CHROOT_EMPTY, "$withval", [Define directory to chroot during lowering privileges if -n option is given])
+ AC_MSG_RESULT(to \"$withval\")
+fi
+
+AC_ARG_WITH(chroot-resolv,
+ [ --with-chroot-resolv=DIRECTORY When lowering privileges and -n option is not given, chroot to resolver DIRECTORY])
+AC_MSG_CHECKING([whether to chroot when -n option is not given])
+if test -z "$with_chroot_resolv" -o "$try_drop_priv" = "no" -o "$ac_cv_func_chroot" = no; then
+ AC_MSG_RESULT(no)
+else
+ AC_DEFINE_UNQUOTED(NMAP_CHROOT_RESOLV, "$withval", [Define directory to chroot during lowering privileges if -n option is not given])
+ AC_MSG_RESULT(to \"$withval\")
+fi
+
dnl Checks for library functions.
AC_CHECK_FUNCS(strerror)
RECVFROM_ARG6_TYPE
--- /dev/null
+++ nmap/droppriv.cc
@@ -0,0 +1,96 @@
+#include "nmap.h"
+#include "service_scan.h"
+#include "utils.h"
+#include "droppriv.h"
+
+#ifndef NMAP_USER
+
+void drop_priv(void) {}
+
+#else
+
+#if HAVE_GRP_H
+# include <grp.h>
+#endif
+#if HAVE_SYS_CAPABILITY_H
+# include <sys/capability.h>
+#endif
+#if HAVE_SYS_PRCTL_H
+# include <sys/prctl.h>
+#endif
+
+#include "NmapOps.h"
+extern NmapOps o; /* option structure */
+
+#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 o.noresolve ? NMAP_CHROOT_EMPTY : NMAP_CHROOT_RESOLV;
+}
+
+void
+drop_priv(void)
+{
+ const char *user = NMAP_USER;
+ const char *dir;
+ struct passwd *pw;
+ cap_t caps;
+
+ if (geteuid())
+ return;
+
+ nmap_services_init();
+ nmap_protocols_init();
+ rpc_services_init();
+ AllProbes::service_scan_init();
+ routethrough_init();
+ mac_prefix_init();
+ init_payloads();
+ if (!o.noresolve) etchosts_init();
+
+ 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/droppriv.h
@@ -0,0 +1,14 @@
+#ifndef NMAP_DROPPRIV_H__
+#define NMAP_DROPPRIV_H__
+
+extern const char *drop_priv_dir(void);
+extern void drop_priv(void);
+extern int nmap_services_init(void);
+extern int nmap_protocols_init(void);
+extern void rpc_services_init(void);
+extern void routethrough_init(void);
+extern void mac_prefix_init(void);
+extern void etchosts_init(void);
+extern void init_payloads(void);
+
+#endif /* NMAP_DROPPRIV_H__ */
--- nmap/libnetutil/netutil.cc
+++ nmap/libnetutil/netutil.cc
@@ -1258,6 +1258,13 @@ struct interface_info *getinterfaces(int *howmany, char *errstr, size_t errstrle
return mydevs;
}
+static FILE *routefp;
+
+void routethrough_init(void)
+{
+ if (!routefp)
+ routefp = fopen("/proc/net/route", "r");
+}
/* The 'dev' passed in must be at least 32 bytes long. Returns 0 on success. */
int ipaddr2devname(char *dev, const struct in_addr *addr) {
@@ -1610,7 +1617,6 @@ static struct sys_route *getsysroutes_dnet(int *howmany, char *errstr, size_t er
struct sys_route *getsysroutes(int *howmany, char *errstr, size_t errstrlen) {
static struct sys_route *routes = NULL;
static int numroutes = 0;
- FILE *routefp;
assert(howmany);
if (routes != NULL) {
@@ -1620,14 +1626,16 @@ struct sys_route *getsysroutes(int *howmany, char *errstr, size_t errstrlen) {
}
/* First let us try Linux-style /proc/net/route */
- routefp = fopen("/proc/net/route", "r");
+ routethrough_init();
if (routefp) {
routes = getsysroutes_proc(routefp, howmany, errstr, errstrlen);
- fclose(routefp);
} else {
routes = getsysroutes_dnet(howmany, errstr, errstrlen);
}
+ fclose(routefp);
+ routefp = NULL;
+
/* Check if we managed to get the routes and sort them if we did */
if(routes==NULL){
*howmany=-1;
--- nmap/nmap.cc
+++ nmap/nmap.cc
@@ -96,6 +96,7 @@
#include "scan_engine.h"
#include "idle_scan.h"
#include "timing.h"
+#include "droppriv.h"
#include "NmapOps.h"
#include "MACLookup.h"
#include "traceroute.h"
@@ -1414,6 +1415,27 @@ int nmap_main(int argc, char *argv[]) {
o.sendpref = PACKET_SEND_ETH_STRONG;
}
+#ifndef NOLUA
+ if (o.scriptupdatedb) {
+ o.max_ips_to_scan = o.numhosts_scanned; // disable warnings?
+ }
+ if (o.servicescan)
+ o.scriptversion = 1;
+ if (o.scriptversion || o.script || o.scriptupdatedb)
+ open_nse();
+
+ /* Run the script pre-scanning phase */
+ if (o.script) {
+ new_targets = NewTargets::get();
+ script_scan_results = get_script_scan_results_obj();
+ script_scan(Targets, SCRIPT_PRE_SCAN);
+ printscriptresults(script_scan_results, SCRIPT_PRE_SCAN);
+ script_scan_results->clear();
+ }
+#endif
+
+ drop_priv();
+
/* By now, we've got our port lists. Give the user a warning if no
* ports are specified for the type of scan being requested. Other things
* (such as OS ident scan) might break cause no ports were specified, but
@@ -1612,25 +1634,6 @@ int nmap_main(int argc, char *argv[]) {
dumpExclude(exclude_group);
}
-#ifndef NOLUA
- if (o.scriptupdatedb) {
- o.max_ips_to_scan = o.numhosts_scanned; // disable warnings?
- }
- if (o.servicescan)
- o.scriptversion = 1;
- if (o.scriptversion || o.script || o.scriptupdatedb)
- open_nse();
-
- /* Run the script pre-scanning phase */
- if (o.script) {
- new_targets = NewTargets::get();
- script_scan_results = get_script_scan_results_obj();
- script_scan(Targets, SCRIPT_PRE_SCAN);
- printscriptresults(script_scan_results, SCRIPT_PRE_SCAN);
- script_scan_results->clear();
- }
-#endif
-
/* Time to create a hostgroup state object filled with all the requested
machines. The list is initially empty. It is refilled inside the loop
whenever it is empty. */
--- nmap/nmap_dns.cc
+++ nmap/nmap_dns.cc
@@ -149,6 +149,7 @@
#endif
#include "nmap.h"
+#include "droppriv.h"
#include "NmapOps.h"
#include "nmap_dns.h"
#include "nsock.h"
@@ -1076,7 +1077,7 @@ const char *lookup_cached_host(u32 ip) {
return tmp;
}
-static void etchosts_init(void) {
+void etchosts_init(void) {
static int initialized = 0;
if (initialized) return;
initialized = 1;
--- nmap/nmap_rpc.cc
+++ nmap/nmap_rpc.cc
@@ -94,6 +94,7 @@
#include "nmap_rpc.h"
+#include "droppriv.h"
#include "NmapOps.h"
#include "Target.h"
#include "charpool.h"
@@ -114,7 +115,7 @@ static unsigned long rpc_xid_base = (unsigned long) -1;
static size_t tcp_readlen=0; /* used in get_rpc_results but can be reset in
send_rpc_query */
-static void rpc_services_init() {
+void rpc_services_init() {
static int services_initialized = 0;
if (services_initialized) return;
services_initialized = 1;
--- nmap/protocols.cc
+++ nmap/protocols.cc
@@ -91,6 +91,7 @@
/* $Id: protocols.cc 21904 2011-01-21 00:04:16Z fyodor $ */
#include "protocols.h"
+#include "droppriv.h"
#include "NmapOps.h"
#include "services.h"
#include "charpool.h"
@@ -102,7 +103,7 @@ static int numipprots = 0;
static struct protocol_list *protocol_table[PROTOCOL_TABLE_SIZE];
static int protocols_initialized = 0;
-static int nmap_protocols_init() {
+int nmap_protocols_init() {
if (protocols_initialized) return 0;
char filename[512];
--- nmap/services.cc
+++ nmap/services.cc
@@ -92,6 +92,7 @@
#include "nmap.h"
#include "services.h"
+#include "droppriv.h"
#include "NmapOps.h"
#include "charpool.h"
#include "nmap_error.h"
@@ -138,7 +139,7 @@ static std::list<service_node> services_by_ratio;
static int services_initialized;
static int ratio_format; // 0 = /etc/services no-ratio format. 1 = new nmap format
-static int nmap_services_init() {
+int nmap_services_init() {
if (services_initialized) return 0;
char filename[512];
--- nmap/tcpip.cc
+++ nmap/tcpip.cc
@@ -99,6 +99,7 @@
#include <dnet.h>
#include <net/if_arp.h>
#include "tcpip.h"
+#include "droppriv.h"
#include "NmapOps.h"
#include "Target.h"
#include "utils.h"