亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

同時掃描多個端口時結果不可靠

同時掃描多個端口時結果不可靠

Go
慕沐林林 2022-06-06 16:51:46
背景:我正在閱讀 Black Hat Go,作者展示了一個使用 goroutines 1的簡單端口掃描器:package mainimport (    "fmt"    "net")func main() {    for i := 1; i <= 9000; i++ {        go func(j int) {            address := fmt.Sprintf("127.0.0.1:%d", j)            conn, err := net.Dial("tcp", address)            if err != nil {                return            }            conn.Close()            fmt.Printf("%d open\n", j)        }(i)    }}然后他提到以下內容:同時掃描過多的主機或端口可能會導致網絡或系統限制影響您的結果。為了測試它,我在端口 8000 和 8500 上啟動了 2 個 php 服務器2并運行上面的代碼來掃描我的本地端口。每次它給我的結果不一致。有時它會檢測到兩個打開的端口,有時它不會。問題:不一致的結果是否是由于 TCP 的某些限制?有沒有辦法計算可以并行掃描的最佳端口數,以使結果保持正確?編輯:我似乎錯過了上面代碼中的等待組。除此之外,是否還有其他任何東西(操作系統限制或協議限制)可以防止在大范圍內進行并發端口掃描?
查看完整描述

1 回答

?
紅糖糍粑

TA貢獻1815條經驗 獲得超6個贊

一旦 for 循環完成,您的 main 函數將退出。如果 main 函數退出,所有由它啟動的 goroutines 也會退出。您需要等待 goroutine 完成。例如,這可以通過 來實現sync.WaitGroup。


package main


import (

    "fmt"

    "net"

    "sync"

    "time"

)


func main() {


    // This will help you to keep track of the goroutines

    var wg sync.WaitGroup


    for i := 1; i <= 9000; i++ {


        // Increment the counter for each goroutine you start.

        wg.Add(1)


        go func(j int) {


            // Make sure the wait group counter is decremented when the goroutine exits

            defer wg.Done()


            address := fmt.Sprintf("127.0.0.1:%d", j)

            conn, err := net.DialTimeout("tcp", address, 2 * time.Second)

            if err != nil {

               return

            }

            conn.Close()

            fmt.Printf("%d open\n", j)

        }(i)

    }


    // Wait for all goroutines to finish before exiting main

    wg.Wait()

}

編輯:對我來說,由于缺少文件描述符,代碼原樣不起作用。以下功能可靠地工作。


它需要更好的錯誤處理,但確實有效


package main


import (

    "fmt"

    "log"

    "net"

    "sync"

    "time"

)


var minPort = 1

var maxPort = 65535

var timeout = 2 * time.Second

const parallel = 50


func main(){

    fmt.Println("portscan called")


    // Create a buffered channel with a size equal to the number of goroutines

    ctrl := make(chan int, parallel)


    // Keep track of the currently active goroutines

    var wg sync.WaitGroup


    for p := 1; p <= parallel; p++ {

        wg.Add(1)


        // Start a goroutine...

        go func(p int) {

            log.Printf("Starting goroutine %d", p)


            // ...listening to the control channel.

            // For every value this goroutine reads from the

            // channel...

            for i := range ctrl {

                address := fmt.Sprintf("127.0.0.1:%d", i)


                // ...try to conncet to the port.

                conn, err := net.DialTimeout("tcp", address, timeout)

                if err == nil {

                    conn.Close()

                    log.Printf("[%3d]: %5d open", p, i)

                }

                // TBD: ERROR HANDLING!!!

            }


            // If the channel is closed, this goroutine is done.

            wg.Done()

            log.Printf("[%3d]: Exiting", p)

        }(p)

    }


    // Fill the control channel with values.

    // If the channel is full, the write operation

    // to the channel will block until one of the goroutines

    // reads a value from it.

    for i := minPort; i <= maxPort; i++ {

        ctrl <- i

    }

    // We have sent all values, so the channel can be closed.

    // The goroutines will finish their current connection attempt,

    // notice that the channel is closed and will in turn call wg.Done().

    close(ctrl)


    // When all goroutines have announced that they are done, we can exit.

    wg.Wait()

}



查看完整回答
反對 回復 2022-06-06
  • 1 回答
  • 0 關注
  • 195 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號