Translation Works 5 Coding a TCP Connect Port Scanner: Using VLSM REV 1.0

xiaoxiao2021-03-06  65

Translation Works 5 Coding a TCP Connect Port Scanner: Using VLSM REV 1.0 ???? --- Nightcat

This article assumes that readers have already understood two articles in this series, or already have C base and BSD socket programming skills. At the same time, it is assumed to understand the IP address and subnet knowledge.

-------------------------------------------------- -------------------- ****** Translator supplements the subnet division method, I hope to deepen everyone's understanding: *****

?

IP address planning is always a very headache network and mask calculation: Title 1: The IP address of a host is 202.112.14.137, the mask is 255.255.255.224, requiring the network address and broadcast address of the network where this host is located.

Workaround: Conventional Measures is to convert this host address and subnet mask into binary numbers, and both logic and operations can be obtained. In fact, everyone can get another way to get another method: 255.255.255.224 The IP address accommodated by 256-224 = 32 (including network addresses and broadcast addresses), then the network address with this mask must be It is a multiple of 32. The network address is the beginning of the subnet IP address, the broadcast address is end, and the host address that can be used is within this range, so only 128 of the multiple of 32 and 32, so the network address is 202.12.14.128. The broadcast address is a network address of the next network. The next 32 multiples are 160, so the broadcast address can be obtained 202.112.14.159

?

Title 2: "According to the number of subnet addresses and calculates the subnet mask according to the number of hosts of each network. This can also be calculated as described above.

For example, a subnet has 10 hosts, then 10 1 1 1 = 13 IP addresses are required for this subnet. (Note that the first 1 refers to the gateway address required for this network connection, and the two 1 of the two 1 refer to the network address and broadcast address.) 13 less than 16 (16 equal to 2), the host The bit is 4 digits. 256-16 = 240, so the subnet mask is 255.255.255.240.

If a subnet has 14 hosts, many of the frequent mistakes of many students are: still allocating subnets with 16 address space, and forgetting to assign addresses to the gateway. This is wrong, because 14 1 1 1 = 17, greater than 16, so we can only assign subnets with 32 addresses (32 equal to 2) space. At this time, the subnet mask is: 255.255.255.224.

Class A subnet classification: 192.168.1.1/12

Each subnet has 2 ^ (32-12) host

There are 2 ^ (16-12) B network sections there are 2 ^ (24-12) C network segments

There are 2 ^ (16-12) * 2 ^ (24-12) * 256-2 host

?

Class B Subnet Category: 192.168.1.1/19

Each subnet has 2 ^ (32-19) main unit

There are 2 ^ (24-19) C network segments

There are 2 ^ (24-19) * 256-2 hosts in all network segments.

?

Class C subnet division method:

192.168.1.1/27

Each subnet has 2 ^ (32-27) main unit

There are 2 ^ (32-27) * 256-2 hosts

I hope that the above instructions allow you to understand how to divinate the childnet and how to computer subnet. ------------------------------------]

Most ports and vulnerabilities scanners assume that users just want to scan a subnet, although it will work for a long time, it can be slightly limited. If an attacker displays the target host with a target host with a larger subnet mask (VLSM) and insect-free domain routing (CIDR), then the list of the subnets is a little laborious. In this article I merged slightly, the growth-length subnet mask and the unsuccessful domain routing in a network scanner. I have selected B address 172.16.0.0 as an example of work, to run through the entire article.

• After searching for the existing code and algorithm, I finally came to ipsc.sourgeforge.net. This is the only calculation subnet method I can find with C. There are a lot to write in Jacascript, but those of the algorithms are not good. I have a little trust this article is the first article of this article on the online article. If not, please contact me. I really want to see other solutions.

Sometimes my explanation may be a bit difficult to understand, but I have confidence to divide the problem into several parts while analyzing them at the same time.

?

East-length subnet mask review

Let us assume the target network, INC. A large ISP has been assigned 172.16.0.0/16. We will focus on their four routers. Router-x direct routing, Router-a, router-b, and Router-c is connected to Router-X by point-to-point frame relay

Here is a simple graphical representation:

172.16.14.32/27 <- Router-A -> ------------------ ??????? | ------------ -------- | ????????? 172.16.14.132/30 / ?????????? | 172.16.1.0/24 ?????? / ???? ???? | 172.16.14.64/27 <- router-b -> -------------------------- <- Router-x -> ???????????????????????????????? 172.16.14.136/30? / ???????? |???? ????????????????????????????????? | 172.16.2.0/24172.16.14.96/27 <- router-c -> ---------------- / ??????? | -------------------- | ???? ????? 172.16.14.140/30

An ignorant attacker may specify their tool to scan 172.16.0.0.0/16, this entire Class B network. So what is the way to choose from?

We can merge a program to scan the IP address from an extensible file. (See Paper # 2 of this series) These IPs can easily get from an existing port scanner icon NMAP:

[MODULAR @ Truncode] $ nmap -sl? -n 172.16.14.32/27 | grep '^ Host' | / CUT -D '(' -f 2 | cut -d ')' -f 1> target-ips.txt

This gives the IP address list between our 172.16.14.32-63. When we can enter a list to our scanner. The method is good, but it is a bit difficult to use.

We think about a scanner later, it can easily perform a task.

?

] strtok ()

This TCP port scanner should be able to get a parameter 172.16.14.32/27. For example:? Use '/' to separate into two variables as separated, I will call these variables, the network number, and mask. In order to separate Argv [1], we use a convenient STRTOK function (MAN 3 STRTOK as the following prototype): ----------------------- -------------------------------------------------- - # include ?????? char * STRTOK (Char * S, const char * delim); ?????? -------------------- -------------------------------------------------- -----

This man page solution says that a logo is a string, but it is not all match the 'delim' string. In this case 'delim' uses '/'. We will need to call strtok () twice, in order to contain '/', the string of the following. The second call strtok () should set the first parameter as null, because each call returns a pointer to the next tag and that there is no more tags with null, my description always word The MAN page is separated.

As the following applet uses STRTOK () in the scanner:

-------------------------------------------------- ------------------------- # include

#include

#include

Int main (int Argc, char * argv []) {??? char * network, * mask

??? NetWork = Strtok (Argv [1], "/"); ??? Mask = strtok (null, "/");

??? * print out tokens just for the sake ???? * of example. ???? * / ???printf ("NetWork =% S / NMASK =% S / N", Network, Mask;

??? Return 0;} ------------------------------------------- --------------------------------

Compile this example and run it: [MODULAR @ Truncode] $ GCC STRTOK_EX.C -O STRTOK_EX [MODULAR @ Truncode] $ ./strtok_ex 172.16.14.32/27network = 172.16.14.32mask = 27

Everything is fine, we focus on the technology of displacement.

] Bit operation

The IP address of the target network must be converted to an integer before the start of the operation. Change each decimal to binary integers, making it easier: 172 = 1010110016? = 1000014? = 111032? = 100000

Imagine 24 0 as placeholders (thinking about IP address - 4 decimal). Visualization is more helpful. Each decimal will be moved to it suitable:

172 << 24 --------- 10101100 00000000 0000000 000,00000

16 << 16 -------- 00000000 00010000 0000000 000,00000

14 << 8 -------- 00000000 00000000 0001110 00000000

32 -------- 00000000 00000000 00 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 ------------------- -------------------------------- ?????? 10101100 00010000 0001110 00100000 = 2886733344

This now has this - an integer represents a decimal IP address separated by a bit number.

You may immediately pay attention to this integer is very large. A unsigned long integer has a variable range from 0 to 4,294,967,295 This should be large enough.

A function is written based on previous examples:

-------------------------------------------------- ------------------------- unsigned long convert_ip (const char * t_addr) {??? int = 0; ??? int in in = = 0 ??? INT OCTET3 = 0; ??? INT OCTET4 = 0; ??? IF (SSCANF (T_ADDR, "% D.% d.% d.% d", ?? & octet1, & octet2, & ocT3, & ocT4) <1) ??? {? Fprintf (stderr, "not a standard IPv4 ip address./n") ;? EXIT (1); ???} ??? Return ((ocTet1 << 24) | (OcTet2 < <16) | (ocTet3 << 8) | ocTet4);} ----------------------------------- ----------------------------------------

If you know the example of displacement, this function should be like a block cake. Function SSCANF () expects "% d.% D.% D.% D" format in string variable t_addr and separated each integer into new variables. At that time we initialize our operations and returns an integer of unsigned long integers with << and | operators. This returned integer is of course the first address of the subnet.

Add this new Convert_ip () function to the first example program:

-------------------------------------------------- ------------------------- # include

#include

#include

Unsigned long convert_ip (const char * t_addr);

INT main (int Argc, char * argv []) {? char * network, * mask;? network = strtok (argv [1], "/") ;? mask = strtok (null, "/");? / * Print out tokens just for the sake? * of example.? * /? printf ("NetWork =% S / NMASK =% S / N", network, mask) ;? Printf ("" Our TransforMed IP Address% s% Lu / N ", ??? argv [1], convert_ip (argv [1])) ;? Return 0;}

UNSIGNED Long Convert_ip (const char * t_addr) {? int = 0;? int = 0;? int = 0;? IF (SSCANF (T_ADDR, "% D.% d.% D.% d ", ???? & octet1, & ocT2, & octet3, & octet4) <1)? {?? fprintf (stderr," not a standard ipv4 ip address./n" ";? perxit(1);? }? Return ((OcTet1 << 24) | (OcTet2 << 16) | (OcTet3 << 8) | c (} --------------------- -------------------------------------------------- ----] Calculate mask offset

Subnet, / 27 or 255.255.255.224 in this example is selected as this subnet mask. This gives 2 ^ 5 = 32 addresses in each subnet, when this conversion IP address is added to 32 and minus 1. Let's look back at the Convert_ip () function to us integer in the 172.16.14.32 network. First, a form of integer 2886733344 and converted into binary:

10101100 0001000000001110 00011111

Add 32: ----------- 10101100 0001000000001110 0001111000000000000000000000000000000000 ------------------------------------------------------------------------------------------------------ ------- 10101100 00010000 00001110 0011111

This way you can see this new address that just gives us 32 IPs. Our new function returns this number as an end of a subnet:

-------------------------------------------------- ------------------------- unsigned long address_masking (const char * t_addr, int mask) {? if (Mask> 32 || Mask <0) / * Check for valid value * /? {?? fprintf (stderr, "not a valid subnet mask./n" ";? perexit( 1 );? }?return ((- )pow(2, 32 - Mask ) Convert_ip (t_addr) -1);} --------------------------------------- ------------------------------------

?

] Convert the modified IP address to an integer

This is what we can write a complete VLSM IP generating program. This algorithm that is used is basically a Convert_ip reverse function. The AND operator is used to zero the eight-bit bytes that are not required. In summary, all the bits were moved to the right. Take a look at the first integer we used.

10101100 00010000 0001110 00100000 = 2886733344

10101100 00010000 0001110 00000000000000000000000000000 & ------------------------------------ 10101100 000,000 = 2885681152

Move this integer now to the right ....

2885681152 >> 24 --------------- 00000000 00000000 0000000 10101100 = 172, etc.

Here is a function of a decimal IP address transformed into an integer:

-------------------------------------------------- ------------------------- CHAR * REVERSE_INT (UNSIGNED Long Addr) {? static char * buffer [buf_size] ;? snprintf ((char *) Buffer, buf_size, "% d.% d.% d.% d", ??? (addr & 0xff000000) >> 24, ??? (addR & 0x00FF0000) >> 16, ??? (AddR & 0x0000FF00) >> 8,?? (AddR & 0x000000FF)); roll ((char *) buffer;} ------------------------- --------------------------------------------------

The snprintf () function is format "% d.% d.% d.% d" and write string 'buffer'. Any one familiar to write BPF filters in TCPDUMP should know the logic of and and 0xff, in the Reverse_int () function.

] A routine:

-------------------------------------------------- ------------------------- # include

#include

#include

#include

#define buf_size 128

Unsigned long communication_ip (const char * t_addr); unsigned long add_masking (const char * t_addr, int mask); char * reverse_int (unsigned long addr);

INT main (int Argc, char * argv []) {??? char * network, * mask; ??? unsigned long start = 0, end = 0, current = 0;

???? * Separate Network and mask INTO TWO ???? * usable tokens ???? * / ??? NetWork = STRTOK (Argv [1], "/"); ??? mask = strtok (NULL, "/");

??? START = Convert_ip; ??? end = add_masking (network, atoi (mask));

??? for (current = start; current <= end; current ) ??? {? printf ("% s / n", reverse_int (current)); ???}

??? RETURN 0;}

UNSIGNED Long Convert_ip (const char * t_addr) {??? int = 0; ??? Int actt2 = 0; ??? INT OCTET4 = 0;

??? IF (SSCANF (T_ADDR, "% D.% d.% d.% d", ?? & octet1, & octet2, & ocT3, & oct4) <1) ??? {fprintf (stderr, "not a standard IPv4 IP address./n ") ;? EXIT (1); ???} ??? Return ((OcTet1 << 24) | (OcTet2 << 16) | (OcTet3 << 8) | c o} Unsigned Long Add_masking (const char * t_addr, int mask) {??? if (Mask> 32 || Mask <0) / * check for valid value * / ??? {fprintf (stderr, "not a valid subnet mask./ N ") ;? EXIT (1); ???} ??? Return ((int) POW (2, 32 - Mask) Convert_ip (T_ADDR) -1);}

Char * reverse_int (unsigned long addr) {??? static char * buffer [buf_size]; ??? snprintf ((char *) buffer, buf_size, "% d.% d.% d.% d",??? ? (AddR & 0xFF000000) >> 24, ???? (addR & 0x00FF0000)? >> 16, ???? (addR & 0x0000FF00) >> 8, ????? (addr & 0x000000FF);? ?? return ((char *) buffer;} -------------------------------------- -------------------------------------

Make sure don't forget to compile compilation is with a MantH library. This is necessary for POW ().

[Modular @ visioncode] $ gcc -o ipgen ipgen.c -lm [modular @ visioncode] $ ./ipgen 172.16.14.32/27172.16.14.32172.16.14.33172.16.14.34172.16.14.35172.16.14.36172.16.14.37172.16.14.38172. 16.14.39172.16.14.40172.16.14.41172.16.14.42172.16.14.43172.16.14.44172.16.14.45172.16.14.46172.16.14.47172.16.14.48172.16.14.49172.16.14.50172.16.14.51172.16.14.52172.16.14.53172.16.14.54172.16.14. 55172.16.14.57172.16.14.58172.16.14.59172.16.14.60172.16.14.61

It's so good, we can get a list of IP addresses of the target host network 172.16.14.32/27.

?

] Connect the scanner in the TCP port to VLSM

Now is the time when all new information is used, and the first and second article of this series understand the port scan code.

-------------------------------------------------- ------------------------- # include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#DEFINE TRUE? 1

#DEFINE FALSE? 0 # define buf_size 128

Unsigned long communication_ip (const char * t_addr); unsigned long add_masking (const char * t_addr, int mask); Char * Reverse_int (unsigned long addr); int portscan (char * remote_ip, u_short port);

INT main (int Argc, char * argv []) {??? struct hostent * he; ??? Struct server * srvc; ??? Struct in_addr t_addr; ??? int start_port, end_port, counter; ??? Int i; ???? ??? / * variables for vlsm routines * / ??? char * network, * mask; ??? unsigned long start = 0, End = 0, current = 0;

??? * start and ends * / ??? START_PORT = ATOI (Argv [2]); ??? End_port = ATOI (Argv [3]);

???? * Separate Network and mask INTO TWO ???? * usable tokens ???? * / ??? NetWork = STRTOK (Argv [1], "/"); ??? mask = strtok (NULL, "/");

??? START = Convert_ip; ??? end = add_masking (network, atoi (mask));

??? for (current = start; current <= end; current ) ??? {? t_addr.s_addr = inet_addr (Reverse_int (current));

? if ((he = gethostbyaddr ((t_addr.s_addr), ??? sizeof (Reverse_int), AF_INET) == NULL) {???? Herror ("gethostbyname");? ???????????????????printf ("/ n") ;? Printf ("Interesting Ports ON% S (% s) / n / n", ?? he-> h_name, Reverse_Int (current));? "" port / tState / TService / N "); ?? for (counter = start_port; counter <= end_port; counter )? {??? ???? = ((i = portscan) Reverse_int (current), counter == 0)) ?? Continue; ???? else ?? SRVC = GetServByport (Htons (counter), "tcp"); ???? ???????printf "% D / TCP / TOPEN / T% S / N", Counter, ????? (SRVC == NULL)? "unknown": SRVC-> S_NAME);?} ???} ??? Return 0 }

UNSIGNED Long Convert_ip (const char * t_addr) {??? Int actt1 = 0; ??? INT OCTET2 = 0; ??? INT OCTET3 = 0; ??? INTTET4 = 0; ??? IF (SSCANF (T_ADDR) , "% d.% d.% d.% d", ?? & octet1, & itist2, & ocT3, & octet4) <1) ??? {? fprintf (stderr, "not a standard IPv4 ip address./n"); ? EXIT (1); ???} ??? Return ((ocTet1 << 24) | (OcTet2 << 16) | (OcTet3 << 8) | ocTet4);

Unsigned long add_masking (const char * t_addr, int mask) {??? if (Mask> 32 || Mask <0) / * Check for Valid Values ​​* / ??? {fprintf (stderr, "not a valid subnet mask ./N ") ;? EXIT (1); ???} ??? Return ((int) POW (2, 32 - Mask) Convert_ip (T_ADDR) -1);}

Char * reverse_int (unsigned long addr) {??? static char * buffer [buf_size]; ??? snprintf ((char *) buffer, buf_size, "% d.% d.% d.% d",??? ? (AddR & 0xFF000000) >> 24, ???? (addR & 0x00FF0000)? >> 16, ???? (addR & 0x0000FF00) >> 8, ????? (addr & 0x000000FF);? ?? Return ((char *) buffer;}

INT portscan (char * remote_ip, u_short port) {??? int suck_fd; ??? int state; ??? Struct SockAddr_in target;

??? suck_fd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); ??? Memset (& Target, 0, Sizeof (Target)); ??? Target.sin_Family ?? = AF_ITDR.S_ADDR = INET_ADDR (transote_ip); ??? Target.sin_port = HTONS (port);

??? IF (connection (Sock_fd, (Struct SockAddr *) & target, sizeof (target)) == 0) ??? {? state = true; ???} else {? state = false; ???}? ?? close (sock_fd); ??? Return State;} ------------------------------------ -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

It's so good, but this code is undeniable and not good, but it can run well. When as an example, you can organize and make it better and structured. But in the next article I will do, when I introduce multiple threads. It's said!

转载请注明原文地址:https://www.9cbs.com/read-119173.html

New Post(0)