mirror of
https://github.com/lunchcat/sif.git
synced 2026-06-12 19:11:25 -07:00
d0bdcf1690
every scanner spun up its own &http.Client, so there was no single place to apply a proxy, custom headers, a cookie or a rate limit. add an internal/httpx package that builds one configured transport at startup and hand it to every scanner via httpx.Client(timeout), keeping behavior identical when nothing is set (plain client when Configure was never called). - httpx.Configure wires -proxy (http/https/socks5), -H/--header, -cookie and -rate-limit into a package-level RoundTripper that paces via a rate.Limiter and only sets headers the caller hasn't already, so a scanner's explicit api key still wins. - route the scan/wordlist downloads that used http.DefaultClient through the shared client too; ports tcp dialing is left untouched. - clamp -threads to a floor of 1: it feeds wg.Add across the scanners, so 0 was a silent no-op and a negative value panicked the waitgroup. document the new flags in the readme, usage docs and man page.
90 lines
2.9 KiB
Go
90 lines
2.9 KiB
Go
/*
|
|
·━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━·
|
|
: :
|
|
: █▀ █ █▀▀ · Blazing-fast pentesting suite :
|
|
: ▄█ █ █▀ · BSD 3-Clause License :
|
|
: :
|
|
: (c) 2022-2026 vmfunc, xyzeva, :
|
|
: lunchcat alumni & contributors :
|
|
: :
|
|
·━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━·
|
|
*/
|
|
|
|
/*
|
|
What we are doing is abusing a internal file in Next.js pages router called
|
|
_buildManifest.js which lists all routes and script files ever referenced in
|
|
the application within next.js, this allows us to optimise and not bruteforce
|
|
directories for routes and instead get all of them at once.
|
|
|
|
We are currently parsing this js file with regexes but that should ideally be
|
|
replaced soon.
|
|
*/
|
|
|
|
package frameworks
|
|
|
|
import (
|
|
"bufio"
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"regexp"
|
|
"strings"
|
|
|
|
"github.com/dropalldatabases/sif/internal/httpx"
|
|
urlutil "github.com/projectdiscovery/utils/url"
|
|
)
|
|
|
|
// nextPagesRegex matches JavaScript file references in Next.js build manifest.
|
|
var nextPagesRegex = regexp.MustCompile(`\[("([^"]+\.js)"(,?))`)
|
|
|
|
func GetPagesRouterScripts(scriptUrl string) ([]string, error) {
|
|
baseUrl, err := urlutil.Parse(scriptUrl)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
req, err := http.NewRequestWithContext(context.TODO(), http.MethodGet, scriptUrl, http.NoBody)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return nil, err
|
|
}
|
|
|
|
// no timeout in scope here; 0 matches the previous DefaultClient behavior
|
|
// while still routing through the shared transport (proxy/headers/rate-limit).
|
|
resp, err := httpx.Client(0).Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
var sb strings.Builder
|
|
scanner := bufio.NewScanner(resp.Body)
|
|
scanner.Split(bufio.ScanLines)
|
|
for scanner.Scan() {
|
|
sb.WriteString(scanner.Text())
|
|
}
|
|
manifestText := sb.String()
|
|
|
|
list := nextPagesRegex.FindAllStringSubmatch(manifestText, -1)
|
|
|
|
var scripts []string
|
|
|
|
for _, el := range list {
|
|
var script = strings.ReplaceAll(el[2], "\\u002F", "/")
|
|
url, err := urlutil.Parse(script)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
if url.IsRelative {
|
|
url.Host = baseUrl.Host
|
|
url.Scheme = baseUrl.Scheme
|
|
url.Path = "/_next/" + url.Path
|
|
}
|
|
scripts = append(scripts, url.String())
|
|
}
|
|
|
|
return scripts, nil
|
|
}
|