14 Commits
Author SHA1 Message Date
shadow1ng c27eccbcc9 Merge remote-tracking branch 'origin/main' into main
# Conflicts:
#	README.md
2020-12-06 10:51:53 +08:00
shadow1ng 90b848a3dc 优化icmp模块,新增-domain 参数(用于smb爆破模块,适用于域用户) 2020-12-06 10:50:47 +08:00
shadow1ng 767fff84ed 优化icmp模块,新增-domain 参数(用于smb爆破模块,适用于域用户) 2020-12-06 10:50:40 +08:00
shadow1ng b4fb1efb3a 优化icmp模块 2020-12-05 16:57:01 +08:00
影舞者 c4d1cd950a Update README.md 2020-12-03 23:24:21 +08:00
shadow1ng 818102a814 优化ip段处理模块、端口扫描模块。 2020-12-03 23:20:39 +08:00
shadow1ng b00a5d4403 优化参数处理 2020-12-03 17:02:21 +08:00
shadow1ng f638d3a1e2 优化ip段处理模块,新增支持192.168.1.1-192.168.255.255 2020-12-03 16:00:40 +08:00
shadow1ng 8ca4d2c89a 优化ip段处理模块,新增支持192.168.1.1-192.168.255.255 2020-12-03 15:55:29 +08:00
shadow1ng 13a3cacd93 mac下修改ping所需的bash路径,改为/bin/bash。(原为/usr/local/bin/bash),并把超时参数由-w 改为-W。 2020-11-17 16:04:56 +08:00
shadow1ng 3282f4abcb Merge remote-tracking branch 'origin/main' into main 2020-11-17 15:49:33 +08:00
shadow1ng 0cff8351ac 修改mac下ping所需的bash路径,改为/bin/bash。(原为/usr/local/bin/bash) 2020-11-17 15:48:53 +08:00
影舞者 cd29281e72 Update README.md 2020-11-17 14:31:38 +08:00
shadow1ng db028ba0cc 增加-ping 参数,作用是存活探测模块用ping代替icmp发包。 2020-11-17 14:27:15 +08:00
9 changed files with 329 additions and 332 deletions
+49 -67
View File
@@ -2,7 +2,6 @@ package Plugins
import (
"bytes"
"encoding/binary"
"fmt"
"net"
"os"
@@ -14,17 +13,9 @@ import (
"time"
)
var icmp ICMP
var AliveHosts []string
type ICMP struct {
Type uint8
Code uint8
Checksum uint16
Identifier uint16
SequenceNum uint16
}
var SysInfo = GetSys()
type SystemInfo struct {
OS string
@@ -56,38 +47,30 @@ func GetSys() SystemInfo {
}
func isping(ip string) bool {
icmp.Type = 8
icmp.Code = 0
icmp.Checksum = 0
icmp.Identifier = 0
icmp.SequenceNum = 0
recvBuf := make([]byte, 32)
var buffer bytes.Buffer
binary.Write(&buffer, binary.BigEndian, icmp)
icmp.Checksum = CheckSum(buffer.Bytes())
buffer.Reset()
binary.Write(&buffer, binary.BigEndian, icmp)
IcmpByte := []byte{8, 0, 247, 255, 0, 0, 0, 0}
Time, _ := time.ParseDuration("3s")
conn, err := net.DialTimeout("ip4:icmp", ip, Time)
if err != nil {
return false
}
_, err = conn.Write(buffer.Bytes())
if err != nil {
return false
}
conn.SetReadDeadline(time.Now().Add(time.Second * 3))
num, err := conn.Read(recvBuf)
defer conn.Close()
_, err = conn.Write(IcmpByte)
if err != nil {
return false
}
conn.SetReadDeadline(time.Time{})
if err := conn.SetReadDeadline(time.Now().Add(time.Second * 3)); err != nil {
return false
}
recvBuf := make([]byte, 40)
num, err := conn.Read(recvBuf[0:40])
if err != nil {
return false
}
if err := conn.SetReadDeadline(time.Time{}); err != nil {
return false
}
if string(recvBuf[0:num]) != "" {
fmt.Printf("(ICMP) Target '%s' is alive\n", ip)
return true
@@ -96,32 +79,13 @@ func isping(ip string) bool {
}
func CheckSum(data []byte) uint16 {
var (
sum uint32
length int = len(data)
index int
)
for length > 1 {
sum += uint32(data[index])<<8 + uint32(data[index+1])
index += 2
length -= 2
}
if length > 0 {
sum += uint32(data[index])
}
sum += (sum >> 16)
return uint16(^sum)
}
func IcmpCheck(hostslist []string, IcmpThreads int) {
var wg sync.WaitGroup
mutex := &sync.Mutex{}
limiter := make(chan int, IcmpThreads)
limiter := make(chan struct{}, IcmpThreads)
for _, host := range hostslist {
wg.Add(1)
limiter <- 1
limiter <- struct{}{}
go func(host string) {
defer wg.Done()
if isping(host) {
@@ -136,20 +100,25 @@ func IcmpCheck(hostslist []string,IcmpThreads int) {
wg.Wait()
}
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"
var command *exec.Cmd
if SysInfo.OS == "windows" {
command = exec.Command("cmd", "/c", "ping -n 1 -w 1 "+ip+" && echo true || echo false") //ping -c 1 -i 0.5 -t 4 -W 2 -w 5 "+ip+" >/dev/null && echo true || echo false"
} else if SysInfo.OS == "linux" {
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"
} else if SysInfo.OS == "darwin" {
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{}
command.Stdout = &outinfo
err := command.Start()
if err != nil {
return false
}
if err = command.Wait(); err != nil {
return false
} else {
if(strings.Contains(outinfo.String(), "true")) {
if strings.Contains(outinfo.String(), "true") {
return true
} else {
return false
@@ -177,24 +146,37 @@ func PingCMDcheck(hostslist []string,bsenv string) {
}
wg.Wait()
}
func ICMPRun(hostslist []string, IcmpThreads int, Ping bool) []string {
func ICMPRun(hostslist []string,IcmpThreads int) []string{
var sysinfo SystemInfo
sysinfo = GetSys()
if sysinfo.OS == "windows" {
if SysInfo.OS == "windows" {
if Ping == false {
IcmpCheck(hostslist, IcmpThreads)
}else if sysinfo.OS == "linux" {
if (sysinfo.Groupid == "0" || sysinfo.Userid == "0" || sysinfo.Username == "root") {
} else {
PingCMDcheck(hostslist, "")
}
} else if SysInfo.OS == "linux" {
if SysInfo.Groupid == "0" || SysInfo.Userid == "0" || SysInfo.Username == "root" {
if Ping == false {
IcmpCheck(hostslist, IcmpThreads)
} else {
PingCMDcheck(hostslist, "/bin/bash")
}
}else if sysinfo.OS == "darwin" {
if (sysinfo.Groupid == "0" || sysinfo.Userid == "0" || sysinfo.Username == "root") {
} else {
fmt.Println("The current user permissions unable to send icmp packets")
fmt.Println("start ping")
PingCMDcheck(hostslist, "/bin/bash")
}
} else if SysInfo.OS == "darwin" {
if SysInfo.Groupid == "0" || SysInfo.Userid == "0" || SysInfo.Username == "root" {
if Ping == false {
IcmpCheck(hostslist, IcmpThreads)
} else {
PingCMDcheck(hostslist,"/usr/local/bin/bash")
PingCMDcheck(hostslist, "/bin/bash")
}
} else {
fmt.Println("The current user permissions unable to send icmp packets")
fmt.Println("start ping")
PingCMDcheck(hostslist, "/bin/bash")
}
}
return AliveHosts
+5 -21
View File
@@ -35,12 +35,9 @@ func ParsePort(ports string) []int {
return scanPorts
}
func ProbeHosts(host string, ports <-chan int, respondingHosts chan<- string, done chan<- bool, model string, adjustedTimeout int) {
Timeout := time.Duration(adjustedTimeout) * time.Second
func ProbeHosts(host string, ports <-chan int, respondingHosts chan<- string, done chan<- bool, adjustedTimeout int) {
for port := range ports {
start := time.Now()
con, err := net.DialTimeout("tcp4", fmt.Sprintf("%s:%d", host, port), time.Duration(adjustedTimeout)*time.Second)
duration := time.Now().Sub(start)
if err == nil {
defer con.Close()
address := host + ":" + strconv.Itoa(port)
@@ -48,21 +45,17 @@ func ProbeHosts(host string, ports <-chan int, respondingHosts chan<- string, do
common.LogSuccess(result)
respondingHosts <- address
}
if duration < Timeout {
difference := Timeout - duration
Timeout = Timeout - (difference / 2)
}
}
done <- true
}
func ScanAllports(address string, probePorts []int, threads int, timeout time.Duration, model string, adjustedTimeout int) ([]string, error) {
func ScanAllports(address string, probePorts []int, threads int, adjustedTimeout int) ([]string, error) {
ports := make(chan int, 20)
results := make(chan string, 10)
done := make(chan bool, threads)
for worker := 0; worker < threads; worker++ {
go ProbeHosts(address, ports, results, done, model, adjustedTimeout)
go ProbeHosts(address, ports, results, done, adjustedTimeout)
}
for _, port := range probePorts {
@@ -80,13 +73,11 @@ func ScanAllports(address string, probePorts []int, threads int, timeout time.Du
if threads == 0 {
return responses, nil
}
case <-time.After(timeout):
return responses, nil
}
}
}
func TCPportScan(hostslist []string, ports string, model string, timeout int) ([]string, []string) {
func TCPportScan(hostslist []string, ports string, timeout int) ([]string, []string) {
var AliveAddress []string
var aliveHosts []string
probePorts := ParsePort(ports)
@@ -119,18 +110,12 @@ func TCPportScan(hostslist []string, ports string, model string, timeout int) ([
var wg sync.WaitGroup
mutex := &sync.Mutex{}
limiter := make(chan struct{}, lm)
aliveHost := make(chan string, lm/2)
go func() {
for s := range aliveHost {
fmt.Println(s)
}
}()
for _, host := range hostslist {
wg.Add(1)
limiter <- struct{}{}
go func(host string) {
defer wg.Done()
if aliveAdd, err := ScanAllports(host, probePorts, thread, 5*time.Second, model, timeout); err == nil && len(aliveAdd) > 0 {
if aliveAdd, err := ScanAllports(host, probePorts, thread, timeout); err == nil && len(aliveAdd) > 0 {
mutex.Lock()
aliveHosts = append(aliveHosts, host)
for _, addr := range aliveAdd {
@@ -142,6 +127,5 @@ func TCPportScan(hostslist []string, ports string, model string, timeout int) ([
}(host)
}
wg.Wait()
close(aliveHost)
return aliveHosts, AliveAddress
}
+3 -8
View File
@@ -15,10 +15,8 @@ func scan_func(m map[string]interface{}, name string, infos ...interface{}) (res
f := reflect.ValueOf(m[name])
if len(infos) != f.Type().NumIn() {
err = errors.New("The number of infos is not adapted.")
if err != nil {
fmt.Println(err.Error())
}
}
in := make([]reflect.Value, len(infos))
for k, info := range infos {
in[k] = reflect.ValueOf(info)
@@ -39,10 +37,10 @@ func Scan(info common.HostInfo) {
fmt.Println("scan start")
Hosts, _ := common.ParseIP(info.Host, info.HostFile)
if info.Isping == false {
Hosts = ICMPRun(Hosts, info.IcmpThreads)
Hosts = ICMPRun(Hosts, info.IcmpThreads, info.Ping)
fmt.Println("icmp alive hosts len is:", len(Hosts))
}
_, AlivePorts := TCPportScan(Hosts, info.Ports, "icmp", 3) //return AliveHosts,AlivePorts
_, AlivePorts := TCPportScan(Hosts, info.Ports, 3) //return AliveHosts,AlivePorts
var severports []string //severports := []string{"21","22","135"."445","1433","3306","5432","6379","9200","11211","27017"...}
for _, port := range common.PORTList {
severports = append(severports, strconv.Itoa(port))
@@ -54,12 +52,12 @@ func Scan(info common.HostInfo) {
for _, targetIP := range AlivePorts {
scan_ip, scan_port := strings.Split(targetIP, ":")[0], strings.Split(targetIP, ":")[1]
info.Host = scan_ip
info.Ports = scan_port
if info.Scantype == "all" {
if IsContain(severports, scan_port) {
AddScan(scan_port, info, ch, &wg)
} else {
if !IsContain(severports1, scan_port) {
info.Ports = scan_port
AddScan("1000003", info, ch, &wg) //webtitle
}
}
@@ -78,9 +76,6 @@ func Scan(info common.HostInfo) {
func AddScan(scantype string, info common.HostInfo, ch chan int, wg *sync.WaitGroup) {
wg.Add(1)
if info.Scantype == "webtitle" {
scantype = "1000003"
}
go scan_func(PluginList, scantype, &info, ch, wg)
ch <- 1
}
+10 -4
View File
@@ -27,7 +27,7 @@ Loop:
}
func SmblConn(info *common.HostInfo, user string, pass string) (flag bool, err error) {
func SmblConn(info *common.HostInfo, user string, pass string, Domain string) (flag bool, err error) {
flag = false
Host, Port, Username, Password := info.Host, common.PORTList["smb"], user, pass
options := smb.Options{
@@ -35,7 +35,7 @@ func SmblConn(info *common.HostInfo, user string, pass string) (flag bool, err e
Port: 445,
User: Username,
Password: Password,
Domain: "",
Domain: Domain,
Workstation: "",
}
@@ -43,7 +43,13 @@ func SmblConn(info *common.HostInfo, user string, pass string) (flag bool, err e
if err == nil {
defer session.Close()
if session.IsAuthenticated {
result := fmt.Sprintf("SMB:%v:%v:%v %v", Host, Port, Username, Password)
var result string
if Domain != "" {
result = fmt.Sprintf("SMB:%v:%v:%v\\%v %v", Host, Port, Domain, Username, Password)
} else {
result = fmt.Sprintf("SMB:%v:%v:%v %v", Host, Port, Username, Password)
}
common.LogSuccess(result)
flag = true
}
@@ -56,7 +62,7 @@ func doWithTimeOut(info *common.HostInfo, user string, pass string) (flag bool,
defer cancel()
signal := make(chan int, 1)
go func() {
flag, err = SmblConn(info, user, pass)
flag, err = SmblConn(info, user, pass, info.Domain)
signal <- 1
}()
+1 -3
View File
@@ -4,13 +4,12 @@ import (
"crypto/tls"
"fmt"
"github.com/shadow1ng/fscan/WebScan"
"github.com/shadow1ng/fscan/common"
"io/ioutil"
"net/http"
"regexp"
"sync"
"time"
"github.com/shadow1ng/fscan/common"
)
func WebTitle(info *common.HostInfo, ch chan int, wg *sync.WaitGroup) (err error, result string) {
@@ -33,7 +32,6 @@ func WebTitle(info *common.HostInfo, ch chan int, wg *sync.WaitGroup) (err error
func geturl(info *common.HostInfo) (err error, result string) {
url := info.Url
info.Timeout = 20
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
+8 -1
View File
@@ -14,6 +14,9 @@
因为用习惯了f-scrack,习惯一条命令跑完所有模块,省去一个个模块单独调用的时间,当然我附加了-m 指定模块的功能。
## 最近更新
[+] 2020/12/6 优化icmp模块,新增-domain 参数(用于smb爆破模块,适用于域用户)
[+] 2020/12/03 优化ip段处理模块、icmp、端口扫描模块。新增支持192.168.1.1-192.168.255.255。
[+] 2020/11/17 增加-ping 参数,作用是存活探测模块用ping代替icmp发包。
[+] 2020/11/17 增加WebScan模块,新增shiro简单识别。https访问时,跳过证书认证。将服务模块和web模块的超时分开,增加-wt 参数(WebTimeout)。
[+] 2020/11/16 对icmp模块进行优化,增加-it 参数(IcmpThreads),默认11000,适合扫B段
[+] 2020/11/15 支持ip以文件导入,-hs ip.txt,并对去重做了处理
@@ -46,7 +49,7 @@ fscan.exe -h 192.168.1.1/24 -m ms17010 (指定模块)
-hf string
host file, -hs ip.txt
-it int
Icmp Threads nums (default 3000)
Icmp Threads nums (default 11000)
-m string
Select scan type ,as: -m ssh (default "all")
-no
@@ -57,6 +60,8 @@ fscan.exe -h 192.168.1.1/24 -m ms17010 (指定模块)
Outputfile (default "result.txt")
-p string
Select a port,for example: 22 | 1-65535 | 22,80,3306 (default "21,22,23,80,135,443,445,1433,1521,3306,5432,6379,7001,8080,8089,9000,9200,11211,27017")
-ping
using ping replace icmp
-pwd string
password
-pwdf string
@@ -73,6 +78,8 @@ fscan.exe -h 192.168.1.1/24 -m ms17010 (指定模块)
username
-userf string
username file
-wt int
Set web timeout (default 3)
```
+31 -5
View File
@@ -18,6 +18,7 @@ var ParseIPErr =errors.New("host parsing error\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.255.255\n" +
"192.168.1.1-255")
func ParseIP(ip string, filename string) (hosts []string, err error) {
@@ -76,6 +77,7 @@ func ParseIPone(ip string)([]string,error){
return []string{ip}, nil
}
}
//Parsing CIDR IP
func ParseIPA(ip string) ([]string, error) {
realIP := ip[:len(ip)-3]
@@ -105,10 +107,12 @@ func ParseIPB(ip string)([]string,error){
}
//Resolving a range of IP,for example: 192.168.111.1-255
//Resolving a range of IP,for example: 192.168.111.1-255,192.168.111.1-192.168.112.255
func ParseIPC(ip string) ([]string, error) {
IPRange := strings.Split(ip, "-")
testIP := net.ParseIP(IPRange[0])
var AllIP []string
if len(IPRange[1]) < 4 {
Range, err := strconv.Atoi(IPRange[1])
if testIP == nil || Range > 255 || err != nil {
return nil, ParseIPErr
@@ -117,13 +121,37 @@ func ParseIPC(ip string)([]string,error){
ip1, err1 := strconv.Atoi(SplitIP[3])
ip2, err2 := strconv.Atoi(IPRange[1])
PrefixIP := strings.Join(SplitIP[0:3], ".")
var AllIP []string
if ip1 > ip2 || err1 != nil || err2 != nil {
return nil, ParseIPErr
}
for i := ip1; i <= ip2; i++ {
AllIP = append(AllIP, PrefixIP+"."+strconv.Itoa(i))
}
} else {
SplitIP1 := strings.Split(IPRange[0], ".")
SplitIP2 := strings.Split(IPRange[1], ".")
fmt.Println(SplitIP1, SplitIP2, len(SplitIP1), len(SplitIP2))
if len(SplitIP1) != 4 || len(SplitIP2) != 4 {
return nil, ParseIPErr
}
start, end := [4]int{}, [4]int{}
for i := 0; i < 4; i++ {
ip1, err1 := strconv.Atoi(SplitIP1[i])
ip2, err2 := strconv.Atoi(SplitIP2[i])
if ip1 > ip2 || err1 != nil || err2 != nil {
return nil, ParseIPErr
}
start[i], end[i] = ip1, ip2
}
startNum := (start[0]<<24 | start[1]<<16 | start[2]<<8 | start[3])
endNum := (end[0]<<24 | end[1]<<16 | end[2]<<8 | end[3])
fmt.Println(startNum, endNum)
for num := startNum; num < endNum; num++ {
ip := (strconv.Itoa((num>>24)&0xff) + "." + strconv.Itoa((num>>16)&0xff) + "." + strconv.Itoa((num>>8)&0xff) + "." + strconv.Itoa((num)&0xff))
AllIP = append(AllIP, ip)
}
}
return AllIP, nil
}
@@ -184,8 +212,7 @@ func Readipfile(filename string)([]string,error){
return content, nil
}
func RemoveDuplicate(old []string) ([]string) {
func RemoveDuplicate(old []string) []string {
result := make([]string, 0, len(old))
temp := map[string]struct{}{}
for _, item := range old {
@@ -196,4 +223,3 @@ func RemoveDuplicate(old []string) ([]string) {
}
return result
}
+4 -4
View File
@@ -1,4 +1,5 @@
package common
//fscan version 1.3
var Userdict = map[string][]string{
"ftp": {"www", "admin", "root", "db", "wwwroot", "data", "web", "ftp"},
@@ -52,17 +53,18 @@ var PORTList_bak = map[string]int{
var Outputfile = "result.txt"
var IsSave = true
var DefaultPorts = "21,22,23,80,135,443,445,1433,1521,3306,5432,6379,7001,8080,8089,9000,9200,11211,27017"
var DefaultPorts = "21,22,80,81,135,443,445,1433,1521,3306,5432,6379,7001,8000,8080,8089,11211,27017"
type HostInfo struct {
Host string
HostFile string
Ports string
Domain string
Url string
Timeout int64
WebTimeout int64
Scantype string
Ping bool
Isping bool
Threads int
IcmpThreads int
@@ -78,5 +80,3 @@ type HostInfo struct {
RedisFile string
RedisShell string
}
+2 -3
View File
@@ -16,9 +16,6 @@ func Banner(){
print(banner)
}
func Flag(Info *HostInfo) {
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")
@@ -28,7 +25,9 @@ func Flag(Info *HostInfo) {
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.Ping, "ping", false, "using ping replace icmp")
flag.BoolVar(&Info.IsSave, "no", false, "not to save output log")
flag.StringVar(&Info.Domain, "domain", "", "smb domain")
flag.StringVar(&Info.Username, "user", "", "username")
flag.StringVar(&Info.Userfile, "userf", "", "username file")
flag.StringVar(&Info.Password, "pwd", "", "password")