2016-03-28 4 views
0

У меня есть «honeypot», который я разрабатываю на C#, который прослушивает серию портов (пользователь вводит). Это большой проект/служба Windows, который функционирует так, как ожидалось, для почти любого введенного порта и не будет прослушивать порты, в которых в настоящее время уже есть что-то прослушивание. Проблема в том, что при тестировании службы с использованием telnet или netcat открытие соединения на порте 23 не улавливается моей службой и поэтому устанавливает соединение.Устранение неполадок TCP-трафика на порте 23 - C#

открыть порты в брандмауэре, выполнив следующие действия:

for (int i = 0; i < ports.Length; i++) 
     { 
      string arg = "advfirewall firewall add rule name=\"PeepHole Open" + "\" dir=in action=allow protocol=TCP localport=" + ports[i]; 
      string arg1 = "advfirewall firewall add rule name=\"PeepHole Open" + "\" dir=in action=allow protocol=UDP localport=" + ports[i]; 

      ProcessStartInfo procStartInfo = new ProcessStartInfo("netsh", arg); 
      ProcessStartInfo procStartInfo1 = new ProcessStartInfo("netsh", arg1); 
      procStartInfo.RedirectStandardOutput = true; 
      procStartInfo1.RedirectStandardOutput = true; 

      procStartInfo.UseShellExecute = false; 
      procStartInfo1.UseShellExecute = false; 

      procStartInfo.CreateNoWindow = true; 
      procStartInfo1.CreateNoWindow = true; 

      Process.Start(procStartInfo1); 
      Process.Start(procStartInfo); 

     } 

И я начинаю слушателей:

IPEndPoint Ep = new IPEndPoint(IPAddress.Parse("0.0.0.0"), current_port); 
//TcpListener tempListener = new TcpListener(hostIP, current_port); 
TcpListener tempListener = new TcpListener(Ep); 
TCP_Listener listen = new TCP_Listener(); //my defined tcplistener struct 
listen.listener = tempListener;    //set the Listener's TcpListener field 
listen.port = current_port;     //set the Listener's Port field         
listen.listener.Start();     //start this particular TcpListener 
tcp_listener_list.Add(listen);    //add the struct to the list of Listeners 

и принять соединение TCP по:

for (int i = 0; i < tcp_listener_list.Count - 1; i++) 
{ 
    if (tcp_listener_list[i].listener.Pending()) 
    { 
     TcpClient client = tcp_listener_list[i].listener.AcceptTcpClient(); 
     int clientPort = tcp_listener_list[i].port; 
     IPEndPoint ep = client.Client.RemoteEndPoint as IPEndPoint; 
     ThreadPool.QueueUserWorkItem(LogTCP, new object[] { client, clientPort, ep }); 
     } 
    } 

И в LogTCP я закрываю соединение (где клиент является объектом TcpClient):

NetworkStream networkStream = client.GetStream(); 
networkStream.Close(); 
client.Close(); //close the connection, all the data is gleaned from the attacker already 

Теперь проблема заключается в том, что при запуске telnet или netcat для проверки закрытия и регистрации порта мой код никогда не выполняется и соединение установлено, поскольку порт открыт; TCP-соединение никогда не является .Pending(), и если я удалю это, проблема будет постоянной. Кроме того, у меня такая же проблема, если я настроил слушателей на использование IPAddress.Any и если я перенастрою метод accept в AcceptSocket с или без оператора .Pending() if. Описывают ли окна определенные порты по-разному на низком уровне с определенными программами?

Я запускаю службу Windows из Windows 8.1 и отправляю TCP-соединения через telnet на putty (на машине, на которой установлена ​​служба), и telnet и netcat на виртуальной машине Linux. Как Telnet Client, так и Telnet-сервер отключены на машине «host».

Я пробовал много разных вариантов закрытия сокетов и соединений, которые я нашел во время своих исследований.

client.Client.Close() производит ObjectDisposedException client.Client.Shutdown (SocketShutdown.Both) делает все ранее 'работает' порты повесить соединения с CLOSE_WAIT

ответ

0

Я думаю, что ключ здесь, вы упоминаете в качестве отступления, что вы создали свою собственную структуру. Структуры очень сложны. Вы можете подумать, что приведенный ниже код будет иметь экземпляр TCP_Listener с вашим tempListener и current_port. Но если вы установите точку останова, вы, вероятно, заметите обратное. Каждая модификация, которую вы делаете в структуре, фактически возвращает совершенно новую структуру, поэтому вы не можете назначать поля по одному, как в случае с классом.

TCP_Listener listen = new TCP_Listener(); //my defined tcplistener struct 
listen.listener = tempListener;    //set the Listener's TcpListener field 
listen.port = current_port;     //set the Listener's Port field         
listen.listener.Start(); 

Я бы рекомендовал, а не структуру, использовать класс. Или вы инициализируете свою структуру как новый TCP_Listener (tempListener, current_port), а затем запустите его.

Это, по крайней мере, часть вашей проблемы. После того, как вы исправите это, сообщите нам, если он все еще не работает, и мы можем рассмотреть следующую проблему.

+0

На самом деле, поскольку я смотрю на это, я удивлен, что вы не получаете исключение NullReferenceException. Но то, как вы назначаете структуру, не кажется правильным. Это действительно структура? –

+0

Это работает для меня. Наверное, мне повезло с другими портами, и порт 23 обнаружил этот неожиданный результат. В итоге я создал простой класс для замены структуры. Спасибо! – tyler

0

Pending никогда не требуется. Просто постоянно принимайте всех слушателей. Начните одну задачу на слушателя, чтобы сделать это:

while (true) { 
ProcessConnectionAsync(await listener.AcceptAsync()); 
} 

Нечто подобное.

И вот ошибка, связанная с ошибкой: tcp_listener_list.Count - 1. Но эта ошибка исчезает, когда вы делаете это, как объяснялось выше.

Что касается закрытия, почему бы не просто client.Dispose();? Это обычный способ управления ресурсами в .NET. Больше ничего не требуется.

+0

Хороший улов. Я изменил его на цикл foreach, который у меня есть почти везде, а также удалил вызов Pending(). Наверное, я просто получил туннельное видение этого проекта. Спасибо! – tyler