Пример #1
0
int initModule(_MODULE_DATA *_psSessionData, sLogin* psLogin)
{
  int hSocket = -1;
  enum MODULE_STATE nState = MSTATE_NEW;
  unsigned char bufSend[BUF_SIZE];
  sCredentialSet *psCredSet = NULL;
  sConnectParams params;

  psCredSet = malloc( sizeof(sCredentialSet) );
  memset(psCredSet, 0, sizeof(sCredentialSet));

  if (getNextCredSet(psLogin, psCredSet) == FAILURE)
  {
    writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME);
    nState = MSTATE_COMPLETE;
  }
  else if (psCredSet->psUser)
  {
    writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser);
  }
  else
  {
    writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME);
    nState = MSTATE_COMPLETE;
  }

  memset(&params, 0, sizeof(sConnectParams));
  if (psLogin->psServer->psAudit->iPortOverride > 0)
    params.nPort = psLogin->psServer->psAudit->iPortOverride;
  else if (psLogin->psServer->psHost->iUseSSL > 0)
    params.nPort = PORT_IMAPS;
  else
    params.nPort = PORT_IMAP;
  initConnectionParams(psLogin, &params);

  /* set TAG, if not specified by user */
  if (_psSessionData->szTag == NULL)
  {
    _psSessionData->szTag = malloc(5);
    memset(_psSessionData->szTag, 0, 5);
    sprintf(_psSessionData->szTag, "gerg");
  }

  while (nState != MSTATE_COMPLETE)
  {  
    switch (nState)
    {
      case MSTATE_NEW:
        // Already have an open socket - close it
        if (hSocket > 0)
          medusaDisconnect(hSocket);

        if (psLogin->psServer->psHost->iUseSSL > 0)
          hSocket = medusaConnectSSL(&params);
        else
          hSocket = medusaConnect(&params);
        
        if (hSocket < 0) 
        {
          writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP);
          psLogin->iResult = LOGIN_RESULT_UNKNOWN;
          return FAILURE;
        }

        if (initConnection(_psSessionData, hSocket, &params) == FAILURE)
        {
          psLogin->iResult = LOGIN_RESULT_UNKNOWN;
          return FAILURE;
        }

        writeError(ERR_DEBUG_MODULE, "Connected");

        nState = MSTATE_RUNNING;
        break;
      case MSTATE_RUNNING:
        /* The IMAP service may be configured to drop connections after an arbitrary number of failed
           logon attempts. We will reuse the established connection to send authentication attempts 
           until that disconnect happens. At that point the connection should be reestablished. */
        if ( medusaCheckSocket(hSocket) )
        {
          nState = tryLogin(hSocket, _psSessionData, &psLogin, psCredSet->psUser->pUser, psCredSet->pPass);

          if (psLogin->iResult != LOGIN_RESULT_UNKNOWN)
          {
            if (getNextCredSet(psLogin, psCredSet) == FAILURE)
            {
              writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME);
              nState = MSTATE_EXITING;
            }
            else
            {
              if (psCredSet->iStatus == CREDENTIAL_DONE)
              {
                writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME);
                nState = MSTATE_EXITING;
              }
              else if (psCredSet->iStatus == CREDENTIAL_NEW_USER)
              {
                writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser);
                nState = MSTATE_NEW;
              }
              else
                writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass);
            }
          }
        }
        else
        {
          writeError(ERR_NOTICE, "[%s] Socket is no longer valid. Server likely dropped connection. Establishing new session.", MODULE_NAME);
          nState = MSTATE_NEW;

          if (hSocket > 0)
            medusaDisconnect(hSocket);
          hSocket = -1;
        }

        break;
      case MSTATE_EXITING:
        if (hSocket > 0)
          medusaDisconnect(hSocket);
        hSocket = -1;
        nState = MSTATE_COMPLETE;
        break;
      default:
        writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState);
        if (hSocket > 0)
          medusaDisconnect(hSocket);
        hSocket = -1;
        psLogin->iResult = LOGIN_RESULT_UNKNOWN;
        return FAILURE;
    }  
  }

  FREE(psCredSet); 
  return SUCCESS;
}
Пример #2
0
int initModule(sLogin* psLogin, _MODULE_DATA *_psSessionData)
{
  int hSocket = -1;
  enum MODULE_STATE nState = MSTATE_NEW;
  unsigned char bufSend[BUF_SIZE];
  unsigned char* bufReceive;
  int nReceiveBufferSize = 0;
  sCredentialSet *psCredSet = NULL;
  sConnectParams params;

  psCredSet = malloc( sizeof(sCredentialSet) );
  memset(psCredSet, 0, sizeof(sCredentialSet));

  if (getNextCredSet(psLogin, psCredSet) == FAILURE)
  {
    writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME);
    nState = MSTATE_COMPLETE;
  }
  else if (psCredSet->psUser)
  {
    writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser);
  }
  else
  {
    writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME);
    nState = MSTATE_COMPLETE;
  }

  memset(&params, 0, sizeof(sConnectParams));
  if (psLogin->psServer->psAudit->iPortOverride > 0)
    params.nPort = psLogin->psServer->psAudit->iPortOverride;
  else if (psLogin->psServer->psHost->iUseSSL > 0)
    params.nPort = PORT_POP3S;
  else
    params.nPort = PORT_POP3;
  initConnectionParams(psLogin, &params);

  while (nState != MSTATE_COMPLETE)
  {  
    switch (nState)
    {
      case MSTATE_NEW:
        // Already have an open socket - close it
        if (hSocket > 0)
          medusaDisconnect(hSocket);

        if (psLogin->psServer->psHost->iUseSSL > 0)
          hSocket = medusaConnectSSL(&params);
        else
          hSocket = medusaConnect(&params);
        
        if (hSocket < 0) 
        {
          writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP);
          psLogin->iResult = LOGIN_RESULT_UNKNOWN;
          return FAILURE;
        }

        /* establish initial connection */
        nReceiveBufferSize = 0;
        if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "\\+OK.*\r\n") == FAILURE) || (bufReceive == NULL))
        {
          writeError(ERR_DEBUG_MODULE, "%s failed: Server did not respond with '+OK'. Exiting...", MODULE_NAME);
          psLogin->iResult = LOGIN_RESULT_UNKNOWN;
          nState = MSTATE_EXITING;
        }
        else
        {
          writeError(ERR_DEBUG_MODULE, "Connected");
          nState = MSTATE_RUNNING;
        }

        /* POP3 STARTTLS Extension
           http://www.faqs.org/rfcs/rfc2595.html
        */

        /* The capability name "STLS" indicates this command is present and 
           permitted in the current state. "CAPA" can be used to test for its
           presence. Are there cases where "STLS" may not be implemented?
        */

        /* Initiate STLS only if we don't already have a SSL connection */
        if (psLogin->psServer->psHost->iUseSSL == 0)
        {
          memset(bufSend, 0, BUF_SIZE);
          sprintf(bufSend, "STLS\r\n");
          if (medusaSend(hSocket, bufSend, strlen(bufSend), 0) < 0)
          {
            writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME);
            return FAILURE;
          }
  
          nReceiveBufferSize = 0;
          if (medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "\\+OK.*\r\n|-ERR.*\r\n") == FAILURE)
          {
            writeError(ERR_ERROR, "[%s] Failed: Unexpected or no data received: %s", MODULE_NAME, bufReceive);
            return FAILURE;
          }
          /*
            [SUPPORTED]     +OK Begin TLS negotiation / +OK Ready to start TLS
            [NOT SUPPORTED] +OK STLS completed
            [ERROR]         -ERR Command not permitted when TLS active
          */
          else if (strstr(bufReceive, "+OK") != NULL)
          {
            FREE(bufReceive);
  
            writeError(ERR_DEBUG_MODULE, "[%s] Starting TLS negotiation.", MODULE_NAME);
            params.nSSLVersion = 3.1; /* Force the use of TLSv1 */
            if (medusaConnectSocketSSL(&params, hSocket) < 0)
            {
              writeError(ERR_ERROR, "[%s] Failed to establish SSLv3 connection.", MODULE_NAME);
              return FAILURE;
            }
          }
          else
          {
            writeError(ERR_DEBUG_MODULE, "[%s] TLS negotiation not available.", MODULE_NAME);
            FREE(bufReceive);
          }
        }
  
        /* Query service for accepted authentication methods */
        if (_psSessionData->nAuthType == AUTH_UNKNOWN)
        {
          getAuthType(hSocket, _psSessionData);

          if (_psSessionData->nAuthType == AUTH_UNKNOWN)
          {
            psLogin->iResult = LOGIN_RESULT_UNKNOWN;
            return FAILURE;
          }
        }
 
        break;
      case MSTATE_RUNNING:
        /* The POP3 service may be configured to drop connections after an arbitrary number of failed
           logon attempts. We will reuse the established connection to send authentication attempts 
           until that disconnect happens. At that point the connection should be reestablished. */
        if ( medusaCheckSocket(hSocket) )
        {
          nState = tryLogin(hSocket, &psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass);

          if (psLogin->iResult != LOGIN_RESULT_UNKNOWN)
          {
            if (getNextCredSet(psLogin, psCredSet) == FAILURE)
            {
              writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME);
              nState = MSTATE_EXITING;
            }
            else
            {
              if (psCredSet->iStatus == CREDENTIAL_DONE)
              {
                writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME);
                nState = MSTATE_EXITING;
              }
              else if (psCredSet->iStatus == CREDENTIAL_NEW_USER)
              {
                writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser);
                nState = MSTATE_NEW;
              }
              else
                writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass);
            }
          }
        }
        else
        {
          writeError(ERR_NOTICE, "[%s] Socket is no longer valid. Server likely dropped connection. Establishing new session.", MODULE_NAME);
          nState = MSTATE_NEW;

          if (hSocket > 0)
            medusaDisconnect(hSocket);
          hSocket = -1;
        }
        break;
      case MSTATE_EXITING:
        if (hSocket > 0)
          medusaDisconnect(hSocket);
        hSocket = -1;
        nState = MSTATE_COMPLETE;
        break;
      default:
        writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState);
        if (hSocket > 0)
          medusaDisconnect(hSocket);
        hSocket = -1;
        psLogin->iResult = LOGIN_RESULT_UNKNOWN;
        return FAILURE;
    }  
  }

  FREE(psCredSet);
  return SUCCESS;
}
Пример #3
0
int initModule(sLogin* psLogin, _MODULE_DATA *_psSessionData)
{
  int hSocket = -1;
  enum MODULE_STATE nState = MSTATE_NEW;
  unsigned char* bufReceive;
  int nReceiveBufferSize = 0;
  sCredentialSet *psCredSet = NULL;

  psCredSet = malloc( sizeof(sCredentialSet) );
  memset(psCredSet, 0, sizeof(sCredentialSet));

  if (getNextCredSet(psLogin, psCredSet) == FAILURE)
  {
    writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME);
    nState = MSTATE_COMPLETE;
  }
  else if (psCredSet->psUser)
  {
    writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser);
  }
  else
  {
    writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME);
    nState = MSTATE_COMPLETE;
  }

  _psSessionData->params = malloc( sizeof(sConnectParams) );
  memset(_psSessionData->params, 0, sizeof(sConnectParams));
  
  if (_psSessionData->nAuthType == AUTH_IMPLICIT)
  {
    psLogin->psServer->psHost->iUseSSL = 1;
    _psSessionData->params->nPort = PORT_FTPS;
  }
  else
  {
    _psSessionData->params->nPort = PORT_FTP;
  }  

  if (psLogin->psServer->psAudit->iPortOverride > 0)
    _psSessionData->params->nPort = psLogin->psServer->psAudit->iPortOverride;
  else if (psLogin->psServer->psHost->iUseSSL > 0)
    _psSessionData->params->nPort = PORT_FTPS;

  initConnectionParams(psLogin, _psSessionData->params);

  while (nState != MSTATE_COMPLETE)
  {  
    switch (nState)
    {
      case MSTATE_NEW:
        // Already have an open socket - close it
        if (hSocket > 0)
          medusaDisconnect(hSocket);

        if (psLogin->psServer->psHost->iUseSSL > 0)
          hSocket = medusaConnectSSL(_psSessionData->params);
        else
          hSocket = medusaConnect(_psSessionData->params);
        
        if (hSocket < 0) 
        {
          writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, _psSessionData->params->nPort, psLogin->psServer->pHostIP);
          psLogin->iResult = LOGIN_RESULT_UNKNOWN;
          return FAILURE;
        }

        /* establish initial connection */
      
        /*  http://www.faqs.org/rfcs/rfc959.html
          
            Thus the format for multi-line replies is that the first line
            will begin with the exact required reply code, followed
            immediately by a Hyphen, "-" (also known as Minus), followed by
            text.  The last line will begin with the same code, followed
            immediately by Space <SP>, optionally some text, and the Telnet
            end-of-line code.
        */
        writeError(ERR_DEBUG_MODULE, "[%s] Retrieving FTP banner.", MODULE_NAME);
        bufReceive = NULL;
        nReceiveBufferSize = 0;
        
        /* Grab entire banner and verify format */
        if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^[0-9]{3,3}-.*\r\n[0-9]{3,3} .*\r\n|^[0-9]{3,3} .*\r\n") == FAILURE) || (bufReceive == NULL))
        {
          writeError(ERR_DEBUG_MODULE, "[%s] failed: Server sent unknown response. Exiting...", MODULE_NAME);
          FREE(bufReceive);
          return FAILURE;
        }

        if (strncmp((char*)bufReceive, "220", 3) == 0)
        {
          writeError(ERR_DEBUG_MODULE, "[%s] Server sent 220 response.", MODULE_NAME);
          FREE(bufReceive);
        }
        else if (strncmp((char*)bufReceive, "421", 3) == 0)
        {
          writeError(ERR_ERROR, "[%s] Server sent 421 response (too many connections).", MODULE_NAME);
          FREE(bufReceive);
          return FAILURE;
        }
        else
        {
          writeError(ERR_ERROR, "[%s] Server sent unknown response code: %c%c%c", MODULE_NAME, bufReceive[0], bufReceive[1], bufReceive[2]);
          FREE(bufReceive);
          return FAILURE;
        }          

        /* Establish Explicit FTPS mode authentication if requested */ 
        if (_psSessionData->nAuthType == AUTH_EXPLICIT)
        {
          if (initAuthSSL(hSocket, _psSessionData) == FAILURE)
          {
            psLogin->iResult = LOGIN_RESULT_UNKNOWN;
            nState = MSTATE_EXITING;
          }
        }

        nState = MSTATE_RUNNING;

        break;
      case MSTATE_RUNNING:
        /* The FTP service may be configured to drop connections after an arbitrary number of failed
           logon attempts. We will reuse the established connection to send authentication attempts 
           until that disconnect happens. At that point the connection should be reestablished. */
        if ( medusaCheckSocket(hSocket, psLogin->psServer->psAudit->iSocketWait) )
        {
          nState = tryLogin(hSocket, &psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass);

          if (psLogin->iResult != LOGIN_RESULT_UNKNOWN)
          {
            if (getNextCredSet(psLogin, psCredSet) == FAILURE)
            {
              writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME);
              nState = MSTATE_EXITING;
            }
            else
            {
              if (psCredSet->iStatus == CREDENTIAL_DONE)
              {
                writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME);
                nState = MSTATE_EXITING;
              }
              else if (psCredSet->iStatus == CREDENTIAL_NEW_USER)
              {
                writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser);
                nState = MSTATE_NEW;
              }
              else
                writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass);
            }
          }
        }
        else
        {
          writeError(ERR_NOTICE, "[%s] Socket is no longer valid. Server likely dropped connection. Establishing new session.", MODULE_NAME);
          nState = MSTATE_NEW;

          if (hSocket > 0)
            medusaDisconnect(hSocket);
          hSocket = -1;
        }

        break;
      case MSTATE_EXITING:
        if (hSocket > 0)
          medusaDisconnect(hSocket);
        hSocket = -1;
        nState = MSTATE_COMPLETE;
        break;
      default:
        writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState);
        if (hSocket > 0)
          medusaDisconnect(hSocket);
        hSocket = -1;
        psLogin->iResult = LOGIN_RESULT_UNKNOWN;
        return FAILURE;
    }  
  }
 
  FREE(psCredSet);
  return SUCCESS;
}
Пример #4
0
int tryLogin(int hSocket, sLogin** psLogin, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword)
{
  int iRet;
  unsigned char bufSend[BUF_SIZE];
  unsigned char* bufReceive = NULL;
  int nReceiveBufferSize = 0;

  /* send username */
  memset(bufSend, 0, sizeof(bufSend));
  sprintf((char*)bufSend, "USER %.250s\r\n", szLogin);

  if (medusaSend(hSocket, bufSend, strlen((char*)bufSend), 0) < 0)
  {
    writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME);
  }
 
  nReceiveBufferSize = 0;
  if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^[0-9]{3,3}-.*\r\n[0-9]{3,3} .*\r\n|^[0-9]{3,3} .*\r\n") == FAILURE) || (bufReceive == NULL))
  {
    writeError(ERR_ERROR, "[%s] failed: Server sent unknown or no response. Server may have dropped connection due to lack of encryption or due to anti-bruteforce measures. Enabling EXPLICIT mode may help with the former cause and increasing the socket check delay (e.g. -c 1000) may help with the later.", MODULE_NAME);
    return FAILURE;
  }

  /* FTP service may be configured to require protected authentication for specific users */
  if ( (strstr((char*)bufReceive, "530 Non-anonymous sessions must use encryption.") != NULL) ||
       (strstr((char*)bufReceive, "331 Non-anonymous sessions must use encryption.") != NULL) || 
       (strstr((char*)bufReceive, "331 Rejected--secure connection required") != NULL) )
  {
    writeError(ERR_NOTICE, "[%s] FTP server (%s) appears to require SSL for specified user.", MODULE_NAME, (*psLogin)->psServer->pHostIP);
    
    FREE(bufReceive);
    
    if ( medusaCheckSocket(hSocket, (*psLogin)->psServer->psAudit->iSocketWait) )
    {
      writeError(ERR_DEBUG_MODULE, "[%s] Checking socket status: OK", MODULE_NAME);
      if (initAuthSSL(hSocket, _psSessionData) == FAILURE)
        return FAILURE;
    }
    else
    {
      writeError(ERR_DEBUG_MODULE, "[%s] Checking socket status: FAIL - restart connection", MODULE_NAME);
      _psSessionData->nAuthType = AUTH_EXPLICIT;      
      return MSTATE_NEW;
    }

    /* re-send username */
    memset(bufSend, 0, sizeof(bufSend));
    sprintf((char*)bufSend, "USER %.250s\r\n", szLogin);

    if (medusaSend(hSocket, bufSend, strlen((char*)bufSend), 0) < 0)
    {
      writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME);
    }
 
    nReceiveBufferSize = 0;
    if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^[0-9]{3,3}-.*\r\n[0-9]{3,3} .*\r\n|^[0-9]{3,3} .*\r\n") == FAILURE) || (bufReceive == NULL))
    {
      writeError(ERR_ERROR, "[%s] failed: Server sent unknown or no response. Exiting...", MODULE_NAME);
      return FAILURE;
    }
  }  

  /* Standard FTP [PR85] specifies a 530 response to the USER command when
     the username is rejected. "Not logged in." */
  if (strncmp((char*)bufReceive, "530 ", 4) == 0) 
  {
    writeError(ERR_ERROR, "[%s] Server sent 530 response (rejected username).", MODULE_NAME);
    FREE(bufReceive);
    return FAILURE;
  }
  /* 421 There are too many connections from your internet address. */
  else if (strncmp((char*)bufReceive, "421 ", 4) == 0) 
  {
    writeError(ERR_ERROR, "[%s] Server sent 421 response (too many connections).", MODULE_NAME);
    FREE(bufReceive);
    return MSTATE_EXITING;
  }
  /* Expect: "331 Please specify the password." */
  else if (strncmp((char*)bufReceive, "331 ", 4) != 0) 
  {
    writeError(ERR_ERROR, "[%s] failed: Server did not respond with a '331'.", MODULE_NAME);
    FREE(bufReceive);
    return FAILURE;
  }
  
  FREE(bufReceive);

  /* send password */
  memset(bufSend, 0, sizeof(bufSend));
  sprintf((char*)bufSend, "PASS %.250s\r\n", szPassword);

  if (medusaSend(hSocket, bufSend, strlen((char*)bufSend), 0) < 0)
  {
    writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME);
  }

  nReceiveBufferSize = 0;
  if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^[0-9]{3,3}-.*\r\n[0-9]{3,3} .*\r\n|^[0-9]{3,3} .*\r\n") == FAILURE) || (bufReceive == NULL))
  {
    writeError(ERR_ERROR, "%s failed: medusaReceive returned no data.", MODULE_NAME);
    return FAILURE;
  }
  
  if (bufReceive[0] == '2')
  {
    writeError(ERR_DEBUG_MODULE, "%s : Login attempt successful.", MODULE_NAME);
    (*psLogin)->iResult = LOGIN_RESULT_SUCCESS;
    iRet = MSTATE_EXITING;
  }
  else
  {
    writeError(ERR_DEBUG_MODULE, "%s : Login attempt failed.", MODULE_NAME);
    (*psLogin)->iResult = LOGIN_RESULT_FAIL;
    /* Restarting session for now as it's currently faster when dealing with anti-bruteforce services */
    iRet = MSTATE_NEW;
  }
  
  FREE(bufReceive);
  setPassResult((*psLogin), szPassword);

  return(iRet);
}
Пример #5
0
int initModule(sLogin* psLogin, _MODULE_DATA *_psSessionData)
{
  int hSocket = -1;
  enum MODULE_STATE nState = MSTATE_NEW;
  sCredentialSet *psCredSet = NULL;
  sConnectParams params;

  psCredSet = malloc( sizeof(sCredentialSet) );
  memset(psCredSet, 0, sizeof(sCredentialSet));

  if (getNextCredSet(psLogin, psCredSet) == FAILURE)
  {
    writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME);
    nState = MSTATE_COMPLETE;
  }
  else if (psCredSet->psUser)
  {
    writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser);
  }
  else
  {
    writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME);
    nState = MSTATE_COMPLETE;
  }

  memset(&params, 0, sizeof(sConnectParams));
  if (psLogin->psServer->psAudit->iPortOverride > 0)
    params.nPort = psLogin->psServer->psAudit->iPortOverride;
  else if (psLogin->psServer->psHost->iUseSSL > 0)
    params.nPort = PORT_SMTPS;
  else
    params.nPort = PORT_SMTP;
  initConnectionParams(psLogin, &params);

  /* set EHLO, if not specified by user */
  if (_psSessionData->szEHLO == NULL)
  {
    _psSessionData->szEHLO = malloc(5);
    memset(_psSessionData->szEHLO, 0, 5);
    sprintf(_psSessionData->szEHLO, "gerg");
  }

  while (nState != MSTATE_COMPLETE)
  {  
    switch(nState)
    {
      case MSTATE_NEW:
        if (hSocket > 0)
          medusaDisconnect(hSocket);
  
        if (psLogin->psServer->psHost->iUseSSL > 0)
          hSocket = medusaConnectSSL(&params);
        else
          hSocket = medusaConnect(&params);

        if (hSocket < 0) 
        {
          writeError(ERR_NOTICE, "[%s] failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP);
          psLogin->iResult = LOGIN_RESULT_UNKNOWN;
          return FAILURE;
        }

        if (initConnection(_psSessionData, hSocket, &params) == FAILURE)
        {
          psLogin->iResult = LOGIN_RESULT_UNKNOWN;
          return FAILURE;
        }

        writeError(ERR_DEBUG_MODULE, "Connected");

        nState = MSTATE_RUNNING;
        break;
      case MSTATE_RUNNING:
        if ( medusaCheckSocket(hSocket, psLogin->psServer->psAudit->iSocketWait) )
        {
          nState = tryLogin(hSocket, &psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass);

          if (psLogin->iResult != LOGIN_RESULT_UNKNOWN)
          {
            if (getNextCredSet(psLogin, psCredSet) == FAILURE)
            {
              writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME);
              nState = MSTATE_EXITING;
            }
            else
            {
              if (psCredSet->iStatus == CREDENTIAL_DONE)
              {
                writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME);
                nState = MSTATE_EXITING;
              }
              else if (psCredSet->iStatus == CREDENTIAL_NEW_USER)
              {
                writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser);
                nState = MSTATE_NEW;
              }
              else
                writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass);
            }
          }
        }
        else
        {
          writeError(ERR_NOTICE, "[%s] Socket is no longer valid. Server likely dropped connection. Establishing new session.", MODULE_NAME);
          nState = MSTATE_NEW;

          if (hSocket > 0)
            medusaDisconnect(hSocket);
          hSocket = -1;
        }
        break;
      case MSTATE_EXITING:
        if (hSocket > 0)
          medusaDisconnect(hSocket);
        hSocket = -1;
        nState = MSTATE_COMPLETE;
        break;
      default:
        writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState);
        if (hSocket > 0)
          medusaDisconnect(hSocket);
        hSocket = -1;
        psLogin->iResult = LOGIN_RESULT_UNKNOWN;
        return FAILURE;
    }  
  }

  FREE(psCredSet);
  return SUCCESS;
}