private Place Detect_BindListenAcceptShell(Place create_process_w_api, Place accepted_sockets) { Place create_process_w_api_mirror = CPNetBlocks.mirror(create_process_w_api); Place socket_listen_accept_in_shell_detected = new Place("Socket_listen_accept_connected_to_stdin"); Place socket_listen_accept_out_shell_detected = new Place("Socket_listen_accept_connected_to_stdout"); Place bind_shell_via_listen_accept_detected = new DetectionPlace("Bind_shell_via_listen_accept_detected"); CPNetBlocks.assembleDiInputStructure(accepted_sockets, Delete.No, create_process_w_api_mirror, Delete.No, socket_listen_accept_in_shell_detected, EQUAL(Hook_WSAAccept.Color.Handle, Hook_CreateProcessInternalW.Color.StdInHandle) ).generating_expression = STANDARD_GENEXP(create_process_w_api_mirror); CPNetBlocks.assembleDiInputStructure(accepted_sockets, Delete.No, create_process_w_api_mirror, Delete.No, socket_listen_accept_out_shell_detected, EQUAL(Hook_WSAAccept.Color.Handle, Hook_CreateProcessInternalW.Color.StdOutHandle) ).generating_expression = STANDARD_GENEXP(create_process_w_api_mirror); CPNetBlocks.assembleDiInputStructure(socket_listen_accept_in_shell_detected, Delete.Yes, socket_listen_accept_out_shell_detected, Delete.Yes, bind_shell_via_listen_accept_detected, EQUAL(Hook_CreateProcessInternalW.Color.ProcessId, Hook_CreateProcessInternalW.Color.ProcessId) ).generating_expression = tuple => { Token result = new Token(); result.loadAllFields("In.", tuple[socket_listen_accept_in_shell_detected]); result.loadAllFields("Out.", tuple[socket_listen_accept_out_shell_detected]); //result.prevTuple = tuple; return(result); }; return(bind_shell_via_listen_accept_detected); }
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> /// Detects when two named pipes are created and attached to the input of the process. /// </summary> /// <param name="create_named_pipe_api">NO Delete</param> /// <param name="connect_named_pipe_api">Mirrored </param> /// <param name="create_process_w_api">Mirrored</param> private Place Detect_NamedPipeShell(Place create_named_pipe_api, Place connect_named_pipe_api, Place create_process_w_api) { Place pipe_connected = CPNetBlocks.getPlaceClosedByZwClose("Pipe_created_&_connected", Hook_CreateNamedPipeW.Color.PipeHandle); CPNetBlocks.assembleDiInputStructure(create_named_pipe_api, Delete.No, CPNetBlocks.mirrorWithRemoval(connect_named_pipe_api), Delete.Yes, pipe_connected, EQUAL(Hook_CreateNamedPipeW.Color.PipeHandle, Hook_ConnectNamedPipe.Color.PipeHandle) ).generating_expression = STANDARD_GENEXP(create_named_pipe_api); Place pipe_shell_in_detected = CPNetBlocks.getPlaceClosedByZwClose("Pipe_connnected_to_process_input_detected", Hook_CreateNamedPipeW.Color.PipeHandle); //pipe_shell_in_detected.addPutReaction(new Place.Reaction(CPNetBlocks.getPrintReactionProvider(ConsoleColor.Green).advancedPrintToken)); Place pipe_shell_out_detected = CPNetBlocks.getPlaceClosedByZwClose("Pipe_connnected_to_process_output_detected", Hook_CreateNamedPipeW.Color.PipeHandle); //pipe_shell_out_detected.addPutReaction(new Place.Reaction(CPNetBlocks.getPrintReactionProvider(ConsoleColor.Blue).advancedPrintToken)); Place create_process_w_api_mirror = CPNetBlocks.mirrorDumped(create_process_w_api); CPNetBlocks.assembleDiInputStructure(pipe_connected, Delete.No, create_process_w_api_mirror, Delete.No, pipe_shell_in_detected, EQUAL(Hook_CreateNamedPipeW.Color.PipeHandle, Hook_CreateProcessInternalW.Color.StdInHandle) ).generating_expression = tuple => { Token result = new Token(tuple[create_process_w_api_mirror]); result.loadFields(new string[] { Hook_CreateNamedPipeW.Color.PipeHandle }, string.Empty, tuple[pipe_connected]); result.prevTuple = tuple; return(result); }; CPNetBlocks.assembleDiInputStructure(pipe_connected, Delete.No, create_process_w_api_mirror, Delete.No, pipe_shell_out_detected, EQUAL(Hook_CreateNamedPipeW.Color.PipeHandle, Hook_CreateProcessInternalW.Color.StdOutHandle) ).generating_expression = tuple => { Token result = new Token(tuple[create_process_w_api_mirror]); result.loadFields(new string[] { Hook_CreateNamedPipeW.Color.PipeHandle }, string.Empty, tuple[pipe_connected]); result.prevTuple = tuple; return(result); }; Place bind_shell_via_named_pipes_detected = new DetectionPlace("Bind_shell_via_named_pipes_detected"); //Pipe shell is obvious when in and out std handles of a process are connected to pipes //so here we check that both std streams of a process are connected to pipes CPNetBlocks.assembleDiInputStructure(pipe_shell_in_detected, Delete.Yes, pipe_shell_out_detected, Delete.Yes, bind_shell_via_named_pipes_detected, EQUAL(Hook_CreateProcessInternalW.Color.ProcessId, Hook_CreateProcessInternalW.Color.ProcessId) ).generating_expression = tuple => { Token result = new Token(); result.loadAllFields("In.", tuple[pipe_shell_in_detected]); result.loadAllFields("Out.", tuple[pipe_shell_out_detected]); //result.prevTuple = tuple; return(result); }; return(bind_shell_via_named_pipes_detected); }