Skip to content

Commit

Permalink
Updated version of go-smb lib to v0.5.2 which introduces support for …
Browse files Browse the repository at this point in the history
…Kerberos authentication
  • Loading branch information
jfjallid committed Jul 21, 2024
1 parent efe1394 commit ac61e93
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 28 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,18 @@ https://social.technet.microsoft.com/Forums/en-US/6e3c4486-f3a1-4d4e-9f5c-bdacdb
Usage: ./go-secdump [options]
options:
--host <target> Hostname or ip address of remote server
--host <target> Hostname or ip address of remote server. Must be hostname when using Kerberos
-P, --port <port> SMB Port (default 445)
-d, --domain <domain> Domain name to use for login
-u, --user <username> Username
-p, --pass <pass> Password
-n, --no-pass Disable password prompt and send no credentials
--hash <NT Hash> Hex encoded NT Hash for user password
--local Authenticate as a local user instead of domain user
-k, --kerberos Use Kerberos authentication. (KRB5CCNAME will be checked on Linux)
--dc-ip Optionally specify ip of KDC when using Kerberos authentication
--target-ip Optionally specify ip of target when using Kerberos authentication
--aes-key Use a hex encoded AES128/256 key for Kerberos authentication
--dump Saves the SAM and SECURITY hives to disk and
transfers them to the local machine.
--sam Extract secrets from the SAM hive explicitly. Only other explicit targets are included.
Expand Down
7 changes: 4 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ module github.com/jfjallid/go-secdump
go 1.19

require (
github.com/jfjallid/go-smb v0.4.0
github.com/jfjallid/go-smb v0.5.2
github.com/jfjallid/golog v0.3.3
golang.org/x/crypto v0.6.0
golang.org/x/net v0.6.0
golang.org/x/net v0.7.0
golang.org/x/term v0.5.0
)

require (
github.com/jfjallid/ber v1.1.0 // indirect
github.com/jfjallid/gofork v1.7.6 // indirect
github.com/jfjallid/gokrb5/v8 v8.4.4 // indirect
golang.org/x/sys v0.5.0 // indirect
)
37 changes: 32 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,14 +1,41 @@
github.com/jfjallid/ber v1.1.0 h1:hVaxa1K4vBwh5Arvc70uhatZephEgJpRTHKQCf4u7OA=
github.com/jfjallid/ber v1.1.0/go.mod h1:EJC7yARA25HsUp0G498XpiJahwGx+T+HKh2LHZ/QslA=
github.com/jfjallid/go-smb v0.4.0 h1:xAk7szRqVzvmG//o/UVccLEcxiCwdFp4NefgnOGBWLA=
github.com/jfjallid/go-smb v0.4.0/go.mod h1:LccOuPoXGyNtqYSfr6p3zPev9BlA12W/5S5YWllgjZI=
github.com/jfjallid/go-smb v0.5.2 h1:TXiFxuCEzcDHNkG6jEUewNgIoZcS0ZnkXLhydJjpO+A=
github.com/jfjallid/go-smb v0.5.2/go.mod h1:gCorMd5NXhyMR3f1/x+qTZRSN35/6iY5TuqFIWb+Ovg=
github.com/jfjallid/gofork v1.7.6 h1:OYyS2HH597860gkDxxjNsl+NZRxoAnuRI6ZsP++kYKE=
github.com/jfjallid/gofork v1.7.6/go.mod h1:r1EH4W9KY5iqtiGhAupnbzMRONsLDApdJ9EZH5NWFSc=
github.com/jfjallid/gokrb5/v8 v8.4.4 h1:log4i4lIQDOKe/RHWTHdTGeeJTYMW/+M07JgHAiE0as=
github.com/jfjallid/gokrb5/v8 v8.4.4/go.mod h1:RbpQRNWdL0hXz/jTmtRB1Gcx4ZqFzJpyJLSarBMehrI=
github.com/jfjallid/golog v0.3.3 h1:dY6qf8wTxJ9OwBPVTadVRDmt/6MVXSWwXrxaGMMyXsU=
github.com/jfjallid/golog v0.3.3/go.mod h1:19Q/zg5OgPPd0xhFllokPnMzthzhFPZmiAGAokE7k58=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
88 changes: 69 additions & 19 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,12 @@ import (
"github.com/jfjallid/go-smb/smb/dcerpc"
"github.com/jfjallid/go-smb/smb/dcerpc/msrrp"
"github.com/jfjallid/go-smb/smb/encoder"
"github.com/jfjallid/go-smb/spnego"
"github.com/jfjallid/golog"
)

var log = golog.Get("")
var release string = "0.2.2"
var release string = "0.3.0"

var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")

Expand Down Expand Up @@ -715,14 +716,18 @@ var helpMsg = `
Usage: ` + os.Args[0] + ` [options]
options:
--host <target> Hostname or ip address of remote server
--host <target> Hostname or ip address of remote server. Must be hostname when using Kerberos
-P, --port <port> SMB Port (default 445)
-d, --domain <domain> Domain name to use for login
-u, --user <username> Username
-p, --pass <pass> Password
-n, --no-pass Disable password prompt and send no credentials
--hash <NT Hash> Hex encoded NT Hash for user password
--local Authenticate as a local user instead of domain user
-k, --kerberos Use Kerberos authentication. (KRB5CCNAME will be checked on Linux)
--dc-ip Optionally specify ip of KDC when using Kerberos authentication
--target-ip Optionally specify ip of target when using Kerberos authentication
--aes-key Use a hex encoded AES128/256 key for Kerberos authentication
--dump Saves the SAM and SECURITY hives to disk and
transfers them to the local machine.
--sam Extract secrets from the SAM hive explicitly. Only other explicit targets are included.
Expand All @@ -748,9 +753,9 @@ var helpMsg = `
`

func main() {
var host, username, password, hash, domain, socksIP, backupFilename, outputFilename string
var host, username, password, hash, domain, socksIP, backupFilename, outputFilename, targetIP, dcIP, aesKey string
var port, dialTimeout, socksPort, relayPort int
var debug, noEnc, forceSMB2, localUser, dump, version, verbose, relay, noPass, sam, lsaSecrets, dcc2, backupDacl, restoreDacl bool
var debug, noEnc, forceSMB2, localUser, dump, version, verbose, relay, noPass, sam, lsaSecrets, dcc2, backupDacl, restoreDacl, kerberos bool
var err error

flag.Usage = func() {
Expand Down Expand Up @@ -792,28 +797,39 @@ func main() {
flag.StringVar(&backupFilename, "backup-file", "dacl.backup", "")
flag.StringVar(&outputFilename, "o", "", "")
flag.StringVar(&outputFilename, "output", "", "")
flag.BoolVar(&kerberos, "k", false, "")
flag.BoolVar(&kerberos, "kerberos", false, "")
flag.StringVar(&targetIP, "target-ip", "", "")
flag.StringVar(&dcIP, "dc-ip", "", "")
flag.StringVar(&aesKey, "aes-key", "", "")

flag.Parse()

if debug {
golog.Set("github.com/jfjallid/go-smb/smb", "smb", golog.LevelDebug, golog.LstdFlags|golog.Lshortfile, golog.DefaultOutput, golog.DefaultErrOutput)
golog.Set("github.com/jfjallid/go-smb/spnego", "spnego", golog.LevelDebug, golog.LstdFlags|golog.Lshortfile, golog.DefaultOutput, golog.DefaultErrOutput)
golog.Set("github.com/jfjallid/go-smb/gss", "gss", golog.LevelDebug, golog.LstdFlags|golog.Lshortfile, golog.DefaultOutput, golog.DefaultErrOutput)
golog.Set("github.com/jfjallid/go-smb/smb/dcerpc", "dcerpc", golog.LevelDebug, golog.LstdFlags|golog.Lshortfile, golog.DefaultOutput, golog.DefaultErrOutput)
golog.Set("github.com/jfjallid/go-smb/smb/dcerpc/msrrp", "msrrp", golog.LevelDebug, golog.LstdFlags|golog.Lshortfile, golog.DefaultOutput, golog.DefaultErrOutput)
golog.Set("github.com/jfjallid/go-smb/krb5ssp", "krb5ssp", golog.LevelDebug, golog.LstdFlags|golog.Lshortfile, golog.DefaultOutput, golog.DefaultErrOutput)
log.SetFlags(golog.LstdFlags | golog.Lshortfile)
log.SetLogLevel(golog.LevelDebug)
} else if verbose {
golog.Set("github.com/jfjallid/go-smb/smb", "smb", golog.LevelInfo, golog.LstdFlags|golog.Lshortfile, golog.DefaultOutput, golog.DefaultErrOutput)
golog.Set("github.com/jfjallid/go-smb/spnego", "spnego", golog.LevelInfo, golog.LstdFlags|golog.Lshortfile, golog.DefaultOutput, golog.DefaultErrOutput)
golog.Set("github.com/jfjallid/go-smb/gss", "gss", golog.LevelInfo, golog.LstdFlags|golog.Lshortfile, golog.DefaultOutput, golog.DefaultErrOutput)
golog.Set("github.com/jfjallid/go-smb/smb/dcerpc", "dcerpc", golog.LevelInfo, golog.LstdFlags|golog.Lshortfile, golog.DefaultOutput, golog.DefaultErrOutput)
golog.Set("github.com/jfjallid/go-smb/smb/dcerpc/msrrp", "msrrp", golog.LevelInfo, golog.LstdFlags|golog.Lshortfile, golog.DefaultOutput, golog.DefaultErrOutput)
golog.Set("github.com/jfjallid/go-smb/krb5ssp", "krb5ssp", golog.LevelInfo, golog.LstdFlags|golog.Lshortfile, golog.DefaultOutput, golog.DefaultErrOutput)
log.SetFlags(golog.LstdFlags | golog.Lshortfile)
log.SetLogLevel(golog.LevelInfo)
} else {
golog.Set("github.com/jfjallid/go-smb/smb", "smb", golog.LevelNotice, golog.LstdFlags, golog.DefaultOutput, golog.DefaultErrOutput)
golog.Set("github.com/jfjallid/go-smb/spnego", "spnego", golog.LevelNotice, golog.LstdFlags|golog.Lshortfile, golog.DefaultOutput, golog.DefaultErrOutput)
golog.Set("github.com/jfjallid/go-smb/gss", "gss", golog.LevelNotice, golog.LstdFlags, golog.DefaultOutput, golog.DefaultErrOutput)
golog.Set("github.com/jfjallid/go-smb/smb/dcerpc", "dcerpc", golog.LevelNotice, golog.LstdFlags, golog.DefaultOutput, golog.DefaultErrOutput)
golog.Set("github.com/jfjallid/go-smb/smb/dcerpc/msrrp", "msrrp", golog.LevelNotice, golog.LstdFlags, golog.DefaultOutput, golog.DefaultErrOutput)
golog.Set("github.com/jfjallid/go-smb/krb5ssp", "krb5ssp", golog.LevelNotice, golog.LstdFlags|golog.Lshortfile, golog.DefaultOutput, golog.DefaultErrOutput)
}

if version {
Expand Down Expand Up @@ -868,12 +884,18 @@ func main() {

share := ""
var hashBytes []byte
var aesKeyBytes []byte

if host == "" {
log.Errorln("Must specify a hostname")
if host == "" && targetIP == "" {
log.Errorln("Must specify a hostname or ip")
flag.Usage()
return
}
if host != "" && targetIP == "" {
targetIP = host
} else if host == "" && targetIP != "" {
host = targetIP
}

if socksIP != "" && isFlagSet("timeout") {
log.Errorln("When a socks proxy is specified, --timeout is not supported")
Expand All @@ -895,11 +917,25 @@ func main() {
}
}

if aesKey != "" {
aesKeyBytes, err = hex.DecodeString(aesKey)
if err != nil {
fmt.Println("Failed to decode aesKey")
log.Errorln(err)
return
}
if len(aesKeyBytes) != 16 && len(aesKeyBytes) != 32 {
fmt.Println("Invalid keysize of AES Key")
return
}
}

if noPass {
password = ""
hashBytes = nil
aesKeyBytes = nil
} else {
if (password == "") && (hashBytes == nil) {
if (password == "") && (hashBytes == nil) && (aesKeyBytes == nil) {
fmt.Printf("Enter password: ")
passBytes, err := term.ReadPassword(int(os.Stdin.Fd()))
fmt.Println()
Expand All @@ -911,23 +947,37 @@ func main() {
}
}

options := smb.Options{
Host: host,
Port: port,
Initiator: &smb.NTLMInitiator{
smbOptions := smb.Options{
Host: targetIP,
Port: port,
DisableEncryption: noEnc,
ForceSMB2: forceSMB2,
//DisableSigning: true,
}

if kerberos {
smbOptions.Initiator = &spnego.KRB5Initiator{
User: username,
Password: password,
Domain: domain,
Hash: hashBytes,
AESKey: aesKeyBytes,
SPN: "cifs/" + host,
DCIP: dcIP,
}
} else {
smbOptions.Initiator = &spnego.NTLMInitiator{
User: username,
Password: password,
Hash: hashBytes,
Domain: domain,
LocalUser: localUser,
},
DisableEncryption: noEnc,
ForceSMB2: forceSMB2,
}
}

// Only if not using SOCKS
if socksIP == "" {
options.DialTimeout, err = time.ParseDuration(fmt.Sprintf("%ds", dialTimeout))
smbOptions.DialTimeout, err = time.ParseDuration(fmt.Sprintf("%ds", dialTimeout))
if err != nil {
log.Errorln(err)
return
Expand All @@ -942,14 +992,14 @@ func main() {
log.Errorln(err)
return
}
options.ProxyDialer = dialSocksProxy
smbOptions.ProxyDialer = dialSocksProxy
}

if relay {
options.RelayPort = relayPort
session, err = smb.NewRelayConnection(options)
smbOptions.RelayPort = relayPort
session, err = smb.NewRelayConnection(smbOptions)
} else {
session, err = smb.NewConnection(options)
session, err = smb.NewConnection(smbOptions)
}
if err != nil {
log.Criticalln(err)
Expand Down

0 comments on commit ac61e93

Please sign in to comment.