@@ -11,6 +11,7 @@ import (
1111 "net/http"
1212 "net/http/httptest"
1313 "net/http/httputil"
14+ "net/url"
1415 "os"
1516 "strconv"
1617 "strings"
@@ -36,6 +37,7 @@ import (
3637 sliceutil "github.com/projectdiscovery/utils/slice"
3738 stringsutil "github.com/projectdiscovery/utils/strings"
3839 "github.com/things-go/go-socks5"
40+ "golang.org/x/net/proxy"
3941)
4042
4143type OnRequestFunc func (req * http.Request , ctx * martian.Context ) error
@@ -50,15 +52,15 @@ type Options struct {
5052 CertCacheSize int
5153 Directory string
5254 ListenAddrHTTP string
53- ListenAddrSocks5 string
55+ ListenAddrSOCKS5 string
5456 OutputDirectory string
5557 OutputFile string
5658 OutputFormat string
5759 OutputHar string
5860 RequestDSL []string
5961 ResponseDSL []string
6062 UpstreamHTTPProxies []string
61- UpstreamSock5Proxies []string
63+ UpstreamSOCKS5Proxies []string
6264 ListenDNSAddr string
6365 DNSMapping string
6466 DNSFallbackResolver string
@@ -79,12 +81,12 @@ type Proxy struct {
7981 options * Options
8082 logger * logger.Logger
8183 httpProxy * martian.Proxy
82- socks5proxy * socks5.Server
83- socks5tunnel * superproxy.SuperProxy
84+ socks5Proxy * socks5.Server
85+ socks5Tunnel * superproxy.SuperProxy
8486 bufioPool * bufiopool.Pool
85- tinydns * tinydns.TinyDNS
86- rbhttp * rbtransport.RoundTransport
87- rbsocks5 * rbtransport.RoundTransport
87+ tinyDNS * tinydns.TinyDNS
88+ rbHTTP * rbtransport.RoundTransport
89+ rbSOCKS5 * rbtransport.RoundTransport
8890 proxifyMux * http.ServeMux // serve banner page and static files
8991 listenAddr string
9092}
@@ -115,27 +117,27 @@ func NewProxy(options *Options) (*Proxy, error) {
115117 Kafka : options .Kafka ,
116118 })
117119
118- var tdns * tinydns.TinyDNS
120+ var tDNS * tinydns.TinyDNS
119121
120122 fastdialerOptions := fastdialer .DefaultOptions
121123 fastdialerOptions .EnableFallback = true
122124 fastdialerOptions .Deny = options .Deny
123125 fastdialerOptions .Allow = options .Allow
124126 if options .ListenDNSAddr != "" {
125- dnsmapping := make (map [string ]* tinydns.DnsRecord )
127+ dnsMapping := make (map [string ]* tinydns.DnsRecord )
126128 for _ , record := range strings .Split (options .DNSMapping , "," ) {
127129 data := strings .Split (record , ":" )
128130 if len (data ) != 2 {
129131 continue
130132 }
131- dnsmapping [data [0 ]] = & tinydns.DnsRecord {A : []string {data [1 ]}}
133+ dnsMapping [data [0 ]] = & tinydns.DnsRecord {A : []string {data [1 ]}}
132134 }
133135 var err error
134- tdns , err = tinydns .New (& tinydns.Options {
136+ tDNS , err = tinydns .New (& tinydns.Options {
135137 ListenAddress : options .ListenDNSAddr ,
136138 Net : "udp" ,
137139 UpstreamServers : []string {options .DNSFallbackResolver },
138- DnsRecords : dnsmapping ,
140+ DnsRecords : dnsMapping ,
139141 })
140142 if err != nil {
141143 return nil , err
@@ -151,8 +153,8 @@ func NewProxy(options *Options) (*Proxy, error) {
151153 fastdialerOptions .ProxyDialer = & proxyDialer
152154 }
153155
154- if len (options .UpstreamSock5Proxies ) > 0 {
155- dialer , err := newSOCKS5ProxyRoundRobinDialer (options .UpstreamSock5Proxies )
156+ if len (options .UpstreamSOCKS5Proxies ) > 0 {
157+ dialer , err := newSOCKS5ProxyRoundRobinDialer (options .UpstreamSOCKS5Proxies )
156158 if err != nil {
157159 return nil , err
158160 }
@@ -164,20 +166,20 @@ func NewProxy(options *Options) (*Proxy, error) {
164166 return nil , err
165167 }
166168
167- var rbhttp , rbsocks5 * rbtransport.RoundTransport
169+ var rbHTTP , rbSOCKS5 * rbtransport.RoundTransport
168170 if len (options .UpstreamHTTPProxies ) > 0 {
169- rbhttp , err = rbtransport .NewWithOptions (options .UpstreamProxyRequestsNumber , options .UpstreamHTTPProxies ... )
171+ rbHTTP , err = rbtransport .NewWithOptions (options .UpstreamProxyRequestsNumber , options .UpstreamHTTPProxies ... )
170172 if err != nil {
171173 return nil , err
172174 }
173175 }
174- if len (options .UpstreamSock5Proxies ) > 0 {
175- rbsocks5 , err = rbtransport .NewWithOptions (options .UpstreamProxyRequestsNumber , options .UpstreamSock5Proxies ... )
176+ if len (options .UpstreamSOCKS5Proxies ) > 0 {
177+ rbSOCKS5 , err = rbtransport .NewWithOptions (options .UpstreamProxyRequestsNumber , options .UpstreamSOCKS5Proxies ... )
176178 if err != nil {
177179 return nil , err
178180 }
179181 }
180- pmux , err := getProxifyServerMux ()
182+ pMux , err := getProxifyServerMux ()
181183 if err != nil {
182184 return nil , err
183185 }
@@ -186,31 +188,31 @@ func NewProxy(options *Options) (*Proxy, error) {
186188 logger : logger ,
187189 options : options ,
188190 Dialer : dialer ,
189- tinydns : tdns ,
190- rbhttp : rbhttp ,
191- rbsocks5 : rbsocks5 ,
192- proxifyMux : pmux ,
191+ tinyDNS : tDNS ,
192+ rbHTTP : rbHTTP ,
193+ rbSOCKS5 : rbSOCKS5 ,
194+ proxifyMux : pMux ,
193195 }
194196
195197 if err := proxy .setupHTTPProxy (); err != nil {
196198 return nil , err
197199 }
198200
199- var socks5proxy * socks5.Server
200- if options .ListenAddrSocks5 != "" {
201+ var socks5Proxy * socks5.Server
202+ if options .ListenAddrSOCKS5 != "" {
201203 if options .Verbosity <= types .VerbositySilent {
202- socks5proxy = socks5 .NewServer (
204+ socks5Proxy = socks5 .NewServer (
203205 socks5 .WithLogger (socks5 .NewLogger (log .New (io .Discard , "" , log .Ltime | log .Lshortfile ))),
204206 socks5 .WithDial (proxy .httpTunnelDialer ),
205207 )
206208 } else {
207- socks5proxy = socks5 .NewServer (
209+ socks5Proxy = socks5 .NewServer (
208210 socks5 .WithDial (proxy .httpTunnelDialer ),
209211 )
210212 }
211213 }
212214
213- proxy .socks5proxy = socks5proxy
215+ proxy .socks5Proxy = socks5Proxy
214216
215217 return proxy , nil
216218}
@@ -419,11 +421,11 @@ func (p *Proxy) MatchReplaceResponse(resp *http.Response) error {
419421func (p * Proxy ) Run () error {
420422 var wg sync.WaitGroup
421423
422- if p .tinydns != nil {
424+ if p .tinyDNS != nil {
423425 wg .Add (1 )
424426 go func () {
425427 defer wg .Done ()
426- if err := p .tinydns .Run (); err != nil {
428+ if err := p .tinyDNS .Run (); err != nil {
427429 gologger .Warning ().Msgf ("Could not start dns server: %s\n " , err )
428430 }
429431 }()
@@ -452,7 +454,7 @@ func (p *Proxy) Run() error {
452454 }
453455
454456 // socks5 proxy
455- if p .socks5proxy != nil {
457+ if p .socks5Proxy != nil {
456458 if p .httpProxy != nil {
457459 httpProxyIP , httpProxyPort , err := net .SplitHostPort (p .options .ListenAddrHTTP )
458460 if err != nil {
@@ -462,7 +464,7 @@ func (p *Proxy) Run() error {
462464 if err != nil {
463465 return err
464466 }
465- p .socks5tunnel , err = superproxy .NewSuperProxy (httpProxyIP , uint16 (httpProxyPortUint ), superproxy .ProxyTypeHTTP , "" , "" , "" )
467+ p .socks5Tunnel , err = superproxy .NewSuperProxy (httpProxyIP , uint16 (httpProxyPortUint ), superproxy .ProxyTypeHTTP , "" , "" , "" )
466468 if err != nil {
467469 return err
468470 }
@@ -473,7 +475,7 @@ func (p *Proxy) Run() error {
473475 go func () {
474476 defer wg .Done ()
475477
476- gologger .Fatal ().Msgf ("%v" , p .socks5proxy .ListenAndServe ("tcp" , p .options .ListenAddrSocks5 ))
478+ gologger .Fatal ().Msgf ("%v" , p .socks5Proxy .ListenAndServe ("tcp" , p .options .ListenAddrSOCKS5 ))
477479 }()
478480 }
479481
@@ -516,11 +518,34 @@ func (p *Proxy) getRoundTripper() (http.RoundTripper, error) {
516518 InsecureSkipVerify : true ,
517519 },
518520 }
521+
522+ if len (p .options .UpstreamHTTPProxies ) > 0 {
523+ roundtrip = & http.Transport {Proxy : func (req * http.Request ) (* url.URL , error ) {
524+ return url .Parse (p .rbHTTP .Next ())
525+ }, TLSClientConfig : & tls.Config {InsecureSkipVerify : true }}
526+ } else if len (p .options .UpstreamSOCKS5Proxies ) > 0 {
527+ // for each socks5 proxy create a dialer
528+ socks5Dialers := make (map [string ]proxy.Dialer )
529+ for _ , socks5Proxy := range p .options .UpstreamSOCKS5Proxies {
530+ dialer , err := proxy .SOCKS5 ("tcp" , socks5Proxy , nil , proxy .Direct )
531+ if err != nil {
532+ return nil , err
533+ }
534+ socks5Dialers [socks5Proxy ] = dialer
535+ }
536+ roundtrip = & http.Transport {Dial : func (network , addr string ) (net.Conn , error ) {
537+ // lookup next dialer
538+ socks5Proxy := p .rbSOCKS5 .Next ()
539+ socks5Dialer := socks5Dialers [socks5Proxy ]
540+ // use it to perform the request
541+ return socks5Dialer .Dial (network , addr )
542+ }, TLSClientConfig : & tls.Config {InsecureSkipVerify : true }}
543+ }
519544 return roundtrip , nil
520545}
521546
522547func (p * Proxy ) httpTunnelDialer (ctx context.Context , network , addr string ) (net.Conn , error ) {
523- return p .socks5tunnel .MakeTunnel (nil , nil , p .bufioPool , addr )
548+ return p .socks5Tunnel .MakeTunnel (nil , nil , p .bufioPool , addr )
524549}
525550
526551func (p * Proxy ) hijackNServe (req * http.Request , ctx * martian.Context ) error {
0 commit comments