Forum: PC-Programmierung TCP-Portscnanner in C


von Manuel S. (doc-snyder)


Lesenswert?

Hallo Leute

Ich habe mit folgendem Programm 2 Probleme:
1
#include <stdio.h>
2
#include <windows.h>
3
4
5
6
int main(int argc, char **argv)
7
{
8
  //Definitionen und Deklarationen
9
  int temp;
10
  int begin;
11
  int end;
12
  int sd;
13
  int loop;
14
  WSADATA firstsock;
15
  char hostname[100];
16
  struct sockaddr_in HOST_ADDR;
17
18
19
  // Input
20
  printf("Enter ip to scan :\t");
21
  gets(hostname);
22
  if(!(isdigit(hostname[0])))
23
    exit(EXIT_FAILURE);
24
  printf("Enter starting port :\t");
25
  scanf("%d" , &begin);
26
  printf("Enter ending port :\t");
27
  scanf("%d" , &end);
28
  system("cls");
29
30
31
  //Initialisiere winsock
32
  if (WSAStartup(MAKEWORD(2,0),&firstsock) != 0)
33
    {
34
    fprintf(stderr,"WSAStartup() failed!");
35
    exit(EXIT_FAILURE);
36
    }
37
38
39
  //Host definieren
40
  HOST_ADDR.sin_family = AF_INET;
41
  HOST_ADDR.sin_addr.s_addr = inet_addr(hostname);
42
43
44
  // Alle Daten Ausgeben und mainloop starten
45
  printf("Hostname:\t%s\t%d\n"
46
      "Startport:\t%d\n"
47
      "Endport:\t%d\n\n", hostname, HOST_ADDR.sin_addr.s_addr, begin, end);
48
49
50
  // Schleife um die einzelnen Ports abzufragen
51
  for(loop = begin; loop <= end; loop++)
52
    {
53
    HOST_ADDR.sin_port = htons(loop);
54
55
    //Socket öffnen
56
    sd = socket(AF_INET , SOCK_STREAM , IPPROTO_TCP);
57
    if (sd == -1)
58
      printf("Socket could not be created.\n");
59
60
    //Versuche mit Port zu verbinden
61
    temp = connect(sd , (struct sockaddr *)&HOST_ADDR , sizeof HOST_ADDR);
62
    if (temp == -1)
63
      printf("Port %d is closed.\n", loop);
64
    else
65
      printf("Port %d is open\n", loop);
66
67
    //Socket schließen
68
    temp = closesocket(sd);
69
    if (temp == -1)
70
      printf("Socket %s:%d could not be closed properly.\n",hostname, loop);
71
    }
72
73
74
  //Beende winsock
75
  WSACleanup();
76
77
78
  printf("Portscan has finished\n");
79
  system("pause");
80
  return EXIT_SUCCESS;
81
}


Erstens funktioniert er nicht mit dem localhost (127.0.0.1) und zweitens 
ist das kreieren der Sockets ziemlich langwierig. ( 1 Portscan dauert 
ungefähr eine halbe Sekunde - bei 65k ports - phu ...)
Hat jemand eine Idee wie ich dem Programm ein bisschen Feuer unterm 
A.... machen und/oder mich selbst scannen kann?
Ich sollte vllt dazu erwähnen, dass ich wenn ich andere Hosts scanne mit 
wireshark die Pakete auf dem Interface flitzen sehe. Wenn ich aber 
localhost scanne nicht( ist vllt auch normal bin mir aber nicht sicher 
).

Wäre für jede Hilfe dankbar.

Grüße
Manuel

von Tobias O. (tobey)


Lesenswert?

Nicht das Erstellen vom Socket dauert so lange, sondern das Verbinden. 
Ich weiß nicht genau ob man alle Signale unter Windows benutzen kann, 
aber wenn, dann wäre das aller einfachste ein sig alarm nach 5 Sekunden 
oder so zu senden, wodurch das Verbinden abgebrochen wird. Das zweit 
einfachste wäre es, den Socket nicht blockieren zu lassen, dann 
Verbinden und per select() darauf warten, ob man in den Socket schreiben 
darf.

von Manuel S. (doc-snyder)


Lesenswert?

Tobias O. schrieb:
> Nicht das Erstellen vom Socket dauert so lange, sondern das Verbinden.
> Ich weiß nicht genau ob man alle Signale unter Windows benutzen kann,
> aber wenn, dann wäre das aller einfachste ein sig alarm nach 5 Sekunden

Ich will den Port nur öffnen und wieder schließen. Ob offen oder nicht 
prüfe cih dann am Rückgabewert. 5 Sekunden sind viel zu lange!

> oder so zu senden, wodurch das Verbinden abgebrochen wird. Das zweit

Das erledige ich mit closesocket() allerdings kann ich da nicht während 
dem Verbinden reinpfuschen weil socket() solange blockiert, bis die 
Verbindung steht.

> einfachste wäre es, den Socket nicht blockieren zu lassen, dann
> Verbinden und per select() darauf warten, ob man in den Socket schreiben
> darf.

Socket nict blockieren lassen??? Wie meinen?

von Klaus (Gast)


Lesenswert?

mach für jeden Verbindungsversuch nen eigenen Thread. Und dann immer 
eine bestimmte Anzahl von Threads gleichzeitig laufen lassen.

von g457 (Gast)


Lesenswert?

..nennt mich einen Spielverderber, aber wäre es nicht einfacher, einen 
fertigen Scanner wie nmap [1, 2] zu verwenden?

HTH

[1] http://de.wikipedia.org/wiki/Nmap
[2] http://nmap.org/

von Rolf M. (rmagnus)


Lesenswert?

Manuel Schneider schrieb:
> Tobias O. schrieb:
>> Nicht das Erstellen vom Socket dauert so lange, sondern das Verbinden.
>> Ich weiß nicht genau ob man alle Signale unter Windows benutzen kann,
>> aber wenn, dann wäre das aller einfachste ein sig alarm nach 5 Sekunden
>
> Ich will den Port nur öffnen und wieder schließen. Ob offen oder nicht
> prüfe cih dann am Rückgabewert. 5 Sekunden sind viel zu lange!

Wenn auf dem Port keine Antwort erfolgt, weil die Firewall des Rechners 
die blockiert, dauert es ziemlich lange, bis ein Timeouut kommt.

>> oder so zu senden, wodurch das Verbinden abgebrochen wird. Das zweit
>
> Das erledige ich mit closesocket() allerdings kann ich da nicht während
> dem Verbinden reinpfuschen weil socket() solange blockiert, bis die
> Verbindung steht.

Nicht socket(), sondern connect() blockiert.

>> einfachste wäre es, den Socket nicht blockieren zu lassen, dann
>> Verbinden und per select() darauf warten, ob man in den Socket schreiben
>> darf.
>
> Socket nict blockieren lassen??? Wie meinen?

Du kannst vor dem connect() den Socket auf non-blocking stellen. Dann 
kehrt die Funktion sofort zurück.
Dann kannst du per select mit timeout warten. Damit kannst du auch auf 
mehrere Sockets gleichzeitig warten. Alternativ kann man sich auch ein 
SIGIO schicken lassen, wenn die Verbindung aufgebaut ist und dann darauf 
reagieren.
Oder du kannst die Timeouts des Sockets verstellen, damit er schneller 
zurückkehrt. Zumindest unter Linux geht das, aber Windows kann das 
bestimmt auch.

von doc-snyder (Gast)


Lesenswert?

> Du kannst vor dem connect() den Socket auf non-blocking stellen. Dann
> kehrt die Funktion sofort zurück.

Wie funktioniert das?

> Dann kannst du per select mit timeout warten. Damit kannst du auch auf
> mehrere Sockets gleichzeitig warten. Alternativ kann man sich auch ein
> SIGIO schicken lassen, wenn die Verbindung aufgebaut ist und dann darauf
> reagieren.
> Oder du kannst die Timeouts des Sockets verstellen, damit er schneller
> zurückkehrt. Zumindest unter Linux geht das, aber Windows kann das
> bestimmt auch

...und das?

Laut www.sockets.com gibbets da nix mit timeout...
1
SOCKET PASCAL FAR socket ( int af, int type, int protocol);
2
3
af
4
    An address format specification. The only format currently supported is PF_INET, which is the ARPA Internet address format. 
5
type
6
    A type specification for the new socket. 
7
protocol
8
    A particular protocol to be used with the socket, or 0 if the caller does not wish to specify a protocol.
1
int PASCAL FAR connect ( SOCKET s, const struct sockaddr FAR * name, int namelen);
2
s
3
    A descriptor identifying an unconnected socket. 
4
name
5
    The name of the peer to which the socket is to be connected. 
6
namelen
7
    The length of the name.

Grüße vom Kaiserstuhl

von Tobias O. (tobey)


Lesenswert?

er meint ja auch setsockopt()

von smoerre (Gast)


Lesenswert?

> ..nennt mich einen Spielverderber, aber wäre es nicht einfacher, einen
> fertigen Scanner wie nmap [1, 2] zu verwenden?
der Tip war eigentlich gut, weil nmap auch im Quelltext vorliegt.

von doc-snyder (Gast)


Lesenswert?

Ja allerdings ca. 30 MB Source-code wenn ich mich Recht erinnern kann. 
Wer so nett ist und suchen will darf mir gerne die Richti8ge stelle 
raussuchen.
Aber sonst ist nmap natürlich klasse. Ich nutze es natürlich auch um 
meinen Portscannner zu testen.
Trotzdem Danke

von Gerry E. (micky01)


Lesenswert?

Vielleicht hilft Dir ja der Hinweis auf "netcat" weiter. Das liegt im 
Quellcode vor; der Code ist zwar nicht jedermanns Sache, aber vom Umfang 
schön klein...

Suche auch mal nach O_NONBLOCKING.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.