Projects STRLCPY afrog Commits e870ff30
🤬
  • ■ ■ ■ ■ ■ ■
    cmd/afrog/main.go
    skipped 4 lines
    5 5   "os"
    6 6   "strings"
    7 7   "sync"
     8 + "sync/atomic"
    8 9   "time"
    9 10   
    10 11   "github.com/urfave/cli/v2"
    skipped 12 lines
    23 24  var options = &config.Options{}
    24 25  var htemplate = &html.HtmlTemplate{}
    25 26  var lock sync.Mutex
    26  -var number = 0
     27 +var number int64 = 0
    27 28   
    28 29  func main() {
    29 30   app := cli.NewApp()
    skipped 33 lines
    63 64   return nil
    64 65   }
    65 66   
    66  - starttime := time.Now()
    67 67   upgrade := upgrade.New()
    68 68   upgrade.IsUpdatePocs = options.UpdatePocs
    69 69   upgrade.UpgradeAfrogPocs()
    skipped 10 lines
    80 80   if err := htemplate.New(); err != nil {
    81 81   return err
    82 82   }
     83 + 
     84 + starttime := time.Now()
    83 85   
    84 86   // fixed 99% bug
    85 87   go func() {
    86 88   startcount := options.CurrentCount
    87 89   for {
    88  - time.Sleep(3 * time.Minute)
    89  - if options.CurrentCount > 0 && startcount == options.CurrentCount {
    90  - endtime := time.Now()
    91  - fmt.Println(log.LogColor.High("Error, Time: ", endtime.Sub(starttime)))
     90 + time.Sleep(2 * time.Minute)
     91 + if options.CurrentCount > 0 && startcount == options.CurrentCount && len(options.TargetLive.ListRequestTargets()) == 0 {
     92 + fmt.Printf("\r%d/%d/%d%%/%s | hosts: %d, closed: %d | except: The program runs to %d end", options.CurrentCount, options.Count, int(options.CurrentCount)*100/options.Count, strings.Split(time.Now().Sub(starttime).String(), ".")[0]+"s", len(options.Targets), options.TargetLive.GetNoLiveAtomicCount(), int(options.CurrentCount)*100/options.Count)
     93 + fmt.Println(" close wait 3 seconds...")
     94 + time.Sleep(time.Second * 3)
    92 95   os.Exit(1)
    93 96   }
    94 97   startcount = options.CurrentCount
    skipped 3 lines
    98 101   err := runner.New(options, htemplate, func(result any) {
    99 102   r := result.(*core.Result)
    100 103   
    101  - lock.Lock()
    102  - 
    103  - // if !options.Silent {
    104  - options.CurrentCount++
    105  - // }
     104 + atomic.AddInt64(&options.CurrentCount, 1)
    106 105   
     106 + lock.Lock()
    107 107   if r.IsVul {
    108 108   if r.FingerResult != nil {
    109 109   fr := r.FingerResult.(fingerprint.Result)
    110 110   printFingerprintInfoConsole(fr)
    111 111   } else {
    112  - // PoC Scan
    113  - number++
    114 112   
    115  - r.PrintColorResultInfoConsole(utils.GetNumberText(number))
     113 + atomic.AddInt64(&number, 1)
     114 + r.PrintColorResultInfoConsole(utils.GetNumberText(int(number)))
    116 115   
    117 116   htemplate.Result = r
    118  - htemplate.Number = utils.GetNumberText(number)
     117 + htemplate.Number = utils.GetNumberText(int(number))
    119 118   htemplate.Append()
    120 119   }
    121 120   }
     121 + lock.Unlock()
    122 122   
    123 123   if !options.Silent {
    124  - fmt.Printf("\r%d/%d | %d%% ", options.CurrentCount, options.Count, options.CurrentCount*100/options.Count)
     124 + fmt.Printf("\r%d/%d/%d%%/%s | hosts: %d, closed: %d", options.CurrentCount, options.Count, int(options.CurrentCount)*100/options.Count, strings.Split(time.Now().Sub(starttime).String(), ".")[0]+"s", len(options.Targets), options.TargetLive.GetNoLiveAtomicCount())
    125 125   }
    126  - 
    127  - lock.Unlock()
    128 126   
    129 127   })
    130 128   if err != nil {
    131 129   return err
    132 130   }
    133 131   
    134  - endtime := time.Now()
    135  - fmt.Println(log.LogColor.Vulner(" Time: ", endtime.Sub(starttime)))
    136  - 
    137 132   return err
    138 133   }
    139 134   
    skipped 3 lines
    143 138   fmt.Println(log.LogColor.High("start afrog failed,", err.Error()))
    144 139   }
    145 140   
    146  - utils.RandSleep(1000)
     141 + fmt.Println(" close wait 3 seconds...")
     142 + time.Sleep(time.Second * 3)
    147 143  }
    148 144   
    149 145  func printFingerprintInfoConsole(fr fingerprint.Result) {
    skipped 2 lines
    152 148   if !strings.HasPrefix(fr.StatusCode, "2") {
    153 149   statusCode = log.LogColor.Midium("" + fr.StatusCode + "")
    154 150   }
     151 + space := " "
     152 + if len(fr.Title) == 0 && len(fr.Name) == 0 {
     153 + space = " "
     154 + } else if len(fr.Title) != 0 && len(fr.Name) == 0 {
     155 + space = " "
     156 + }
    155 157   fmt.Printf("\r" + fr.Url + " " +
    156 158   statusCode + " " +
    157 159   fr.Title + " " +
    158  - log.LogColor.Critical(fr.Name) + "\r\n")
     160 + log.LogColor.Critical(fr.Name) + space + "\r\n")
    159 161   }
    160 162  }
    161 163   
    skipped 14 lines
  • ■ ■ ■ ■ ■
    go.mod
    skipped 9 lines
    10 10   github.com/gookit/color v1.5.0
    11 11   github.com/karrick/godirwalk v1.16.1
    12 12   github.com/natefinch/lumberjack v2.0.0+incompatible
    13  - github.com/panjf2000/ants/v2 v2.5.0
     13 + github.com/panjf2000/ants/v2 v2.6.0
    14 14   github.com/pkg/errors v0.9.1
    15 15   github.com/projectdiscovery/rawhttp v0.1.1
    16 16   github.com/remeh/sizedwaitgroup v1.0.0
    skipped 15 lines
    32 32   github.com/golang/snappy v0.0.4 // indirect
    33 33   github.com/klauspost/compress v1.15.9 // indirect
    34 34   github.com/miekg/dns v1.1.43 // indirect
     35 + github.com/panjf2000/ants v1.3.0
    35 36   github.com/projectdiscovery/blackrock v0.0.0-20210415162320-b38689ae3a2e // indirect
    36 37   github.com/projectdiscovery/cryptoutil v0.0.0-20210805184155-b5d2512f9345 // indirect
    37 38   github.com/projectdiscovery/fastdialer v0.0.15 // indirect
    skipped 28 lines
  • ■ ■ ■ ■ ■ ■
    go.sum
    skipped 124 lines
    125 125  github.com/onsi/gomega v1.10.5 h1:7n6FEkpFmfCoo2t+YYqXH0evK+a9ICQz0xcAy9dYcaQ=
    126 126  github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48=
    127 127  github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
     128 +github.com/panjf2000/ants v1.3.0 h1:8pQ+8leaLc9lys2viEEr8md0U4RN6uOSUCE9bOYjQ9M=
     129 +github.com/panjf2000/ants v1.3.0/go.mod h1:AaACblRPzq35m1g3enqYcxspbbiOJJYaxU2wMpm1cXY=
    128 130  github.com/panjf2000/ants/v2 v2.5.0 h1:1rWGWSnxCsQBga+nQbA4/iY6VMeNoOIAM0ZWh9u3q2Q=
    129 131  github.com/panjf2000/ants/v2 v2.5.0/go.mod h1:cU93usDlihJZ5CfRGNDYsiBYvoilLvBF5Qp/BT2GNRE=
     132 +github.com/panjf2000/ants/v2 v2.6.0 h1:xOSpw42m+BMiJ2I33we7h6fYzG4DAlpE1xyI7VS2gxU=
     133 +github.com/panjf2000/ants/v2 v2.6.0/go.mod h1:cU93usDlihJZ5CfRGNDYsiBYvoilLvBF5Qp/BT2GNRE=
    130 134  github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
    131 135  github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
    132 136  github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
    skipped 256 lines
  • ■ ■ ■ ■
    internal/runner/banner.go
    skipped 8 lines
    9 9  )
    10 10   
    11 11  func ShowBanner() string {
    12  - return log.LogColor.Bold("afrog ") + log.LogColor.Banner("")
     12 + return log.LogColor.Bold("afrog ") + log.LogColor.Banner(" · ")
    13 13  }
    14 14   
    15 15  func ShowUsage() string {
    skipped 17 lines
  • ■ ■ ■ ■ ■ ■
    internal/runner/runner.go
    skipped 12 lines
    13 13   "github.com/zan8in/afrog/pkg/log"
    14 14   "github.com/zan8in/afrog/pkg/poc"
    15 15   http2 "github.com/zan8in/afrog/pkg/protocols/http"
     16 + "github.com/zan8in/afrog/pkg/targets"
    16 17   "github.com/zan8in/afrog/pkg/utils"
    17 18   "github.com/zan8in/afrog/pocs"
    18 19  )
    skipped 5 lines
    24 25   
    25 26  func New(options *config.Options, htemplate *html.HtmlTemplate, acb config.ApiCallBack) error {
    26 27   runner := &Runner{options: options}
     28 + 
     29 + // init TargetLive
     30 + options.TargetLive = utils.New()
    27 31   
    28 32   // init callback
    29 33   options.ApiCallBack = acb
    skipped 29 lines
    59 63   if len(options.Targets) == 0 {
    60 64   return errors.New("not found targets")
    61 65   }
    62  - // targets handler
    63  - for _, v := range options.Targets {
    64  - options.SetCheckLiveValue(v)
    65  - }
    66 66   
    67 67   // init pocs
    68 68   allPocsEmbedYamlSlice := []string{}
    skipped 32 lines
    101 101   fmt.Println(ShowTips())
    102 102   }
    103 103   
    104  - // fmt.Println("port scan before : ", len(options.Targets))
    105  - // if options.WebPort {
    106  - // if scan, err := scan.New(options); err == nil {
    107  - // scan.Execute()
    108  - // }
    109  - // }
    110  - // fmt.Println("port scan after : ", len(options.Targets))
    111  - // for k, v := range options.Targets {
    112  - // fmt.Println(k, v)
    113  - // }
    114  - 
    115 104   // fingerprint
    116 105   if !options.NoFinger {
    117 106   s, _ := fingerprint.New(options)
    skipped 4 lines
    122 111   }
    123 112   }
    124 113   
    125  - //
     114 + //check target live
     115 + go targets.RunTargetLivenessCheck(options)
     116 + 
    126 117   e := core.New(options)
    127 118   e.Execute(allPocsYamlSlice, allPocsEmbedYamlSlice)
    128 119   
    skipped 2 lines
    131 122   
    132 123  func printFingerResultConsole() {
    133 124   fmt.Printf("\r" + log.LogColor.Time("000 "+utils.GetNowDateTime()) + " " +
    134  - log.LogColor.Vulner("Fingerprint") + " " + log.LogColor.Info("INFO") + "\r\n")
     125 + log.LogColor.Vulner("Fingerprint") + " " + log.LogColor.Info("INFO") + " \r\n")
    135 126   
    136 127  }
    137 128   
  • ■ ■ ■ ■ ■ ■
    pkg/config/config.go
    skipped 39 lines
    40 40  }
    41 41   
    42 42  const afrogConfigFilename = "afrog-config.yaml"
    43  -const Version = "1.3.9"
     43 +const Version = "2.0.0"
    44 44   
    45 45  // Create and initialize afrog-config.yaml configuration info
    46 46  func New() (*Config, error) {
    skipped 5 lines
    52 52   configHttp := c.ConfigHttp
    53 53   configHttp.Proxy = ""
    54 54   configHttp.DialTimeout = 10
    55  - configHttp.ReadTimeout = "500ms"
    56  - configHttp.WriteTimeout = "500ms"
     55 + configHttp.ReadTimeout = "10000ms"
     56 + configHttp.WriteTimeout = "3000ms"
    57 57   configHttp.MaxIdle = "1h"
    58 58   configHttp.MaxRedirect = 3
    59 59   configHttp.Concurrency = 4096
    skipped 97 lines
  • ■ ■ ■ ■ ■
    pkg/config/options.go
    skipped 66 lines
    67 67   Count int
    68 68   
    69 69   // Current Scan count num
    70  - CurrentCount int
     70 + CurrentCount int64
    71 71   
    72 72   // Thread lock
    73 73   OptLock sync.Mutex
    skipped 1 lines
    75 75   // Callback scan result
    76 76   ApiCallBack ApiCallBack
    77 77   
    78  - // CheckLive
    79  - CheckLiveMap sync.Map
     78 + // check target live status
     79 + TargetLive *utils.TargetLive
    80 80  }
    81 81   
    82 82  type ApiCallBack func(any)
    skipped 47 lines
    130 130   return false
    131 131  }
    132 132   
    133  -// check live by count, alive if result is true else not alive.
    134  -func (o *Options) CheckLiveByCount(url string) bool {
    135  - c, b := o.GetCheckLiveValue(url)
    136  - if c >= 6 {
    137  - // fmt.Println(url, "c>3", c, b)
    138  - return false
    139  - }
    140  - if !b {
    141  - o.SetCheckLiveValue(url)
    142  - 
    143  - // c, b := o.GetCheckLiveValue(url)
    144  - // fmt.Println(url, "no http(s)", c, b)
    145  - }
    146  - return true
    147  -}
    148  - 
    149  -func (o *Options) SetCheckLiveValue(key string) {
    150  - c, b := o.CheckLiveMap.Load(key)
    151  - if b && c.(int) < 6 {
    152  - o.CheckLiveMap.Store(key, c.(int)+1)
    153  - } else {
    154  - o.CheckLiveMap.Store(key, 0)
    155  - }
    156  -}
    157  - 
    158  -func (o *Options) GetCheckLiveValue(key string) (int, bool) {
    159  - c, b := o.CheckLiveMap.LoadOrStore(key, 0)
    160  - return c.(int), b
    161  -}
    162  - 
  • ■ ■ ■ ■ ■
    pkg/core/checker.go
    skipped 38 lines
    39 39   }()
    40 40   
    41 41   // check target alive.
    42  - if alive := c.Options.CheckLiveByCount(target); !alive {
     42 + if c.Options.TargetLive.HandleTargetLive(target, -1) == -1 || len(target) == 0 {
    43 43   c.Result.IsVul = false
    44 44   c.Options.ApiCallBack(c.Result)
    45 45   return err
    skipped 43 lines
    89 89   c.UpdateVariableMap(pocItem.Payloads.Payloads)
    90 90   }
    91 91   
     92 + c.FastClient.Target = target
     93 + 
    92 94   for _, ruleMap := range pocItem.Rules {
    93 95   k := ruleMap.Key
    94 96   rule := ruleMap.Value
     97 + 
     98 + if c.Options.TargetLive.HandleTargetLive(target, -1) == -1 || len(target) == 0 {
     99 + fmt.Println("来到这里,你可不简单哦", target)
     100 + c.Result.IsVul = false
     101 + c.Options.ApiCallBack(c.Result)
     102 + return err
     103 + }
    95 104   
    96 105   if rule.BeforeSleep != 0 {
    97 106   time.Sleep(time.Duration(rule.BeforeSleep) * time.Second)
    skipped 78 lines
    176 185   gpa := gopoc.New(target)
    177 186   
    178 187   // check target alive.
    179  - if alive := c.Options.CheckLiveByCount(target); !alive {
     188 + if c.Options.TargetLive.HandleTargetLive(target, -1) == -1 || len(target) == 0 {
    180 189   c.Result.IsVul = false
    181 190   c.Options.ApiCallBack(c.Result)
    182 191   return err
    183 192   }
    184 193   
     194 + c.Options.TargetLive.AddRequestTarget(target+gopocName, 1)
    185 195   fun := gopoc.GetGoPocFunc(gopocName)
    186 196   r, err := fun(gpa)
    187 197   if err != nil {
     198 + c.Options.TargetLive.AddRequestTarget(target+gopocName, 2)
    188 199   c.Result.IsVul = false
    189 200   c.Result.PocInfo = gpa.Poc
    190 201   c.Options.ApiCallBack(c.Result)
    191 202   return err
    192 203   }
     204 + c.Options.TargetLive.AddRequestTarget(target+gopocName, 2)
    193 205   
    194 206   c.Result.Target = target
    195 207   c.Result.FullTarget = target
    skipped 58 lines
  • ■ ■ ■ ■ ■
    pkg/core/engine.go
    skipped 24 lines
    25 25   c := CheckerPool.Get().(*Checker)
    26 26   c.Options = e.options
    27 27   c.Result.Output = e.options.Output
     28 + c.FastClient.Options = e.options
    28 29   return c
    29 30  }
    30 31   
    skipped 28 lines
  • ■ ■ ■ ■ ■
    pkg/core/excute.go
    skipped 6 lines
    7 7   "github.com/zan8in/afrog/pkg/gopoc"
    8 8   "github.com/zan8in/afrog/pkg/log"
    9 9   "github.com/zan8in/afrog/pkg/poc"
    10  - http2 "github.com/zan8in/afrog/pkg/protocols/http"
    11 10   "github.com/zan8in/afrog/pkg/utils"
    12 11   "github.com/zan8in/afrog/pocs"
    13 12  )
    skipped 64 lines
    78 77   // init scan sum
    79 78   e.options.Count += len(e.options.Targets) * len(newPocSlice)
    80 79   
    81  - // outdated: 2022.7.25
    82  - // swg := e.workPool.PocSwg
    83  - // swg := e.workPool.NewPool(e.workPool.config.PocConcurrencyType)
    84  - // for _, p := range newPocSlice {
    85  - // swg.WaitGroup.Add()
    86  - // go func(p poc.Poc) {
    87  - // defer swg.WaitGroup.Done()
    88  - // e.executeTargets(p)
    89  - // }(p)
    90  - // }
    91  - // swg.WaitGroup.Wait()
    92  - 
    93 80   var wg sync.WaitGroup
    94 81   p, _ := ants.NewPoolWithFunc(e.workPool.config.PocConcurrency, func(p any) {
    95 82   e.executeTargets(p.(poc.Poc))
    skipped 1 lines
    97 84   })
    98 85   defer p.Release()
    99 86   for _, poc := range newPocSlice {
    100  - wg.Add(1)
    101  - _ = p.Invoke(poc)
     87 + err := p.Invoke(poc)
     88 + if err == nil {
     89 + wg.Add(1)
     90 + }
    102 91   }
    103 92   wg.Wait()
    104 93  }
    skipped 11 lines
    116 105   return
    117 106   }
    118 107   
    119  - // outdated: 2022.7.25
    120  - // wg := e.workPool.NewPool(e.workPool.config.TargetConcurrencyType)
    121  - // for k, target := range allTargets {
    122  - // wg.WaitGroup.Add()
    123  - // go func(k int, target string, poc1 poc.Poc) {
    124  - // defer wg.WaitGroup.Done()
    125  - 
    126  - // // add: check target alive
    127  - // if alive := e.options.CheckLiveByCount(target); alive && !http2.IsFullHttpFormat(target) {
    128  - // target = http2.CheckLive(target)
    129  - // if !http2.IsFullHttpFormat(target) {
    130  - // e.options.SetCheckLiveValue(target)
    131  - // } else {
    132  - // e.options.Targets[k] = target
    133  - // }
    134  - // }
    135  - 
    136  - // e.executeExpression(target, poc1)
    137  - 
    138  - // // fmt.Println("poc the number of goroutines: ", runtime.NumGoroutine())
    139  - // }(k, target, poc1)
    140  - // }
    141  - // wg.WaitGroup.Wait()
    142  - 
    143 108   var wg sync.WaitGroup
    144 109   p, _ := ants.NewPoolWithFunc(e.workPool.config.TargetConcurrency, func(wgTask any) {
    145 110   defer wg.Done()
    146 111   target := wgTask.(poc.WaitGroupTask).Value.(string)
    147  - key := wgTask.(poc.WaitGroupTask).Key
     112 + // key := wgTask.(poc.WaitGroupTask).Key
    148 113   //add: check target alive
    149  - if alive := e.options.CheckLiveByCount(target); alive && !http2.IsFullHttpFormat(target) {
    150  - target = http2.CheckLive(target)
    151  - if !http2.IsFullHttpFormat(target) {
    152  - e.options.SetCheckLiveValue(target)
    153  - } else {
    154  - e.options.Targets[key] = target
    155  - }
     114 + if e.options.TargetLive.HandleTargetLive(target, -1) == 1 {
     115 + e.executeExpression(target, poc1)
     116 + } else {
     117 + e.executeExpression("", poc1)
    156 118   }
    157 119   
    158  - e.executeExpression(target, poc1)
    159 120   })
    160 121   defer p.Release()
    161 122   for k, target := range allTargets {
    162  - wg.Add(1)
    163  - _ = p.Invoke(poc.WaitGroupTask{Value: target, Key: k})
     123 + err := p.Invoke(poc.WaitGroupTask{Value: target, Key: k})
     124 + if err == nil {
     125 + wg.Add(1)
     126 + }
    164 127   }
    165 128   wg.Wait()
    166 129  }
    skipped 27 lines
  • ■ ■ ■ ■ ■ ■
    pkg/fingerprint/fingerprint.go
    skipped 76 lines
    77 77   size = int(s.Options.Config.FingerprintSizeWaitGroup)
    78 78   }
    79 79   
    80  - // swg := sizedwaitgroup.New(size)
    81  - // for k, url := range s.Options.Targets {
    82  - // swg.Add()
    83  - // go func(k int, url string) {
    84  - // defer swg.Done()
    85  - 
    86  - // // add: check target alive
    87  - // if alive := s.Options.CheckLiveByCount(url); alive && !http2.IsFullHttpFormat(url) {
    88  - // url = http2.CheckLive(url)
    89  - // if !http2.IsFullHttpFormat(url) {
    90  - // s.Options.SetCheckLiveValue(url)
    91  - // s.PrintColorResultInfoConsole(Result{})
    92  - // return
    93  - // } else {
    94  - // s.Options.Targets[k] = url
    95  - // }
    96  - // }
    97  - 
    98  - // s.processFingerPrintInputPair(url)
    99  - 
    100  - // // fmt.Println("the number of goroutines: ", runtime.NumGoroutine())
    101  - // }(k, url)
    102  - // }
    103  - // swg.Wait()
    104  - 
    105 80   var wg sync.WaitGroup
    106 81   p, _ := ants.NewPoolWithFunc(size, func(wgTask any) {
    107 82   defer wg.Done()
    108 83   url := wgTask.(poc.WaitGroupTask).Value.(string)
    109 84   key := wgTask.(poc.WaitGroupTask).Key
    110  - //add: check target alive
    111  - if alive := s.Options.CheckLiveByCount(url); alive && !http2.IsFullHttpFormat(url) {
    112  - url = http2.CheckLive(url)
    113  - if !http2.IsFullHttpFormat(url) {
    114  - s.Options.SetCheckLiveValue(url)
    115  - } else {
    116  - s.Options.Targets[key] = url
    117  - }
     85 + if s.Options.TargetLive.HandleTargetLive(url, -1) == -1 {
     86 + // 该 url 在 targetlive 黑名单里面
     87 + s.PrintColorResultInfoConsole(Result{})
     88 + } else {
     89 + // 该 url 未在 targetlive 黑名单里面
     90 + s.processFingerPrintInputPair(url, key)
    118 91   }
    119  - 
    120  - s.processFingerPrintInputPair(url)
    121 92   })
    122 93   defer p.Release()
    123 94   for k, target := range s.Options.Targets {
    124  - wg.Add(1)
    125  - _ = p.Invoke(poc.WaitGroupTask{Value: target, Key: k})
     95 + err := p.Invoke(poc.WaitGroupTask{Value: target, Key: k})
     96 + if err == nil {
     97 + wg.Add(1)
     98 + }
    126 99   }
    127 100   wg.Wait()
    128 101   }
    129 102  }
    130 103   
    131  -func (s *Service) processFingerPrintInputPair(url string) error {
     104 +func (s *Service) processFingerPrintInputPair(url string, key int) error {
    132 105   if len(s.fpSlice) == 0 {
    133 106   s.PrintColorResultInfoConsole(Result{})
    134 107   return nil
    135 108   }
    136 109   
    137  - // check target alive.
    138  - if alive := s.Options.CheckLiveByCount(url); !alive {
     110 + // 检测 http or https 并更新 targets 列表
     111 + url, statusCode := http2.CheckTargetHttps2(url)
     112 + if statusCode == -1 {
     113 + // url 加入 targetlive 黑名单 +1
     114 + s.Options.TargetLive.HandleTargetLive(url, 0)
    139 115   s.PrintColorResultInfoConsole(Result{})
    140 116   return nil
    141  - }
    142  - 
    143  - if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") {
    144  - url = "http://" + url
     117 + } else {
     118 + s.Options.TargetLive.HandleTargetLive(url, 1)
     119 + s.Options.Targets[key] = url
    145 120   }
    146 121   
    147 122   req, err := http.NewRequest("GET", url, nil)
    skipped 85 lines
  • pkg/fingerprint/web_fingerprint_v3.json
    Unable to diff as the file is too large.
  • ■ ■ ■ ■ ■
    pkg/protocols/http/http.go
    skipped 31 lines
    32 32   MaxRedirect int32
    33 33   DialTimeout int32
    34 34   UserAgent string
     35 + Options *config.Options
     36 + Target string
    35 37  }
    36 38   
    37 39  func Init(options *config.Options) {
    skipped 122 lines
    160 162   // 新增功能:HTTP请求超时,自动重连机制(3次,每次累加超时时间)
    161 163   repeatCount := 0
    162 164   for {
     165 + fc.Options.TargetLive.AddRequestTarget(fmt.Sprintf("%s://%s%s", protoRequest.Url.Scheme, protoRequest.Url.Host, protoRequest.Url.Path), 1)
     166 + if fc.Options.TargetLive.HandleTargetLive(fc.Target, -1) == -1 {
     167 + return errors.New("target nolive")
     168 + }
     169 + // starttime := time.Now().Second()
    163 170   if rule.Request.FollowRedirects {
    164 171   maxrd := 3 // follow redirects default 3
    165 172   if fc.MaxRedirect > 0 {
    skipped 10 lines
    176 183   }
    177 184   err = F.DoTimeout(fastReq, fastResp, time.Second*time.Duration(dialtimeout))
    178 185   }
     186 + fc.Options.TargetLive.AddRequestTarget(fmt.Sprintf("%s://%s%s", protoRequest.Url.Scheme, protoRequest.Url.Host, protoRequest.Url.Path), 2)
     187 + // endtime := time.Now().Second()
     188 + // if endtime-starttime > 20 {
     189 + // fmt.Println(log.LogColor.Vulner(httpRequest.URL, fastResp.StatusCode(), endtime-starttime))
     190 + // }
    179 191   if err != nil {
    180 192   errName, known := httpConnError(err)
    181 193   if known {
    skipped 2 lines
    184 196   log.Log().Error(fmt.Sprintf("ERR conn failure: %s %s\n", errName, err))
    185 197   }
    186 198   if errName == "timeout" {
    187  - repeatCount++
     199 + repeatCount += 1
    188 200   if repeatCount > 1 {
    189 201   break
    190 202   }
    skipped 418 lines
    609 621   fastResp := fasthttp.AcquireResponse()
    610 622   defer fasthttp.ReleaseResponse(fastResp)
    611 623   
    612  - // currd := 0
    613  - // for {
    614  - // currd++
    615  - // err = F.DoTimeout(fastReq, fastResp, time.Second*time.Duration(6))
    616  - // statusCode := fastResp.Header.StatusCode()
    617  - // if statusCode != fasthttp.StatusMovedPermanently &&
    618  - // statusCode != fasthttp.StatusFound &&
    619  - // statusCode != fasthttp.StatusSeeOther &&
    620  - // statusCode != fasthttp.StatusTemporaryRedirect &&
    621  - // statusCode != fasthttp.StatusPermanentRedirect {
    622  - // break
    623  - // }
    624  - 
    625  - // location := fastResp.Header.PeekBytes(strLocation)
    626  - // if len(location) == 0 {
    627  - // break
    628  - // }
    629  - 
    630  - // u := fastReq.URI()
    631  - // u.UpdateBytes(location)
    632  - 
    633  - // if currd >= 3 {
    634  - // break
    635  - // }
    636  - // }
    637  - // fasthttp bug, https://github.com/valyala/fasthttp/issues/1361
    638 624   err = F.DoRedirects(fastReq, fastResp, 3)
    639 625   
    640 626   newheader := make(map[string][]string)
    skipped 59 lines
    700 686   }
    701 687   
    702 688   return []byte(fastReq.String()), fastResp.Body(), []byte(fastResp.Header.String()), fastResp.StatusCode(), urlType, err
     689 +}
     690 + 
     691 +// 返回 -1,表示 request 请求失败(无法访问)
     692 +func CheckTargetHttps(target string) (string, int) {
     693 + if strings.HasPrefix(target, "http://") || strings.HasPrefix(target, "https://") {
     694 + statusCode, _, err := fasthttp.Get(nil, target)
     695 + if err == nil {
     696 + return target, statusCode
     697 + }
     698 + return target, -1
     699 + }
     700 + 
     701 + u, err := url.Parse("http://" + target)
     702 + if err != nil {
     703 + return target, -1
     704 + }
     705 + 
     706 + port := u.Port()
     707 + 
     708 + switch {
     709 + case port == "80" || len(port) == 0:
     710 + statusCode, _, err := fasthttp.Get(nil, "http://"+target)
     711 + if err == nil {
     712 + return "http://" + target, statusCode
     713 + }
     714 + return target, -1
     715 + 
     716 + case port == "443":
     717 + statusCode, _, err := fasthttp.Get(nil, "https://"+target)
     718 + if err == nil {
     719 + return "https://" + target, statusCode
     720 + }
     721 + return target, -1
     722 + }
     723 + 
     724 + statusCode, resp, err := fasthttp.Get(nil, "http://"+target)
     725 + if err == nil {
     726 + if bytes.Contains(resp, []byte("<title>400 The plain HTTP request was sent to HTTPS port</title>")) {
     727 + return "https://" + target, statusCode
     728 + }
     729 + return "http://" + target, statusCode
     730 + }
     731 + 
     732 + statusCode, _, err = fasthttp.Get(nil, "https://"+target)
     733 + if err == nil {
     734 + return "https://" + target, statusCode
     735 + }
     736 + 
     737 + return target, -1
     738 +}
     739 + 
     740 +// 返回 -1,表示 request 请求失败(无法访问)
     741 +func CheckTargetHttps2(target string) (string, int) {
     742 + if strings.HasPrefix(target, "http://") || strings.HasPrefix(target, "https://") {
     743 + _, statusCode, err := GetTimeout(target, 6)
     744 + if err == nil {
     745 + return target, statusCode
     746 + }
     747 + return target, -1
     748 + }
     749 + 
     750 + u, err := url.Parse("http://" + target)
     751 + if err != nil {
     752 + return target, -1
     753 + }
     754 + 
     755 + port := u.Port()
     756 + 
     757 + switch {
     758 + case port == "80" || len(port) == 0:
     759 + _, statusCode, err := GetTimeout("http://"+target, 6)
     760 + if err == nil {
     761 + return "http://" + target, statusCode
     762 + }
     763 + return target, -1
     764 + 
     765 + case port == "443":
     766 + _, statusCode, err := GetTimeout("https://"+target, 6)
     767 + if err == nil {
     768 + return "https://" + target, statusCode
     769 + }
     770 + return target, -1
     771 + }
     772 + 
     773 + resp, statusCode, err := GetTimeout("http://"+target, 6)
     774 + if err == nil {
     775 + if bytes.Contains(resp, []byte("<title>400 The plain HTTP request was sent to HTTPS port</title>")) {
     776 + return "https://" + target, statusCode
     777 + }
     778 + return "http://" + target, statusCode
     779 + }
     780 + 
     781 + _, statusCode, err = GetTimeout("https://"+target, 6)
     782 + if err == nil {
     783 + return "https://" + target, statusCode
     784 + }
     785 + 
     786 + return target, -1
    703 787  }
    704 788   
    705 789  // target is not alive if return value is none http(s) else is alive.
    skipped 225 lines
  • ■ ■ ■ ■ ■ ■
    pkg/targets/targets.go
     1 +package targets
     2 + 
     3 +import (
     4 + "sync"
     5 + "time"
     6 + 
     7 + "github.com/panjf2000/ants"
     8 + "github.com/zan8in/afrog/pkg/config"
     9 + "github.com/zan8in/afrog/pkg/poc"
     10 + http2 "github.com/zan8in/afrog/pkg/protocols/http"
     11 +)
     12 + 
     13 +func RunTargetLivenessCheck(options *config.Options) {
     14 + first := true
     15 + for {
     16 + // fmt.Println("\r\nRunTargetLivenessCheck start", len(options.Targets), options.TargetLive.GetNoLiveAtomicCount())
     17 + // reqCount := 0
     18 + if len(options.Targets) > 0 {
     19 + size := 100
     20 + if options.Config.FingerprintSizeWaitGroup > 0 {
     21 + size = int(options.Config.FingerprintSizeWaitGroup)
     22 + }
     23 + 
     24 + var wg sync.WaitGroup
     25 + p, _ := ants.NewPoolWithFunc(size, func(wgTask any) {
     26 + defer wg.Done()
     27 + url := wgTask.(poc.WaitGroupTask).Value.(string)
     28 + key := wgTask.(poc.WaitGroupTask).Key
     29 + // 首次检测 target list
     30 + if first && options.TargetLive.HandleTargetLive(url, -1) != -1 {
     31 + url, statusCode := http2.CheckTargetHttps(url)
     32 + // fmt.Println("once", url, statusCode)
     33 + if statusCode == -1 || statusCode >= 500 {
     34 + // url 加入 targetlive 黑名单 +1
     35 + options.TargetLive.HandleTargetLive(url, 0)
     36 + } else {
     37 + options.TargetLive.HandleTargetLive(url, 1)
     38 + }
     39 + // reqCount += 1
     40 + }
     41 + // 非首次检测 target list
     42 + if !first && options.TargetLive.HandleTargetLive(url, -1) == 2 {
     43 + url, statusCode := http2.CheckTargetHttps(url)
     44 + // fmt.Println(url, statusCode)
     45 + if statusCode == -1 || statusCode >= 500 {
     46 + // url 加入 targetlive 黑名单 +1
     47 + options.TargetLive.HandleTargetLive(url, 0)
     48 + } else {
     49 + options.TargetLive.HandleTargetLive(url, 1)
     50 + }
     51 + // reqCount += 1
     52 + }
     53 + if options.Targets[key] != url {
     54 + options.Targets[key] = url
     55 + }
     56 + })
     57 + defer p.Release()
     58 + 
     59 + for k, target := range options.Targets {
     60 + wg.Add(1)
     61 + _ = p.Invoke(poc.WaitGroupTask{Value: target, Key: k})
     62 + }
     63 + wg.Wait()
     64 + }
     65 + // fmt.Println("request count", reqCount)
     66 + // reqCount = 0
     67 + first = false
     68 + time.Sleep(time.Second * 30)
     69 + // fmt.Println("target noLive count: ", options.TargetLive.GetNoLiveCount(), options.TargetLive.GetNoLiveAtomicCount())
     70 + // for _, target := range options.TargetLive.GetNoLiveSlice() {
     71 + // fmt.Println("\r\nnolive target: ", target)
     72 + // }
     73 + // lt := options.TargetLive.ListRequestTargets()
     74 + // if len(lt) > 0 {
     75 + // for _, v := range lt {
     76 + // fmt.Println("777777777777777", v, " 仍在请求中...")
     77 + // }
     78 + // }
     79 + // fmt.Println("正在请求中....总数:", len(lt))
     80 + }
     81 + 
     82 +}
     83 + 
  • ■ ■ ■ ■ ■ ■
    pkg/utils/targetLive.go
     1 +package utils
     2 + 
     3 +import (
     4 + "strings"
     5 + "sync"
     6 + "sync/atomic"
     7 +)
     8 + 
     9 +type TargetLive struct {
     10 + live sync.Map
     11 + nolive sync.Map
     12 + max int
     13 + noliveCount int64
     14 + noliveSlice []string
     15 + mutex *sync.Mutex
     16 + rtMutex *sync.Mutex
     17 + white []string
     18 + black []string
     19 +}
     20 + 
     21 +type RequestTarget struct {
     22 + t string
     23 + v int
     24 +}
     25 + 
     26 +func New() *TargetLive {
     27 + return &TargetLive{live: sync.Map{}, nolive: sync.Map{}, max: 3, noliveSlice: []string{}, mutex: &sync.Mutex{}, white: []string{}, black: []string{}, rtMutex: &sync.Mutex{}}
     28 +}
     29 + 
     30 +func (tl *TargetLive) AddRequestTarget(t string, v int) {
     31 + tl.rtMutex.Lock()
     32 + if v == 1 {
     33 + tl.white = append(tl.white, t)
     34 + }
     35 + if v == 2 {
     36 + tl.black = append(tl.black, t)
     37 + }
     38 + tl.rtMutex.Unlock()
     39 +}
     40 + 
     41 +func (tl *TargetLive) ListRequestTargets() []string {
     42 + r := []string{}
     43 + for _, t := range tl.white {
     44 + rb := false
     45 + for _, b := range tl.black {
     46 + if b == t {
     47 + rb = true
     48 + break
     49 + }
     50 + }
     51 + if !rb {
     52 + r = append(r, t)
     53 + }
     54 + }
     55 + return r
     56 +}
     57 + 
     58 +// Target 存活处理函数
     59 +// target 待验证得 target
     60 +// live 如果 target 请求返回状态码小于 500 的话 live = 1
     61 +// 如果参数 live = 1 ,添加target到liveMap
     62 +// 如果参数 live = 0, 添加target到noliveMap
     63 +// 如果参数 live = -1, 判断 target 状态,live返回1,nolive返回-1(黑名单),未确定live/nolive的返回 2
     64 +func (tl *TargetLive) HandleTargetLive(target string, live int) int {
     65 + target = strings.TrimSpace(target)
     66 + 
     67 + if live == 1 {
     68 + // TODO: handle live
     69 + _, ok := tl.live.Load(target)
     70 + if !ok {
     71 + tl.live.Store(target, 0)
     72 + }
     73 + return 0
     74 + }
     75 + 
     76 + if live == 0 {
     77 + // TODO: handle nolive
     78 + c, b := tl.nolive.Load(target)
     79 + if b && c.(int) >= tl.max {
     80 + atomic.AddInt64(&tl.noliveCount, 1)
     81 + tl.appendNoliveSlices(target)
     82 + return 0
     83 + }
     84 + if b {
     85 + tl.nolive.Store(target, c.(int)+1)
     86 + if c.(int)+1 >= tl.max {
     87 + atomic.AddInt64(&tl.noliveCount, 1)
     88 + tl.appendNoliveSlices(target)
     89 + }
     90 + // fmt.Println("tl.nolive.Store(target, c.(int)+1)", target, c.(int)+1)
     91 + return 0
     92 + }
     93 + tl.nolive.Store(target, 1)
     94 + // fmt.Println("tl.nolive.Store(target, 1)", target, 1)
     95 + return 0
     96 + }
     97 + 
     98 + if live == -1 {
     99 + // TODO: handle checkLive
     100 + _, ok := tl.live.Load(target)
     101 + if ok {
     102 + return 1
     103 + }
     104 + v, ok := tl.nolive.Load(target)
     105 + if ok && v.(int) >= tl.max {
     106 + // fmt.Println(">>>>>", target, ok, v.(int), tl.max, v.(int) >= tl.max, len(tl.noliveSlice))
     107 + return -1
     108 + }
     109 + }
     110 + 
     111 + return 2
     112 +}
     113 + 
     114 +func (tl *TargetLive) appendNoliveSlices(t string) {
     115 + tl.mutex.Lock()
     116 + defer tl.mutex.Unlock()
     117 + if len(tl.noliveSlice) == 0 {
     118 + tl.noliveSlice = append(tl.noliveSlice, t)
     119 + return
     120 + }
     121 + for _, v := range tl.noliveSlice {
     122 + if v == t {
     123 + return
     124 + }
     125 + }
     126 + tl.noliveSlice = append(tl.noliveSlice, t)
     127 +}
     128 + 
     129 +func (tl *TargetLive) GetNoLiveCount() int {
     130 + tl.mutex.Lock()
     131 + defer tl.mutex.Unlock()
     132 + return len(tl.noliveSlice)
     133 +}
     134 + 
     135 +func (tl *TargetLive) GetNoLiveSlice() []string {
     136 + tl.mutex.Lock()
     137 + defer tl.mutex.Unlock()
     138 + return tl.noliveSlice
     139 +}
     140 + 
     141 +func (tl *TargetLive) GetNoLiveAtomicCount() int64 {
     142 + return tl.noliveCount
     143 +}
     144 + 
  • ■ ■ ■ ■ ■ ■
    pkg/utils/utils.go
    skipped 176 lines
    177 177   return num
    178 178  }
    179 179   
    180  -//16进制解码
     180 +// 16进制解码
    181 181  func HexDecode(s string) []byte {
    182 182   dst := make([]byte, hex.DecodedLen(len(s))) //申请一个切片, 指明大小. 必须使用hex.DecodedLen
    183 183   n, err := hex.Decode(dst, []byte(s)) //进制转换, src->dst
    skipped 4 lines
    188 188   return dst[:n] //返回0:n的数据.
    189 189  }
    190 190   
    191  -//字符串转为16进制
     191 +// 字符串转为16进制
    192 192  func HexEncode(s string) []byte {
    193 193   dst := make([]byte, hex.EncodedLen(len(s))) //申请一个切片, 指明大小. 必须使用hex.EncodedLen
    194 194   n := hex.Encode(dst, []byte(s)) //字节流转化成16进制
    skipped 14 lines
  • pocs/temp/afrog-pocs/vulnerability/thinkcmf-file-include.yaml pocs/afrog-pocs/e-vulnerability/thinkcmf-file-include.yaml
    Content is identical
  • pocs/temp/afrog-pocs/CVE/2022/CVE-2022-0656.yaml pocs/afrog-pocs/g-CVE/2022/CVE-2022-0656.yaml
    Content is identical
  • pocs/temp/afrog-pocs/CVE/2022/CVE-2022-1020.yaml pocs/afrog-pocs/g-CVE/2022/CVE-2022-1020.yaml
    Content is identical
  • pocs/temp/afrog-pocs/CVE/2022/CVE-2022-1119.yaml pocs/afrog-pocs/g-CVE/2022/CVE-2022-1119.yaml
    Content is identical
  • pocs/temp/afrog-pocs/CVE/2022/CVE-2022-1390.yaml pocs/afrog-pocs/g-CVE/2022/CVE-2022-1390.yaml
    Content is identical
  • pocs/temp/afrog-pocs/CVE/2022/CVE-2022-40684.yaml pocs/afrog-pocs/g-CVE/2022/CVE-2022-40684.yaml
    Content is identical
  • ■ ■ ■ ■
    pocs/temp/afrog-pocs/version
    1  -0.1.72
     1 +0.1.73
  • pocs/v/afrog-pocs.zip
    Binary file.
  • ■ ■ ■ ■
    pocs/v/afrog.version
    1  -1.3.9
     1 +2.0.0
  • ■ ■ ■ ■
    pocs/v/version
    1  -0.1.72
     1 +0.1.73
Please wait...
Page is in error, reload to recover