【解決方法】autoit で開いている udp ポートをスキャンするにはどうすればよいですか?

プログラミングQA


TCP/UDP ポート スキャン用のプログラムに取り組んでいます。 TCP は正常に動作していますが、AutoIt を使用して UDP ポート スキャンを実行する方法がわかりません。

UDP ポートはコネクションレスであるため、UDPOpen 関数を使用して $PortIP と $PortStartNumberB をバインドしています。 残念ながら、スキャンするとすべてのポートが一覧表示されます。 ここまでで、4008 などの UDP でポート 4008 に対してのみ許可されるように設定された、アプリケーションからのそれぞれの開いているポートが表示されます (高度なポート スキャナー ツールを使用してテストしており、このポートのみが開いている必要があるため)。

AutoItスクリプトでUDPオープンポートリストを再現できないため、以下に投稿された関数コードを変更する方法について、私よりも知識のある人が理解できるように助けてくれませんか? プラットフォームは Win7 x86 です。

$portList = "  "
$PortIP = "192.168.11.1"
$PortEndNumberB = "4010"
$PortStartNumberB = "4000"

Func ScanUDP()
    UDPStartup()
    $timerstart = TimerInit()

    For $LetsGo = $PortStartNumberB To $PortEndNumberB
        $a = UDPOpen($PortIP, $PortStartNumberB, 1)
        If @error <> 0 Then
            $portList = $portList & $PortStartNumberB & @CRLF
        EndIf

        $PortStartNumberB = $PortStartNumberB + 1
    Next

    UDPShutdown()
    $timerend = TimerDiff($timerstart)
    TrayTip("Port Scanner", "Done Process took " & Round($timerend,-1)/1000 & " seconds", 7, 1)
EndFunc

私が試したこと:

実行しようとすると、すべてのポートが一覧表示されます。

4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010

当然のことながら、正しい開いている udp ポートである 4008 のみを表示する必要があります (他のフリーウェア ツール – アドバンス ポート スキャンを使用してテストしました)

解決策 1

UDP はコネクションレスであるため、データを送信して、受信した場合はしばらく待つ必要があります。 ICMP 宛先に到達できません (ウィキペディア)[^] ポートに到達できないことを示すコード 3 のメッセージ。

ただし、タイムアウトは、UDP サービスがリッスンしていることを示す信頼できる指標ではないことに注意してください。

プロトコルを知っている場合は、適切にフォーマットされたリクエストを送信し、対応する応答を (タイムアウトを使用して) 待機することをお勧めします。

解決策 2

助かるかも

Local $port

If $CmdLine[0] == 0 Then
   MsgBox(0x0,"Err","arg is empty")
   Exit 1
Else
   $port = $CmdLine[1]
EndIf

Func _MyPortExists($port)
   Local $sRead, $sBuffer, $CMD_PId
   $CMD_PId = Run(@ComSpec & ' /c netstat -an | find "UDP" | find ":' & $port & ' " /C', "C:\", @SW_HIDE, 0x2)

   While 1
	   $sBuffer = StdoutRead($CMD_PId)
	   If @error Then ExitLoop
	   If $sBuffer Then
		   $sRead &= $sBuffer
	   EndIf
	   Sleep(2)
   WEnd

   $sRead = StringLeft ( $sRead, 1 )
   If $sRead == 0 Or $sRead == 1 Or $sRead == 2 Then
	  Return $sRead
   Else
;~	  _Log_MyInfo( $flog, $sRead & ", " & VarGetType($sRead) & ", -->" & $sRead & "<--")
	  Return _MyPortExists($port)
   EndIf

EndFunc

If _MyPortExists($port) <> 0 Then
   MsgBox(0x0,"PortLst","Open")
Else
   MsgBox(0x0,"PortLst","Closed")
EndIf

コメント

タイトルとURLをコピーしました