comments; update schema

This commit is contained in:
Justin Bastress 2018-03-16 13:21:05 -04:00
parent c05c00a743
commit 65d1789860
3 changed files with 105 additions and 21 deletions

@ -7,52 +7,100 @@ import (
"fmt"
"net"
"unicode/utf16"
"github.com/zmap/zgrab2/lib/smb/gss"
"github.com/zmap/zgrab2/lib/smb/ntlmssp"
"github.com/zmap/zgrab2/lib/smb/smb/encoder"
"unicode/utf16"
)
// HeaderLog contains the relevant parts of the header that is included with each packet.
type HeaderLog struct {
// ProtocolID identifies the SMB protocol version (e.g. ProtocolSmb == "\xFFSMB")
ProtocolID []byte `json:"protocol_id"`
// Status is the server's status; e.g. NTSTATUS (https://msdn.microsoft.com/en-us/library/cc704588.aspx).
Status uint32 `json:"status"`
// Command is the command identifier.
Command uint16 `json:"command"`
// Credits is the number of credits granted to the client.
Credits uint16 `json:"credits"`
// Flags is the flags for the request (see https://msdn.microsoft.com/en-us/library/cc246529.aspx)
Flags uint32 `json:"flags"`
NextCommand uint32 `json:"next_command"`
TreeID uint32 `json:"tree_id"`
}
// NegotiationLog contains the relevant parts of the negotiation response packet.
// See https://msdn.microsoft.com/en-us/library/cc246561.aspx.
type NegotiationLog struct {
HeaderLog
// SecurityMode is the server's security mode (e.g. signing enabled/required).
SecurityMode uint16 `json:"security_mode"`
// DialectRevision is the SMB2 dialect number; 0x2FF is the wildcard.
DialectRevision uint16 `json:"dialect_revision"`
// ServerGuid is the server's globally unique identifier.
ServerGuid []byte `json:"server_guid"`
// Capabilities specifies protocol capabilities for the server.
Capabilities uint32 `json:"capabilities"`
SystemTime uint64 `json:"system_time"`
ServerStartTime uint64 `json:"server_start_time"`
// SystemTime is the time (in seconds since Unix epoch) the server received the negotiation request.
SystemTime uint32 `json:"system_time"`
// ServerStartTime is the time (in seconds since the Unix epoch) the server started.
ServerStartTime uint32 `json:"server_start_time"`
// AuthenticationTypes is a list of OBJECT IDENTIFIERs (in dotted-decimal format) identifying authentication modes
// // that the server supports.
AuthenticationTypes []string `json:"authentication_types,omitempty"`
}
// SessionSetupLog contains the relevant parts of the first session setup response packet.
// See https://msdn.microsoft.com/en-us/library/cc246564.aspx
type SessionSetupLog struct {
HeaderLog
// SetupFlags is the gives additional information on the session.
SetupFlags uint16 `json:"setup_flags"`
// TargetName is the target name from the challenge packet
TargetName string `json:"target_name"`
// NegotiateFlags are the flags from the challenge packet
NegotiateFlags uint32 `json:"negotiate_flags"`
}
// SMBLog logs the relevant information about the session.
type SMBLog struct {
// SupportV1 is true if the server's protocol ID indicates support for version 1.
SupportV1 bool `json:"smbv1_support"`
// NegotiationLog, if present, contains the server's response to the negotiation request.
NegotiationLog *NegotiationLog `json:"negotiation_log"`
// SessionSetupLog, if present, contains the server's response to the session setup request.
SessionSetupLog *SessionSetupLog `json:"session_setup_log"`
}
// LoggedSession wraps the Session struct, and holds a Log struct alongside it to track its progress.
type LoggedSession struct {
Session
Log *SMBLog
}
// zschema doesn't support uint64, so convert this into a standard 32-bit timestamp
func getTime(time uint64) uint32 {
// SMB timestamps are tenths of a millisecond since 1/1/1601.
// Between Jan 1, 1601 and Jan 1, 1970, you have 369 complete years, of which 89 are leap years (1700, 1800, and 1900 were not leap years). That gives you a total of 134774 days or 11644473600 seconds
const offset uint64 = 11644473600
return uint32(time/1e7 - offset)
}
func getHeaderLog(src *Header) HeaderLog {
return *fillHeaderLog(src, nil)
}
@ -62,15 +110,14 @@ func fillHeaderLog(src *Header, dest *HeaderLog) *HeaderLog {
dest = new(HeaderLog)
}
dest.ProtocolID = append(make([]byte, len(src.ProtocolID)), src.ProtocolID...)
dest.Status = src.Status
dest.Command = src.Command
dest.Credits = src.Credits
dest.Status = src.Status
dest.Command = src.Command
dest.Credits = src.Credits
dest.Flags = src.Flags
dest.NextCommand = src.NextCommand
dest.TreeID = src.TreeID
return dest
}
// GetSMBLog attempts to negotiate a SMB session on the given connection.
func GetSMBLog(conn net.Conn) (*SMBLog, error) {
opt := Options{}
@ -94,15 +141,17 @@ func GetSMBLog(conn net.Conn) (*SMBLog, error) {
}
func wstring(input []byte) string {
u16 := make([]uint16, len(input) / 2)
u16 := make([]uint16, len(input)/2)
for i := 0; i < len(u16); i++ {
u16[i] = uint16(input[i * 2]) | (uint16(input[i * 2 + 1]) << 8)
u16[i] = uint16(input[i*2]) | (uint16(input[i*2+1]) << 8)
}
return string(utf16.Decode(u16))
}
// LoggedNegotiateProtocol performs the same operations as Session.NegotiateProtocol() up to the point where user
// credentials would be required, and logs the server's responses.
func (ls *LoggedSession) LoggedNegotiateProtocol() error {
s := &ls.Session
negReq := s.NewNegotiateReq()
@ -124,13 +173,13 @@ func (ls *LoggedSession) LoggedNegotiateProtocol() error {
ls.Log = logStruct
ls.Log.SupportV1 = string(negRes.Header.ProtocolID) == ProtocolSmb
logStruct.NegotiationLog = &NegotiationLog{
HeaderLog: getHeaderLog(&negRes.Header),
SecurityMode: negRes.SecurityMode,
HeaderLog: getHeaderLog(&negRes.Header),
SecurityMode: negRes.SecurityMode,
DialectRevision: negRes.DialectRevision,
ServerGuid: append(make([]byte, len(negRes.ServerGuid)), negRes.ServerGuid...),
Capabilities: negRes.Capabilities,
SystemTime: negRes.SystemTime,
ServerStartTime: negRes.ServerStartTime,
ServerGuid: append(make([]byte, len(negRes.ServerGuid)), negRes.ServerGuid...),
Capabilities: negRes.Capabilities,
SystemTime: getTime(negRes.SystemTime),
ServerStartTime: getTime(negRes.ServerStartTime),
}
if negRes.Header.Status != StatusOk {
return errors.New(fmt.Sprintf("NT Status Error: %d\n", negRes.Header.Status))
@ -211,7 +260,7 @@ func (ls *LoggedSession) LoggedNegotiateProtocol() error {
return err
}
logStruct.SessionSetupLog = &SessionSetupLog{
HeaderLog: getHeaderLog(&ssres.Header),
HeaderLog: getHeaderLog(&ssres.Header),
SetupFlags: ssres.Flags,
}
challenge := ntlmssp.NewChallenge()

@ -3,10 +3,10 @@
package smb
import (
"github.com/jb/tcpwrap"
log "github.com/sirupsen/logrus"
"github.com/zmap/zgrab2"
"github.com/zmap/zgrab2/lib/smb/smb"
"github.com/jb/tcpwrap"
)
// ScanResults instances are returned by the module's Scan function.
@ -93,7 +93,7 @@ func (scanner *Scanner) GetPort() uint {
// 2. Call smb.GetSMBBanner() on the connection
// 3. Return the result.
func (scanner *Scanner) Scan(target zgrab2.ScanTarget) (zgrab2.ScanStatus, interface{}, error) {
conn, err:= target.Open(&scanner.config.BaseFlags)
conn, err := target.Open(&scanner.config.BaseFlags)
if err != nil {
return zgrab2.TryGetScanStatus(err), nil, err
}

@ -7,9 +7,44 @@ import zschema.registry
import schemas.zcrypto as zcrypto
import schemas.zgrab2 as zgrab2
header_log = {
'protocol_id': Binary(),
'status': Unsigned32BitInteger(),
'command': Unsigned16BitInteger(),
'credits': Unsigned16BitInteger(),
'flags': Unsigned32BitInteger(),
}
# Return a (shallow) copy of base, with the fields of new merged atop it
def extended(base, new):
copy = {
k: v for k, v in base.items()
}
for k, v in new.items():
copy[k] = v
return copy
negotiate_log = SubRecord(extended(header_log, {
'security_mode': Unsigned16BitInteger(),
'dialect_revision': Unsigned16BitInteger(),
'server_guid': Binary(),
'capabilities': Unsigned32BitInteger(),
'system_time': Unsigned32BitInteger(),
'server_start_time': Unsigned32BitInteger(),
'authentication_types': ListOf(String()),
}))
session_setup_log = SubRecord(extended(header_log, {
'setup_flags': Unsigned16BitInteger(),
'target_name': String(),
'negotiate_flags': Unsigned32BitInteger(),
}))
smb_scan_response = SubRecord({
"result": SubRecord({
"smbv1_support": Boolean(),
"negotiation_log": negotiate_log,
"session_setup_log": session_setup_log,
})
}, extends=zgrab2.base_scan_response)