Use VC # to create a multi-thread TCP connect Scanner

Source: Internet
Author: User
Use VC # to create a multi-thread TCP connect Scanner

(Author: mikespook | Release Date: | views: 250)

Keywords: Network, C #, scan, multithreading
This article has contributed to the hacker security base. The article is owned by the hacker security base and cannot be reproduced without the consent of the hacker security base. Thank you for your cooperation!

If you want to know what services the other computer provides, what tools are most commonly used by you? That's right! Scanner. Now there are hundreds of kinds of scanners. From haktek a long time ago (this is not the earliest scanner, but the first scanner I saw .) X-scan. There are countless foreign countries in China.
Today, I want to teach you how to use VC # to create your own multi-threaded scanner. First, we will take x-scan as an example to briefly introduce the principle of the scanner.
I think we have used X-scan? Have you ever seen it before? (Oh, you always use your own scanner? Yes, you can refer to the next page .) X-scan mainly sets the host address and port range. Another method is TCP or SYN scan. There is nothing to explain about the host address and port range. The key is the TCP/SYN scan method. TCP scan or TCP connect scan is the most basic scan method, which uses the full TCP protocol for connection attempts. When the connection is successful on the same host, the connection is cut off and the next port is switched to verify that the connection is successful. Try again and again until all port scans are completed. The TCP connect scanner is easy to create and fast to scan without special permissions (this is a UNIX host permission issue, which is not covered in this article .). However, TCP connect scanning has one of the biggest drawbacks. It is easy to detect, and it is also possible to filter out well-protected hosts. System logs are recorded. SYN scan is also called semi-scan. In fact, it means that the TCP three-way handshake is not completed for the last time. Initiate a connection request. When receiving the SYN signal from the host, that is, the connection signal is allowed, the next port is switched without sending connection confirmation. In this way, the connection to the host is not completed and is not logged. Make up for the shortcomings of TCP connect. However, it should be noted that most servers now record this connection, because SYN scanning is too popular.
Here I want to explain why I want to use VC # as a development tool. C # It may be disdain in the eyes of many experts. However, C # is a language with relatively balanced development efficiency and operation efficiency. The development environment of VC # gives full play to its advantages. With the powerful support of the. NET class library, it is suitable for beginners to get started quickly.
Well, let's talk about it. Next we will start to build our own TCP connect scanner.
Create a new project for a Windows Application in VC # and name it scantest. The content in the brackets below is the property settings of the control. Add a button (Name: btnscan text: Scan), a text box (Name: txtip), two numericupdown controls (name1: numportmin value1: 1 maximum1: 65535 minimum1: 1, name2: numportmax valude2: 1024 maximum1: 65535 minimum1: 1), and a ListBox (Name: lbresult) used to display scan results ). 1:
Figure 1
After the program interface is designed, the code is started below.
Since the TCP connect scanner is required, the TCP Connection Library is indispensable. Here we mainly use two classes: system. net. IPaddress and system. net. sockets. tcpclient. You need to include the namespace of these two classes in your form. CS file. As follows:
Using system. net;
Using system. net. Sockets;
These two classes have very powerful functions, but we can use only one of them. If you are interested, you can check msdn to learn more.
Add a method isportopen to the form class. As follows:
Public bool isportopen (string IP, int port)
{
Try
{
Tcpclient client = new tcpclient (); // create a tcpclient instance
IPaddress address = IPaddress. parse (IP); // convert a string-type IP address to IPaddress
Client. Connect (address, Port); // connect to the port of the server address
Client. Close (); // The connection is successful. Disconnect immediately.
Return true; // return true. The connection is successful.
}
Catch (exception e) // connection failure tcpclient class throws an exception, caught here
{
Return false; // if false is returned, the connection fails.
}
}
This method is easy to use. For example, add the following code to the btnscan click event:
Private void btnscan_click (Object sender, system. eventargs E)
{
If (this. isportopen ("127.0.0.1", 80 ))
Lbresult. Items. Add (object) "local computer port 80 connection successful ");
Else
Lbresult. Items. Add (object) "local computer port 80 connection failed ");
}
Click the btnscan button on the form to check whether port 80 of the Local Computer is open.
Now you are approaching your goal.
This only checks whether a port is open and does not control which computer to check. Well, make the following changes to the above Code:
Private void btnscan_click (Object sender, system. eventargs E)
{
For (INT I = (INT) numportmin. value; I <= (INT) numportmax. value; I ++)
If (this. isportopen (txtip. Text, I ))
Lbresult. Items. Add (object) (txtip. Text + ":" + I. tostring () + "port connection successful "));
Else
Lbresult. items. add (object) (txtip. text + ":" + I. tostring () + "port connection failed"); // in general, the scan program does not record the port of the connection failure. This is only for demonstration.
}
Compile and run the project, and enter your target address in the txtip text box, such as 127.0.0.1 or 192.168.1.14. Set the numportmin and numportmax values, such as 50 and 100, to scan ports from 50 to 100. I suggest that the two values are not too big, or you have to be patient. I will explain why later. Click btnscan. The program has no response !!!! As long as you do not set the scan port range too large, the scan results will be displayed in a few seconds.
Well, are you very excited? You can scan any port range on a computer.
Wait. Don't worry about the experiment. We have another serious problem that cannot be solved: Program interrupt response!
Why? In fact, we use a loop here. When you click the btnscan division Click Event, the program runs in this loop. The response does not continue until the loop execution ends. Well, I know why. Let's see how to solve this problem.
Let's talk about the preparations you have to make. First, let your form. CS file contain the namespace system. threading. The content in this namespace is used by the control thread. Then add the following two fields to the form class:
Threadstart;
Thread thread;
Add the thread construction content to the constructor of the form as follows:
Public frmmain ()
{
Initializecomponent ();
Threadstart = new threadstart (scanthread); // the two statements you want to add
Thread = new thread (threadstart );
}
Scanthread is a method you want to add. This method must have no parameters and the return value is void. Put the code in the Click Event of the btnscan button in this scanthread method:
Public void scanthread ()
{
For (INT I = (INT) numportmin. value; I <= (INT) numportmax. value; I ++)
{
If (this. isportopen (txtip. Text, I ))
Lbresult. Items. Add (object) (txtip. Text + ":" + I. tostring () + "port connection successful "));
/* Else
Lbresult. Items. Add (object) (txtip. Text + ":" + I. tostring () + "port connection failed "));
We only record successful ports, So I blocked these codes. However, I keep these comments to make them clearer. */
This. Text = "scantest is scanning the port:" + I. tostring (); // here is what the original code does not have, just to make it clearer.
}
}
Code for modifying the Click Event of the button btnscan:
Private void btnscan_click (Object sender, system. eventargs E)
{
If (thread. threadstate. Equals (threadstate. Running) // judge whether the thread is running
{
Thread. Abort (); // interrupt thread running
Btnscan. Text = "scan ";
}
Else
{
Thread. Start (); // start the thread
Btnscan. Text = "stop ";
}
}
Compile and run the project to see the effect. We can understand the scanning progress and the program will not stop responding. Haha, great!
Finished? No !!! This is not multithreading. Now you have created only one thread to scan the ports slowly one by one. Then we will continue our work. "Take it easy! You will see New York ."
Before we create a multi-thread scan, we have a problem to solve: because we cannot call the thread function by passing parameters, therefore, it is critical to let the thread know which port to scan. By the way, public variables are used. Next we will make a big transformation to the program.
First, modify the thread declaration in the Form class as follows:
Threadstart;
Thread [] thread;
And add two integer fields to the form class:
Int port; // The port currently being scanned
Int portmax; // maximum number of scan ports
Modify the code in the form constructor as follows:
Public frmmain ()
{
Initializecomponent ();
Threadstart = new threadstart (scanthread );
Thread = new thread [10]; // 10 threads are set here
For (INT I = 0; I <10; I ++) // use a loop to initialize 10 threads
{
Thread t = new thread (threadstart );
Thread [I] = T;
}
}
Since it is multithreading, the execution thread and stop thread are of course not the same as the single thread:
Private void btnscan_click (Object sender, system. eventargs E)
{
If (btnscan. Text. Equals ("scan") // I am lazy here. Good programs should not write this way.
{
Portmax = (INT) numportmax. value; // variable used to initialize thread execution
Port = (INT) numportmin. value;
For (INT I = 0; I <10; I ++) // The loop execution thread is still used here.
Thread [I]. Start ();
Btnscan. Text = "stop ";
}
Else
{
For (INT I = 0; I <10; I ++) // The thread is still stopped by loop.
Thread [I]. Abort ();
Btnscan. Text = "scan ";
}
}
Now, we need to rebuild the most critical function scanthread. Please carefully explain my Annotations:
Public void scanthread ()
{
Lock (this) // to avoid scanning the same port repeatedly, set the following execution as a critical section, that is, only one thread can execute code in the critical section at the same time.
{
While (Port <= portmax) // The for statement is not used here because the port does not increase one by one for a single thread.
{
If (this. isportopen (txtip. Text, Port ))
Lbresult. Items. Add (object) (txtip. Text + ":" + port. tostring () + "port connection successful "));
/* Else
Lbresult. Items. Add (object) (txtip. Text + ":" + I. tostring () + "port connection failed "));
We only record successful ports, So I blocked these codes. However, I keep these comments to make them clearer. */
This. Text = "scantest is scanning port:" + port. tostring ();
Port ++;
}
}
}
It has a critical section, supports multi-thread execution, and does not conflict with each other. A very good piece of code. Run it to see?
(...... Long wait ......)
"Are you sure this is multithreading ?" Some readers may finally have to ask. Yes, this is indeed multi-thread. But there is a problem with our code !!! The scanning speed is very slow.
We noticed that my critical section is the entire scan function. At the same time, only one thread can perform scanning. Although multiple threads are set, the execution speed is not much faster than that of a single thread. It is even slower (if the thread switching time is counted ). What should I do? First, let's see why we need to set this critical section to solve the problem of multi-thread execution.
If there is no critical section, a thread may execute the IF (this. isportopen (txtip. Text, Port) statement when it runs. One of your ports has been skipped and has not been scanned. We must put all the operations on the variable port in the critical section. Ensure that when a thread uses the variable port or operates on it, other threads must wait. The scanthread function above satisfies this requirement well. However, because the port detection code is also included in the critical section, only one thread can be operated during port detection.
If you know the problem, use your brains to solve the problem. Now we need to put the operation on the variable port into the critical section for protection. At the same time, the isportopen operation should be placed out of the critical section to facilitate concurrent multi-thread scanning.
Then the new scanthread function is generated:
Public void scanthread ()
{
While (true) // we keep the loop going
{
Int nowport; // The port to be scanned. This is a local variable.
Lock (this) // enters the critical section
{
If (Port> portmax)
Return; // stop the function when the maximum port is scanned.
Else
{
Nowport = port; // otherwise, set the real scan Port
Port ++; // jump to the next port
}
} // Exit critical section
If (this. isportopen (txtip. Text, nowport) // note the nowprot variable I used here. At this time, the port operations of other threads on the variable port do not affect the port detection. nowport is a local variable and is not affected by other threads.
Lbresult. Items. Add (object) (txtip. Text + ":" + nowport. tostring () + "port connection successful "));
/* Else
Lbresult. Items. Add (object) (txtip. Text + ":" + I. tostring () + "port connection failed "));
We only record successful ports, So I blocked these codes. However, I keep these comments to make them clearer. */
This. Text = "scantest is scanning port:" + nowport. tostring ();

}
}
Now you can compile and run it again? Is it faster?
So far, a standard multi-threaded TCP connect scanner is ready. Here I want to add some simple instructions (by the way, I will cheat you more about the draft fee, ~).
1. C # itself is not very fast, so the speed of this scanner is definitely not as high as that of the C/C ++ scanner.
2. I have not set the number of threads as X-scan does. But I think this is no longer a problem. (Tip: You just need to find a proper place to put the code about thread initialization in the constructor, add some controls, and adjust the code to control the number of threads .)
3. Although this is just a scan of the port of a computer, I already have an answer to the question of how to scan multiple hosts. (It is not difficult for you to change the host address while changing the port ?)
In fact, a good scanner should also have many functions, such as vulnerability detection. However, knowing the basic principles of these features should not be a problem. You can check the opened ports that scan for vulnerabilities by sending specific data.
Have a good time. ^ @ ^ The End.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.