Skip to content

Commit 6b6c4cb

Browse files
committed
Merge branch 'dev' into pr/735
2 parents 3b85c07 + f2381b5 commit 6b6c4cb

File tree

5 files changed

+73
-48
lines changed

5 files changed

+73
-48
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
<a href="https://discord.gg/projectdiscovery">Join Discord</a>
2323
</p>
2424

25-
Swiss Army Knife Proxy for rapid deployments. Supports multiple operations such as request/response dump, filtering and manipulation via DSL language, upstream HTTP/Socks5 proxy.
25+
Swiss Army Knife Proxy for rapid deployments. Supports multiple operations such as request/response dump, filtering and manipulation via DSL language, upstream HTTP/SOCKS5 proxy.
2626
Additionally, a replay utility allows to import the dumped traffic (request/responses with correct domain name) into BurpSuite or any other proxy by simply setting the upstream proxy to proxify.
2727

2828
# Features
@@ -60,7 +60,7 @@ proxify -h
6060
This will display help for the tool. Here are all the switches it supports.
6161

6262
```console
63-
Swiss Army Knife Proxy for rapid deployments. Supports multiple operations such as request/response dump,filtering and manipulation via DSL language, upstream HTTP/Socks5 proxy
63+
Swiss Army Knife Proxy for rapid deployments. Supports multiple operations such as request/response dump,filtering and manipulation via DSL language, upstream HTTP/SOCKS5 proxy
6464

6565
Usage:
6666
./proxify [flags]

internal/runner/options.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ type Options struct {
3737
Verbosity types.Verbosity
3838
Version bool
3939
ListenAddrHTTP string
40-
ListenAddrSocks5 string
40+
ListenAddrSOCKS5 string
4141
ListenDNSAddr string
4242
DNSMapping string // DNSMapping contains user provided hosts
4343
DNSFallbackResolver string // Listen DNS Ip and port (ip:port)
@@ -47,7 +47,7 @@ type Options struct {
4747
ResponseDSL goflags.StringSlice // Response Filter DSL
4848
ResponseMatchReplaceDSL goflags.StringSlice // Request Match-Replace DSL
4949
UpstreamHTTPProxies goflags.StringSlice // Upstream HTTP comma separated Proxies (e.g. http://proxyip:proxyport)
50-
UpstreamSocks5Proxies goflags.StringSlice // Upstream SOCKS5 comma separated Proxies (e.g. socks5://proxyip:proxyport)
50+
UpstreamSOCKS5Proxies goflags.StringSlice // Upstream SOCKS5 comma separated Proxies (e.g. socks5://proxyip:proxyport)
5151
UpstreamProxyRequestsNumber int // Number of requests before switching upstream proxy
5252
DumpRequest bool // Dump requests in separate files
5353
DumpResponse bool // Dump responses in separate files
@@ -71,7 +71,7 @@ func ParseOptions() (*Options, error) {
7171
options := &Options{}
7272

7373
flagSet := goflags.NewFlagSet()
74-
flagSet.SetDescription(`Swiss Army Knife Proxy for rapid deployments. Supports multiple operations such as request/response dump,filtering and manipulation via DSL language, upstream HTTP/Socks5 proxy`)
74+
flagSet.SetDescription(`Swiss Army Knife Proxy for rapid deployments. Supports multiple operations such as request/response dump,filtering and manipulation via DSL language, upstream HTTP/SOCKS5 proxy`)
7575

7676
flagSet.CreateGroup("output", "Output",
7777
// Todo: flagSet.BoolVar(&options.Dump, "dump", true, "Dump HTTP requests/response to output file"),
@@ -98,15 +98,15 @@ func ParseOptions() (*Options, error) {
9898

9999
flagSet.CreateGroup("network", "Network",
100100
flagSet.StringVarP(&options.ListenAddrHTTP, "http-addr", "ha", "127.0.0.1:8888", "Listening HTTP IP and Port address (ip:port)"),
101-
flagSet.StringVarP(&options.ListenAddrSocks5, "socks-addr", "sa", "127.0.0.1:10080", "Listening SOCKS IP and Port address (ip:port)"),
101+
flagSet.StringVarP(&options.ListenAddrSOCKS5, "socks-addr", "sa", "127.0.0.1:10080", "Listening SOCKS IP and Port address (ip:port)"),
102102
flagSet.StringVarP(&options.ListenDNSAddr, "dns-addr", "da", "", "Listening DNS IP and Port address (ip:port)"),
103103
flagSet.StringVarP(&options.DNSMapping, "dns-mapping", "dm", "", "Domain to IP DNS mapping (eg domain:ip,domain:ip,..)"),
104104
flagSet.StringVarP(&options.DNSFallbackResolver, "resolver", "r", "", "Custom DNS resolvers to use (ip:port)"),
105105
)
106106

107107
flagSet.CreateGroup("proxy", "Proxy",
108108
flagSet.StringSliceVarP(&options.UpstreamHTTPProxies, "http-proxy", "hp", nil, "Upstream HTTP Proxies (eg http://proxy-ip:proxy-port)", goflags.NormalizedStringSliceOptions),
109-
flagSet.StringSliceVarP(&options.UpstreamSocks5Proxies, "socks5-proxy", "sp", nil, "Upstream SOCKS5 Proxies (eg socks5://proxy-ip:proxy-port)", goflags.NormalizedStringSliceOptions),
109+
flagSet.StringSliceVarP(&options.UpstreamSOCKS5Proxies, "socks5-proxy", "sp", nil, "Upstream SOCKS5 Proxies (eg socks5://proxy-ip:proxy-port)", goflags.NormalizedStringSliceOptions),
110110
flagSet.IntVar(&options.UpstreamProxyRequestsNumber, "c", 1, "Number of requests before switching to the next upstream proxy"),
111111
)
112112

internal/runner/runner.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,15 @@ func NewRunner(options *Options) (*Runner, error) {
3737
CertCacheSize: options.CertCacheSize,
3838
Verbosity: options.Verbosity,
3939
ListenAddrHTTP: options.ListenAddrHTTP,
40-
ListenAddrSocks5: options.ListenAddrSocks5,
40+
ListenAddrSOCKS5: options.ListenAddrSOCKS5,
4141
OutputFile: options.OutputFile,
4242
OutputFormat: options.OutputFormat,
4343
OutputDirectory: options.OutputDirectory,
4444
OutputHar: options.OutputHar,
4545
RequestDSL: options.RequestDSL,
4646
ResponseDSL: options.ResponseDSL,
4747
UpstreamHTTPProxies: options.UpstreamHTTPProxies,
48-
UpstreamSock5Proxies: options.UpstreamSocks5Proxies,
48+
UpstreamSOCKS5Proxies: options.UpstreamSOCKS5Proxies,
4949
ListenDNSAddr: options.ListenDNSAddr,
5050
DNSMapping: options.DNSMapping,
5151
DNSFallbackResolver: options.DNSFallbackResolver,
@@ -91,8 +91,8 @@ func (r *Runner) Run() error {
9191
if r.options.ListenAddrHTTP != "" {
9292
gologger.Info().Msgf("HTTP Proxy Listening on %s\n", r.options.ListenAddrHTTP)
9393
}
94-
if r.options.ListenAddrSocks5 != "" {
95-
gologger.Info().Msgf("Socks5 Proxy Listening on %s\n", r.options.ListenAddrSocks5)
94+
if r.options.ListenAddrSOCKS5 != "" {
95+
gologger.Info().Msgf("SOCKS5 Proxy Listening on %s\n", r.options.ListenAddrSOCKS5)
9696
}
9797

9898
if r.options.OutputFile != "" {
@@ -112,8 +112,8 @@ func (r *Runner) Run() error {
112112

113113
if len(r.options.UpstreamHTTPProxies) > 0 {
114114
gologger.Info().Msgf("Using upstream HTTP proxies: %s\n", r.options.UpstreamHTTPProxies)
115-
} else if len(r.options.UpstreamSocks5Proxies) > 0 {
116-
gologger.Info().Msgf("Using upstream SOCKS5 proxies: %s\n", r.options.UpstreamSocks5Proxies)
115+
} else if len(r.options.UpstreamSOCKS5Proxies) > 0 {
116+
gologger.Info().Msgf("Using upstream SOCKS5 proxies: %s\n", r.options.UpstreamSOCKS5Proxies)
117117
}
118118

119119
if r.options.DNSMapping != "" {

proxy.go

Lines changed: 59 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -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

4143
type 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 {
419421
func (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

522547
func (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

526551
func (p *Proxy) hijackNServe(req *http.Request, ctx *martian.Context) error {

static/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@
162162
<div class="center-text">
163163
Swiss Army Knife Proxy for rapid deployments. <br>
164164
Supports multiple operations such as request/response dump,<br>
165-
filtering and manipulation via DSL language, upstream HTTP/Socks5 proxy.<br>
165+
filtering and manipulation via DSL language, upstream HTTP/SOCKS5 proxy.<br>
166166
Additionally, a replay utility allows to import the dumped traffic <br>
167167
(request/responses with correct domain name) into BurpSuite or <br>
168168
any other proxy by simply setting the upstream proxy to proxify.

0 commit comments

Comments
 (0)