Add capabilities check for CAP_NET_RAW (root always has it)
Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
parent
8a299112b8
commit
e3550c1a47
|
@ -21,6 +21,47 @@ static const unsigned int capabilityIDs[] = { CAP_CHOWN , CAP_DAC_OVERRIDE ,
|
|||
static const char* capabilityNames[] = {"CAP_CHOWN", "CAP_DAC_OVERRIDE", "CAP_DAC_READ_SEARCH", "CAP_FOWNER", "CAP_FSETID", "CAP_KILL", "CAP_SETGID", "CAP_SETUID", "CAP_SETPCAP", "CAP_LINUX_IMMUTABLE", "CAP_NET_BIND_SERVICE", "CAP_NET_BROADCAST", "CAP_NET_ADMIN", "CAP_NET_RAW", "CAP_IPC_LOCK", "CAP_IPC_OWNER", "CAP_SYS_MODULE", "CAP_SYS_RAWIO", "CAP_SYS_CHROOT", "CAP_SYS_PTRACE", "CAP_SYS_PACCT", "CAP_SYS_ADMIN", "CAP_SYS_BOOT", "CAP_SYS_NICE", "CAP_SYS_RESOURCE", "CAP_SYS_TIME", "CAP_SYS_TTY_CONFIG", "CAP_MKNOD", "CAP_LEASE", "CAP_AUDIT_WRITE", "CAP_AUDIT_CONTROL", "CAP_SETFCAP"};
|
||||
static const unsigned int numCaps = sizeof(capabilityIDs) / sizeof(*capabilityIDs);
|
||||
|
||||
bool check_capability(const unsigned int cap)
|
||||
{
|
||||
// First assume header version 1
|
||||
int capsize = 1; // VFS_CAP_U32_1
|
||||
cap_user_data_t data = NULL;
|
||||
cap_user_header_t hdr = calloc(sizeof(*hdr), capsize);
|
||||
|
||||
// Determine capabilities version used by the current kernel
|
||||
capget(hdr, NULL);
|
||||
|
||||
// Check version
|
||||
if (hdr->version != LINUX_CAPABILITY_VERSION_1)
|
||||
{
|
||||
// If unknown version, use largest supported version (3)
|
||||
// Version 2 is deprecated according to linux/capability.h
|
||||
if (hdr->version != LINUX_CAPABILITY_VERSION_2)
|
||||
{
|
||||
hdr->version = LINUX_CAPABILITY_VERSION_3;
|
||||
capsize = 2; // VFS_CAP_U32_3
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use version 2
|
||||
capsize = 2; // VFS_CAP_U32_2
|
||||
}
|
||||
}
|
||||
|
||||
// Get current capabilities
|
||||
data = calloc(sizeof(*data), capsize);
|
||||
capget(hdr, data);
|
||||
|
||||
// Check if the capability is available
|
||||
const bool available = ((data->permitted & (1 << cap)) && (data->effective & (1 << cap)));
|
||||
|
||||
// Free memory
|
||||
free(hdr);
|
||||
free(data);
|
||||
|
||||
return available;
|
||||
}
|
||||
|
||||
bool check_capabilities(void)
|
||||
{
|
||||
// First assume header version 1
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#ifndef CAPABILITIES_H
|
||||
#define CAPABILITIES_H
|
||||
|
||||
bool check_capability(const unsigned int cap);
|
||||
bool check_capabilities(void);
|
||||
|
||||
#endif //CAPABILITIES_H
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
#include "dhcp-discover.h"
|
||||
// sleepms()
|
||||
#include "timers.h"
|
||||
// check_capability()
|
||||
#include "capabilities.h"
|
||||
#include <linux/capability.h>
|
||||
|
||||
#include <linux/if_packet.h>
|
||||
#include <linux/if_ether.h>
|
||||
|
@ -184,7 +187,9 @@ static int create_arp_socket(const int ifindex, const char *iface, const char **
|
|||
if(arp_socket < 0)
|
||||
{
|
||||
*error = strerror(errno);
|
||||
#ifdef DEBUG
|
||||
printf("Unable to create socket for ARP communications on interface %s: %s\n", iface, *error);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -196,7 +201,9 @@ static int create_arp_socket(const int ifindex, const char *iface, const char **
|
|||
if (bind(arp_socket, (struct sockaddr*) &sll, sizeof(struct sockaddr_ll)) < 0)
|
||||
{
|
||||
*error = strerror(errno);
|
||||
#ifdef DEBUG
|
||||
printf("Unable to bind socket for ARP communications on interface %s: %s\n", iface, *error);
|
||||
#endif
|
||||
close(arp_socket);
|
||||
return -1;
|
||||
}
|
||||
|
@ -208,7 +215,9 @@ static int create_arp_socket(const int ifindex, const char *iface, const char **
|
|||
if (setsockopt(arp_socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0)
|
||||
{
|
||||
*error = strerror(errno);
|
||||
#ifdef DEBUG
|
||||
printf("Unable to set timeout for ARP communications on interface %s: %s\n", iface, *error);
|
||||
#endif
|
||||
close(arp_socket);
|
||||
return -1;
|
||||
}
|
||||
|
@ -530,6 +539,13 @@ static void print_results(struct thread_data *thread_data)
|
|||
|
||||
int run_arp_scan(const bool scan_all)
|
||||
{
|
||||
// Check if we are capable of sending ARP packets
|
||||
if(!check_capability(CAP_NET_RAW))
|
||||
{
|
||||
puts("Error: Insufficient permissions or capabilities (needs CAP_NET_RAW). Try running as root (sudo)");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
arp_all = scan_all;
|
||||
puts("Discovering IPv4 hosts on the network using the Address Resolution Protocol (ARP)...\n");
|
||||
|
||||
|
|
Loading…
Reference in New Issue