Quellcode durchsuchen

Better 'parsing' of negotation response. Saves sessionkey/challenge/caps/sec_mode in session. Links to libcrypto for future ntlmv2 support

Julien 'Lta' BALLET vor 11 Jahren
Ursprung
Commit
b8762ec045
7 geänderte Dateien mit 46 neuen und 16 gelöschten Zeilen
  1. 3 2
      Makefile
  2. 5 2
      dsm.c
  3. 14 2
      include/bdsm/smb_defs.h
  4. 7 1
      include/bdsm/smb_session.h
  5. 0 1
      src/netbios_utils.c
  6. 2 1
      src/smb_message.c
  7. 15 7
      src/smb_session.c

+ 3 - 2
Makefile

@@ -1,7 +1,7 @@
 # Makefile for libdsm
 
-CFLAGS      = -g3 -I include -DBDSM_DEBUG=1 -D_BSD_SOURCE -std=c99
-LDFLAGS     = #-levent
+CFLAGS      = -g3 -Iinclude -DBDSM_DEBUG=1 -D_BSD_SOURCE -std=c99 #-Wall -Wextra
+LDFLAGS     = -lcrypto #-levent
 CC          = clang
 
 UTIL				= dsm
@@ -25,6 +25,7 @@ clean:
 	rm -f $(UTIL) $(UTIL_OBJS)
 
 re: clean all
+c: clean
 
 $(UTIL): $(UTIL_OBJS)
 	$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(UTIL_OBJS)

+ 5 - 2
dsm.c

@@ -25,7 +25,6 @@ int main(int ac, char **av)
 {
   struct sockaddr_in  addr;
   bdsm_context_t      *ctx;
-  const char          *dialects[]= SMB_DIALECTS;
 
   printf("sizeof(smb_header_t) = %lu", sizeof(smb_header_t));
 
@@ -59,7 +58,11 @@ int main(int ac, char **av)
     exit(42);
   }
   if (smb_session_negotiate_protocol(session))
-    printf("cool\n");
+  {
+    fprintf(stderr, "Dialect/Security Mode negotation success.\n");
+    fprintf(stderr, "Session key is 0x%lx\n", session->srv.session_key);
+    fprintf(stderr, "Challenge key is 0x%llx\n", session->srv.challenge);
+  }
   else
     printf("Unable to negotiate SMB Dialect\n");
 

+ 14 - 2
include/bdsm/smb_defs.h

@@ -67,8 +67,20 @@ typedef struct
 
 typedef struct
 {
-  uint8_t         wct; // +-17 :)
-  uint8_t         payload[];
+  uint8_t         wct;            // +-17 :)
+  uint16_t        dialect_index;  //
+  uint8_t         security_mode;  // Share/User. Plaintext/Challenge
+  uint32_t        diplodocus;
+  uint32_t        max_bufsize;    // Max buffer size requested by server.
+  uint32_t        max_rawbuffer;  // Max raw buffer size requested by serv.
+  uint32_t        session_key;    // 'MUST' be returned to server
+  uint32_t        caps;
+  uint64_t        time;           // I don't give a fuck
+  uint16_t        tz;             // Even less fuck given
+  uint8_t         key_length;     // Size of challenge key, if > 8 then shit
+  uint16_t        bct;
+  uint64_t        challenge;      // Normally 8 bytes, if not then wtf monkey
+  uint8_t         payload[];      // The rest isn't really meaningfull for us
 } __attribute__((packed))   smb_negotiate_resp_t;
 
 typedef struct

+ 7 - 1
include/bdsm/smb_session.h

@@ -18,8 +18,14 @@
 typedef struct
 {
   int                 state;
-  unsigned            dialect;
   netbios_session_t   *nb_session;
+  struct {
+    uint16_t            dialect;        // The selected dialect
+    uint16_t            security_mode;  // Security mode
+    uint32_t            caps;           // Server caps replyed during negotiate
+    uint32_t            session_key;    // XXX Is this really usefull?
+    uint64_t            challenge;      // For challenge response security
+  }                   srv;
 }                   smb_session_t;
 
 

+ 0 - 1
src/netbios_utils.c

@@ -31,7 +31,6 @@ void  netbios_name_level1_encode(const char *name, char *encoded_name,
                                  unsigned type)
 {
   size_t    name_length = strlen(name);
-  char      symbol;
 
   if (name_length > NETBIOS_NAME_LENGTH)
     name_length = NETBIOS_NAME_LENGTH;

+ 2 - 1
src/smb_message.c

@@ -101,5 +101,6 @@ void            smb_message_set_default_flags(smb_message_t *msg)
   assert(msg != NULL && msg->packet != NULL);
 
   msg->packet->header.flags   = 0x18;
-  msg->packet->header.flags2  = 0xc843;
+  //msg->packet->header.flags2  = 0xc843; // w/ extended security;
+  msg->packet->header.flags2  = 0xc043; // w/o extended security;
 }

+ 15 - 7
src/smb_session.c

@@ -99,9 +99,11 @@ size_t          smb_session_recv_msg(smb_session_t *s, smb_message_t *msg)
 
 int             smb_session_negotiate_protocol(smb_session_t *s)
 {
-  smb_message_t *msg = NULL;
-  smb_message_t answer;
-  const char    *dialects[] = SMB_DIALECTS;
+  const char            *dialects[] = SMB_DIALECTS;
+  smb_message_t         *msg = NULL;
+  smb_message_t         answer;
+  smb_negotiate_resp_t  *nego;
+
 
   msg = smb_message_new(SMB_CMD_NEGOTIATE, 64);
   smb_message_set_default_flags(msg);
@@ -123,13 +125,19 @@ int             smb_session_negotiate_protocol(smb_session_t *s)
   if (!smb_session_recv_msg(s, &answer))
     goto error;
 
+  nego = (smb_negotiate_resp_t *)answer.packet->payload;
   if (answer.packet->header.status != NT_STATUS_SUCCESS
-      && answer.packet->payload[0] != 0x11)
+      && nego->wct != 0x11 && nego->security_mode & 0x03)
     goto error;
 
-  // we dont provide more than 256 dialects, so we use it as an unsigned char
-  s->dialect  = answer.packet->payload[1];
-  s->state    = SMB_STATE_DIALECT_OK;
+  s->srv.dialect        = nego->dialect_index;
+  s->srv.security_mode  = nego->security_mode;
+  s->srv.caps           = nego->caps;
+  s->srv.session_key    = nego->session_key;
+  s->srv.challenge      = nego->challenge;
+
+  // Yeah !
+  s->state              = SMB_STATE_DIALECT_OK;
 
   return (1);