Ӕ Central

Welcome to the hidden lair of AE Central. From cars and beer to hardcore software development, you might find interesting topics in all areas. Feel free to browse!
Home

To menu | To search

Multi-threaded port scanning in Delphi

, 20:41 - Permalink

Delphi 7There were several times when my team had to do a port scan in a commercial environment to discover rouge or lingering devices on the network. I always had troubles finding a portable, commercial-free, easy-to-use, fast and trusted application so I decided to write my own.
The idea came from this blog, but it was far away from sufficient in a mass port scanner. Sometimes the Winsock connect function times out in 20 seconds, so checking only 3 ports with the original procedure would take a minute. I had to do a manual timeout, which I achieved by calling the connect function in a separate thread, which I forcefully terminate after 500 ms. Since in a port scanner we want to maximize the speed I needed to put the above in a thread, so I can launch multiple port checks at the same time.
 
Type
  TConnectRec = record
   Socket: Integer;
   Client: sockaddr_in;
   Success: Boolean;
  end;
  PConnectRec = ^TConnectRec;
 
  TWellKnownPorts = Record
   PortNR: Word;
   PortFunction: String;
  End;
 
  TCheckThread = class(TThread)
  protected
    PortIndex: Integer;
    IPToCheck: String;
    ConnectRec: TConnectRec;
    procedure Execute; Override;
  published
    Constructor Create(In_PortIndex: Integer; In_IP: String);
  End;
 
const
  WellKnownPorts: Array[0..20] Of TWellKnownPorts =
  ( (PortNR: 20; PortFunction: 'FTP data'),
    (PortNR: 21; PortFunction: 'FTP control'),
    (PortNR: 22; PortFunction: 'SSH'),
    (PortNR: 23; PortFunction: 'Telnet'),
    (PortNR: 25; PortFunction: 'SMTP'),
    (PortNR: 80; PortFunction: 'HTTP'),
    (PortNR: 110; PortFunction: 'POP3'),
    (PortNR: 115; PortFunction: 'SFTP'),
    (PortNR: 139; PortFunction: 'NetBIOS Session'),
    (PortNR: 143; PortFunction: 'IMAP'),
    (PortNR: 389; PortFunction: 'LDAP'),
    (PortNR: 443; PortFunction: 'HTTPS'),
    (PortNR: 445; PortFunction: 'SMB over IP'),
    (PortNR: 601; PortFunction: 'Syslog'),
    (PortNR: 631; PortFunction: 'Internet Printing Protocol'),
    (PortNR: 860; PortFunction: 'iSCSI'),
    (PortNR: 1433; PortFunction: 'MSSQL'),
    (PortNR: 3268; PortFunction: 'Microsoft Global Catalog'),
    (PortNR: 3306; PortFunction: 'MySQL'),
    (PortNR: 3389; PortFunction: 'Remote Desktop Connection')
  );
 
  TCP_Connection_Timeout = 500;
 
procedure Conn(Parameter: Pointer);
begin
 PConnectRec(Parameter).Success := connect(PConnectRec(Parameter).Socket,PConnectRec(Parameter).Client,SizeOf(PConnectRec(Parameter).Client)) = 0;
end;
 
Constructor TCheckThread.Create(In_PortIndex: Integer; In_IP: String);
Begin
 inherited Create(False);
 PortIndex := In_PortIndex;
 IPToCheck := In_IP;
 ConnectRec.Success := False;
End;
 
Procedure TCheckThread.Execute;
var
 client: sockaddr_in;
 sock, ret: Integer;
 wsdata: WSAData;
 ThId: Cardinal;
 ThH: THandle;
Begin
 ret := WSAStartup($0002, wsdata);
 If Ret <> 0 Then Exit;
 Try
  client.sin_family := AF_INET;
  client.sin_port := htons(WellKnownPorts[PortIndex].PortNR);
  client.sin_addr.s_addr := inet_addr(PChar(IPToCheck));
  sock := socket(AF_INET, SOCK_STREAM, 0);
  ConnectRec.Socket := sock;
  ConnectRec.Client := Client;
  ThH := BeginThread(nil,0,Addr(Conn),Addr(ConnectRec),0,ThId);
  If ThH <> 0 Then Begin
                   If (WaitForSingleObject(ThH,TCP_Connection_Timeout)<>WAIT_OBJECT_0) And (sock<>INVALID_SOCKET) Then closesocket(sock);
                   CloseHandle(ThH);
                   End;
 Finally
  WSACleanup;
 End;
End;

 
You can launch the process with TCheckThread.Create(0,'127.0.0.1') or you can create an array of TThread objects - I'll leave this part to you. You can see if the port check is done by calling WaitForSingleObject, and the result in CheckThread.ConnectRect.Success. For easy understanding the WellKnownPorts[CheckThread.PortIndex].PortFunction will return the general use of the port instead of a port number.
 
Enjoy!

Comments

1. On 2018.10.18, 06:59 by site

Excellent blog you have here but I was curious about if you knew of any community
forums that cover the same topics talked about in this article?
I'd really like to be a part of online community
where I can get opinions from other knowledgeable individuals that share the same interest.
If you have any recommendations, please let me know.

Appreciate it!

Add a comment

HTML code is displayed as text and web addresses are automatically converted.

This post's comments feed