This commit is contained in:
SleepingBag945 2024-06-07 19:17:14 +08:00
parent 1d08496a68
commit 33b6e2876b
17 changed files with 141 additions and 52 deletions

View File

@ -28,23 +28,29 @@ var (
options = &types.Options{}
)
func CallNuclei(TargetAndPocsName map[string][]string,
proxy string,
callBack func(result output.ResultEvent),
nameForSearch string,
NoInteractsh bool,
fs embed.FS,
np string,
excludeTags []string,
severities []string) []output.ResultEvent {
type NucleiParams struct {
TargetAndPocsName map[string][]string
Proxy string
CallBack func(result output.ResultEvent)
NameForSearch string
NoInteractsh bool
Fs embed.FS
NP string
ExcludeTags []string
Severities []string
InteractshServer string
InteractshToken string
}
func CallNuclei(param NucleiParams) []output.ResultEvent {
// 设置结果回调
output.AddResultCallback = callBack
output.AddResultCallback = param.CallBack
if err := exportrunner.ExportRunnerConfigureOptions(); err != nil {
gologger.Fatal().Msgf("Could not initialize options: %s\n", err)
}
readConfig(TargetAndPocsName, proxy, nameForSearch, NoInteractsh, np, excludeTags)
readConfig(param)
// configPath, _ := flagSet.GetConfigFilePath()
if options.ListDslSignatures {
@ -81,8 +87,8 @@ func CallNuclei(TargetAndPocsName map[string][]string,
return []output.ResultEvent{}
}
nucleiRunner.EmbedPocsFS = fs
nucleiRunner.EnableSeverities = severities
nucleiRunner.EmbedPocsFS = param.Fs
nucleiRunner.EnableSeverities = param.Severities
// Setup graceful exits
resumeFileName := types.DefaultResumeFilePath()
@ -97,7 +103,7 @@ func CallNuclei(TargetAndPocsName map[string][]string,
}
}()
if err := nucleiRunner.RunEnumeration(TargetAndPocsName); err != nil {
if err := nucleiRunner.RunEnumeration(param.TargetAndPocsName); err != nil {
if options.Validate {
gologger.Fatal().Msgf("Could not validate templates: %s\n", err)
} else {
@ -112,19 +118,14 @@ func CallNuclei(TargetAndPocsName map[string][]string,
return output.Results
}
func readConfig(TargetAndPocsName map[string][]string,
proxy string,
nameForSearch string,
NoInteractsh bool,
np string,
excludeTags []string) {
func readConfig(param NucleiParams) {
pwd, _ := os.Getwd()
// target URLs/hosts to scan
// 扫描目标
var targets []string
for k, _ := range TargetAndPocsName {
for k, _ := range param.TargetAndPocsName {
targets = append(targets, k)
}
options.Targets = targets
@ -166,12 +167,12 @@ func readConfig(TargetAndPocsName map[string][]string,
// 不嵌入可执行文件是为了方便增删poc。
// dddd v2.0开始默认支持内嵌此文件夹内的pocs做补充处理
if strings.HasPrefix(np, "/") || np[1] == ':' {
if strings.HasPrefix(param.NP, "/") || param.NP[1] == ':' {
// unix绝对路径windows绝对路径
options.Templates = []string{np}
options.Templates = []string{param.NP}
} else {
// 相对路径转绝对路径
options.Templates = []string{pwd + "/" + np}
options.Templates = []string{pwd + "/" + param.NP}
}
// list of template urls to run (comma-separated, file)
@ -216,7 +217,7 @@ func readConfig(TargetAndPocsName map[string][]string,
// templates to exclude based on tags (comma-separated, file)
// 排除执行带有标记的模板(逗号分隔,文件)
options.ExcludeTags = excludeTags
options.ExcludeTags = param.ExcludeTags
// tags to be executed even if they are excluded either by default or configuration
// 执行默认或者配置排除的标记模板
@ -395,10 +396,10 @@ func readConfig(TargetAndPocsName map[string][]string,
options.TlsImpersonate = false
// 使用interactsh反连检测平台默认为oast.pro,oast.live,oast.site,oast.online,oast.fun,oast.me
options.InteractshURL = ""
options.InteractshURL = param.InteractshServer
// 指定反连检测平台的身份凭证
options.InteractshToken = ""
options.InteractshToken = param.InteractshToken
// 指定保存在交互缓存中的请求数默认5000
options.InteractionsCacheSize = 5000
@ -413,7 +414,7 @@ func readConfig(TargetAndPocsName map[string][]string,
options.InteractionsCoolDownPeriod = 5
// 禁用反连检测平台,同时排除基于反连检测的模板
options.NoInteractsh = NoInteractsh
options.NoInteractsh = param.NoInteractsh
// overrides fuzzing type set in template (replace, prefix, postfix, infix)
// 覆盖模板中设置的模糊类型(替换、前缀、后缀、中缀)
@ -497,10 +498,10 @@ func readConfig(TargetAndPocsName map[string][]string,
// 显示所有响应
options.DebugResponse = false
// 使用http/socks5代理逗号分隔文件
if proxy == "" {
if param.Proxy == "" {
options.Proxy = nil
} else {
options.Proxy = []string{proxy}
options.Proxy = []string{param.Proxy}
}
// 代理所有请求
options.ProxyInternal = false
@ -557,7 +558,7 @@ func readConfig(TargetAndPocsName map[string][]string,
options.SignTemplates = false
options.PocNameForSearch = nameForSearch
options.PocNameForSearch = param.NameForSearch
gologger.DefaultLogger.SetTimestamp(options.Timestamp, levels.LevelDebug)

View File

@ -41,7 +41,7 @@ func GC() {
debug.FreeOSMemory()
}
var version = "2.0.1"
var version = "2.0.2"
func showBanner() {
banner := fmt.Sprintf(`
@ -575,6 +575,7 @@ func Flag() {
flagSet.CreateGroup("portscan", "端口扫描",
flagSet.StringVarP(&PortString, "port", "p", "", "端口设置。 默认扫描Top1000"),
flagSet.StringVarP(&structs.GlobalConfig.NoPortString, "no-port", "np", "", "禁止扫描的端口"),
flagSet.StringVarP(&structs.GlobalConfig.PortScanType, "scan-type", "st", "tcp", "端口扫描方式 | \"-st tcp\"设置TCP扫描 | \"-st syn\"设置SYN扫描"),
flagSet.IntVarP(&structs.GlobalConfig.TCPPortScanThreads, "tcp-scan-threads", "tst", 1000, "TCP扫描线程 | Windows/Mac默认1000线程 Linux默认4000"),
flagSet.IntVarP(&structs.GlobalConfig.SYNPortScanThreads, "syn-scan-threads", "sst", 10000, "SYN扫描线程"),
@ -637,12 +638,18 @@ func Flag() {
flagSet.CreateGroup("vuln-detect", "漏洞探测",
flagSet.BoolVar(&structs.GlobalConfig.NoPoc, "npoc", false, "关闭漏洞探测,只进行信息收集"),
flagSet.StringVarP(&structs.GlobalConfig.PocNameForSearch, "poc-name", "poc", "", "模糊匹配Poc名称"),
flagSet.BoolVarP(&structs.GlobalConfig.NoInteractsh, "no-interactsh", "ni", false, "禁用Interactsh服务器排除反连模版"),
flagSet.IntVarP(&structs.GlobalConfig.GoPocThreads, "golang-poc-threads", "gpt", 50, "GoPoc运行线程"),
flagSet.BoolVarP(&structs.GlobalConfig.NoGolangPoc, "no-golang-poc", "ngp", false, "关闭Golang Poc探测"),
flagSet.BoolVarP(&structs.GlobalConfig.DisableGeneralPoc, "disable-general-poc", "dgp", false, "禁用无视指纹的漏洞映射"),
flagSet.StringVarP(&structs.GlobalConfig.ExcludeTags, "exclude-tags", "et", "", "通过tags排除模版 | 多个tags请用,连接"),
flagSet.StringVarP(&structs.GlobalConfig.Severities, "severity", "s", "", "只允许指定严重程度的模板运行 | 多参数用,连接 | 允许的值: "+strings.ReplaceAll(severity.GetSupportedSeverities().String(), " ", "")),
flagSet.BoolVarP(&structs.GlobalConfig.NoServiceBruteForce, "no-brute", "nb", false, "禁用服务爆破 | 不包括Shiro Keys"),
)
flagSet.CreateGroup("interact-sh", "反连配置",
flagSet.BoolVarP(&structs.GlobalConfig.NoInteractsh, "no-interactsh", "ni", false, "禁用Interactsh服务器排除反连模版"),
flagSet.StringVarP(&structs.GlobalConfig.InteractshURL, "interactsh-server", "iserver", "", "指定Interactsh服务器 | http://xxx.com | 默认使用Nuclei自带的服务"),
flagSet.StringVarP(&structs.GlobalConfig.InteractshToken, "interactsh-token", "itoken", "", "Interactsh Token"),
)
flagSet.CreateGroup("config", "配置文件",

View File

@ -56,10 +56,25 @@ func ParsePort(ports string) (scanPorts []int) {
var BackList map[string]struct{}
var BackListLock sync.Mutex
func PortScanTCP(IPs []string, Ports string, timeout int) []string {
func PortScanTCP(IPs []string, Ports string, NoPorts string, timeout int) []string {
var AliveAddress []string
gologger.AuditTimeLogger("开始TCP端口扫描端口设置: %s\nTCP端口扫描目标:%s", Ports, strings.Join(IPs, ","))
probePorts := ParsePort(Ports)
ports := ParsePort(Ports)
noPorts := ParsePort(NoPorts)
var probePorts []int
for _, port := range ports {
ok := false
for _, nport := range noPorts {
if nport == port {
ok = true
break
}
}
if !ok {
probePorts = append(probePorts, port)
}
}
IPPortCount := make(map[string]int)
BackList = make(map[string]struct{})
@ -68,8 +83,8 @@ func PortScanTCP(IPs []string, Ports string, timeout int) []string {
if workers > len(IPs)*len(probePorts) {
workers = len(IPs) * len(probePorts)
}
Addrs := make(chan Addr, len(IPs)*len(probePorts))
results := make(chan string, len(IPs)*len(probePorts))
Addrs := make(chan Addr, structs.GlobalConfig.TCPPortScanThreads)
results := make(chan string, structs.GlobalConfig.TCPPortScanThreads)
var wg sync.WaitGroup
//接收结果

View File

@ -144,6 +144,7 @@ func SearchHunterCore(keyword string, pageSize int, maxQueryPage int) ([]string,
if responseJson.Data.Total == 0 {
gologger.Error().Msgf("[Hunter] %s 无结果。", keyword)
time.Sleep(time.Second * 3)
return results, ipResult
}

View File

@ -14,6 +14,9 @@ import (
var ftpUserPasswdDict string
func FtpScan(info *structs.HostInfo) (tmperr error) {
if structs.GlobalConfig.NoServiceBruteForce {
return
}
starttime := time.Now().Unix()
// 先检测匿名访问

View File

@ -15,6 +15,9 @@ import (
var mssqlUserPasswdDict string
func MssqlScan(info *structs.HostInfo) (tmperr error) {
if structs.GlobalConfig.NoServiceBruteForce {
return
}
starttime := time.Now().Unix()
userPasswdList := sortUserPassword(info, mssqlUserPasswdDict, []string{"mssql", "sqlserver"})

View File

@ -15,6 +15,9 @@ import (
var mysqlUserPasswdDict string
func MysqlScan(info *structs.HostInfo) (tmperr error) {
if structs.GlobalConfig.NoServiceBruteForce {
return
}
starttime := time.Now().Unix()
userPasswdList := sortUserPassword(info, mysqlUserPasswdDict, []string{"mysql"})

View File

@ -15,6 +15,9 @@ import (
var oracleUserPasswdDict string
func OracleScan(info *structs.HostInfo) (tmperr error) {
if structs.GlobalConfig.NoServiceBruteForce {
return
}
starttime := time.Now().Unix()
userPasswdList := sortUserPassword(info, oracleUserPasswdDict, []string{"oracle"})

View File

@ -16,6 +16,9 @@ import (
var postgreSQLUserPasswdDict string
func PostgresScan(info *structs.HostInfo) (tmperr error) {
if structs.GlobalConfig.NoServiceBruteForce {
return
}
starttime := time.Now().Unix()
defer gologger.AuditTimeLogger("[Go] [PostgreSQL] PostgresScan return! %s:%v", info.Host, info.Ports)

View File

@ -33,6 +33,9 @@ type Brutelist struct {
}
func RdpScan(info *structs.HostInfo) (tmperr error) {
if structs.GlobalConfig.NoServiceBruteForce {
return
}
userPasswdList := sortUserPassword(info, rdpUserPasswdDict, []string{})
gologger.AuditTimeLogger("[Go] [RDP-Brute] start try %s:%v", info.Host, info.Ports)
defer gologger.AuditTimeLogger("[Go] [RDP-Brute] RdpScan return %s:%v", info.Host, info.Ports)

View File

@ -25,6 +25,10 @@ func RedisScan(info *structs.HostInfo) (tmperr error) {
return errA
}
if structs.GlobalConfig.NoServiceBruteForce {
return errA
}
var upList []string
if structs.GlobalConfig.Password != "" {

View File

@ -36,6 +36,11 @@ func AddScan(scantype string, info structs.HostInfo, ch *chan struct{}, wg *sync
}
func ScanFunc(name *string, info *structs.HostInfo) {
defer func() {
if err := recover(); err != nil {
gologger.Error().Msgf("[-] %v:%v %v error: %v\n", info.Host, info.Ports, name, err)
}
}()
f := reflect.ValueOf(PluginList[*name])
in := []reflect.Value{reflect.ValueOf(info)}
f.Call(in)
@ -94,11 +99,15 @@ func GoPocsDispatcher(nucleiResults []output.ResultEvent) {
&ch, &wg)
}
if protocol == "rdp" || port == "3389" {
if structs.GlobalConfig.NoServiceBruteForce {
continue
}
AddScan("RDP-Crack",
structs.HostInfo{Host: host, Ports: port},
&ch, &wg)
}
if protocol == "redis" || port == "6379" {
// 有未授权检测
AddScan("Redis-Crack",
structs.HostInfo{Host: host, Ports: port},
&ch, &wg)

View File

@ -16,6 +16,9 @@ import (
var smbUserPasswdDict string
func SmbScan(info *structs.HostInfo) (tmperr error) {
if structs.GlobalConfig.NoServiceBruteForce {
return
}
starttime := time.Now().Unix()
gologger.AuditTimeLogger("[Go] [SMB-Brute] start try %s:%v", info.Host, info.Ports)
defer gologger.AuditTimeLogger("[Go] [SMB-Brute] SmbScan return %s:%v", info.Host, info.Ports)

View File

@ -16,6 +16,10 @@ import (
var sshUserPasswdDict string
func SshScan(info *structs.HostInfo) (tmperr error) {
if structs.GlobalConfig.NoServiceBruteForce {
return
}
starttime := time.Now().Unix()
gologger.AuditTimeLogger("[Go] [SSH-Brute] start try %s:%v", info.Host, info.Ports)
defer gologger.AuditTimeLogger("[Go] [SSH-Brute] SshScan return %s:%v", info.Host, info.Ports)

View File

@ -73,6 +73,10 @@ func TelnetScan(info *structs.HostInfo) (tmperr error) {
return tmperr
}
if structs.GlobalConfig.NoServiceBruteForce {
return
}
var upList []string
if structs.GlobalConfig.Password != "" {
upList = append(upList, structs.GlobalConfig.Password)

49
main.go
View File

@ -112,6 +112,7 @@ func workflow() {
gologger.Info().Msg("TCP存活探测")
common.PortScan = false
tcpAliveIPPort := common.PortScanTCP(uncheck, "80,443,3389,445,22",
structs.GlobalConfig.NoPortString,
structs.GlobalConfig.TCPPortScanTimeout)
for _, tIPPort := range tcpAliveIPPort {
t := strings.Split(tIPPort, ":")
@ -139,6 +140,7 @@ func workflow() {
} else {
common.PortScan = true
tmpIPPort = common.PortScanTCP(ips, structs.GlobalConfig.Ports,
structs.GlobalConfig.NoPortString,
structs.GlobalConfig.TCPPortScanTimeout)
}
@ -163,9 +165,8 @@ func workflow() {
// 获取http响应
for hostPort, service := range structs.GlobalIPPortMap {
if service == "http" {
if strings.Contains(service, "http") {
urls = append(urls, "http://"+hostPort)
} else if service == "https" {
urls = append(urls, "https://"+hostPort)
}
}
@ -195,13 +196,21 @@ func workflow() {
TargetAndPocsName[url] = []string{}
}
report.GenerateHTMLReportHeader()
callnuclei.CallNuclei(TargetAndPocsName,
structs.GlobalConfig.HTTPProxy,
report.AddResultByResultEvent,
structs.GlobalConfig.PocNameForSearch,
structs.GlobalConfig.NoInteractsh,
structs.GlobalEmbedPocs, structs.GlobalConfig.NucleiTemplate, strings.Split(structs.GlobalConfig.ExcludeTags, ","),
strings.Split(structs.GlobalConfig.Severities, ","))
param := callnuclei.NucleiParams{
TargetAndPocsName: TargetAndPocsName,
Proxy: structs.GlobalConfig.HTTPProxy,
CallBack: report.AddResultByResultEvent,
NameForSearch: structs.GlobalConfig.PocNameForSearch,
NoInteractsh: structs.GlobalConfig.NoInteractsh,
Fs: structs.GlobalEmbedPocs,
NP: structs.GlobalConfig.NucleiTemplate,
ExcludeTags: strings.Split(structs.GlobalConfig.ExcludeTags, ","),
Severities: strings.Split(structs.GlobalConfig.Severities, ","),
InteractshServer: structs.GlobalConfig.InteractshURL,
InteractshToken: structs.GlobalConfig.InteractshToken,
}
callnuclei.CallNuclei(param)
utils.DeleteReportWithNoResult()
return
}
@ -244,12 +253,22 @@ func workflow() {
var nucleiResults []output.ResultEvent
TargetAndPocsName, count := http.GetPocs(structs.WorkFlowDB)
if count > 0 {
nucleiResults = callnuclei.CallNuclei(TargetAndPocsName,
structs.GlobalConfig.HTTPProxy,
report.AddResultByResultEvent,
"", structs.GlobalConfig.NoInteractsh, structs.GlobalEmbedPocs,
structs.GlobalConfig.NucleiTemplate, strings.Split(structs.GlobalConfig.ExcludeTags, ","),
strings.Split(structs.GlobalConfig.Severities, ","))
param := callnuclei.NucleiParams{
TargetAndPocsName: TargetAndPocsName,
Proxy: structs.GlobalConfig.HTTPProxy,
CallBack: report.AddResultByResultEvent,
NameForSearch: "",
NoInteractsh: structs.GlobalConfig.NoInteractsh,
Fs: structs.GlobalEmbedPocs,
NP: structs.GlobalConfig.NucleiTemplate,
ExcludeTags: strings.Split(structs.GlobalConfig.ExcludeTags, ","),
Severities: strings.Split(structs.GlobalConfig.Severities, ","),
InteractshServer: structs.GlobalConfig.InteractshURL,
InteractshToken: structs.GlobalConfig.InteractshToken,
}
nucleiResults = callnuclei.CallNuclei(param)
}
// GoPoc引擎

View File

@ -54,6 +54,7 @@ type Config struct {
NucleiTemplate string
ExcludeTags string
Severities string
NoServiceBruteForce bool
WorkflowYamlPath string
ReportName string
GoPocThreads int
@ -74,6 +75,9 @@ type Config struct {
FingerConfigFilePath string
PasswordFile string
Password string
InteractshURL string
InteractshToken string
NoPortString string
}
type CDNResult struct {