From d774023da71b23e69f9db33b80282f16bb6755eb Mon Sep 17 00:00:00 2001 From: ccreater <1126774947@qq.com> Date: Sat, 7 May 2022 23:46:22 +0800 Subject: [PATCH 1/4] add socks5 support --- Plugins/CVE-2020-0796.go | 3 +- Plugins/NetBIOS.go | 2 +- Plugins/fcgiscan.go | 3 +- Plugins/findnet.go | 3 +- Plugins/memcached.go | 3 +- Plugins/mongodb.go | 3 +- Plugins/ms17010.go | 3 +- Plugins/portscan.go | 3 +- Plugins/rdp.go | 3 +- Plugins/redis.go | 4 +-- Plugins/webtitle.go | 4 +-- WebScan/lib/client.go | 21 ++++++++++++- common/config.go | 1 + common/flag.go | 1 + common/proxy.go | 65 ++++++++++++++++++++++++++++++++++++++++ 15 files changed, 100 insertions(+), 22 deletions(-) create mode 100644 common/proxy.go diff --git a/Plugins/CVE-2020-0796.go b/Plugins/CVE-2020-0796.go index 38c8e05..a4dcb2a 100644 --- a/Plugins/CVE-2020-0796.go +++ b/Plugins/CVE-2020-0796.go @@ -3,7 +3,6 @@ package Plugins import ( "bytes" "fmt" - "net" "time" "github.com/shadow1ng/fscan/common" @@ -106,7 +105,7 @@ func SmbGhost(info *common.HostInfo) error { func SmbGhostScan(info *common.HostInfo) error { ip, port, timeout := info.Host, 445, time.Duration(info.Timeout)*time.Second addr := fmt.Sprintf("%s:%v", info.Host, port) - conn, err := net.DialTimeout("tcp", addr, timeout) + conn, err := common.WrapperTcpWithTimeout("tcp", addr, timeout) defer func() { if conn != nil { conn.Close() diff --git a/Plugins/NetBIOS.go b/Plugins/NetBIOS.go index f99e17b..0255e94 100644 --- a/Plugins/NetBIOS.go +++ b/Plugins/NetBIOS.go @@ -75,7 +75,7 @@ func NetBIOS1(info *common.HostInfo) (nbname NbnsName, err error) { payload0 = append(payload0, []byte("\x00 EOENEBFACACACACACACACACACACACACA\x00")...) } realhost := fmt.Sprintf("%s:%v", info.Host, info.Ports) - conn, err := net.DialTimeout("tcp", realhost, time.Duration(info.Timeout)*time.Second) + conn, err := common.WrapperTcpWithTimeout("tcp", realhost, time.Duration(info.Timeout)*time.Second) defer func() { if conn != nil{ conn.Close() diff --git a/Plugins/fcgiscan.go b/Plugins/fcgiscan.go index 4d3bd93..2a9631d 100644 --- a/Plugins/fcgiscan.go +++ b/Plugins/fcgiscan.go @@ -8,7 +8,6 @@ import ( "fmt" "github.com/shadow1ng/fscan/common" "io" - "net" "strconv" "strings" "sync" @@ -184,7 +183,7 @@ type FCGIClient struct { } func New(addr string, timeout int64) (fcgi *FCGIClient, err error) { - conn, err := net.DialTimeout("tcp", addr, time.Duration(timeout)*time.Second) + conn, err := common.WrapperTcpWithTimeout("tcp", addr, time.Duration(timeout)*time.Second) fcgi = &FCGIClient{ rwc: conn, keepAlive: false, diff --git a/Plugins/findnet.go b/Plugins/findnet.go index acf2274..1864a28 100644 --- a/Plugins/findnet.go +++ b/Plugins/findnet.go @@ -5,7 +5,6 @@ import ( "encoding/hex" "fmt" "github.com/shadow1ng/fscan/common" - "net" "strings" "time" ) @@ -23,7 +22,7 @@ func Findnet(info *common.HostInfo) error { func FindnetScan(info *common.HostInfo) error { realhost := fmt.Sprintf("%s:%v", info.Host, 135) - conn, err := net.DialTimeout("tcp", realhost, time.Duration(info.Timeout)*time.Second) + conn, err := common.WrapperTcpWithTimeout("tcp", realhost, time.Duration(info.Timeout)*time.Second) defer func() { if conn != nil { conn.Close() diff --git a/Plugins/memcached.go b/Plugins/memcached.go index d4dfe7a..3f6e72c 100644 --- a/Plugins/memcached.go +++ b/Plugins/memcached.go @@ -3,14 +3,13 @@ package Plugins import ( "fmt" "github.com/shadow1ng/fscan/common" - "net" "strings" "time" ) func MemcachedScan(info *common.HostInfo) (err error) { realhost := fmt.Sprintf("%s:%v", info.Host, info.Ports) - client, err := net.DialTimeout("tcp", realhost, time.Duration(info.Timeout)*time.Second) + client, err := common.WrapperTcpWithTimeout("tcp", realhost, time.Duration(info.Timeout)*time.Second) defer func() { if client != nil{ client.Close() diff --git a/Plugins/mongodb.go b/Plugins/mongodb.go index 55a073b..b4e70a0 100644 --- a/Plugins/mongodb.go +++ b/Plugins/mongodb.go @@ -4,7 +4,6 @@ import ( "fmt" _ "github.com/denisenkom/go-mssqldb" "github.com/shadow1ng/fscan/common" - "net" "strings" "time" ) @@ -26,7 +25,7 @@ func MongodbUnauth(info *common.HostInfo) (flag bool, err error) { flag = false senddata := []byte{72, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 212, 7, 0, 0, 0, 0, 0, 0, 97, 100, 109, 105, 110, 46, 36, 99, 109, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 33, 0, 0, 0, 2, 103, 101, 116, 76, 111, 103, 0, 16, 0, 0, 0, 115, 116, 97, 114, 116, 117, 112, 87, 97, 114, 110, 105, 110, 103, 115, 0, 0} realhost := fmt.Sprintf("%s:%v", info.Host, info.Ports) - conn, err := net.DialTimeout("tcp", realhost, time.Duration(info.Timeout)*time.Second) + conn, err := common.WrapperTcpWithTimeout("tcp", realhost, time.Duration(info.Timeout)*time.Second) defer func() { if conn != nil { conn.Close() diff --git a/Plugins/ms17010.go b/Plugins/ms17010.go index 21803a5..0269499 100644 --- a/Plugins/ms17010.go +++ b/Plugins/ms17010.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "github.com/shadow1ng/fscan/common" - "net" "strings" "time" ) @@ -34,7 +33,7 @@ func MS17010(info *common.HostInfo) error { func MS17010Scan(info *common.HostInfo) error { ip := info.Host // connecting to a host in LAN if reachable should be very quick - conn, err := net.DialTimeout("tcp", ip+":445", time.Duration(info.Timeout)*time.Second) + conn, err := common.WrapperTcpWithTimeout("tcp", ip+":445", time.Duration(info.Timeout)*time.Second) defer func() { if conn != nil { conn.Close() diff --git a/Plugins/portscan.go b/Plugins/portscan.go index 3c8c48a..d5d56ce 100644 --- a/Plugins/portscan.go +++ b/Plugins/portscan.go @@ -3,7 +3,6 @@ package Plugins import ( "fmt" "github.com/shadow1ng/fscan/common" - "net" "sort" "strconv" "sync" @@ -74,7 +73,7 @@ func PortScan(hostslist []string, ports string, timeout int64) []string { func PortConnect(addr Addr, respondingHosts chan<- string, adjustedTimeout int64, wg *sync.WaitGroup) { host, port := addr.ip, addr.port - conn, err := net.DialTimeout("tcp4", fmt.Sprintf("%s:%v", host, port), time.Duration(adjustedTimeout)*time.Second) + conn, err := common.WrapperTcpWithTimeout("tcp4", fmt.Sprintf("%s:%v", host, port), time.Duration(adjustedTimeout)*time.Second) defer func() { if conn != nil { conn.Close() diff --git a/Plugins/rdp.go b/Plugins/rdp.go index f716295..e4c7c85 100644 --- a/Plugins/rdp.go +++ b/Plugins/rdp.go @@ -14,7 +14,6 @@ import ( "github.com/tomatome/grdp/protocol/tpkt" "github.com/tomatome/grdp/protocol/x224" "log" - "net" "os" "strconv" "strings" @@ -127,7 +126,7 @@ func NewClient(host string, logLevel glog.LEVEL) *Client { } func (g *Client) Login(domain, user, pwd string, timeout int64) error { - conn, err := net.DialTimeout("tcp", g.Host, time.Duration(timeout)*time.Second) + conn, err := common.WrapperTcpWithTimeout("tcp", g.Host, time.Duration(timeout)*time.Second) defer func() { if conn != nil { conn.Close() diff --git a/Plugins/redis.go b/Plugins/redis.go index 80a0b78..03dd783 100644 --- a/Plugins/redis.go +++ b/Plugins/redis.go @@ -47,7 +47,7 @@ func RedisScan(info *common.HostInfo) (tmperr error) { func RedisConn(info *common.HostInfo, pass string) (flag bool, err error) { flag = false realhost := fmt.Sprintf("%s:%v", info.Host, info.Ports) - conn, err := net.DialTimeout("tcp", realhost, time.Duration(info.Timeout)*time.Second) + conn, err := common.WrapperTcpWithTimeout("tcp", realhost, time.Duration(info.Timeout)*time.Second) defer func() { if conn != nil { conn.Close() @@ -87,7 +87,7 @@ func RedisConn(info *common.HostInfo, pass string) (flag bool, err error) { func RedisUnauth(info *common.HostInfo) (flag bool, err error) { flag = false realhost := fmt.Sprintf("%s:%v", info.Host, info.Ports) - conn, err := net.DialTimeout("tcp", realhost, time.Duration(info.Timeout)*time.Second) + conn, err := common.WrapperTcpWithTimeout("tcp", realhost, time.Duration(info.Timeout)*time.Second) defer func() { if conn != nil { conn.Close() diff --git a/Plugins/webtitle.go b/Plugins/webtitle.go index 4ccdb5c..df7c62b 100644 --- a/Plugins/webtitle.go +++ b/Plugins/webtitle.go @@ -10,7 +10,6 @@ import ( "golang.org/x/text/encoding/simplifiedchinese" "io" "io/ioutil" - "net" "net/http" "net/url" "regexp" @@ -218,7 +217,8 @@ func GetProtocol(host string, Timeout int64) (protocol string) { return } - conn, err := tls.DialWithDialer(&net.Dialer{Timeout: time.Duration(Timeout) * time.Second}, "tcp", host, &tls.Config{InsecureSkipVerify: true}) + socksconn, err := common.WrapperTcpWithTimeout("tcp", host, time.Duration(Timeout) * time.Second) + conn := tls.Client(socksconn, &tls.Config{InsecureSkipVerify: true}) defer func() { if conn != nil { conn.Close() diff --git a/WebScan/lib/client.go b/WebScan/lib/client.go index 3cc0e07..f34aa31 100644 --- a/WebScan/lib/client.go +++ b/WebScan/lib/client.go @@ -1,8 +1,11 @@ package lib import ( + "context" "crypto/tls" + "errors" "github.com/shadow1ng/fscan/common" + "golang.org/x/net/proxy" "log" "net" "net/http" @@ -27,13 +30,29 @@ func Inithttp(PocInfo common.PocInfo) { } func InitHttpClient(ThreadsNum int, DownProxy string, Timeout time.Duration) error { + type DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) + var dialContext DialContext dialer := &net.Dialer{ Timeout: dialTimout, KeepAlive: keepAlive, } + if common.Socks5Proxy != "" { + dialSocksProxy, err := common.Socks5Dailer(dialer) + if err != nil { + return err + } + if contextDialer, ok := dialSocksProxy.(proxy.ContextDialer); ok { + dialContext = contextDialer.DialContext + } else { + return errors.New("Failed type assertion to DialContext") + } + }else { + dialContext = dialer.DialContext + } + tr := &http.Transport{ - DialContext: dialer.DialContext, + DialContext: dialContext, MaxConnsPerHost: 5, MaxIdleConns: 0, MaxIdleConnsPerHost: ThreadsNum * 2, diff --git a/common/config.go b/common/config.go index d1c9745..b509297 100644 --- a/common/config.go +++ b/common/config.go @@ -106,4 +106,5 @@ var ( PassAdd string BruteThread int LiveTop int + Socks5Proxy string ) diff --git a/common/flag.go b/common/flag.go index 2c04ee1..b886c14 100644 --- a/common/flag.go +++ b/common/flag.go @@ -55,6 +55,7 @@ func Flag(Info *HostInfo) { flag.StringVar(&UrlFile, "uf", "", "urlfile") flag.StringVar(&Pocinfo.PocName, "pocname", "", "use the pocs these contain pocname, -pocname weblogic") flag.StringVar(&Pocinfo.Proxy, "proxy", "", "set poc proxy, -proxy http://127.0.0.1:8080") + flag.StringVar(&Socks5Proxy, "socks5", "", "set socks5 proxy, will be used in tcp connection, timeout setting will not work") flag.StringVar(&Pocinfo.Cookie, "cookie", "", "set poc cookie") flag.Int64Var(&Pocinfo.Timeout, "wt", 5, "Set web timeout") flag.IntVar(&Pocinfo.Num, "num", 20, "poc rate") diff --git a/common/proxy.go b/common/proxy.go new file mode 100644 index 0000000..43c30a5 --- /dev/null +++ b/common/proxy.go @@ -0,0 +1,65 @@ +package common + +import ( + "errors" + "golang.org/x/net/proxy" + "net" + "net/url" + "strings" + "time" +) + +func WrapperTcpWithTimeout(network, address string, timeout time.Duration) (net.Conn, error) { + d := &net.Dialer{Timeout: timeout/2} + return WrapperTCP(network, address, d) +} + +func WrapperTCP(network, address string,forward * net.Dialer) (net.Conn, error) { + //get conn + var conn net.Conn + if Socks5Proxy == "" { + var err error + conn,err = forward.Dial(network, address) + if err != nil { + return nil, err + } + }else { + dailer, err := Socks5Dailer(forward) + if err != nil{ + return nil, err + } + conn,err = dailer.Dial(network, address) + if err != nil { + return nil, err + } + } + return conn, nil + +} + +func Socks5Dailer(forward * net.Dialer) (proxy.Dialer, error) { + u,err := url.Parse(Socks5Proxy) + if err != nil { + return nil, err + } + if strings.ToLower(u.Scheme) != "socks5" { + return nil, errors.New("Only support socks5") + } + address := u.Host + var auth proxy.Auth + var dailer proxy.Dialer + if u.User.String() != "" { + auth = proxy.Auth{} + auth.User = u.User.Username() + password,_ := u.User.Password() + auth.Password = password + dailer, err = proxy.SOCKS5("tcp", address, &auth, forward) + }else { + dailer, err = proxy.SOCKS5("tcp", address, nil, forward) + } + + if err != nil { + return nil, err + } + return dailer, nil +} From 6f15f835f012747f7719c3b6ea29ec97f49338fc Mon Sep 17 00:00:00 2001 From: ccreater <1126774947@qq.com> Date: Sun, 8 May 2022 00:16:58 +0800 Subject: [PATCH 2/4] handle error --- Plugins/webtitle.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Plugins/webtitle.go b/Plugins/webtitle.go index df7c62b..e9fe66f 100644 --- a/Plugins/webtitle.go +++ b/Plugins/webtitle.go @@ -221,6 +221,11 @@ func GetProtocol(host string, Timeout int64) (protocol string) { conn := tls.Client(socksconn, &tls.Config{InsecureSkipVerify: true}) defer func() { if conn != nil { + defer func() { + if err := recover(); err != nil { + common.LogError(err) + } + }() conn.Close() } }() From 5c112e0ca8b656950db90d9a2a62a49ba9a3ffd4 Mon Sep 17 00:00:00 2001 From: ccreater <1126774947@qq.com> Date: Sun, 8 May 2022 02:19:41 +0800 Subject: [PATCH 3/4] fix bug --- Plugins/webtitle.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Plugins/webtitle.go b/Plugins/webtitle.go index e9fe66f..2c812f2 100644 --- a/Plugins/webtitle.go +++ b/Plugins/webtitle.go @@ -218,6 +218,9 @@ func GetProtocol(host string, Timeout int64) (protocol string) { } socksconn, err := common.WrapperTcpWithTimeout("tcp", host, time.Duration(Timeout) * time.Second) + if err != nil { + return + } conn := tls.Client(socksconn, &tls.Config{InsecureSkipVerify: true}) defer func() { if conn != nil { @@ -229,7 +232,6 @@ func GetProtocol(host string, Timeout int64) (protocol string) { conn.Close() } }() - if err == nil || strings.Contains(err.Error(), "handshake failure") { protocol = "https" } From ab60c985a6fcc94d40c4f3b635f35e718598fcf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BD=B1=E8=88=9E=E8=80=85?= Date: Mon, 9 May 2022 12:08:29 +0800 Subject: [PATCH 4/4] Update client.go --- WebScan/lib/client.go | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/WebScan/lib/client.go b/WebScan/lib/client.go index f34aa31..f9ed985 100644 --- a/WebScan/lib/client.go +++ b/WebScan/lib/client.go @@ -31,28 +31,13 @@ func Inithttp(PocInfo common.PocInfo) { func InitHttpClient(ThreadsNum int, DownProxy string, Timeout time.Duration) error { type DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) - var dialContext DialContext dialer := &net.Dialer{ Timeout: dialTimout, KeepAlive: keepAlive, } - if common.Socks5Proxy != "" { - dialSocksProxy, err := common.Socks5Dailer(dialer) - if err != nil { - return err - } - if contextDialer, ok := dialSocksProxy.(proxy.ContextDialer); ok { - dialContext = contextDialer.DialContext - } else { - return errors.New("Failed type assertion to DialContext") - } - }else { - dialContext = dialer.DialContext - } - tr := &http.Transport{ - DialContext: dialContext, + DialContext: dialer.DialContext, MaxConnsPerHost: 5, MaxIdleConns: 0, MaxIdleConnsPerHost: ThreadsNum * 2, @@ -61,7 +46,18 @@ func InitHttpClient(ThreadsNum int, DownProxy string, Timeout time.Duration) err TLSHandshakeTimeout: 5 * time.Second, DisableKeepAlives: false, } - if DownProxy != "" { + + if common.Socks5Proxy != "" { + dialSocksProxy, err := common.Socks5Dailer(dialer) + if err != nil { + return err + } + if contextDialer, ok := dialSocksProxy.(proxy.ContextDialer); ok { + tr.DialContext = contextDialer.DialContext + } else { + return errors.New("Failed type assertion to DialContext") + } + }else if DownProxy != "" { if DownProxy == "1" { DownProxy = "http://127.0.0.1:8080" } else if DownProxy == "2" { @@ -69,6 +65,9 @@ func InitHttpClient(ThreadsNum int, DownProxy string, Timeout time.Duration) err } else if !strings.Contains(DownProxy, "://") { DownProxy = "http://127.0.0.1:" + DownProxy } + if !strings.HasPrefix(DownProxy,"socks") && !strings.HasPrefix(DownProxy,"http") { + return errors.New("no support this proxy") + } u, err := url.Parse(DownProxy) if err != nil { return err