gpt4 book ai didi

转到 channel ,tcp/ip 端口映射不返回所有打开的端口

转载 作者:IT王子 更新时间:2023-10-29 02:02:03 26 4
gpt4 key购买 nike

我一直在学习 Golang,以便将我所有的渗透测试工具都转移到它上面。因为我喜欢编写自己的工具,所以这是学习一门新语言的完美方式。在这种特殊情况下,我认为我使用 channel 的方式有问题。我知道一个没有完成端口映射的事实,因为我使用的我在 ruby​​ 上编写的其他工具正在查找所有打开的端口,但我的 golang 工具没有。有人可以帮我理解我做错了什么吗? channel 是执行此操作的正确方法吗?

package main

import (
"fmt"
"log"
"net"
"strconv"
"time"
)

func portScan(TargetToScan string, PortStart int, PortEnd int, openPorts []int) []int {
activeThreads := 0
doneChannel := make(chan bool)

for port := PortStart; port <= PortEnd; port++ {
go grabBanner(TargetToScan, port, doneChannel)
activeThreads++
}

// Wait for all threads to finish
for activeThreads > 0 {
<-doneChannel
activeThreads--
}
return openPorts
}

func grabBanner(ip string, port int, doneChannel chan bool) {
connection, err := net.DialTimeout(
"tcp",
ip+":"+strconv.Itoa(port),
time.Second*10)
if err != nil {
doneChannel <- true
return
}
// append open port to slice
openPorts = append(openPorts, port)

fmt.Printf("+ Port %d: Open\n", port)
// See if server offers anything to read
buffer := make([]byte, 4096)
connection.SetReadDeadline(time.Now().Add(time.Second * 5))
// Set timeout
numBytesRead, err := connection.Read(buffer)
if err != nil {
doneChannel <- true
return
}
log.Printf("+ Banner of port %d\n%s\n", port,
buffer[0:numBytesRead])
// here we add to map port and banner
targetPorts[port] = string(buffer[0:numBytesRead])

doneChannel <- true
return
}

注意:似乎找到了第一批端口,但没有找到高于数字示例 8080 的端口,但它通常会得到 80 和 443...所以我怀疑某些事情超时了,或者发生了一些奇怪的事情。

有很多糟糕的代码破解,主要是因为我正在学习和搜索很多关于如何做事的东西,所以请随时提供提示甚至更改/拉取请求。谢谢

最佳答案

您的代码有一些问题。在 grabBanner 中,您似乎引用了 openPorts 但它未在任何地方定义。您可能正在引用一个全局变量,并且此追加操作不会是线程安全的。除了线程安全问题之外,您还可能会用尽文件描述符限制。也许您应该通过执行以下操作来限制并发工作量:

package main

import (
"fmt"
"net"
"strconv"
"sync"
"time"
)

func main() {
fmt.Println(portScan("127.0.0.1", 1, 65535))
}

// startBanner spins up a handful of async workers
func startBannerGrabbers(num int, target string, portsIn <-chan int) <-chan int {
portsOut := make(chan int)

var wg sync.WaitGroup

wg.Add(num)

for i := 0; i < num; i++ {
go func() {
for p := range portsIn {
if grabBanner(target, p) {
portsOut <- p
}
}
wg.Done()
}()
}

go func() {
wg.Wait()
close(portsOut)
}()

return portsOut

}

func portScan(targetToScan string, portStart int, portEnd int) []int {
ports := make(chan int)

go func() {
for port := portStart; port <= portEnd; port++ {
ports <- port
}
close(ports)
}()

resultChan := startBannerGrabbers(16, targetToScan, ports)

var openPorts []int
for port := range resultChan {
openPorts = append(openPorts, port)
}

return openPorts
}

var targetPorts = make(map[int]string)

func grabBanner(ip string, port int) bool {
connection, err := net.DialTimeout(
"tcp",
ip+":"+strconv.Itoa(port),
time.Second*20)

if err != nil {
return false
}
defer connection.Close() // you should close this!

buffer := make([]byte, 4096)
connection.SetReadDeadline(time.Now().Add(time.Second * 5))
numBytesRead, err := connection.Read(buffer)

if err != nil {
return true
}

// here we add to map port and banner
// ******* MAPS ARE NOT SAFE FOR CONCURRENT WRITERS ******
// ******************* DO NOT DO THIS *******************
targetPorts[port] = string(buffer[0:numBytesRead])

return true
}

您对 var open bool 的使用并不断设置它,然后返回它既不必要又不符合习惯。此外,检查 if someBoolVar != false 是一种非惯用且冗长的编写方式 if someBoolVar

此外, map 对于并发访问并不安全,但您的 grabBanner 函数正在写入以并发方式从许多 go 例程映射。 请停止在函数内部改变全局状态。而是返回值。

这是对正在发生的事情的最新解释。首先,我们创建一个 channel ,我们将把端口号推送到我们的工作人员进行处理。然后我们启动一个 go-routine,它将尽可能快地将范围内的端口写入该 channel 。一旦我们将每个可用端口写入该 channel ,我们就会关闭该 channel ,以便我们的读者能够退出。

然后我们调用一个方法来启动可配置数量的 bannerGrabber worker。我们传递 ip 地址和 channel 以读取候选端口号。此函数生成 num 个 goroutine,每个 goroutine 分布在传递的 portsIn channel 上,调用 grab banner 函数,然后将端口推送到出站 channel ,如果成功。最后,我们开始另一个等待 sync.WaitGroup 完成的 go 例程,这样我们就可以在所有工作人员完成后关闭传出(结果) channel 。

回到 portScan 函数 我们从 startBannerGrabbers 函数接收出站 channel 作为返回值。然后,我们遍历返回给我们的结果 channel ,将所有打开的端口附加到列表中,然后返回结果。

我还改变了一些风格上的东西,比如将你的函数参数名称小写。

冒着听起来像是破唱片的风险,我将再次强调以下内容。 停止改变全局状态。您不应设置 targetPorts,而应以并发安全的方式累积这些值并将它们返回给调用者以供使用。在这种情况下,您对全局变量的使用似乎考虑不周,既方便又没有考虑如何在没有全局变量的情况下解决问题。

关于转到 channel ,tcp/ip 端口映射不返回所有打开的端口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50081925/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com