refactor wip
This commit is contained in:
32
proxychain/requestmodifers/masquerade_as_trusted_bot.go
Normal file
32
proxychain/requestmodifers/masquerade_as_trusted_bot.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package requestmodifers
|
||||
|
||||
import (
|
||||
"ladder/proxychain"
|
||||
)
|
||||
|
||||
// MasqueradeAsGoogleBot modifies user agent and x-forwarded for
|
||||
// to appear to be a Google Bot
|
||||
func MasqueradeAsGoogleBot() proxychain.RequestModification {
|
||||
const botUA string = "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Googlebot/2.1; http://www.google.com/bot.html) Chrome/79.0.3945.120 Safari/537.36"
|
||||
const botIP string = "66.249.78.8" // TODO: create a random ip pool from https://developers.google.com/static/search/apis/ipranges/googlebot.json
|
||||
return masqueradeAsTrustedBot(botUA, botIP)
|
||||
}
|
||||
|
||||
// MasqueradeAsBingBot modifies user agent and x-forwarded for
|
||||
// to appear to be a Bing Bot
|
||||
func MasqueradeAsBingBot() proxychain.RequestModification {
|
||||
const botUA string = "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm) Chrome/79.0.3945.120 Safari/537.36"
|
||||
const botIP string = "13.66.144.9" // https://www.bing.com/toolbox/bingbot.json
|
||||
return masqueradeAsTrustedBot(botUA, botIP)
|
||||
}
|
||||
|
||||
func masqueradeAsTrustedBot(botUA string, botIP string) proxychain.RequestModification {
|
||||
return func(px *proxychain.ProxyChain) error {
|
||||
px.AddRequestModifications(
|
||||
SpoofUserAgent(botUA),
|
||||
SpoofXForwardedFor(botIP),
|
||||
SpoofReferrer(""),
|
||||
)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
13
proxychain/requestmodifers/modify_domain_with_regex.go
Normal file
13
proxychain/requestmodifers/modify_domain_with_regex.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package requestmodifers
|
||||
|
||||
import (
|
||||
"ladder/proxychain"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
func ModifyDomainWithRegex(match regexp.Regexp, replacement string) proxychain.RequestModification {
|
||||
return func(px *proxychain.ProxyChain) error {
|
||||
px.Request.URL.Host = match.ReplaceAllString(px.Request.URL.Host, replacement)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
41
proxychain/requestmodifers/modify_outgoing_cookies.go
Normal file
41
proxychain/requestmodifers/modify_outgoing_cookies.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package requestmodifers
|
||||
|
||||
import (
|
||||
"ladder/proxychain"
|
||||
)
|
||||
|
||||
// BlockOutgoingCookies prevents ALL cookies from being sent from the client
|
||||
// to the upstream proxy server.
|
||||
func BlockOutgoingCookies() proxychain.RequestModification {
|
||||
return func(px *proxychain.ProxyChain) error {
|
||||
px.Request.Header.Del("Cookie")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// BlockOutgoingCookiesExcept prevents non-whitelisted cookies from being sent from the client
|
||||
// to the upstream proxy server. Cookies whose names are in the whitelist are not removed.
|
||||
func BlockOutgoingCookiesExcept(whitelist ...string) proxychain.RequestModification {
|
||||
return func(px *proxychain.ProxyChain) error {
|
||||
// Convert whitelist slice to a map for efficient lookups
|
||||
whitelistMap := make(map[string]struct{})
|
||||
for _, cookieName := range whitelist {
|
||||
whitelistMap[cookieName] = struct{}{}
|
||||
}
|
||||
|
||||
// Get all cookies from the request header
|
||||
cookies := px.Request.Cookies()
|
||||
|
||||
// Clear the original Cookie header
|
||||
px.Request.Header.Del("Cookie")
|
||||
|
||||
// Re-add cookies that are in the whitelist
|
||||
for _, cookie := range cookies {
|
||||
if _, found := whitelistMap[cookie.Name]; found {
|
||||
px.Request.AddCookie(cookie)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
13
proxychain/requestmodifers/modify_path_with_regex.go
Normal file
13
proxychain/requestmodifers/modify_path_with_regex.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package requestmodifers
|
||||
|
||||
import (
|
||||
"ladder/proxychain"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
func ModifyPathWithRegex(match regexp.Regexp, replacement string) proxychain.RequestModification {
|
||||
return func(px *proxychain.ProxyChain) error {
|
||||
px.Request.URL.Path = match.ReplaceAllString(px.Request.URL.Path, replacement)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
20
proxychain/requestmodifers/modify_query_params.go
Normal file
20
proxychain/requestmodifers/modify_query_params.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package requestmodifers
|
||||
|
||||
import (
|
||||
"ladder/proxychain"
|
||||
)
|
||||
|
||||
// ModifyQueryParams replaces query parameter values in URL's query params in a ProxyChain's URL.
|
||||
// If the query param key doesn't exist, it is created.
|
||||
func ModifyQueryParams(key string, value string) proxychain.RequestModification {
|
||||
return func(px *proxychain.ProxyChain) error {
|
||||
q := px.Request.URL.Query()
|
||||
if value == "" {
|
||||
q.Del(key)
|
||||
return nil
|
||||
}
|
||||
q.Set(key, value)
|
||||
px.Request.URL.RawQuery = q.Encode()
|
||||
return nil
|
||||
}
|
||||
}
|
||||
23
proxychain/requestmodifers/modify_request_headers.go
Normal file
23
proxychain/requestmodifers/modify_request_headers.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package requestmodifers
|
||||
|
||||
import (
|
||||
"ladder/proxychain"
|
||||
)
|
||||
|
||||
// SetRequestHeader modifies a specific outgoing header
|
||||
// This is the header that the upstream server will see.
|
||||
func SetRequestHeader(name string, val string) proxychain.RequestModification {
|
||||
return func(px *proxychain.ProxyChain) error {
|
||||
px.Request.Header.Set(name, val)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// DeleteRequestHeader modifies a specific outgoing header
|
||||
// This is the header that the upstream server will see.
|
||||
func DeleteRequestHeader(name string) proxychain.RequestModification {
|
||||
return func(px *proxychain.ProxyChain) error {
|
||||
px.Request.Header.Del(name)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
27
proxychain/requestmodifers/request_archive_is.go
Normal file
27
proxychain/requestmodifers/request_archive_is.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package requestmodifers
|
||||
|
||||
import (
|
||||
"ladder/proxychain"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
const archivistUrl string = "https://archive.is/latest/"
|
||||
|
||||
// RequestArchiveIs modifies a ProxyChain's URL to request an archived version from archive.is
|
||||
func RequestArchiveIs() proxychain.RequestModification {
|
||||
return func(px *proxychain.ProxyChain) error {
|
||||
px.Request.URL.RawQuery = ""
|
||||
newURLString := archivistUrl + px.Request.URL.String()
|
||||
newURL, err := url.Parse(newURLString)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// archivist seems to sabotage requests from cloudflare's DNS
|
||||
// bypass this just in case
|
||||
px.AddRequestModifications(ResolveWithGoogleDoH())
|
||||
|
||||
px.Request.URL = newURL
|
||||
return nil
|
||||
}
|
||||
}
|
||||
21
proxychain/requestmodifers/request_google_cache.go
Normal file
21
proxychain/requestmodifers/request_google_cache.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package requestmodifers
|
||||
|
||||
import (
|
||||
"ladder/proxychain"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
const googleCacheUrl string = "https://webcache.googleusercontent.com/search?q=cache:"
|
||||
|
||||
// RequestGoogleCache modifies a ProxyChain's URL to request its Google Cache version.
|
||||
func RequestGoogleCache() proxychain.RequestModification {
|
||||
return func(px *proxychain.ProxyChain) error {
|
||||
encodedURL := url.QueryEscape(px.Request.URL.String())
|
||||
newURL, err := url.Parse(googleCacheUrl + encodedURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
px.Request.URL = newURL
|
||||
return nil
|
||||
}
|
||||
}
|
||||
22
proxychain/requestmodifers/request_wayback_machine.go
Normal file
22
proxychain/requestmodifers/request_wayback_machine.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package requestmodifers
|
||||
|
||||
import (
|
||||
"ladder/proxychain"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
const waybackUrl string = "https://web.archive.org/web/"
|
||||
|
||||
// RequestWaybackMachine modifies a ProxyChain's URL to request the wayback machine (archive.org) version.
|
||||
func RequestWaybackMachine() proxychain.RequestModification {
|
||||
return func(px *proxychain.ProxyChain) error {
|
||||
px.Request.URL.RawQuery = ""
|
||||
newURLString := waybackUrl + px.Request.URL.String()
|
||||
newURL, err := url.Parse(newURLString)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
px.Request.URL = newURL
|
||||
return nil
|
||||
}
|
||||
}
|
||||
80
proxychain/requestmodifers/resolve_with_google_doh.go
Normal file
80
proxychain/requestmodifers/resolve_with_google_doh.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package requestmodifers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"ladder/proxychain"
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// resolveWithGoogleDoH resolves DNS using Google's DNS-over-HTTPS
|
||||
func resolveWithGoogleDoH(host string) (string, error) {
|
||||
url := "https://dns.google/resolve?name=" + host + "&type=A"
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var result struct {
|
||||
Answer []struct {
|
||||
Data string `json:"data"`
|
||||
} `json:"Answer"`
|
||||
}
|
||||
err = json.NewDecoder(resp.Body).Decode(&result)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Get the first A record
|
||||
if len(result.Answer) > 0 {
|
||||
return result.Answer[0].Data, nil
|
||||
}
|
||||
return "", fmt.Errorf("no DoH DNS record found for %s", host)
|
||||
}
|
||||
|
||||
// ResolveWithGoogleDoH modifies a ProxyChain's client to make the request but resolve the URL
|
||||
// using Google's DNS over HTTPs service
|
||||
func ResolveWithGoogleDoH() proxychain.RequestModification {
|
||||
return func(px *proxychain.ProxyChain) error {
|
||||
client := &http.Client{
|
||||
Timeout: px.Client.Timeout,
|
||||
}
|
||||
|
||||
dialer := &net.Dialer{
|
||||
Timeout: 5 * time.Second,
|
||||
KeepAlive: 5 * time.Second,
|
||||
}
|
||||
|
||||
customDialContext := func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
host, port, err := net.SplitHostPort(addr)
|
||||
if err != nil {
|
||||
// If the addr doesn't include a port, determine it based on the URL scheme
|
||||
if px.Request.URL.Scheme == "https" {
|
||||
port = "443"
|
||||
} else {
|
||||
port = "80"
|
||||
}
|
||||
host = addr // assume the entire addr is the host
|
||||
}
|
||||
|
||||
resolvedHost, err := resolveWithGoogleDoH(host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return dialer.DialContext(ctx, network, net.JoinHostPort(resolvedHost, port))
|
||||
}
|
||||
|
||||
patchedTransportWithDoH := &http.Transport{
|
||||
DialContext: customDialContext,
|
||||
}
|
||||
|
||||
client.Transport = patchedTransportWithDoH
|
||||
px.Client = client // Assign the modified client to the ProxyChain
|
||||
return nil
|
||||
}
|
||||
}
|
||||
24
proxychain/requestmodifers/spoof_origin.go
Normal file
24
proxychain/requestmodifers/spoof_origin.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package requestmodifers
|
||||
|
||||
import (
|
||||
"ladder/proxychain"
|
||||
)
|
||||
|
||||
// SpoofOrigin modifies the origin header
|
||||
// if the upstream server returns a Vary header
|
||||
// it means you might get a different response if you change this
|
||||
func SpoofOrigin(url string) proxychain.RequestModification {
|
||||
return func(px *proxychain.ProxyChain) error {
|
||||
px.Request.Header.Set("origin", url)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// HideOrigin modifies the origin header
|
||||
// so that it is the original origin, not the proxy
|
||||
func HideOrigin() proxychain.RequestModification {
|
||||
return func(px *proxychain.ProxyChain) error {
|
||||
px.Request.Header.Set("origin", px.Request.URL.String())
|
||||
return nil
|
||||
}
|
||||
}
|
||||
29
proxychain/requestmodifers/spoof_referrer.go
Normal file
29
proxychain/requestmodifers/spoof_referrer.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package requestmodifers
|
||||
|
||||
import (
|
||||
"ladder/proxychain"
|
||||
)
|
||||
|
||||
// SpoofReferrer modifies the referrer header
|
||||
// useful if the page can be accessed from a search engine
|
||||
// or social media site, but not by browsing the website itself
|
||||
// if url is "", then the referrer header is removed
|
||||
func SpoofReferrer(url string) proxychain.RequestModification {
|
||||
return func(px *proxychain.ProxyChain) error {
|
||||
if url == "" {
|
||||
px.Request.Header.Del("referrer")
|
||||
return nil
|
||||
}
|
||||
px.Request.Header.Set("referrer", url)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// HideReferrer modifies the referrer header
|
||||
// so that it is the original referrer, not the proxy
|
||||
func HideReferrer() proxychain.RequestModification {
|
||||
return func(px *proxychain.ProxyChain) error {
|
||||
px.Request.Header.Set("referrer", px.Request.URL.String())
|
||||
return nil
|
||||
}
|
||||
}
|
||||
13
proxychain/requestmodifers/spoof_user_agent.go
Normal file
13
proxychain/requestmodifers/spoof_user_agent.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package requestmodifers
|
||||
|
||||
import (
|
||||
"ladder/proxychain"
|
||||
)
|
||||
|
||||
// SpoofUserAgent modifies the user agent
|
||||
func SpoofUserAgent(ua string) proxychain.RequestModification {
|
||||
return func(px *proxychain.ProxyChain) error {
|
||||
px.Request.Header.Set("user-agent", ua)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
14
proxychain/requestmodifers/spoof_x_forwarded_for.go
Normal file
14
proxychain/requestmodifers/spoof_x_forwarded_for.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package requestmodifers
|
||||
|
||||
import (
|
||||
"ladder/proxychain"
|
||||
)
|
||||
|
||||
// SpoofXForwardedFor modifies the X-Forwarded-For header
|
||||
// in some cases, a forward proxy may interpret this as the source IP
|
||||
func SpoofXForwardedFor(ip string) proxychain.RequestModification {
|
||||
return func(px *proxychain.ProxyChain) error {
|
||||
px.Request.Header.Set("X-FORWARDED-FOR", ip)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user