Skip to content

Commit 9d760c9

Browse files
committed
scan nmap output ask user for choice
1 parent 658c215 commit 9d760c9

File tree

8 files changed

+145
-29
lines changed

8 files changed

+145
-29
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ arpmess
55
.bash_history
66
peda*
77
manuf
8+
res
89
.gdb_history
910
.vscode

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ NAME = arpmess
22

33
CC = gcc
44

5-
CFLAGS = -I$(HEAD_DIR) -lpthread
5+
CFLAGS = -I$(HEAD_DIR) -lpthread -lm
66

77
HEAD_DIR = ./head/
88

head/define.h

+21-7
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
# define MACCOLOR ANSI_COLOR_BRIGHT_YELLOW
2424
# define NETMASKCOLOR ANSI_COLOR_BRIGHT_MAGENTA
2525

26-
# define PROG_NAME "arpmess"
26+
# define PROGNAME "arpmess"
27+
# define PROMPT ANSI_COLOR_BRIGHT_MAGENTA""PROGNAME""ANSI_COLOR_RESET" "ANSI_COLOR_BRIGHT_WHITE"Ɛ> "ANSI_COLOR_RESET
2728
# define SOCKET int
2829
# define IPV4_LEN 4
2930
// # define ETH_HLEN sizeof(eth)
@@ -39,17 +40,20 @@
3940
# define TELLIFACE(IFACENAME) { printf("%sFound available interface "IFACECOLOR"%s"ANSI_COLOR_RESET"\n", SAMPLE_NEW, IFACENAME); }
4041
# define TELLGATEWAY(GATEWAYPA) { printf("%sFound gateway protocol address "IPV4COLOR"%hhu.%hhu.%hhu.%hhu"ANSI_COLOR_RESET"\n", SAMPLE_NEW, GATEWAYPA[0], GATEWAYPA[1], GATEWAYPA[2], GATEWAYPA[3]); }
4142
# define TELLIFACEINFO(IFACENAME, IPV4, MASK, MAC) { printf("%sFound netmask for network: "NETMASKCOLOR"%hhu.%hhu.%hhu.%hhu"ANSI_COLOR_RESET"\n%sFound ipv4 for interface "IFACECOLOR"%s"ANSI_COLOR_RESET": "IPV4COLOR"%d.%d.%d.%d"ANSI_COLOR_RESET"\n%sFound mac for interface "IFACECOLOR"%s"ANSI_COLOR_RESET": "MACCOLOR"%02x:%02x:%02x:%02x:%02x:%02x"ANSI_COLOR_RESET"\n", SAMPLE_NEW, MASK[0], MASK[1], MASK[2], MASK[3], SAMPLE_NEW, IFACENAME, IPV4[0], IPV4[1], IPV4[2], IPV4[3], SAMPLE_NEW, IFACENAME, MAC[0], MAC[1], MAC[2], MAC[3], MAC[4], MAC[5]); }
42-
# define TELLSCAN(IPV4, MASK) { printf("%susing nmap, arp scanning network "IPV4COLOR"%hhu.%hhu.%hhu.%hhu"ANSI_COLOR_RESET"/"NETMASKCOLOR"%d"ANSI_COLOR_RESET"\n", SAMPLE_INFO, IPV4[0] & MASK[0], IPV4[1] & MASK[1], IPV4[2] & MASK[2], IPV4[3] & MASK[3], __builtin_popcount(*(uint32_t*)MASK)); }
43+
# define TELLSCAN(IPV4, MASK) { printf("%sUsing nmap, arp scanning network "IPV4COLOR"%hhu.%hhu.%hhu.%hhu"ANSI_COLOR_RESET"/"NETMASKCOLOR"%d"ANSI_COLOR_RESET"\n", SAMPLE_INFO, IPV4[0] & MASK[0], IPV4[1] & MASK[1], IPV4[2] & MASK[2], IPV4[3] & MASK[3], __builtin_popcount(*(uint32_t*)MASK)); }
4344
# define TELLHANGON() { printf("%snmap scan running, hang on...\n", SAMPLE_INFO); }
44-
# define TELLDONESCANNING(N, NT) { printf("%sdone scanning %d out of %d hosts are up\n", SAMPLE_INFO, N, NT); }
45+
# define TELLDONESCANNING(N, NT) { printf("%sDone scanning, %d out of %d hosts are up\n", SAMPLE_INFO, N, NT); }
46+
# define TELLGATEWAYHA(HA) { printf("%sFound gateway hardware address: "MACCOLOR"%02x:%02x:%02x:%02x:%02x:%02x"ANSI_COLOR_RESET"\n", SAMPLE_NEW, HA[0], HA[1], HA[2], HA[3], HA[4], HA[5]); }
4547

4648
# define TELLEXITING() { printf("Exiting program...\n"); }
4749

48-
# define ERROR_UID(UID, PROG_PATH) { fprintf(stderr, "%sexpected uid %d to run %s, got %d\n", SAMPLE_ERROR, 0, PROG_PATH, UID); }
50+
# define ERROR_UID(UID, PROG_PATH) { fprintf(stderr, "%sExpected uid %d to run %s, got %d\n", SAMPLE_ERROR, 0, PROG_PATH, UID); }
4951
# define ERROR_EXIT() { fprintf(stderr, "%s"ANSI_COLOR_RED"Exiting...\n"ANSI_COLOR_RESET, SAMPLE_ERROR); }
50-
# define ERROR_NO_IFACE(IFACENAME) { IFACENAME == NULL ? fprintf(stderr, "%scould not find a fitting interface\n", SAMPLE_ERROR) : printf("%sinterface %s not found or not fitting\n", SAMPLE_ERROR, IFACENAME); }
51-
# define ERROR_NO_GATEWAY() { fprintf(stderr, "%scould not find a gateway\n", SAMPLE_ERROR); }
52-
# define ERROR_NO_INFO_FOR_IFACE(IFACENAME) { fprintf(stderr, "%scould not find ipv4 and harware address of interface %s\n", SAMPLE_ERROR, IFACENAME); }
52+
# define ERROR_NO_IFACE(IFACENAME) { IFACENAME == NULL ? fprintf(stderr, "%sCould not find a fitting interface\n", SAMPLE_ERROR) : printf("%sinterface %s not found or not fitting\n", SAMPLE_ERROR, IFACENAME); }
53+
# define ERROR_NO_GATEWAY() { fprintf(stderr, "%sCould not find a gateway\n", SAMPLE_ERROR); }
54+
# define ERROR_NO_INFO_FOR_IFACE(IFACENAME) { fprintf(stderr, "%sCould not find ipv4 and harware address of interface %s\n", SAMPLE_ERROR, IFACENAME); }
55+
# define ERROR_MALLOC() { fprintf(stderr, "%smalloc() returned NULL\n", SAMPLE_ERROR); }
56+
# define ERROR_NMAP(LINE) { fprintf(stderr, "%s The nmap scan returned an incomprehensible line: |%s|", SAMPLE_ERROR, LINE); }
5357

5458
# define ASK_OLD_OR_NEW_IP(uchoice, name, old, new) {\
5559
printf("More than 1 ipv4 have been detected for the selected interface %s\n\
@@ -71,6 +75,16 @@
7175
}\
7276
}
7377

78+
# define ASK_ATTACK_TYPE() { printf("\n%sChoose an option from the menu:\n\
79+
\n\
80+
\t"ANSI_COLOR_BRIGHT_YELLOW"["ANSI_COLOR_BRIGHT_RED"1"ANSI_COLOR_BRIGHT_YELLOW"]"ANSI_COLOR_RESET" Kick "ANSI_COLOR_BRIGHT_WHITE"ONE"ANSI_COLOR_RESET" Off\n\
81+
\t"ANSI_COLOR_BRIGHT_YELLOW"["ANSI_COLOR_BRIGHT_RED"2"ANSI_COLOR_BRIGHT_YELLOW"]"ANSI_COLOR_RESET" Kick "ANSI_COLOR_BRIGHT_WHITE"SOME"ANSI_COLOR_RESET" Off\n\
82+
\t"ANSI_COLOR_BRIGHT_YELLOW"["ANSI_COLOR_BRIGHT_RED"3"ANSI_COLOR_BRIGHT_YELLOW"]"ANSI_COLOR_RESET" Kick "ANSI_COLOR_BRIGHT_WHITE"ALL"ANSI_COLOR_RESET" Off\n\
83+
\n\
84+
\t"ANSI_COLOR_BRIGHT_YELLOW"["ANSI_COLOR_BRIGHT_RED"E"ANSI_COLOR_BRIGHT_YELLOW"]"ANSI_COLOR_BRIGHT_WHITE" Exit"ANSI_COLOR_RESET"\n\
85+
\n\
86+
"PROMPT, SAMPLE_INFO); }
87+
7488
# include "struct.h"
7589

7690
#endif

head/struct.h

+10
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,21 @@ typedef struct arguments
4646
int verbose;
4747
char *target_list;
4848
char ifacename[IF_NAMESIZE];
49+
uint32_t scanamount; /* number of result in the scan */
4950
uint8_t gateway_pa[IPV4_LEN]; /* gateway protocol (IPv4) addr */
5051
uint8_t gateway_ha[ETH_ALEN]; /* gateway hardware addr */
5152
uint8_t netmask[IPV4_LEN]; /* network mask */
5253
uint8_t self_pa[IPV4_LEN]; /* sender protocol (IPv4) addr */
5354
uint8_t self_ha[ETH_ALEN]; /* sender hardware addr */
5455
} t_arguments;
5556

57+
typedef struct nmap_t
58+
{
59+
uint32_t idx;
60+
uint8_t pa[IPV4_LEN];
61+
uint8_t ha[ETH_ALEN];
62+
char *vendor;
63+
char *vendor_extra;
64+
} nmap_r;
65+
5666
# endif

head/utils.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,14 @@ int argparse(int argc, char **argv, struct arguments *arguments);
1010
int get_gateway_ip(void);
1111
int get_network_interface(char ifacename[IF_NAMESIZE], uint8_t gateway_pa[IPV4_LEN]);
1212
int get_network_interface_addresses(char name[IF_NAMESIZE], uint8_t ipv4[IPV4_LEN], uint8_t mac[ETH_ALEN], uint8_t netmask[ETH_ALEN]);
13-
int nmapscan(uint8_t gateway_pa[IPV4_LEN], uint8_t netmask[IPV4_LEN]);
13+
nmap_r **nmapscan(struct arguments *arguments);
14+
nmap_r **parse_arp_scan(FILE *fd, const struct arguments *arguments);
15+
void free_arp_scan(nmap_r **scan);
16+
1417

1518
/* interactive.c */
1619
int ask_user_for_gateway();
20+
int ask_attack_type();
1721

1822
/* utils.c */
1923
int is_hbroadcast_addr(const uint8_t addr[ETH_ALEN]);

srcs/interactive.c

+10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
11
# include <stdio.h>
2+
# include "utils.h"
3+
4+
int ask_attack_type()
5+
{
6+
int action;
7+
8+
ASK_ATTACK_TYPE();
9+
while (scanf(" %c", &action) == 0)
10+
ASK_ATTACK_TYPE();
11+
}
212

313
int ask_user_for_gateway()
414
{

srcs/main.c

+11-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
int main(int argc, char **argv)
66
{
77
struct arguments arguments = { 0x0 };
8+
nmap_r **scan = NULL; /* hold result of the arp nmap scan */
9+
int action;
810

911
argparse(argc, argv, &arguments);
1012

@@ -20,12 +22,19 @@ int main(int argc, char **argv)
2022
if (get_network_interface_addresses(arguments.ifacename, arguments.self_pa, arguments.self_pa, arguments.netmask) != 0)
2123
goto err;//error no hardware addr or protocol address for specified interface
2224

23-
if (arguments.target_list == NULL)
24-
nmapscan(arguments.gateway_pa, arguments.netmask);
25+
/* the target arg should be handle around here */
26+
/* arguments.target_list == NULL */
27+
if (!(scan = nmapscan(&arguments)))
28+
goto err;
2529

30+
action = ask_attack_type();
31+
32+
free_arp_scan(scan);
2633
return 0;
2734

2835
err:
36+
if (scan)
37+
free_arp_scan(scan);
2938
ERROR_EXIT();
3039
return 1;
3140
}

srcs/network.c

+86-18
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111
#include <pthread.h>
1212
#include <unistd.h>
1313
#include <sys/time.h>
14+
#include <math.h>
1415

1516
#include "define.h"
1617
#include "utils.h"
18+
#include "struct.h"
1719

1820
/* retreive IPv4 address and mac address of the requestes name interface */
1921
int get_network_interface_addresses(char name[IF_NAMESIZE], uint8_t ipv4[IPV4_LEN], uint8_t mac[ETH_ALEN], uint8_t netmask[ETH_ALEN])
@@ -135,37 +137,103 @@ static void *print_nmap_running(void *argp)
135137
}
136138
}
137139

140+
void free_arp_scan(nmap_r **scan)
141+
{
142+
for (size_t i = 0; scan && scan[i] != NULL; ++i) {
143+
if (scan[i]->vendor != NULL)
144+
free(scan[i]->vendor);
145+
if (scan[i]->vendor_extra != NULL)
146+
free(scan[i]->vendor_extra);
147+
free(scan[i]);
148+
}
149+
if (scan)
150+
free(scan);
151+
}
152+
153+
nmap_r **parse_arp_scan(FILE *fd, const struct arguments *arguments)
154+
{
155+
char *line = NULL;
156+
size_t size = 0;
157+
uint32_t idx = 0;
158+
nmap_r **scan = NULL;
159+
nmap_r *current = NULL;
160+
161+
while (getline(&line, &size, fd) > 0) {
162+
163+
/* new host */
164+
if (strncmp("Nmap scan report for ", line, 21) == 0) {
165+
if (!(scan = realloc(scan, (idx + 2) * sizeof(nmap_r*))))
166+
{ ERROR_MALLOC(); goto err; }
167+
scan[idx + 1] = NULL;
168+
if (!(scan[idx] = calloc(1, sizeof(nmap_r))))
169+
{ ERROR_MALLOC(); goto err; }
170+
scan[idx]->idx = idx;
171+
current = scan[idx];
172+
sscanf(line, "Nmap scan report for %hhu.%hhu.%hhu.%hhu", &current->pa[0], &current->pa[1], &current->pa[2], &current->pa[3]);
173+
++idx;
174+
}
175+
/* fille the mac addr of the current host */
176+
if (strncmp("MAC Address: ", line, 13) == 0) {
177+
if (current == NULL)
178+
{ ERROR_NMAP(line); goto err; }
179+
sscanf(line, "MAC Address: %hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &current->ha[0], &current->ha[1], &current->ha[2], &current->ha[3], &current->ha[4], &current->ha[5]);
180+
current = NULL;
181+
}
182+
free(line);
183+
line = NULL;
184+
}
185+
free(line);
186+
return scan;
187+
188+
err:
189+
free_arp_scan(scan);
190+
return NULL;
191+
}
192+
138193
/* scan the network with arp request using nmap */
139-
int nmapscan(uint8_t gateway_pa[IPV4_LEN], uint8_t netmask[IPV4_LEN])
194+
nmap_r **nmapscan(struct arguments *arguments)
140195
{
141196
char command[128];
142197
FILE *fd;
143198
pthread_t thread; /* used to print hang on to stdout */
144199
int scan_status = 1;
200+
nmap_r **scan = NULL; /* hold result of the arp nmap scan */
145201

146202
/* this ISNT portable at all but give me a simpler anwser than what's on this thread and i put it
147203
https://stackoverflow.com/questions/6657475/netmask-conversion-to-cidr-format-in-c */
148204
snprintf(command, 128, "nmap -PR -sn %hhu.%hhu.%hhu.%hhu/%d",
149-
gateway_pa[0] & netmask[0], gateway_pa[1] & netmask[1],
150-
gateway_pa[2] & netmask[2], gateway_pa[3] & netmask[3],
151-
__builtin_popcount(*(uint32_t*)netmask)
205+
arguments->gateway_pa[0] & arguments->netmask[0], arguments->gateway_pa[1] & arguments->netmask[1],
206+
arguments->gateway_pa[2] & arguments->netmask[2], arguments->gateway_pa[3] & arguments->netmask[3],
207+
__builtin_popcount(*(uint32_t*)arguments->netmask)
152208
);
153-
TELLSCAN(gateway_pa, netmask);
209+
TELLSCAN(arguments->gateway_pa, arguments->netmask);
154210

155-
fd = popen(command, "r");
211+
// fd = popen(command, "r");
212+
fd = fopen("res", "r");
156213
pthread_create(&thread, NULL, print_nmap_running, &scan_status);
157-
if ( fd ) {
158-
char line[256];
159-
while (!feof(fd)) {
160-
char *line = NULL;
161-
size_t size;
162-
getline(&line, &size, fd);
163-
// printf("%s\n", line);
164-
free(line);
165-
}
166-
pclose(fd);
167-
}
214+
215+
if (!(scan = parse_arp_scan(fd, arguments)))
216+
goto err;
217+
pclose(fd);
218+
168219
scan_status = 0;
169220
pthread_join(thread, NULL);
170-
TELLDONESCANNING(2, 256);
221+
222+
/* retreive the gateway HA from the scan and get the amount of entry */
223+
size_t i;
224+
for (i = 0; scan[i] != NULL; ++i) {
225+
if (is_ipv4_equal(scan[i]->pa, arguments->gateway_pa)) {
226+
for (int j = 0; j < ETH_ALEN; ++j)
227+
arguments->gateway_ha[j] = scan[i]->ha[j];
228+
}
229+
}
230+
arguments->scanamount = i;
231+
232+
TELLDONESCANNING(arguments->scanamount, (int)pow(2, ((32 - __builtin_popcount(*(uint32_t*)arguments->netmask)))));
233+
TELLGATEWAYHA(arguments->gateway_ha);
234+
return scan;
235+
236+
err:
237+
pclose(fd);
238+
return NULL;
171239
}

0 commit comments

Comments
 (0)