Monday 9 March 2015

Synchrolock FileLock

This creates a file placement to prevent a new file being created with the same name. 


#include <windows.h> #include <stdio.h> /* All Variables are here! */ FILE *readFile; // Read from file FILE *logFile; // Log File SynchroLock.log FILE *heartbeat; // File to output process heartbeat CHAR lockName[512]; // !Prone to Overflow! INT countFile; // Number of Files CHAR *removeNewLine; // Removes NewLine Char at end of gets() INT createPass; SYSTEMTIME HeartBeatTime; // For LocalTime information for logging heartbeat. BOOL LogExists=FALSE; //SECURITY_ATTRIBUTES MutexAttributes; // Global var used by RegisterMyMutex functn // Function LockMyFile int LockMyFile(CHAR *currentFile[]) { HANDLE *fileHandle; fileHandle = CreateFile(currentFile, // open MYFILE.TXT SYNCHRONIZE, // open for reading 0, // no share until closed NULL, // no security CREATE_NEW, // Create New File FILE_FLAG_DELETE_ON_CLOSE, // Delete on Close NULL); // no attr. template if (GetLastError() == NULL) return 1; else if (GetLastError() == 183) return -1; else if (GetLastError() == 80) return -1; else if (GetLastError() == 3) return -2; return 0; } // Entry Point void main() { countFile = 0; // Initialise counter mutex loaded readFile = fopen("c:\\SynchroLock\\File.list","r"); logFile = fopen("c:\\SynchroLock\\SynchroLock.log","a+"); if (logFile==NULL){ MessageBox(0,"No results will be written.","Error: Cannot open LogFile", MB_OK); // TO DO - FILE already created and running, QUIT! fclose(readFile); ExitProcess(0); } else LogExists=TRUE; if (readFile==NULL) { fprintf(logFile, "ERROR: No INPUT file. QUITTING\n", lockName); ExitProcess(0); } GetLocalTime(&HeartBeatTime); fprintf(logFile, "\n+Log file appended on %02d/%02d/%d %02d:%02d:%02d by FileLock \n", HeartBeatTime.wDay, HeartBeatTime.wMonth, HeartBeatTime.wYear, HeartBeatTime.wHour, HeartBeatTime.wMinute, HeartBeatTime.wSecond); while(fgets(lockName, 512, readFile)!=NULL) { if ((removeNewLine=strchr(lockName,'\n'))!=NULL) *removeNewLine='\0'; // Remove NewLine char from eos, replace with NULL countFile++; createPass = LockMyFile(lockName); if(createPass==1) fprintf(logFile, "%s has been synchronized succesfully.\n", lockName); else if (createPass==-1) fprintf(logFile, "ATTENTION - %s already exists. %d\n", lockName, GetLastError()); else if (createPass==-2) fprintf(logFile, "ATTENTION - %s was Denied Access. %d\n", lockName, GetLastError()); else if (createPass==0) fprintf(logFile, "WARNING - unknown error when creating %s - %d.\n", lockName, GetLastError()); } // End While Loop fclose(readFile); fclose(logFile); // Create a hearbeat and circulate while (LogExists){ heartbeat = fopen("\\SynchroLock\\Heartbeat.log","a+"); GetLocalTime(&HeartBeatTime); fprintf(heartbeat, "FileLock %02d/%02d/%d %02d:%02d:%02d \n", HeartBeatTime.wDay, HeartBeatTime.wMonth, HeartBeatTime.wYear, HeartBeatTime.wHour, HeartBeatTime.wMinute, HeartBeatTime.wSecond); fclose(heartbeat); Sleep(360000); // sleep 60 minutes } }

Synchrolock MutexLock

The Mutex Lock component

#define _WIN32_WINNT 0x0500 #include <windows.h> #include <sddl.h> #include <tchar.h> #include <stdio.h> /* All Variables are here! */ FILE *mutexFile; // Read from file FILE *logFile; // Log File SynchroLock.log FILE *heartbeat; // File to output process heartbeat CHAR stringMutex[256]; // !Prone to Overflow! INT countMutex; // Number of Mutexes HANDLE hMutex[1024]; // Handle of Mutexes CHAR *removeNewLine; // Removes NewLine Char at end of gets() INT createPass; SYSTEMTIME HeartBeatTime; // For LocalTime information for logging heartbeat. BOOL LogExists=FALSE; SECURITY_ATTRIBUTES MutexAttributes; // Global var used by RegisterMyMutex functn // Function RegisterMyMutex registers each Mutex as a globally accessible unit per computer int RegisterMyMutex(CHAR *currentMutex[]) { HANDLE registerMutex; registerMutex = CreateMutex(&MutexAttributes, FALSE, currentMutex); if (GetLastError()==ERROR_ALREADY_EXISTS) return -1; if (registerMutex == NULL) return 0; return 1; } // End Of Function RegisterMyMutex // Entry Point void main() { const TCHAR * szSD = _T("D:") // Discretionary // _T("(A;OICI;GRGWGX;;;AU)"); // Allow RWX to Authenticated Users _T("(A;OICI;GA;;;AU)"); // Allow Generic Access to all authenticated users // Initialise Mutex Security Attributes to run as Service ZeroMemory( &MutexAttributes, sizeof(MutexAttributes) ); MutexAttributes.nLength = sizeof( MutexAttributes ); // Set SecurityAttrib structures MutexAttributes.bInheritHandle = FALSE; if (!ConvertStringSecurityDescriptorToSecurityDescriptor(szSD, SDDL_REVISION_1, &MutexAttributes.lpSecurityDescriptor, NULL)) printf("Failed to ConvertStringSecurityDescriptorToSecurityDescriptor\n"); //SetSecurityDescriptorDacl( &MutexAttributes, TRUE, pDacl, FALSE ); // SecurityDescriptor is now prepared countMutex = 0; // Initialise counter mutex loaded mutexFile = fopen("c:\\SynchroLock\\Mutex.list","r"); logFile = fopen("c:\\SynchroLock\\SynchroLock.log","a+"); if (mutexFile==NULL) { MessageBox(0,"Cannot Open Mutex File","Cannot Read", MB_OK); ExitProcess(0); } if (logFile==NULL){ MessageBox(0,"No results will be written.","Error: Cannot open LogFile", MB_OK); // TO DO - FILE already created and running, QUIT! fclose(mutexFile); ExitProcess(0); } else LogExists=TRUE; // Load All Mutexes in Mutex.List file // Maximum Mutex length = 256 chars GetLocalTime(&HeartBeatTime); fprintf(logFile, "\n+Log file appended on %02d/%02d/%d %02d:%02d:%02d by MutexLock.\n", HeartBeatTime.wDay, HeartBeatTime.wMonth, HeartBeatTime.wYear, HeartBeatTime.wHour, HeartBeatTime.wMinute, HeartBeatTime.wSecond); while(fgets(stringMutex, 256, mutexFile)!=NULL) { if ((removeNewLine=strchr(stringMutex,'\n'))!=NULL) *removeNewLine='\0'; // Remove NewLine char from eos, replace with NULL countMutex++; // printf("%d %s",countMutex, stringMutex); // debug // MessageBox(0,stringMutex,"Registering", MB_OK); createPass = RegisterMyMutex(stringMutex); if(createPass==0) fprintf(logFile, "WARNING! %s failed to create. %d\n", stringMutex, GetLastError()); else if (createPass==-1) fprintf(logFile, "ATTENTION! prohibited application %s may already be in use!\n" , stringMutex); } // End While Loop fclose(mutexFile); fclose(logFile); // Create a hearbeat and circulate while (LogExists){ heartbeat = fopen("\\SynchroLock\\Heartbeat.log","a+"); GetLocalTime(&HeartBeatTime); fprintf(heartbeat, "MutexLock %02d/%02d/%d %02d:%02d:%02d \n", HeartBeatTime.wDay, HeartBeatTime.wMonth, HeartBeatTime.wYear, HeartBeatTime.wHour, HeartBeatTime.wMinute, HeartBeatTime.wSecond); fclose(heartbeat); Sleep(360000); // sleep 60 seconds } }



Synchrolock Service

This is the service handler.


#include <stdio.h> #include <windows.h> #include <winsvc.h> void WINAPI ServiceMain(DWORD argc, LPTSTR *argv); void WINAPI ServiceCtrlHandler(DWORD Opcode); SERVICE_STATUS MyServiceStatus; SERVICE_STATUS_HANDLE MyServiceStatusHandle; SERVICE_TABLE_ENTRY Table[]={ {"Service1",ServiceMain}, {NULL,NULL}}; BOOL srvcRunning = TRUE; BOOL handleMutexLock=FALSE; BOOL handleFileLock=FALSE; STARTUPINFO si = { sizeof(si) }; PROCESS_INFORMATION piMutexLock, piFileLock; HANDLE HandleMutex; HANDLE FileLock; // Change of Service state handled in switch case void WINAPI ServiceCtrlHandler(DWORD Opcode) { switch(Opcode) { case SERVICE_CONTROL_STOP: // Asked to stop service on request MyServiceStatus.dwWin32ExitCode = 0; MyServiceStatus.dwCurrentState = SERVICE_STOPPED; MyServiceStatus.dwCheckPoint = 0; MyServiceStatus.dwWaitHint = 0; SetServiceStatus (MyServiceStatusHandle,&MyServiceStatus); if (srvcRunning==TRUE){ // Kill the child processes! HandleMutex = OpenProcess(PROCESS_ALL_ACCESS, FALSE, piMutexLock.dwProcessId); TerminateProcess(HandleMutex, -1); // argghh!! FileLock = OpenProcess(PROCESS_ALL_ACCESS, FALSE, piFileLock.dwProcessId); TerminateProcess(FileLock, -1); // argghh!! } // end if srvcRunning=FALSE; break; case SERVICE_CONTROL_CONTINUE: // Handle Start and Continue states MyServiceStatus.dwCurrentState = SERVICE_RUNNING; break; case SERVICE_CONTROL_INTERROGATE: // Interrogate state break; } // end case return; } // end handler // Service Controller will enter here to check on status of service void WINAPI ServiceMain(DWORD argc, LPTSTR *argv) { DWORD status; DWORD specificError; MyServiceStatus.dwServiceType = SERVICE_WIN32; MyServiceStatus.dwCurrentState = SERVICE_START_PENDING; // Tell SCM service is starting up MyServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; MyServiceStatus.dwWin32ExitCode = 0; MyServiceStatus.dwServiceSpecificExitCode = 0; MyServiceStatus.dwCheckPoint = 0; MyServiceStatus.dwWaitHint = 0; MyServiceStatusHandle = RegisterServiceCtrlHandler("SynchroLock", ServiceCtrlHandler); if (MyServiceStatusHandle == (SERVICE_STATUS_HANDLE)0) { return; } MyServiceStatus.dwCurrentState = SERVICE_RUNNING; MyServiceStatus.dwCheckPoint = 0; MyServiceStatus.dwWaitHint = 0; if (!SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus)) { } srvcRunning=TRUE; while(srvcRunning) { if (!handleMutexLock) { // Attempt to start MutexLock handleMutexLock = CreateProcess(0, "C:\\Synchrolock\\MutexLock.exe", 0, 0, FALSE, CREATE_NO_WINDOW, 0, 0, &si, &piMutexLock); if (!handleMutexLock) { if(MessageBox(0,"Would you like to retry","MutexLock Failed.", MB_RETRYCANCEL)==IDCANCEL) { ServiceCtrlHandler(SERVICE_CONTROL_STOP); srvcRunning=FALSE; // Set SERVICE CONTROLLER to fail if user gives up trying else try again } } } if (!handleFileLock) { // Attempt to start FileLock process handleFileLock = CreateProcess(0, "C:\\Synchrolock\\FileLock.exe", 0, 0, FALSE, CREATE_NO_WINDOW, 0, 0, &si, &piFileLock); if (!handleFileLock) { if(MessageBox(0,"Would you like to retry","FileLock Failed", MB_RETRYCANCEL)==IDCANCEL) { ServiceCtrlHandler(SERVICE_CONTROL_STOP); srvcRunning=FALSE; // Set SERVICE CONTROLLER to fail if user gives up trying else try again } } // end if !handleFileLock } // End if else Sleep(3000); } // end while loop return; } void main() { StartServiceCtrlDispatcher(Table); return; }



Public discussions SYNCHROLOCK

I have been working on this idea for a while, and once upon a time, I wrote it up and put it into code circa 10 years ago. A very close friend of mine linked me to a blog written by Lenny Zelster, describing the idea, so I decided it is time to share the code now, as I am no developer.

Remember I wrote this a long time ago, and programming is not my thing, so it is full of bugs ( for example, the big fixed array resulting in overflow). Regardless it is only a proof of concept.

Use:

An application like this is especially useful in an enterprise or large network to protect against attacks either pro-actively or reactively by a large network of security researches, such as say AV. If these can be pushed out in an environment with an imminent threat, machines with the file and mutex's in place might be prevented from infection due to the worms or threats on mechanism to prevent multiple copies.

This concept also includes a file locker. The entire PoC sits on a service, which reads off a list of files containing the strings, but the idea is that the list of file and mutexes are administered by a server, gets pushed onto the Synchrolock agents, and are replicated onto machines for protection.

Architecturally, Synchrolock consists of 3 components

  • The service 
  • Mutex Lock
  • File Lock


It creates an output of the log file containing errors, which should be audited.

Ok enough, The code follows in the next 3 entries.