static int get_cpio_entries_internal(byte_p ramdisk_cpio_data,size_t ramdisk_size,cpio_entry_list_t*** entriesp){ cpio_entry_list_t** entries=(*entriesp); int count=0; byte_p next_value,start =ramdisk_cpio_data; if((next_value = (start=find_in_memory(start,ramdisk_size,magic_cpio_ascii,6)))){ while(next_value){ entries[count]->start.position=next_value; next_value+=CPIO_HEADER_SIZE; entries[count]->name=next_value; int name_size =strlen(entries[count]->name); entries[count]->name_padding=(((4 - (CPIO_HEADER_SIZE+name_size) % 4)) % 4); next_value+=entries[count]->name_padding+name_size; entries[count]->data=next_value; next_value=find_in_memory(next_value,ramdisk_size-(next_value-start),magic_cpio_ascii,6); if(!next_value){ // No Values after this get the remaining padding.. This should be the trailer if not we have a problem entries[count]->data_size=ramdisk_size-(entries[count]->data-start); //ramend; //entries[count]->data-test; }else{ entries[count]->data_size=next_value-entries[count]->data; entries[count]->next=next_value; } count++; } } return count; }
// count the number of cpio entries. find the amount of times the cpio_magic occurs in ramdisk_data. int count_cpio_entries(byte_p uncompressed_ramdisk_data,size_t uncompressed_ramdisk_size){ byte_p next_value ; int cpio_entry_count=0; if((next_value = (find_in_memory(uncompressed_ramdisk_data,uncompressed_ramdisk_size,magic_cpio_ascii,6)))){ while(next_value){ cpio_entry_count++; next_value=find_in_memory(next_value+1,uncompressed_ramdisk_size-(next_value-uncompressed_ramdisk_data),magic_cpio_ascii,6); } } return cpio_entry_count; }
/********************************** Функция: sniffer_thread Параметры: VOID *lpParameter - параметр передаваемый в функцию, при запуске нити. Описание: Точка входа рабочего потока. Выбирает из TCP-стека пакет и ищет в данных один из операторов SQL (SELECT, INSERT, UPDATE, DELETE). В случае нахождения - отсылает все печатываемые символы от найденного оператора вправо - в поток-логгер. ***********************************/ DWORD WINAPI sniffer_thread( VOID *lpParameter ) { SnifferThreadParams *params = (SnifferThreadParams *)lpParameter; UINT8 packet[PACKET_SIZE]; WINDIVERT_ADDRESS addr; UINT packet_len; const char *sql_commands [] = { "insert", "select", "update", "delete", "alter", "create", "drop", "grant", nullptr }; while( WinDivertRecv( params->handle(), &packet, sizeof(packet), &addr, &packet_len ) ) { WINDIVERT_IPHDR *ip_header; WINDIVERT_TCPHDR *tcp_header; void *payload = nullptr; UINT payload_len = 0; WinDivertHelperParsePacket(&packet, packet_len, &ip_header, NULL, NULL, NULL, &tcp_header, NULL, &payload, &payload_len); if( payload != nullptr ){ const char *sql_beg = find_in_memory( (const char *)payload, payload_len, sql_commands ); int count = 0; if( sql_beg != nullptr ){ while( sql_beg+count < ((const char *)payload)+payload_len && ( isprint(sql_beg[count]) || sql_beg[count]=='\n') ){ ++count; } std::string sql_request(sql_beg, count); for( std::size_t pos = sql_request.find("\n"); pos != std::string::npos; pos = sql_request.find("\n", pos) ){ sql_request.replace( pos, 1, " " ); } log( ip_header->SrcAddr, tcp_header->SrcPort, sql_request ); } } } return 0; }
/********************************** Функция: find_in_memory Параметры: const char *payload - указатель на начало буфера int payload_len - длина буфера char *sql_commands[]- перечень строк для поиска, должен заканчиваться nullptr Описание: Ищет в буфере одну из строк Возвращает: nullptr - в случае отсутствия строк для поиска, указатель на начало одной из строк для поиска в буфере ***********************************/ const char *find_in_memory( const char *payload, int payload_len, const char *sql_commands[] ) { const char *rc = nullptr; int i=0; while( sql_commands[i] != nullptr ){ rc = find_in_memory( payload, payload_len, sql_commands[i] ); if( rc != nullptr ){ return rc; } ++i; } return rc; }
int load_kernel_image_from_memory(unsigned char* kernel_addr,unsigned kernel_size,kernel_image* image ){ // Look for the kernel zImage Magic int return_value = 0 ; D("kernel_addr=%p kernel_size=%u\n",kernel_addr,kernel_size); unsigned char * kernel_magic_offset_p = find_in_memory(kernel_addr,kernel_size,KERNEL_ZIMAGE_MAGIC, KERNEL_ZIMAGE_MAGIC_SIZE ); if(!kernel_magic_offset_p){ D("kernel_magic_offset not found\n") return_value = ENOEXEC; goto exit; } // Get the address that zImage starts at. // This is normally found at offset 0x28 in a standard zImage // which is 4 bytes along from the kernel magic offset which is // normally found at 0x24 unsigned char* kernel_start_address = kernel_magic_offset_p+4; // zImage ends at 0x2C unsigned char* kernel_end_address = kernel_magic_offset_p+8; D("kernel_start_address=%d%d%d%d kernel_end_address=%p\n",kernel_start_address[0],kernel_start_address[1],kernel_start_address[2],kernel_start_address[3],kernel_end_address); unsigned char * compressed_kernel_offset_p = get_kernel_compression_type_and_offset(kernel_addr,kernel_size,kernel_magic_offset_p,image); D("compressed_kernel_offset_p %p kernel_size=%u\n",compressed_kernel_offset_p,kernel_size) ; unsigned char *uncompressed_kernel_data = calloc(MAX_KERNEL_SIZE,sizeof(unsigned char)) ; long uncompressed_kernel_size = 0; errno = 0 ; switch(image->compression_type){ case KERNEL_COMPRESSION_GZIP: uncompressed_kernel_size = uncompress_gzip_memory(compressed_kernel_offset_p,kernel_size,uncompressed_kernel_data,MAX_KERNEL_SIZE); break ; case KERNEL_COMPRESSION_LZO:{ uncompressed_kernel_size = uncompress_lzo_memory(compressed_kernel_offset_p,kernel_size,uncompressed_kernel_data,MAX_KERNEL_SIZE); break; } case KERNEL_COMPRESSION_XZ:{ uncompressed_kernel_size = uncompress_xz_memory(compressed_kernel_offset_p,kernel_size,uncompressed_kernel_data,MAX_KERNEL_SIZE); break; } default: break; } if(errno){ D("errno: %u %s\n",errno,strerror(errno)); free(uncompressed_kernel_data); return uncompressed_kernel_size; } D("uncompressed_kernel_size : %ld\n",uncompressed_kernel_size); // fill in the basic values image->start_addr = uncompressed_kernel_data; image->size = uncompressed_kernel_size; image->version = (char *)find_in_memory(uncompressed_kernel_data,uncompressed_kernel_size,KERNEL_VERSION_STRING,KERNEL_VERSION_STRING_SIZE); // find the first number string image->version_number = image->version + KERNEL_VERSION_STRING_SIZE + 1 ; char* first_space = strchr(image->version_number,32); D("first_space : %p\n",first_space); D("image->version_number : %s\n",image->version_number); image->version_number_length = first_space - image->version_number; D("image->version_number_length : %d\n",image->version_number_length); // find the config.gz if there is one image->config_addr = find_in_memory(uncompressed_kernel_data,uncompressed_kernel_size,KERNEL_IKCFG_ST,KERNEL_IKCFG_SIZE); if(image->config_addr){ // Advance the config_addr position along to the start of the gzip "file" image->config_addr += KERNEL_IKCFG_SIZE; // find the end unsigned char * config_end = find_in_memory_start_at(uncompressed_kernel_data , uncompressed_kernel_size ,image->config_addr, KERNEL_IKCFG_ED, KERNEL_IKCFG_SIZE); // if we can't find a KERNEL_IKCFG_ED then something is very wrong if(!config_end){ errno = EINVAL; return_value =errno; free(uncompressed_kernel_data); goto exit; } image->config_size = config_end - image->config_addr ; } exit: return return_value; }