Satrap: ARP scanner
This commit is contained in:
parent
e8dde3776f
commit
f980c11566
3 changed files with 153 additions and 2 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -4,3 +4,4 @@ simple_request
|
||||||
arp_spoof
|
arp_spoof
|
||||||
arp_mitm
|
arp_mitm
|
||||||
arp_scan
|
arp_scan
|
||||||
|
satrap
|
||||||
|
|
6
Makefile
6
Makefile
|
@ -3,7 +3,7 @@ CFLAGS=-g -Wall
|
||||||
|
|
||||||
.PHONY: clean all
|
.PHONY: clean all
|
||||||
|
|
||||||
all: simple_request arp_spoof arp_mitm arp_scan
|
all: simple_request arp_spoof arp_mitm arp_scan satrap
|
||||||
|
|
||||||
simple_request: simple_request.o arp.o
|
simple_request: simple_request.o arp.o
|
||||||
|
|
||||||
|
@ -13,8 +13,10 @@ arp_mitm: arp_mitm.o arp.o
|
||||||
|
|
||||||
arp_scan: arp_scan.o arp.o
|
arp_scan: arp_scan.o arp.o
|
||||||
|
|
||||||
|
satrap: satrap.o arp.o
|
||||||
|
|
||||||
%.o: %.c %.h
|
%.o: %.c %.h
|
||||||
$(CC) -c $< $(CFLAGS)
|
$(CC) -c $< $(CFLAGS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm *.o simple_request arp_spoof arp_mitm arp_scan
|
rm *.o simple_request arp_spoof arp_mitm arp_scan satrap
|
||||||
|
|
148
satrap.c
Normal file
148
satrap.c
Normal file
|
@ -0,0 +1,148 @@
|
||||||
|
/* Satrap/satrap.c */
|
||||||
|
|
||||||
|
#include "arp.h"
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Argument parsing:
|
||||||
|
network interface to use */
|
||||||
|
if (argc < 2) {
|
||||||
|
printf("[FAIL] Too few arguments\n"
|
||||||
|
"Usage: %s <interface>\n", argv[0]);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *if_name = argv[1];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ====================================================================== */
|
||||||
|
|
||||||
|
/* RAW SOCKET CREATION */
|
||||||
|
|
||||||
|
/* We open the raw socket */
|
||||||
|
/* AF_PACKET: This is a raw Ethernet packet (Linux only, requires root)
|
||||||
|
SOCK_DGRAM: The link-layer header is constructed automatically
|
||||||
|
(to build it ourselves, we could have used SOCK_RAW)
|
||||||
|
ETH_P_ALL: We want to listen to every EtherType (here, we could
|
||||||
|
also have chosen ETH_P_ARP) */
|
||||||
|
int sockfd = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL));
|
||||||
|
if (sockfd < 0) {
|
||||||
|
perror("[FAIL] socket()");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("[OK] Raw Ethernet socket started successfully\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ====================================================================== */
|
||||||
|
|
||||||
|
/* INFORMATION ON THE LOCAL COMPUTER:
|
||||||
|
- index number of the network interface
|
||||||
|
- local IP address
|
||||||
|
- local MAC address
|
||||||
|
- subnet mask
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Since this is very low-level, we can't use the usual interface
|
||||||
|
name (e.g. "eth0"), so we need to get the index number of the
|
||||||
|
ethernet interface. */
|
||||||
|
//char *if_name = "wlp3s0"; /* Change this if needed */
|
||||||
|
struct ifreq ifrindex;
|
||||||
|
size_t if_name_len = strlen(if_name);
|
||||||
|
if (if_name_len < sizeof(ifrindex.ifr_name)) {
|
||||||
|
memcpy(ifrindex.ifr_name, if_name, if_name_len);
|
||||||
|
ifrindex.ifr_name[if_name_len] = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("[FAIL] Error: interface name is too long\n");
|
||||||
|
}
|
||||||
|
/* We use ioctl() with SIOCGIFINDEX */
|
||||||
|
if (ioctl(sockfd, SIOCGIFINDEX, &ifrindex) == -1) {
|
||||||
|
perror("[FAIL] ioctl()");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
int ifindex = ifrindex.ifr_ifindex;
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("[OK] Index number of the Ethernet interface %s: %d\n", if_name, ifindex);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* We get our IP address using ioctl() and SIOCGIFADDR */
|
||||||
|
struct ifreq ifraddr;
|
||||||
|
if (if_name_len < sizeof(ifraddr.ifr_name)) {
|
||||||
|
memcpy(ifraddr.ifr_name, if_name, if_name_len);
|
||||||
|
ifraddr.ifr_name[if_name_len] = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("[FAIL] Error: interface name is too long\n");
|
||||||
|
}
|
||||||
|
if (ioctl(sockfd, SIOCGIFADDR, &ifraddr) == -1) {
|
||||||
|
perror("[FAIL] ioctl()");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
struct sockaddr_in *ipaddr = (struct sockaddr_in *) &ifraddr.ifr_addr;
|
||||||
|
char local_ip_string[16];
|
||||||
|
if (!inet_ntop(AF_INET, &ipaddr->sin_addr, local_ip_string, sizeof(local_ip_string))) {
|
||||||
|
perror("[FAIL] inet_ntop()");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("[OK] Local IP address: %s\n", local_ip_string);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* We get the MAC address using ioctl() (again) with SIOCGIFHWADDR */
|
||||||
|
struct ifreq ifrhwaddr;
|
||||||
|
if (if_name_len < sizeof(ifrhwaddr.ifr_name)) {
|
||||||
|
memcpy(ifrhwaddr.ifr_name, if_name, if_name_len);
|
||||||
|
ifrhwaddr.ifr_name[if_name_len] = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("[FAIL] Error: interface name is too long\n");
|
||||||
|
}
|
||||||
|
if (ioctl(sockfd, SIOCGIFHWADDR, &ifrhwaddr) == -1) {
|
||||||
|
perror("[FAIL] ioctl()");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
unsigned char *macaddr = (unsigned char *) &ifrhwaddr.ifr_hwaddr.sa_data;
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("[OK] Local MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||||
|
macaddr[0], macaddr[1], macaddr[2], macaddr[3], macaddr[4], macaddr[5]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* We get the subnet mask using ioctl() with SIOCGIFNETMASK */
|
||||||
|
struct ifreq ifrnetmask;
|
||||||
|
if (if_name_len < sizeof(ifrnetmask.ifr_name)) {
|
||||||
|
memcpy(ifrnetmask.ifr_name, if_name, if_name_len);
|
||||||
|
ifrnetmask.ifr_name[if_name_len] = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("[FAIL] Error: interface name is too long\n");
|
||||||
|
}
|
||||||
|
if (ioctl(sockfd, SIOCGIFNETMASK, &ifrnetmask) == -1) {
|
||||||
|
perror("[FAIL] ioctl()");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
struct sockaddr_in *netmask = (struct sockaddr_in *) &ifrnetmask.ifr_netmask;
|
||||||
|
char netmask_string[16];
|
||||||
|
if (!inet_ntop(AF_INET, &netmask->sin_addr, netmask_string, sizeof(netmask_string))) {
|
||||||
|
perror("[FAIL] inet_ntop()");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("[OK] Local netmask: %s\n", netmask_string);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ====================================================================== */
|
||||||
|
|
||||||
|
/* ARP scan of the subnet */
|
||||||
|
arp_scan(sockfd, ifindex, ipaddr, macaddr, netmask);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue