我在Go中创建了一个工具,该工具可以使用Go并发暴力破解子域。问题在于它只显示前几个结果。我的意思是,如果我指定的线程为10,则显示10,如果为100,则显示100。对此的任何解决方案。我正在关注this示例。
func CheckWildcardSubdomain(state *State, domain string, words <-chan string, wg *sync.WaitGroup) {
defer wg.Done()
for {
preparedSubdomain := <-words + "." + domain
ipAddress, err := net.LookupHost(preparedSubdomain)
if err == nil {
if !state.WildcardIPs.ContainsAny(ipAddress) {
if state.Verbose == true {
fmt.Printf("\n%s", preparedSubdomain)
}
state.FinalResults = append(state.FinalResults, preparedSubdomain)
}
}
}
}
func RemoveWildcardSubdomains(state *State, subdomains []string) []string {
var wg sync.WaitGroup
var channel = make(chan string)
wg.Add(state.Threads)
for i := 0; i < state.Threads; i++ {
go CheckWildcardSubdomain(state, state.Domain, channel, &wg)
}
for _, entry := range subdomains {
sub := strings.Join(strings.Split(entry, ".")[:2][:], ".")
channel <- sub
}
close(channel)
wg.Wait()
return state.FinalResults
}
在此先感谢您的帮助。 最佳答案
2个错误立即突出。
首先,在CheckWildcardSubdomain()
中,您应该像这样在words
channel 上进行设置:
for word := range words {
preparedSubdomain := word + "." + domain
// ...
}
一旦接收到在该 channel 上发送的所有值(在关闭 channel 之前发送),该 channel 上的
for ... range
将终止。请注意,如果 channel 关闭,则简单receive operator不会终止也不会出现 panic ,而是会产生 channel 元素类型的零值。因此,您的原始循环永远不会终止。 Spec: Receive operator:其次,在
CheckWildcardSubdomain()
内,无需同步即可同时读取/修改state.FinalResults
字段。这是未定义的行为。您必须同步对此字段的访问,例如使用互斥锁,或者您应该找到其他沟通和收集结果的方法,例如使用 channel 。
请参阅以下相关问题,以获取一种优雅,高效且可扩展的方法:
Is this an idiomatic worker thread pool in Go?
关于go - 使用无缓冲 channel 的并发问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49875046/