Skip to content

Commit

Permalink
rework everything SMB related, removed some dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
5amu committed Mar 7, 2024
1 parent 03f0b72 commit 40ada7d
Show file tree
Hide file tree
Showing 21 changed files with 1,704 additions and 859 deletions.
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ require (
require (
github.com/docker/go-units v0.5.0 // indirect
github.com/geoffgarside/ber v1.1.0 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
)

require (
Expand All @@ -37,7 +39,6 @@ require (
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/praetorian-inc/fingerprintx v1.1.13
github.com/tidwall/transform v0.0.0-20201103190739-32f242e2dbde // indirect
github.com/zmap/zgrab2 v0.1.8-0.20230806160807-97ba87c0e706
golang.org/x/crypto v0.19.0
golang.org/x/net v0.19.0
golang.org/x/sys v0.17.0 // indirect
Expand Down
704 changes: 0 additions & 704 deletions go.sum

Large diffs are not rendered by default.

9 changes: 5 additions & 4 deletions internal/goad/optkrb5/krb5.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/5amu/goad/internal/goad/optsmb"
"github.com/5amu/goad/internal/printer"
"github.com/5amu/goad/internal/utils"
"github.com/5amu/goad/pkg/smb"
)

type Options struct {
Expand All @@ -29,7 +30,7 @@ type Options struct {
} `group:"Bruteforce Strategy"`

targets []string
target2SMBInfo map[string]*optsmb.SMBInfo
target2SMBInfo map[string]*smb.SMBFingerprint
printMutex sync.Mutex
credentials []utils.Credential
}
Expand All @@ -43,7 +44,7 @@ func (o *Options) getFunction() func(string) {

func (o *Options) Run() {
o.targets = utils.ExtractTargets(o.Targets.TARGETS)
o.target2SMBInfo = optsmb.GatherSMBInfoToMap(o.targets, 88)
o.target2SMBInfo = optsmb.GatherSMBInfoToMap(o.targets, optsmb.DefaultPort)
var f func(string) = o.getFunction()

var strategy utils.Strategy = utils.Clusterbomb
Expand All @@ -69,7 +70,7 @@ func (o *Options) Run() {
}

func (o *Options) userenum(target string) {
prt := printer.NewPrinter("KRB5", target, o.target2SMBInfo[target].NetBIOSName, 88)
prt := printer.NewPrinter("KRB5", target, o.target2SMBInfo[target].NetBIOSComputerName, 88)
defer prt.PrintStored(&o.printMutex)

client, err := NewKerberosClient(o.Connection.Domain, target)
Expand All @@ -95,7 +96,7 @@ func (o *Options) userenum(target string) {
}

func (o *Options) bruteforce(target string) {
prt := printer.NewPrinter("KRB5", target, o.target2SMBInfo[target].NetBIOSName, 88)
prt := printer.NewPrinter("KRB5", target, o.target2SMBInfo[target].NetBIOSComputerName, 88)
defer prt.PrintStored(&o.printMutex)

client, err := NewKerberosClient(o.Connection.Domain, target)
Expand Down
15 changes: 8 additions & 7 deletions internal/goad/optldap/crud.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ import (

"github.com/5amu/goad/internal/printer"
"github.com/5amu/goad/internal/utils"
"github.com/5amu/goad/pkg/krb5/ntlm"
"github.com/5amu/goad/pkg/mstypes"
"github.com/go-ldap/ldap/v3"
)

func (o *Options) read(target string) {
prt := printer.NewPrinter("LDAP", target, o.target2SMBInfo[target].NetBIOSName, o.Connection.Port)
prt := printer.NewPrinter("LDAP", target, o.target2SMBInfo[target].NetBIOSComputerName, o.Connection.Port)
defer prt.PrintStored(&o.printMutex)

prt.StoreInfo("LDAP Query Filter")
Expand All @@ -30,7 +31,7 @@ func (o *Options) read(target string) {

var domain string = o.Connection.Domain
if domain == "" {
domain = o.target2SMBInfo[target].Domain
domain = o.target2SMBInfo[target].DNSDomainName
}

err = FindObjectsWithCallback(lclient, domain, o.filter, func(m map[string]interface{}) error {
Expand All @@ -44,7 +45,7 @@ func (o *Options) read(target string) {
case ManagedPassword:
var blob mstypes.MSDSManagedPasswordBlob
_ = mstypes.UnmarshalBinary(&blob, []byte(UnpackToString(m[ManagedPassword])))
data = append(data, mstypes.HashDataNTLM(blob.CurrentPassword))
data = append(data, ntlm.HashDataNTLM(blob.CurrentPassword))
default:
data = append(data, UnpackToString(m[a]))
}
Expand All @@ -59,7 +60,7 @@ func (o *Options) read(target string) {
}

func (o *Options) create(target string) {
prt := printer.NewPrinter("LDAP", target, o.target2SMBInfo[target].NetBIOSName, o.Connection.Port)
prt := printer.NewPrinter("LDAP", target, o.target2SMBInfo[target].NetBIOSComputerName, o.Connection.Port)
defer prt.PrintStored(&o.printMutex)

lclient, _, err := o.authenticate(target)
Expand All @@ -71,7 +72,7 @@ func (o *Options) create(target string) {

var domain string = o.Connection.Domain
if domain == "" {
domain = o.target2SMBInfo[target].Domain
domain = o.target2SMBInfo[target].DNSDomainName
}

var req *ldap.AddRequest
Expand Down Expand Up @@ -123,7 +124,7 @@ const (
)

func (o *Options) delete(target string) {
prt := printer.NewPrinter("LDAP", target, o.target2SMBInfo[target].NetBIOSName, o.Connection.Port)
prt := printer.NewPrinter("LDAP", target, o.target2SMBInfo[target].NetBIOSComputerName, o.Connection.Port)
defer prt.PrintStored(&o.printMutex)

lclient, _, err := o.authenticate(target)
Expand All @@ -135,7 +136,7 @@ func (o *Options) delete(target string) {

var domain string = o.Connection.Domain
if domain == "" {
domain = o.target2SMBInfo[target].Domain
domain = o.target2SMBInfo[target].DNSDomainName
}

var req *ldap.DelRequest
Expand Down
8 changes: 4 additions & 4 deletions internal/goad/optldap/hashes.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

func (o *Options) asreproast(target string) {
prt := printer.NewPrinter("LDAP", target, o.target2SMBInfo[target].NetBIOSName, o.Connection.Port)
prt := printer.NewPrinter("LDAP", target, o.target2SMBInfo[target].NetBIOSComputerName, o.Connection.Port)
defer prt.PrintStored(&o.printMutex)

lclient, creds, err := o.authenticate(target)
Expand All @@ -21,7 +21,7 @@ func (o *Options) asreproast(target string) {

var domain string = o.Connection.Domain
if domain == "" {
domain = o.target2SMBInfo[target].Domain
domain = o.target2SMBInfo[target].DNSDomainName
}

krb5client, err := optkrb5.NewKerberosClient(domain, target)
Expand Down Expand Up @@ -67,7 +67,7 @@ func (o *Options) asreproast(target string) {
}

func (o *Options) kerberoast(target string) {
prt := printer.NewPrinter("LDAP", target, o.target2SMBInfo[target].NetBIOSName, o.Connection.Port)
prt := printer.NewPrinter("LDAP", target, o.target2SMBInfo[target].NetBIOSComputerName, o.Connection.Port)
defer prt.PrintStored(&o.printMutex)

lclient, creds, err := o.authenticate(target)
Expand All @@ -79,7 +79,7 @@ func (o *Options) kerberoast(target string) {

var domain string = o.Connection.Domain
if domain == "" {
domain = o.target2SMBInfo[target].Domain
domain = o.target2SMBInfo[target].DNSDomainName
}

krb5client, err := optkrb5.NewKerberosClient(domain, target)
Expand Down
9 changes: 5 additions & 4 deletions internal/goad/optldap/ldap.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/5amu/goad/internal/goad/optsmb"
"github.com/5amu/goad/internal/printer"
"github.com/5amu/goad/internal/utils"
"github.com/5amu/goad/pkg/smb"
"github.com/go-ldap/ldap/v3"
)

Expand Down Expand Up @@ -99,7 +100,7 @@ type Options struct {
*/

// Common utils
target2SMBInfo map[string]*optsmb.SMBInfo
target2SMBInfo map[string]*smb.SMBFingerprint
printMutex sync.Mutex
credentials []utils.Credential

Expand Down Expand Up @@ -153,7 +154,7 @@ func (o *Options) parallelExecution(runner func(string)) {
func (o *Options) Run() {
o.target2SMBInfo = optsmb.GatherSMBInfoToMap(
utils.ExtractTargets(o.Targets.TARGETS),
o.Connection.Port,
optsmb.DefaultPort,
)

if !o.Connection.NullSession {
Expand Down Expand Up @@ -208,12 +209,12 @@ func (o *Options) authenticate(target string) (*ldap.Conn, utils.Credential, err
return nil, utils.Credential{}, err
}

prt := printer.NewPrinter("LDAP", target, o.target2SMBInfo[target].NetBIOSName, o.Connection.Port)
prt := printer.NewPrinter("LDAP", target, o.target2SMBInfo[target].NetBIOSComputerName, o.Connection.Port)
defer prt.PrintStored(&o.printMutex)

var domain string = o.Connection.Domain
if domain == "" {
domain = o.target2SMBInfo[target].Domain
domain = o.target2SMBInfo[target].DNSDomainName
}

if o.Connection.NullSession {
Expand Down
93 changes: 1 addition & 92 deletions internal/goad/optsmb/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,105 +2,14 @@ package optsmb

import (
"context"
"fmt"
"os"
"strings"
"time"

"github.com/5amu/goad/pkg/proxyconn"
"github.com/hirochachacha/go-smb2"
"github.com/praetorian-inc/fingerprintx/pkg/plugins"
smbfingerprint "github.com/praetorian-inc/fingerprintx/pkg/plugins/services/smb"
zgrabsmb "github.com/zmap/zgrab2/lib/smb/smb"
)

type SMBInfo struct {
WindowsVersion string
NetBIOSName string
DNSComputerName string
Domain string
SigningRequired bool
SMBv1Support bool
}

func (i *SMBInfo) String() string {
return fmt.Sprintf(
"%s (version:%s) (name:%s) (domain:%s) (signing:%t) (SMBv1:%t)",
i.DNSComputerName,
i.WindowsVersion,
i.NetBIOSName,
i.Domain,
i.SigningRequired,
i.SMBv1Support,
)
}

func getMetadata(host string) (*plugins.ServiceSMB, error) {
conn, err := proxyconn.GetConnection(host, 445)
if err != nil {
return nil, err
}
defer conn.Close()
return smbfingerprint.DetectSMBv2(conn, 1*time.Second)
}

func GatherSMBInfo(host string) (*SMBInfo, error) {
var info SMBInfo
var err error

var metadata *plugins.ServiceSMB
mch := make(chan *plugins.ServiceSMB)
go func() {
if m, err := getMetadata(host); err == nil {
mch <- m
}
}()

select {
case metadata = <-mch:
case <-time.After(time.Second):
return nil, fmt.Errorf("timeout smb metadata")
}

if metadata == nil {
return nil, fmt.Errorf("invalid smb metadata")
}
info.WindowsVersion = metadata.OSVersion
info.NetBIOSName = metadata.NetBIOSComputerName
info.Domain = metadata.DNSDomainName
info.DNSComputerName = strings.ToLower(metadata.DNSComputerName)

var data *zgrabsmb.SMBLog
if data, err = getSMBInfo(host, true, true); err != nil {
if data, err = getSMBInfo(host, true, false); err != nil {
fmt.Println(err)
return nil, err
}
}

if data != nil && data.NegotiationLog != nil {
info.SigningRequired = data.NegotiationLog.SecurityMode&zgrabsmb.SecurityModeSigningRequired > 0
} else {
info.SigningRequired = true
}
return &info, nil
}

func getSMBInfo(host string, setupSession, v1 bool) (*zgrabsmb.SMBLog, error) {
conn, err := proxyconn.GetConnection(host, 445)
if err != nil {
return nil, err
}
defer conn.Close()

_ = conn.SetDeadline(time.Now().Add(1 * time.Second))

result, err := zgrabsmb.GetSMBLog(conn, setupSession, v1, false)
if err != nil {
return nil, err
}
return result, nil
}
const DefaultPort = 445

type Client struct {
Host string
Expand Down
20 changes: 14 additions & 6 deletions internal/goad/optsmb/smb.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ package optsmb

import (
"fmt"
"os"
"slices"
"strings"
"sync"

"github.com/5amu/goad/internal/printer"
"github.com/5amu/goad/internal/utils"
"github.com/5amu/goad/pkg/smb"
"github.com/fatih/color"
)

Expand All @@ -19,13 +22,14 @@ type Options struct {
Username string `short:"u" description:"Provide username (or FILE)"`
Password string `short:"p" description:"Provide password (or FILE)"`
NTLM string `short:"H" long:"hashes" description:"authenticate with NTLM hash"`
Domain string `short:"d" long:"domain" description:"Provide domain"`
Domain string `short:"d" long:"domain" description:"provide domain"`
Port int `long:"port" default:"445" description:"Provide SMB port"`
} `group:"Connection Options" description:"Connection Options"`

Shares bool `long:"shares" description:"list open shares"`

credentials []utils.Credential
target2SMBInfo map[string]*SMBInfo
target2SMBInfo map[string]*smb.SMBFingerprint
printMutex sync.Mutex
targets []string
}
Expand All @@ -39,7 +43,7 @@ func (o *Options) getFunction() func(string) {

func (o *Options) Run() {
o.targets = utils.ExtractTargets(o.Targets.TARGETS)
o.target2SMBInfo = GatherSMBInfoToMap(o.targets, 445)
o.target2SMBInfo = GatherSMBInfoToMap(o.targets, o.Connection.Port)
var f func(string) = o.getFunction()

o.credentials = utils.NewCredentialsDispacher(
Expand All @@ -49,6 +53,10 @@ func (o *Options) Run() {
utils.Clusterbomb,
)

if !slices.Contains(os.Args, "-u") {
return
}

var wg sync.WaitGroup
for t := range o.target2SMBInfo {
wg.Add(1)
Expand All @@ -63,7 +71,7 @@ func (o *Options) Run() {
func (o *Options) testCredentials(target string) {
client := NewClient(target, 445, o.Connection.Domain)

prt := printer.NewPrinter("SMB", client.Host, o.target2SMBInfo[client.Host].NetBIOSName, 445)
prt := printer.NewPrinter("SMB", client.Host, o.target2SMBInfo[client.Host].NetBIOSComputerName, 445)
defer prt.PrintStored(&o.printMutex)

var valid bool = false
Expand Down Expand Up @@ -98,7 +106,7 @@ func (o *Options) testCredentials(target string) {
}

func (o *Options) authenticate(client *Client) (utils.Credential, error) {
prt := printer.NewPrinter("SMB", client.Host, o.target2SMBInfo[client.Host].NetBIOSName, 445)
prt := printer.NewPrinter("SMB", client.Host, o.target2SMBInfo[client.Host].NetBIOSComputerName, 445)
defer prt.PrintStored(&o.printMutex)

for _, creds := range o.credentials {
Expand Down Expand Up @@ -144,7 +152,7 @@ func shareToSlice(s Share) []string {
}

func (o *Options) enumShares(target string) {
prt := printer.NewPrinter("SMB", target, o.target2SMBInfo[target].NetBIOSName, 445)
prt := printer.NewPrinter("SMB", target, o.target2SMBInfo[target].NetBIOSComputerName, 445)
defer prt.PrintStored(&o.printMutex)

client := NewClient(target, 445, o.Connection.Domain)
Expand Down
Loading

0 comments on commit 40ada7d

Please sign in to comment.