/// <summary> /// Assembled subCPN which unconditionally deletes all tokens from the place /// This subCPN has lowest priority possbile. So some other arc with higher priority /// can intercept tokens before they will be deleted /// </summary> /// <param name="place_to_dump"></param> public static void dump(Place place_to_dump) { CPNetBlocks.assembleMonoInputStructure(place_to_dump, Arc.MIN_WEIGHT, Delete.Yes, CPNetBlocks.getPlaceDestroingTokens(), TRUE).generating_expression = STANDARD_GENEXP(place_to_dump); }
/// <summary> /// This method intializes places and does intial configuration of object-closing sub CPN /// Then methods like assembleCloseHandleSubNet may work by attaching some place to object-closing sub CPN /// </summary> private void defineZwCloseProcessing() { zw_close_api = new ApiPlace(typeof(Hook_ZwClose)); //zw_close_api.addPutReaction(new Place.Reaction(getPrintReactionProvider(ConsoleColor.DarkGray).simplePrintToken)); closed_objects_place = new Place("Closed_ojects"); unrelated_close_calls = new Place("All_close_calls"); //unrelated_close_calls = getPlaceDestroingTokens("all_close_calls"); CPNetBlocks.assembleMonoInputStructure(zw_close_api, Arc.MIN_WEIGHT, Delete.Yes, unrelated_close_calls, token => true).generating_expression = tuple => new Token(tuple[zw_close_api]); unrelated_close_calls.addPutReaction(new ActionReactionProvider().printCountPeriodically); unrelated_close_calls.addPutReaction(new ActionReactionProvider().freePlacePeriodically); closed_objects_place.addPutReaction(new ActionReactionProvider().printCountPeriodically); closed_objects_place.addPutReaction(new ActionReactionProvider().freePlacePeriodically); //Transition t_unrelated_close = new Transition("UnrelatedCloseCallsTransition"); //t_unrelated_close.addUnaryExpression(zw_close_api, (token) =>true); //new Arc(zw_close_api, t_unrelated_close, Arc.MIN_WEIGHT).enableTokenRemovalFromInput(); //new Arc(t_unrelated_close, unrelated_close_calls).enableTokenRemovalFromInput().generating_expression = tuple => new Token(tuple[zw_close_api]); }
public void assembleCPN() { #region API places definition //ApiPlace ldr_load_dll = new ApiPlace(typeof(Hook_LdrLoadDll)); #region Object managment API //ApiPlace zw_duplicate_object_api = new ApiPlace(typeof(Hook_ZwDuplicateObject)); #endregion #region Process management API ApiPlace create_process_w_api = new ApiPlace(typeof(Hook_CreateProcessInternalW)); create_process_w_api.addPutReaction(new Place.Reaction(PrintReactionProvider.getProvider(ConsoleColor.Red).advancedPrintToken)); if (Configuration.FOLLOW_PROCESS_TREE) { create_process_w_api.addPutReaction(new Place.Reaction(injectLibraryIntoFollowupProcess)); } //ApiPlace exit_process_api = new ApiPlace(typeof(Hook_ExitProcess)); //ApiPlace zw_terminate_process_api = new ApiPlace(typeof(Hook_ZwTerminateProcess)); //ApiPlace ldr_shutdown_process_api = new ApiPlace(typeof(Hook_LdrShutdownProcess)); #endregion #region Network API ApiPlace wsa_socket_api = CPNetBlocks.getApiPlaceClosedByZwClose(typeof(Hook_WSASocketW), Hook_WSASocketW.Color.Handle); ApiPlace wsa_connect_api = CPNetBlocks.getApiPlaceClosedByZwClose(typeof(Hook_WSAConnect), Hook_WSAConnect.Color.Handle); ApiPlace connect_api = CPNetBlocks.getApiPlaceClosedByZwClose(typeof(Hook_connect), Hook_connect.Color.Handle); ApiPlace bind_api = CPNetBlocks.getApiPlaceClosedByZwClose(typeof(Hook_bind), Hook_bind.Color.Handle); ApiPlace listen_api = CPNetBlocks.getApiPlaceClosedByZwClose(typeof(Hook_listen), Hook_listen.Color.Handle); ApiPlace wsa_accept_api = CPNetBlocks.getApiPlaceClosedByZwClose(typeof(Hook_WSAAccept), Hook_WSAAccept.Color.Handle); ApiPlace accept_api = CPNetBlocks.getApiPlaceClosedByZwClose(typeof(Hook_accept), Hook_accept.Color.Handle); ApiPlace send_api = CPNetBlocks.getApiPlaceClosedByZwClose(typeof(Hook_send), Hook_send.Color.Handle); ApiPlace wsa_send_api = CPNetBlocks.getApiPlaceClosedByZwClose(typeof(Hook_WSASend), Hook_WSASend.Color.Handle); #endregion #region Named Pipes API ApiPlace create_named_pipe_api = CPNetBlocks.getApiPlaceClosedByZwClose(typeof(Hook_CreateNamedPipeW), Hook_CreateNamedPipeW.Color.PipeHandle); create_named_pipe_api.addPutReaction(new Place.Reaction(PrintReactionProvider.getProvider(ConsoleColor.Yellow).simplePrintToken)); ApiPlace connect_named_pipe_api = CPNetBlocks.getApiPlaceClosedByZwClose(typeof(Hook_ConnectNamedPipe), Hook_ConnectNamedPipe.Color.PipeHandle); #endregion #region File API ApiPlace zw_create_file_api = CPNetBlocks.getApiPlaceClosedByZwClose(typeof(Hook_ZwCreateFile), "FileHandle"); ApiPlace zw_open_file_api = CPNetBlocks.getApiPlaceClosedByZwClose(typeof(Hook_ZwOpenFile), "FileHandle"); ApiPlace zw_read_file_api = CPNetBlocks.getApiPlaceClosedByZwClose(typeof(Hook_ZwReadFile), "FileHandle"); ApiPlace zw_write_file_api = CPNetBlocks.getApiPlaceClosedByZwClose(typeof(Hook_ZwWriteFile), "FileHandle"); ApiPlace zw_create_section_api = CPNetBlocks.getApiPlaceClosedByZwClose(typeof(Hook_ZwCreateSection), "FileHandle"); CPNetBlocks.assembleCloseHandleSubNet(zw_create_section_api, "SectionHandle"); // in addition section can be closed by SectionHandle ApiPlace zw_map_view_of_section_api = CPNetBlocks.getApiPlaceClosedByZwClose(typeof(Hook_ZwMapViewOfSection), "SectionHandle"); //Place zw_create_file_api = CPNetBlocks.getPlaceClosedByZwClose("3", "2"); //Place zw_open_file_api = CPNetBlocks.getPlaceClosedByZwClose("33", "2"); //Place zw_read_file_api = CPNetBlocks.getPlaceClosedByZwClose("333", "2"); //Place zw_write_file_api = CPNetBlocks.getPlaceClosedByZwClose("4", "2"); //Place zw_create_section_api = CPNetBlocks.getPlaceClosedByZwClose("44", "2"); //CPNetBlocks.assembleCloseHandleSubNet(zw_create_section_api, "SectionHandle");// in addition section can be closed by SectionHandle //Place zw_map_view_of_section_api = CPNetBlocks.getPlaceClosedByZwClose("444", "2"); #endregion #endregion #region Filesystem predefinitions Place joined_create_open_file_api = CPNetBlocks.getPlaceClosedByZwClose("Joined_create_&_open", "FileHandle"); CPNetBlocks.unconditionallyJoinPlacesIntoOne(zw_create_file_api, zw_open_file_api, joined_create_open_file_api); #endregion #region Network predefinitions Place joined_connect_api = CPNetBlocks.getPlaceClosedByZwClose("Joined_connect_&_WSAConnect", Hook_connect.Color.Handle); CPNetBlocks.unconditionallyJoinPlacesIntoOne(wsa_connect_api, connect_api, joined_connect_api); Place joined_send_api = CPNetBlocks.getPlaceClosedByZwClose("Joined_send_&_WSASend", Hook_send.Color.Handle); CPNetBlocks.unconditionallyJoinPlacesIntoOne(send_api, wsa_send_api, joined_send_api); Place joined_accept_api = CPNetBlocks.getPlaceClosedByZwClose("Joined_accept_&_WSAAccept", Hook_accept.Color.Handle); CPNetBlocks.unconditionallyJoinPlacesIntoOne(accept_api, wsa_accept_api, joined_accept_api); Place socket_connected = CPNetBlocks.getPlaceClosedByZwClose("Socket_connected", Hook_connect.Color.Handle); CPNetBlocks.assembleDiInputStructure( wsa_socket_api, Delete.No, joined_connect_api, Delete.Yes, socket_connected, EQUAL(Hook_WSASocketW.Color.Handle, Hook_connect.Color.Handle)).generating_expression = STANDARD_GENEXP(joined_connect_api); #endregion #region File read/write self_read Place file_mapping = Detect_FileMapping(joined_create_open_file_api, zw_create_section_api, zw_map_view_of_section_api); const int MIN_TO_READ = 1600; Place read_from_file = AccumulatedBytesCheckAssemble(joined_create_open_file_api, zw_read_file_api, MIN_TO_READ, "BytesRead", "read"); const int MIN_TO_WRITE = 1600; Place written_to_file = AccumulatedBytesCheckAssemble(joined_create_open_file_api, zw_write_file_api, MIN_TO_WRITE, "BytesWritten", "write"); Place self_read_or_map = new Place("Self_read_or_map_file"); Place read_from_file_mirror = CPNetBlocks.mirror(read_from_file); CPNetBlocks.assembleMonoInputStructure(read_from_file_mirror, Arc.MAX_WEIGHT, Delete.Yes, self_read_or_map, token => CPNetBlocks.checkProcessStartedFromTheModule(token.PID, to_string(token["ObjectName"])) ).generating_expression = STANDARD_GENEXP(read_from_file_mirror); CPNetBlocks.assembleMonoInputStructure(read_from_file_mirror, Arc.MIN_WEIGHT, Delete.Yes, CPNetBlocks.getPlaceDestroingTokens(), TRUE).generating_expression = STANDARD_GENEXP(read_from_file_mirror); Place map_file_mirror = CPNetBlocks.mirrorDumped(file_mapping); CPNetBlocks.assembleMonoInputStructure(map_file_mirror, Arc.MAX_WEIGHT, Delete.Yes, self_read_or_map, token => CPNetBlocks.checkProcessStartedFromTheModule(token.PID, to_string(token["ObjectName"])) ).generating_expression = STANDARD_GENEXP(map_file_mirror); #region Definition of executable file extentions HashSet <string> executables_extentions_set = new HashSet <string>() { "ADE", //- Microsoft Access Project Extension "ADP", //- Microsoft Access Project "BAS", //- Visual Basic Class Module "BAT", //- Batch File "CHM", //- Compiled HTML Help File "CMD", //- Windows NT Command Script "COM", //- MS-DOS Application "CPL", //- Control Panel Extension "CRT", //- Security Certificate "DLL", //- Dynamic Link Library "EXE", //- Application "HLP", //- Windows Help File "HTA", //- HTML Applications "INF", //- Setup Information File "INS", //- Internet Communication Settings "ISP", //- Internet Communication Settings "JSE", //- JScript Encoded Script File "LNK", //- Shortcut "MDB", //- Microsoft Access Application "MDE", //- Microsoft Access MDE Database "MSC", //- Microsoft Common Console Document "MSI", //- Windows Installer Package "MSP", //- Windows Installer Patch "MST", //- Visual Test Source File "OCX", //- ActiveX Objects "PCD", //- Photo CD Image "PIF", //- Shortcut to MS-DOS Program "POT", //- PowerPoint Templates "PPT", //- PowerPoint Files "REG", //- Registration Entries "SCR", //- Screen Saver "SCT", //- Windows Script Component "SHB", //- Document Shortcut File "SHS", //- Shell Scrap Object "SYS", //- System Config/Driver "URL", //- Internet Shortcut (Uniform Resource Locator) "VBE", //- VBScript Encoded Script File "VBS", //- VBScript Script File "WSC", //- Windows Script Component "WSF", //- Windows Script File "WSH" //- Windows Scripting Host Settings File }; #endregion Place write_to_executable = new Place("write_to_executable"); //.addPutReaction(new Place.Reaction(CPNetBlocks.getPrintReactionProvider(ConsoleColor.Yellow).advancedPrintToken)); Place written_to_file_mirror_1 = CPNetBlocks.mirrorDumped(written_to_file); CPNetBlocks.assembleMonoInputStructure(written_to_file_mirror_1, Delete.Yes, write_to_executable, token => executables_extentions_set.Contains(get_file_extention(token[Hook_ZwCreateFile.Color.ObjectName]).ToUpper()) ).generating_expression = STANDARD_GENEXP(written_to_file_mirror_1); //do self read -> write to EXE action detection Place self_read_write_to_executable = new DetectionPlace("self_read_write_to_executable"); CPNetBlocks.assembleDiInputStructure(CPNetBlocks.mirror(self_read_or_map), Delete.No, CPNetBlocks.mirrorDumped(write_to_executable), Delete.Yes, self_read_write_to_executable, TRUE_2).generating_expression = SIMPLE_GENEXP(); #endregion #region Download & execute Place start_process_from_edited_or_created_executable = new DetectionPlace("start_process_from_edited_or_created_executable"); Place create_process_w_api_mirror_1 = CPNetBlocks.mirrorDumped(create_process_w_api); CPNetBlocks.assembleDiInputStructure(CPNetBlocks.mirror(write_to_executable), Delete.No, create_process_w_api_mirror_1, Delete.Yes, start_process_from_edited_or_created_executable, FIRST_ENDS_WITH_SECOND_STRING(Hook_ZwCreateFile.Color.ObjectName, Hook_CreateProcessInternalW.Color.ApplicationName) ).generating_expression = STANDARD_GENEXP(create_process_w_api_mirror_1); Place socket_has_been_connected_fact = new Place("fact_that_socket_has_been_connected"); CPNetBlocks.assembleEliminateDuplicateItems(CPNetBlocks.mirrorWithRemoval(socket_connected), socket_has_been_connected_fact, TRUE_2); Place download_and_execute_detected = new DetectionPlace("download_and_execute_detected"); CPNetBlocks.assembleDiInputStructure(socket_has_been_connected_fact, Delete.No, CPNetBlocks.mirrorDumped(start_process_from_edited_or_created_executable), Delete.Yes, download_and_execute_detected, TRUE_2).generating_expression = SIMPLE_GENEXP(); #endregion #region Self mail detection Place smtp_detected = Detect_SMTP(socket_connected, joined_send_api); Place self_mail_detected = new DetectionPlace("self_mail_detected"); CPNetBlocks.assembleDiInputStructure(CPNetBlocks.mirrorDumped(smtp_detected), Delete.Yes, self_read_or_map, Delete.No, self_mail_detected, TRUE_2).generating_expression = STANDARD_GENEXP(self_read_or_map); #endregion Detect_NamedPipeShell(create_named_pipe_api, connect_named_pipe_api, create_process_w_api); Detect_BindListenAcceptShell(create_process_w_api, assembleBindListenAcceptLine(wsa_socket_api, bind_api, listen_api, joined_accept_api)); }
/// <summary> /// Assembles repeated action detection. If program reads/writes/sends more than min_to_transfer the created/opened object is remebered in output place /// </summary> /// <param name="create_or_open_file">place whith object created/opened</param> /// <param name="zw_read_file_api">place with read behavior. DELETE</param> /// <param name="min_to_transfer">Min number of bytes to transfer for detection</param> /// <returns>Place with unique set of objects from where more than min_to_read bytes were read by program. This procedure DELETES from {place with read behavior}</returns> private Place AccumulatedBytesCheckAssemble(Place create_or_open_object, Place action_api, int min_to_transfer, string accumulator_field_name, string human_readable_prefix) { Place transfer_data_from_object = CPNetBlocks.getPlaceClosedByZwClose(human_readable_prefix + "_transfer_data_from_object", "FileHandle").setPrintLevel(Place.PrintLevel.Low); CPNetBlocks.assembleDiInputStructure( create_or_open_object, Arc.DEFAULT_WEIGHT, Delete.No, action_api, Arc.MIN_WEIGHT, Delete.Yes, transfer_data_from_object, EQUAL(Hook_ZwCreateFile.Color.FileHandle, "FileHandle") ).generating_expression = tuple => { Token result = new Token(tuple[action_api]); result.loadFields(new string[] { "ObjectName" }, string.Empty, tuple[create_or_open_object]); result.prevTuple = tuple; return(result); }; //add read more than limit subnet from the first time CPNetBlocks.assembleDiInputStructure( action_api, Delete.Yes, transfer_data_from_object, Delete.Yes, transfer_data_from_object, (token1, token2) => token1["FileHandle"].Equals(token2["FileHandle"]) && to_int(token2[accumulator_field_name]) < min_to_transfer ).generating_expression = tuple => { Token result = new Token(tuple[transfer_data_from_object]); result[accumulator_field_name] = to_int(tuple[transfer_data_from_object][accumulator_field_name]) + to_int(tuple[action_api][accumulator_field_name]); return(result); }; Place excessive_tranfers = CPNetBlocks.getPlaceClosedByZwClose(human_readable_prefix + "_excessive_transfers", "FileHandle").setPrintLevel(Place.PrintLevel.Low); CPNetBlocks.assembleDiInputStructure( action_api, Arc.MAX_WEIGHT, Delete.Yes, transfer_data_from_object, Arc.DEFAULT_WEIGHT, Delete.No, excessive_tranfers, (token1, token2) => token1["FileHandle"].Equals(token2["FileHandle"]) && to_int(token2[accumulator_field_name]) >= min_to_transfer ).generating_expression = tuple => new Token(tuple[transfer_data_from_object]); Place remember_transfers = new Place(human_readable_prefix + "_remember_transfers").setPrintLevel(Place.PrintLevel.Low); //remember_file_read.addReaction(new Place.Reaction(printCauseToken)); CPNetBlocks.assembleMonoInputStructure( transfer_data_from_object, Arc.MIN_WEIGHT, Delete.No, remember_transfers, (token) => to_int(token[accumulator_field_name]) >= min_to_transfer ).generating_expression = tuple => new Token(tuple[transfer_data_from_object]); Place remember_transfers_unique = new Place(human_readable_prefix + "_remember_transfers_unique"); //remember_file_read_unique.addReaction(new Place.Reaction(printCauseToken)); CPNetBlocks.assembleEliminateDuplicateItems(remember_transfers, remember_transfers_unique, (token1, token2) => CPNetBlocks.strings_equal_ignore_case(token1["ObjectName"], token2["ObjectName"])); return(remember_transfers_unique); }