/* @(#) $Id: win-common.c,v 1.10 2007/07/26 01:32:03 dcid Exp $ */ /* Copyright (C) 2007 Daniel B. Cid * All right reserved. * * This program is a free software; you can redistribute it * and/or modify it under the terms of the GNU General Public * License (version 2) as published by the FSF - Free Software * Foundation */ #include "shared.h" #include "rootcheck.h" #ifdef WIN32 /** Registry checking values **/ /* Global variables */ HKEY rk_sub_tree; /* Default values */ #define MAX_KEY_LENGTH 255 #define MAX_KEY 2048 #define MAX_VALUE_NAME 16383 /* os_check_ads. * Check if file has NTFS ADS. */ int os_check_ads(char *full_path) { HANDLE file_h; WIN32_STREAM_ID sid; void *context = NULL; char stream_name[MAX_PATH +1]; char final_name[MAX_PATH +1]; DWORD dwRead, shs, dw1, dw2; /* Opening file */ file_h = CreateFile(full_path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_POSIX_SEMANTICS, NULL); if (file_h == INVALID_HANDLE_VALUE) { return 0; } /* Zeroing memory */ ZeroMemory(&sid, sizeof(WIN32_STREAM_ID)); /* Getting stream header size -- should be 20 bytes */ shs = (LPBYTE)&sid.cStreamName - (LPBYTE)&sid+ sid.dwStreamNameSize; while(1) { if(BackupRead(file_h, (LPBYTE) &sid, shs, &dwRead, FALSE, FALSE, &context) == 0) { break; } if(dwRead == 0) { break; } stream_name[0] = '\0'; stream_name[MAX_PATH] = '\0'; if(BackupRead(file_h, (LPBYTE)stream_name, sid.dwStreamNameSize, &dwRead, FALSE, FALSE, &context)) { if(dwRead != 0) { char *tmp_pt; char op_msg[OS_SIZE_1024 +1]; snprintf(final_name, MAX_PATH, "%s%S", full_path, (WCHAR *)stream_name); tmp_pt = strrchr(final_name, ':'); if(tmp_pt) { *tmp_pt = '\0'; } snprintf(op_msg, OS_SIZE_1024, "NTFS Alternate data stream " "found: '%s'. Possible hidden" " content.", final_name); notify_rk(ALERT_ROOTKIT_FOUND, op_msg); } } /* Getting next */ if(!BackupSeek(file_h, sid.Size.LowPart, sid.Size.HighPart, &dw1, &dw2, &context)) { break; } } CloseHandle(file_h); return(0); } /** char *__os_winreg_getkey(char *reg_entry) * Gets registry high level key. */ char *__os_winreg_getkey(char *reg_entry) { char *ret = NULL; char *tmp_str; /* Getting only the sub tree first */ tmp_str = strchr(reg_entry, '\\'); if(tmp_str) { *tmp_str = '\0'; ret = tmp_str+1; } /* Setting sub tree */ if((strcmp(reg_entry, "HKEY_LOCAL_MACHINE") == 0) || (strcmp(reg_entry, "HKLM") == 0)) { rk_sub_tree = HKEY_LOCAL_MACHINE; } else if(strcmp(reg_entry, "HKEY_CLASSES_ROOT") == 0) { rk_sub_tree = HKEY_CLASSES_ROOT; } else if(strcmp(reg_entry, "HKEY_CURRENT_CONFIG") == 0) { rk_sub_tree = HKEY_CURRENT_CONFIG; } else if(strcmp(reg_entry, "HKEY_USERS") == 0) { rk_sub_tree = HKEY_USERS; } else if((strcmp(reg_entry, "HKCU") == 0) || (strcmp(reg_entry, "HKEY_CURRENT_USER") == 0)) { rk_sub_tree = HKEY_CURRENT_USER; } else { /* Setting sub tree to null */ rk_sub_tree = NULL; /* Returning tmp_str to the previous value */ if(tmp_str && (*tmp_str == '\0')) *tmp_str = '\\'; return(NULL); } /* Checking if ret has nothing else. */ if(ret && (*ret == '\0')) ret = NULL; /* fixing tmp_str and the real name of the registry */ if(tmp_str && (*tmp_str == '\0')) *tmp_str = '\\'; return(ret); } /* int __os_winreg_querykey * Query the key and get the value of a specific entry. */ int __os_winreg_querykey(HKEY hKey, char *p_key, char *full_key_name, char *reg_option, char *reg_value) { int i, rc; DWORD j; /* QueryInfo and EnumKey variables */ TCHAR sub_key_name_b[MAX_KEY_LENGTH +1]; TCHAR class_name_b[MAX_PATH +1]; DWORD class_name_s = MAX_PATH; /* Number of sub keys */ DWORD subkey_count = 0; /* Number of values */ DWORD value_count; /* Variables for RegEnumValue */ TCHAR value_buffer[MAX_VALUE_NAME +1]; TCHAR data_buffer[MAX_VALUE_NAME +1]; DWORD value_size; DWORD data_size; /* Data type for RegEnumValue */ DWORD data_type = 0; /* Storage var */ char var_storage[MAX_VALUE_NAME +1]; /* Initializing the memory for some variables */ class_name_b[0] = '\0'; class_name_b[MAX_PATH] = '\0'; sub_key_name_b[0] = '\0'; sub_key_name_b[MAX_KEY_LENGTH] = '\0'; /* We use the class_name, subkey_count and the value count. */ rc = RegQueryInfoKey(hKey, class_name_b, &class_name_s, NULL, &subkey_count, NULL, NULL, &value_count, NULL, NULL, NULL, NULL); /* Check return code of QueryInfo */ if(rc != ERROR_SUCCESS) { return(0); } /* Getting Values (if available) */ if (value_count) { char *mt_data; /* Clearing the values for value_size and data_size */ value_buffer[MAX_VALUE_NAME] = '\0'; data_buffer[MAX_VALUE_NAME] = '\0'; var_storage[MAX_VALUE_NAME] = '\0'; /* Getting each value */ for(i=0;i 2) { strncat(var_storage, mt_data, size_available); strncat(var_storage, " ", 2); size_available = MAX_VALUE_NAME - (strlen(var_storage) +2); } mt_data += strlen(mt_data) +1; } break; case REG_DWORD: snprintf(var_storage, MAX_VALUE_NAME, "%x",(unsigned int)*data_buffer); break; default: size_available = MAX_VALUE_NAME -2; for(j = 0;j 2) { strncat(var_storage, tmp_c, size_available); size_available = MAX_VALUE_NAME - (strlen(var_storage) +2); } } break; } /* Checking if value matches */ if(pt_matches(var_storage, reg_value)) { return(1); } return(0); } } return(0); } /* int __os_winreg_open_key(char *subkey) * Open the registry key */ int __os_winreg_open_key(char *subkey, char *full_key_name, char *reg_option, char *reg_value) { int ret = 1; HKEY oshkey; if(RegOpenKeyEx(rk_sub_tree, subkey, 0, KEY_READ,&oshkey) != ERROR_SUCCESS) { return(0); } /* If option is set, return the value of query key */ if(reg_option) { ret = __os_winreg_querykey(oshkey, subkey, full_key_name, reg_option, reg_value); } RegCloseKey(oshkey); return(ret); } /* is_registry: Check if the entry is present in the registry */ int is_registry(char *entry_name, char *reg_option, char *reg_value) { char *rk; rk = __os_winreg_getkey(entry_name); if(rk_sub_tree == NULL || rk == NULL) { merror(SK_INV_REG, ARGV0, entry_name); return(0); } if(__os_winreg_open_key(rk, entry_name, reg_option, reg_value) == 0) { return(0); } return(1); } /* del_plist:. Deletes the process list */ int del_plist(void *p_list_p) { OSList *p_list = (OSList *)p_list_p; OSListNode *l_node; OSListNode *p_node = NULL; if(p_list == NULL) { return(0); } l_node = OSList_GetFirstNode(p_list); while(l_node) { Win32Proc_Info *pinfo; pinfo = (Win32Proc_Info *)l_node->data; free(pinfo->p_name); free(pinfo->p_path); free(l_node->data); if(p_node) { free(p_node); p_node = NULL; } p_node = l_node; l_node = OSList_GetNextNode(p_list); } if(p_node) { free(p_node); p_node = NULL; } free(p_list); return(1); } /* is_process: Check is a process is running. */ int is_process(char *value, void *p_list_p) { OSList *p_list = (OSList *)p_list_p; OSListNode *l_node; if(p_list == NULL) { return(0); } if(!value) { return(0); } l_node = OSList_GetFirstNode(p_list); while(l_node) { Win32Proc_Info *pinfo; pinfo = (Win32Proc_Info *)l_node->data; /* Checking if value matches */ if(pt_matches(pinfo->p_path, value)) { return(1); } l_node = OSList_GetNextNode(p_list); } return(0); } #else /* WIN32 */ /* Non windows defs for them. */ int os_check_ads(char *full_path) { return(0); } int is_registry(char *entry_name, char *reg_option, char *reg_value) { return(0); } int is_process(char *value, void *p_list) { return(0); } #endif /* EOF */