package smb import ( "encoding/asn1" "encoding/binary" "errors" "fmt" "log" "math/rand" "time" "imuslab.com/smb/driver/mod/gss" "imuslab.com/smb/driver/mod/ntlmssp" "imuslab.com/smb/driver/mod/smb/encoder" ) type SessionSetup1Request struct { Header StructureSize uint16 Flags byte SecurityMode byte Capabilities uint32 Channel uint32 SecurityBufferOffset uint16 `smb:"offset:SecurityBlob"` SecurityBufferLength uint16 `smb:"len:SecurityBlob"` PreviousSessionID uint64 SecurityBlob *gss.NegTokenInit } type SessionSetup1Response struct { Header StructureSize uint16 Flags uint16 SecurityBufferOffset uint16 `smb:"offset:SecurityBlob"` SecurityBufferLength uint16 `smb:"len:SecurityBlob"` SecurityBlob *gss.NegTokenResp } func (r *SessionSetup1Request) challengeData() ntlmssp.Challenge { ServerChallenge := rand.Uint64() challenge := ntlmssp.NewChallenge(ServerChallenge) challenge.TargetName = encoder.ToUnicode("testGoGo") if true { type AvPair struct { AvID uint16 AvLen uint16 `smb:"len:Value"` Value []byte } // var infos []ntlmssp.AvPair var infos ntlmssp.AvPairSlice ft := uint64(time.Now().UnixNano()) / 100 timestamp := make([]byte, 8) binary.LittleEndian.PutUint64(timestamp, ft) infos = append(infos, ntlmssp.AvPair{ AvID: ntlmssp.MsvAvTimestamp, AvLen: 8, Value: timestamp, }) infos = append(infos, ntlmssp.AvPair{ AvID: ntlmssp.MsvAvEOL, AvLen: 8, Value: timestamp, }) challenge.TargetInfo = &infos } return challenge } func (data *SessionSetup1Request) ServerAction(ctx *DataCtx) (interface{}, error) { resp1 := SessionSetup1Response{ SecurityBlob: &gss.NegTokenResp{}, } resp1.Header = data.Header resp1.Header.Credits = 33 resp1.Header.Status = StatusLogonFailure resp1.Header.SessionID = ctx.session.sessionID resp1.StructureSize = 9 resp1.SecurityBufferOffset = 0x48 resp1.Header.Flags = SMB2_FLAGS_RESPONSE log.Println("G1") var ntlmsspneg ntlmssp.Negotiate if err := encoder.Unmarshal(data.SecurityBlob.Data.MechToken, &ntlmsspneg); err != nil { return ERR(data.Header, STATUS_INVALID_PARAMETER) } // logx.Printf("domain name: %v", ntlmsspneg.DomainName) // logx.Printf("domain name: %v", ntlmsspneg.Workstation) log.Println("G2") if false { negotiateFlagmltmsspmsNEGOTIATELMKEY := 1 << 7 fmt.Println(ntlmsspneg.NegotiateFlags) if int(ntlmsspneg.NegotiateFlags)&negotiateFlagmltmsspmsNEGOTIATELMKEY == negotiateFlagmltmsspmsNEGOTIATELMKEY { log.Println("GOT ERROR ") return &resp1, nil // return errors.New("Only NTLM v2 is supported, but server requested v1 (mltmsspms_NEGOTIATE_LM_KEY)") } } log.Println("G3") // ServerChallenge := rand.Uint64() // ctx.session.ServerChallenge = ServerChallenge // challenge := ntlmssp.NewChallenge(ServerChallenge) // challenge.TargetName = encoder.ToUnicode("testGoGo") challenge := data.challengeData() if true { type AvPair struct { AvID uint16 AvLen uint16 `smb:"len:Value"` Value []byte } // var infos []ntlmssp.AvPair var infos ntlmssp.AvPairSlice ft := uint64(time.Now().UnixNano()) / 100 timestamp := make([]byte, 8) binary.LittleEndian.PutUint64(timestamp, ft) infos = append(infos, ntlmssp.AvPair{ AvID: ntlmssp.MsvAvTimestamp, AvLen: 8, Value: timestamp, }) infos = append(infos, ntlmssp.AvPair{ AvID: ntlmssp.MsvAvEOL, AvLen: 0, }) challenge.TargetInfo = &infos } ctx.session.ServerChallenge = challenge.ServerChallenge challengeData, err := encoder.Marshal(&challenge) if err != nil { return ERR(data.Header, STATUS_INVALID_PARAMETER) } resp1.SecurityBlob = &gss.NegTokenResp{ NegResult: asn1.Enumerated(gss.Accept_incomplete), ResponseToken: challengeData, SupportedMech: myMech(), } resp1.Header.Status = StatusMoreProcessingRequired return &resp1, nil } func (requestSetUp1 *SessionSetup1Request) ClientAction(s *SessionC, setupResponse1 *SessionSetup1Response) error { if setupResponse1.Header.Status != StatusMoreProcessingRequired { // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb/115b551a-dcd7-4ff2-8c59-a334b92e01c0 status, _ := StatusMap[setupResponse1.Header.Status] return errors.New(fmt.Sprintf("NT Status Error: %s\n", status)) } s.sessionID = setupResponse1.Header.SessionID challenge := ntlmssp.NewChallenge(0) resp := setupResponse1.SecurityBlob if err := encoder.Unmarshal(resp.ResponseToken, &challenge); err != nil { s.Debug("", err) return err } s.Challenge = challenge return nil } func (s *SessionC) NewSessionSetup1Request(mechType gss.MechTypeOid) SessionSetup1Request { log.Println("HEREGGGG") header := s.newHeader(CommandSessionSetup) log.Println("HERE?") ntlmsspneg := ntlmssp.NewNegotiate(s.options.Domain, s.options.Workstation) data, err := encoder.Marshal(ntlmsspneg) if err != nil { panic(-1) } negInit, _ := gss.NewNegTokenInit(mechType) negInit.Data.MechToken = data switch mechType { case gss.NtLmSSPMechTypeOid: } return SessionSetup1Request{ Header: header, StructureSize: 25, Flags: 0x00, SecurityMode: byte(SecurityModeSigningEnabled), SecurityBufferOffset: 88, SecurityBlob: negInit, Capabilities: 0, Channel: 0, SecurityBufferLength: 0, PreviousSessionID: 0, } }