dddd/main.go
2023-11-01 09:00:03 +01:00

223 lines
5.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"dddd/common"
"dddd/common/callnuclei"
"dddd/common/http"
"dddd/common/report"
"dddd/common/uncover"
"dddd/gopocs"
"dddd/lib/ddfinger"
"dddd/structs"
"dddd/utils"
"dddd/utils/cdn"
"github.com/logrusorgru/aurora"
"github.com/projectdiscovery/gologger"
"github.com/projectdiscovery/httpx"
"github.com/projectdiscovery/nuclei/v3/pkg/output"
)
func main() {
common.Flag()
workflow()
}
func workflow() {
var domains []string
var urls []string
var domainPort []string
var ipPort []string
var ips []string
defer gologger.Info().Msg(aurora.BrightGreen("Done!").String())
// 从Hunter中获取资产
if structs.GlobalConfig.Hunter && !structs.GlobalConfig.Fofa {
gologger.Info().Msgf("准备从 Hunter 获取数据")
structs.GlobalConfig.Targets = uncover.HunterSearch(structs.GlobalConfig.Targets)
}
if structs.GlobalConfig.Fofa && !structs.GlobalConfig.Hunter {
gologger.Info().Msgf("准备从 Fofa 获取数据")
structs.GlobalConfig.Targets = uncover.FOFASearch(structs.GlobalConfig.Targets)
}
for _, input := range structs.GlobalConfig.Targets {
inputType := utils.GetInputType(input)
if inputType == structs.TypeDomain {
domains = append(domains, input)
continue
} else if inputType == structs.TypeDomainPort {
domainPort = append(domainPort, input)
continue
} else if inputType == structs.TypeCIDR {
for _, ip := range utils.CIDRToIP(input) {
ips = append(ips, ip.String())
}
} else if inputType == structs.TypeIPRange {
for _, ip := range utils.RangerToIP(input) {
ips = append(ips, ip.String())
}
} else if inputType == structs.TypeIP {
ips = append(ips, input)
} else if inputType == structs.TypeIPPort {
ipPort = append(ipPort, input)
} else if inputType == structs.TypeURL {
urls = append(urls, input)
}
}
if structs.GlobalConfig.Subdomain && len(domains) > 0 {
subdomains := common.GetSubDomain(domains)
for _, each := range subdomains {
domains = append(domains, each)
}
}
domains = utils.RemoveDuplicateElement(domains)
var cdnDomains []string
var tIPs []string
if len(domains) > 0 {
cdnDomains, _, tIPs = cdn.CheckCDNs(domains, structs.GlobalConfig.SubdomainBruteForceThreads)
for _, each := range tIPs {
if structs.GlobalConfig.AllowLocalAreaDomain && utils.IsLocalIP(each) {
continue
}
ips = append(ips, each)
}
}
ips = utils.RemoveDuplicateElement(ips)
// 处理带CDN的域名只进行https,http的探测不进行端口扫描
for _, cd := range cdnDomains {
urls = append(urls, "http://"+cd)
urls = append(urls, "https://"+cd)
}
urls = utils.RemoveDuplicateElement(urls)
// 端口扫描
if len(ips) > 0 {
if !structs.GlobalConfig.SkipHostDiscovery {
ips = common.CheckLive(ips, false)
}
var tmpIPPort []string
// 检测Masscan安装
if structs.GlobalConfig.PortScanType == "syn" {
if !common.CheckMasScan() {
gologger.Error().Msg("降级TCP扫描")
structs.GlobalConfig.PortScanType = "tcp"
}
}
if structs.GlobalConfig.PortScanType == "syn" {
// 全端口扫描
tmpIPPort = common.PortScanSYN(ips)
} else {
tmpIPPort = common.PortScanTCP(ips, structs.GlobalConfig.Ports,
structs.GlobalConfig.TCPPortScanTimeout)
}
// 单个IP阈值过滤
tmpIPPort = common.RemoveFirewall(tmpIPPort)
for _, each := range tmpIPPort {
ipPort = append(ipPort, each)
}
ipPort = utils.RemoveDuplicateElement(ipPort)
}
getProtocalInput := ipPort
for _, each := range domainPort {
getProtocalInput = append(getProtocalInput, each)
}
if len(getProtocalInput) > 0 {
common.GetProtocol(getProtocalInput, structs.GlobalConfig.GetBannerThreads)
}
// 获取http响应
for hostPort, service := range structs.GlobalIPPortMap {
if service == "http" {
urls = append(urls, "http://"+hostPort)
} else if service == "https" {
urls = append(urls, "https://"+hostPort)
}
}
urls = utils.RemoveDuplicateElement(urls)
httpx.CallHTTPx(urls, http.UrlCallBack,
structs.GlobalConfig.HTTPProxy,
structs.GlobalConfig.WebThreads,
structs.GlobalConfig.WebTimeout)
// 非CDN域名 探测域名绑定资产
// 把只允许域名访问的资产扒拉出来
common.HostBindCheck()
var aliveURLs []string
for rootURL, _ := range structs.GlobalURLMap {
aliveURLs = append(aliveURLs, rootURL)
}
// 模糊搜索Yaml Poc直接打
if structs.GlobalConfig.PocNameForSearch != "" {
TargetAndPocsName := make(map[string][]string)
for _, url := range aliveURLs {
TargetAndPocsName[url] = []string{}
}
report.GenerateHTMLReportHeader()
callnuclei.CallNuclei(TargetAndPocsName,
structs.GlobalConfig.HTTPProxy,
report.AddResultByResultEvent,
structs.GlobalConfig.PocNameForSearch)
utils.DeleteReportWithNoResult()
return
}
// 目录爆破
if !structs.GlobalConfig.NoDirSearch {
var checkURLs []string
for path, _ := range structs.DirDB {
for _, u := range aliveURLs {
Url := ""
if u[len(u)-1:] == "/" && path[0:1] == "/" {
Url = u[:len(u)-1] + path
} else {
Url = u + path
}
checkURLs = append(checkURLs, Url)
}
}
checkURLs = utils.RemoveDuplicateElement(checkURLs)
gologger.Info().Msg("开始主动指纹探测")
httpx.DirBrute(checkURLs,
http.DirBruteCallBack,
structs.GlobalConfig.HTTPProxy,
structs.GlobalConfig.WebThreads,
structs.GlobalConfig.WebTimeout)
}
ddfinger.FingerprintIdentification()
// 生成报告头部
report.GenerateHTMLReportHeader()
// 调用Nuclei
var nucleiResults []output.ResultEvent
TargetAndPocsName, count := http.GetPocs(structs.WorkFlowDB)
if count > 0 {
nucleiResults = callnuclei.CallNuclei(TargetAndPocsName,
structs.GlobalConfig.HTTPProxy,
report.AddResultByResultEvent,
"")
}
// GoPoc引擎
if !structs.GlobalConfig.NoGolangPoc {
gopocs.GoPocsDispatcher(nucleiResults)
}
// 没有漏洞结果删除生成的HTML
utils.DeleteReportWithNoResult()
}