comments; update schema
This commit is contained in:
parent
c05c00a743
commit
65d1789860
@ -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)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user