yellow.git


yellow

~ opinionated web scanning pipeline for pentesters in a hurry
git clone https://github.com/djnnvx/yellow.git
log | files | refs | archive | README | LICENSE

tlsx.go (1695B)

      1 package scan
      2 
      3 import (
      4 	"encoding/json"
      5 	"fmt"
      6 	"net/url"
      7 	"os"
      8 	"strings"
      9 
     10 	"evil.djnn.sh/djnn/yellow/core"
     11 	"github.com/projectdiscovery/tlsx/pkg/tlsx"
     12 	"github.com/projectdiscovery/tlsx/pkg/tlsx/clients"
     13 )
     14 
     15 type Tlsx struct{}
     16 
     17 func (*Tlsx) Name() string { return "tlsx" }
     18 
     19 func (*Tlsx) Run(ctx *core.Context) error {
     20 	fmt.Println("[+] Running tlsx on", ctx.Domain)
     21 	if ctx.DryRun {
     22 		return nil
     23 	}
     24 
     25 	host := tlsxHost(ctx.Domain)
     26 	if host == "" {
     27 		return nil
     28 	}
     29 
     30 	service, err := tlsx.New(&clients.Options{
     31 		Timeout:    5,
     32 		Retries:    1,
     33 		ScanMode:   "auto",
     34 		SAN:        true,
     35 		TLSVersion: true,
     36 	})
     37 	if err != nil {
     38 		fmt.Printf("[!] tlsx: %v\n", err)
     39 		return nil
     40 	}
     41 
     42 	resp, err := service.Connect(host, "", "443")
     43 	if err != nil || resp == nil {
     44 		fmt.Printf("[!] tlsx: could not grab certificate for %s: %v\n", host, err)
     45 		return nil
     46 	}
     47 
     48 	outfile := fmt.Sprintf("%s/tls.json", ctx.ScanPath)
     49 	data, _ := json.MarshalIndent(resp, "", "\t")
     50 	if err := os.WriteFile(outfile, data, 0644); err != nil {
     51 		fmt.Printf("[!] tlsx: could not write %s: %v\n", outfile, err)
     52 	}
     53 
     54 	// certificate SANs frequently reveal extra hostnames worth chasing
     55 	if resp.CertificateResponse != nil && len(resp.Domains) > 0 {
     56 		fmt.Printf("[SCAN %s] tlsx: %d cert hostname(s): %s\n", host, len(resp.Domains), strings.Join(resp.Domains, ", "))
     57 	}
     58 
     59 	fmt.Printf("[SCAN %s] tlsx scan completed (TLS %s), results in %s\n\n", host, resp.Version, outfile)
     60 	return nil
     61 }
     62 
     63 // tlsxHost extracts the bare hostname from a target that may be a full URL.
     64 func tlsxHost(target string) string {
     65 	if u, err := url.Parse(target); err == nil && u.Hostname() != "" {
     66 		return u.Hostname()
     67 	}
     68 	return strings.TrimSpace(target)
     69 }