static PyObject* binding_invoke(PyObject* self, PyObject* args) { dprintf("[PYTHON] a function was invoked on: %s", self->ob_type->tp_name); const char* packetBytes = NULL; BOOL isLocal = FALSE; Py_ssize_t packetLength = 0; PyArg_ParseTuple(args, "is#", &isLocal, &packetBytes, &packetLength); dprintf("[PYTHON] packet %p is %u bytes and is %s", packetBytes, packetLength, isLocal ? "local" : "not local"); Packet packet = { 0 }; packet.header = *(PacketHeader*)packetBytes; packet.payload = (PUCHAR)(packetBytes + sizeof(PacketHeader)); packet.payloadLength = (ULONG)packetLength - sizeof(PacketHeader); // If the functionality doesn't require interaction with MSF, then // make the packet as local so that the packet receives the request // and so that the packet doesn't get sent to Meterpreter packet.local = isLocal; command_handle(gRemote, &packet); // really not sure how to deal with the non-local responses at this point. if (packet.partner == NULL) { // "None" return Py_BuildValue(""); } PyObject* result = PyString_FromStringAndSize(packet.partner->payload, packet.partner->payloadLength); packet_destroy(packet.partner); return result; }
/*! * @brief The servers main dispatch loop for incoming requests using SSL over TCP * @param remote Pointer to the remote endpoint for this server connection. * @returns Indication of success or failure. */ static BOOL server_dispatch_tcp(Remote * remote, THREAD* dispatchThread) { BOOL running = TRUE; LONG result = ERROR_SUCCESS; Packet *packet = NULL; THREAD *cpt = NULL; dprintf("[DISPATCH] entering server_dispatch( 0x%08X )", remote); // Bring up the scheduler subsystem. result = scheduler_initialize(remote); if (result != ERROR_SUCCESS) { return result; } while (running) { if (event_poll(dispatchThread->sigterm, 0)) { dprintf("[DISPATCH] server dispatch thread signaled to terminate..."); break; } result = server_socket_poll(remote, 500000); if (result > 0) { result = packet_receive_via_ssl(remote, &packet); if (result != ERROR_SUCCESS) { dprintf("[DISPATCH] packet_receive returned %d, exiting dispatcher...", result); break; } running = command_handle(remote, packet); dprintf("[DISPATCH] command_process result: %s", (running ? "continue" : "stop")); } else if (result < 0) { dprintf("[DISPATCH] server_socket_poll returned %d, exiting dispatcher...", result); break; } } dprintf("[DISPATCH] calling scheduler_destroy...") scheduler_destroy(); dprintf("[DISPATCH] calling command_join_threads...") command_join_threads(); dprintf("[DISPATCH] leaving server_dispatch."); return result; }
/*! * @brief The servers main NP DISPATCH loop for incoming requests using SSL over named pipes. * @param remote Pointer to the remote endpoint for this server connection. * @param dispatchThread Pointer to the main NP DISPATCH thread. * @returns Indication of success or failure. */ static DWORD server_dispatch_named_pipe(Remote* remote, THREAD* dispatchThread) { Transport* transport = remote->transport; BOOL running = TRUE; LONG result = ERROR_SUCCESS; Packet * packet = NULL; THREAD * cpt = NULL; dprintf("[NP DISPATCH] entering server_dispatch( 0x%08X )", remote); int lastPacket = current_unix_timestamp(); while (running) { if (event_poll(dispatchThread->sigterm, 0)) { dprintf("[NP DISPATCH] server dispatch thread signaled to terminate..."); break; } result = server_pipe_poll(remote, 500); if (result == ERROR_SUCCESS) { result = packet_receive_named_pipe(remote, &packet); if (result != ERROR_SUCCESS) { dprintf("[NP DISPATCH] packet_receive returned %d, exiting dispatcher...", result); break; } if (packet) { running = command_handle(remote, packet); dprintf("[NP DISPATCH] command_process result: %s", (running ? "continue" : "stop")); } else { dprintf("[NP DISPATCH] Received NULL packet, could be metsrv being ignored"); } // packet received, reset the timer lastPacket = current_unix_timestamp(); } else if (result != ERROR_BROKEN_PIPE) { // check if the communication has timed out, or the session has expired, so we should terminate the session int now = current_unix_timestamp(); if (now > remote->sess_expiry_end) { result = ERROR_SUCCESS; dprintf("[NP DISPATCH] session has ended"); break; } else if ((now - lastPacket) > transport->timeouts.comms) { result = ERROR_NETWORK_NOT_AVAILABLE; dprintf("[NP DISPATCH] communications has timed out"); break; } } else { dprintf("[NP DISPATCH] server_pipe_poll returned %d, exiting dispatcher...", result); break; } } dprintf("[NP DISPATCH] leaving server_dispatch."); return result; }
int main(void) { // struct socket_type get_sockettype; u8 i = 0; u8 last_state = 0; init_all(); module_discriminate(); module_config(); relay_all = 0; relay_splithex(0x00); relay_all = 1; delay_ms(200); relay_all = 0; select_port(); while (1) { if(g_ms==4000) { relay_splithex( array_hex()); i=0; g_ms=0; } if (key3 == 0) { g_ms=0; if ( get_sockettype.select_array[i][0] == 1) { sigelarray_init(); if (temp_sigelarry[i] != 1) { temp_sigelarry[i] = 1; } else { temp_sigelarry[i] = 0; } relay_splithex( sigelarry_hex()); do { i++; } while (get_sockettype.select_array[i][0] != 1); while (key3 == 0); if (i >= 8) i = 0; } } if (key1 == 0) { doublearry_init(); relay_splithex( array_hex()); relay_all = 1; while (key3 == 0); relay_all = 0; } command_handle(); } }
/*! * @brief The servers main dispatch loop for incoming requests using HTTP(S). * @param remote Pointer to the remote endpoint for this server connection. * @param dispatchThread Pointer to the main dispatch thread. * @returns Indication of success or failure. */ static DWORD server_dispatch_http(Remote* remote, THREAD* dispatchThread) { BOOL running = TRUE; LONG result = ERROR_SUCCESS; Packet* packet = NULL; THREAD* cpt = NULL; DWORD ecount = 0; DWORD delay = 0; Transport* transport = remote->transport; HttpTransportContext* ctx = (HttpTransportContext*)transport->ctx; while (running) { if (transport->timeouts.comms != 0 && transport->comms_last_packet + transport->timeouts.comms < current_unix_timestamp()) { dprintf("[DISPATCH] Shutting down server due to communication timeout"); break; } if (remote->sess_expiry_end != 0 && remote->sess_expiry_end < current_unix_timestamp()) { dprintf("[DISPATCH] Shutting down server due to hardcoded expiration time"); dprintf("Timestamp: %u Expiration: %u", current_unix_timestamp(), remote->sess_expiry_end); break; } if (event_poll(dispatchThread->sigterm, 0)) { dprintf("[DISPATCH] server dispatch thread signaled to terminate..."); break; } dprintf("[DISPATCH] Reading data from the remote side..."); result = packet_receive_http(remote, &packet); if (result != ERROR_SUCCESS) { // Update the timestamp for empty replies if (result == ERROR_EMPTY) { transport->comms_last_packet = current_unix_timestamp(); } else if (result == ERROR_WINHTTP_CANNOT_CONNECT) { dprintf("[DISPATCH] Failed to work correctly with WinHTTP, moving over to WinINET"); // next we need to indicate that we need to do a switch to wininet when we terminate ctx->move_to_wininet = TRUE; // and pretend to do a transport switch, to ourselves! remote->next_transport = remote->transport; result = ERROR_SUCCESS; break; } else if (result == ERROR_WINHTTP_SECURE_INVALID_CERT) { // This means that the certificate validation failed, and so // we don't trust who we're connecting with, so we need to move // on to another transport. // If we're the only transport, then we should wait for the allotted // time before trying again. Otherwise, we can just switch immediately. // This avoids spinning the process and making way too many requests // in a short period of time (ie. avoiding noise). if (remote->transport == remote->transport->next_transport) { remote->next_transport_wait = remote->transport->timeouts.retry_wait; } break; } else if (result == ERROR_BAD_CONFIGURATION) { // something went wrong with WinINET so break. break; } delay = 10 * ecount; if (ecount >= 10) { delay *= 10; } ecount++; dprintf("[DISPATCH] no pending packets, sleeping for %dms...", min(10000, delay)); Sleep(min(10000, delay)); } else { transport->comms_last_packet = current_unix_timestamp(); // Reset the empty count when we receive a packet ecount = 0; dprintf("[DISPATCH] Returned result: %d", result); if (packet != NULL) { running = command_handle(remote, packet); dprintf("[DISPATCH] command_process result: %s", (running ? "continue" : "stop")); if (ctx->new_uri != NULL) { dprintf("[DISPATCH] Recieved hot-patched URL for stageless: %S", ctx->new_uri); dprintf("[DISPATCH] Old URI is: %S", ctx->uri); dprintf("[DISPATCH] Old URL is: %S", transport->url); // if the new URI needs more space, let's realloc space for the new URL now int diff = (int)wcslen(ctx->new_uri) - (int)wcslen(ctx->uri); if (diff > 0) { dprintf("[DISPATCH] New URI is bigger by %d", diff); transport->url = (wchar_t*)realloc(transport->url, (wcslen(transport->url) + diff + 1) * sizeof(wchar_t)); } // we also need to patch the new URI into the original transport URL, not just the currently // active URI for comms. If we don't, then migration behaves badly. // The URL looks like this: http(s)://<domain-or-ip>:port/lurivalue/UUIDJUNK/ // Start by locating the start of the URI in the current URL, by finding the third slash, // as this value includes the LURI wchar_t* csr = transport->url; for (int i = 0; i < 3; ++i) { // We need to move to the next character first in case // we are currently pointing at the previously found / // we know we're safe skipping the first character in the whole // URL because that'll be part of the scheme (ie. 'h' in http) ++csr; while (*csr != L'\0' && *csr != L'/') { ++csr; } dprintf("[DISPATCH] %d csr: %p -> %S", i, csr, csr); // this shouldn't happen! if (*csr == L'\0') { break; } } // the pointer that we have will be dprintf("[DISPATCH] Pointer is at: %p -> %S", csr, csr); // patch in the new URI wcscpy_s(csr, wcslen(diff > 0 ? ctx->new_uri : ctx->uri) + 1, ctx->new_uri); dprintf("[DISPATCH] New URL is: %S", transport->url); // clean up SAFE_FREE(ctx->uri); ctx->uri = ctx->new_uri; ctx->new_uri = NULL; } } else { dprintf("[DISPATCH] Packet was NULL, this indicates that it was a pivot packet"); } } } return result; }
void console_tick (void) { if (!HEADLESS && !enable_console) { return; } #ifndef _WIN32 char seq[2]; char seq2[2]; char c; console_refresh(); /* * Read nonblocking to get chars. */ int fd = STDIN_FILENO; int flags = fcntl(fd, F_GETFL, 0); size_t nread; fcntl(fd, F_SETFL, flags | O_NONBLOCK); nread = read(fd,&c,1); fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); if (nread <= 0) { return; } char beforecursor[MAXSTR]; char updatedtext[MAXSTR]; char aftercursor[MAXSTR]; char entered[MAXSTR]; char newchar[2]; int origlen; int cnt; newchar[0] = '\0'; newchar[0] = c; origlen = (uint32_t)strlen(wid_text); strlcpy(beforecursor, wid_text, cursor_x + 1); strlcpy(aftercursor, wid_text + cursor_x, sizeof(aftercursor)); switch (c) { case '': if (!history_walk) { history_walk = HISTORY_MAX - 1; } else { history_walk--; } console_set_text(history[history_walk]); cursor_x = (uint32_t)strlen(console_get_text()); break; case '': history_walk++; if (history_walk >= HISTORY_MAX) { history_walk = 0; } console_set_text(history[history_walk]); cursor_x = (uint32_t)strlen(console_get_text()); break; case '': cursor_x = 0; break; case '': cursor_x = origlen; break; case '': case '': if (cursor_x > 0) { strlcpy(updatedtext, beforecursor, cursor_x); strlcat(updatedtext, aftercursor, sizeof(updatedtext)); cursor_x--; console_set_text(updatedtext); } break; case '\t': updatedtext[0] = '\0'; command_handle(console_get_text(), updatedtext, false /* show ambiguous */, true /* show complete */, false /* execute command */, 0 /* context */); if (updatedtext[0]) { console_set_text(updatedtext); cursor_x = (uint32_t)strlen(updatedtext);; } return; case '\n': case '\r': if (origlen) { strlcpy(entered, console_get_text(), sizeof(entered)); if (!command_handle(entered, updatedtext, true /* show ambiguous */, false /* show complete */, true /* execute command */, 0 /* context */)) { return; } if (updatedtext[0]) { console_set_text(updatedtext); cursor_x = (uint32_t)strlen(updatedtext);; } strlcpy(history[history_at], updatedtext, sizeof(history[history_at])); history_at++; if (history_at >= HISTORY_MAX) { history_at = 0; } history_walk = history_at; console_set_text(""); cursor_x = 0; } else { CON(" "); } return; case 27: /* escape sequence */ if (read(fd,seq,2) == -1) break; if (seq[0] == 91 && seq[1] == 68) { if (cursor_x > 0) { cursor_x--; } } else if (seq[0] == 91 && seq[1] == 67) { if (cursor_x < origlen) { cursor_x++; } } else if (seq[0] == 91 && (seq[1] == 65 || seq[1] == 66)) { /* Up and Down arrows */ if (seq[1] == 65) { cnt = 0; while (cnt < HISTORY_MAX) { cnt++; if (!history_walk) { history_walk = HISTORY_MAX - 1; } else { history_walk--; } console_set_text(history[history_walk]); if (!history[history_walk][0]) { continue; } cursor_x = (uint32_t)strlen(console_get_text()); break; } break; } else { cnt = 0; while (cnt < HISTORY_MAX) { cnt++; history_walk++; if (history_walk >= HISTORY_MAX) { history_walk = 0; } console_set_text(history[history_walk]); if (!history[history_walk][0]) { continue; } cursor_x = (uint32_t)strlen(console_get_text()); break; } break; } } else if (seq[0] == 91 && seq[1] > 48 && seq[1] < 55) { /* extended escape, read additional two bytes. */ if (read(fd,seq2,2) == -1) break; if (seq[1] == 51 && seq2[0] == 126) { /* Delete key. */ if (cursor_x > 0) { strlcpy(updatedtext, beforecursor, cursor_x); strlcat(updatedtext, aftercursor, sizeof(updatedtext)); cursor_x--; console_set_text(updatedtext); } break; } } break; case '?': updatedtext[0] = '\0'; command_handle(console_get_text(), updatedtext, true /* show ambiguous */, false /* show complete */, false /* execute command */, 0 /* context */); if (updatedtext[0]) { console_set_text(updatedtext); cursor_x = (uint32_t)strlen(updatedtext);; } return; default: { if (origlen >= (typeof(origlen)) sizeof(updatedtext) - 1) { break; } newchar[1] = '\0'; newchar[0] = c; if (!newchar[0]) { break; } strlcpy(updatedtext, beforecursor, cursor_x + 1); strlcat(updatedtext, newchar, sizeof(updatedtext)); strlcat(updatedtext, aftercursor, sizeof(updatedtext)); cursor_x++; console_set_text(updatedtext); } } #endif }
void mainloop(void) { /* * This is the main program loop. Here's where we're doing all the * spawning and the checking. This is the heart of the program. */ int exitcode, status, command = CMD_OK, event = EV_AOK; while (1) { event = event_check(); command = command_check(); command_handle(command, pid); if (command == CMD_OK && event == EV_AOK) pid = fork(); else pid = -2; switch (pid) { case 0: /* we are the child */ vbprintf("(child) Executing %s in work directory %s\n" ,cmd, workdir); chdir(workdir); logging_rotate(); logging_init(); exitcode = execl(cmd, cmd, args, (char *)NULL); if (exitcode < 0) { perror("execl"); } exit(exitcode); break; case -1: /* error */ err(EX_OSERR, "Couldn't fork: "); break; case -2: /* stop */ vbprintf("Not reforking. Waiting %d seconds\n", delay); sleep(delay); break; default: /* we are the parent */ vbprintf("(parent) Forked process with pid %d\n", pid); while (waitpid(pid, &status, WNOHANG) == 0) { /* Do something while child is running */ dbprintf("Waiting for child (%d) to terminate\n", pid); running = TRUE; command = command_check(); command_handle(command, pid); sleep(delay); } /* if we get here, the child process must have died */ running = FALSE; command = command_check(); command_handle(command, pid); break; } if (command == CMD_STOP) { struct stat st; /* check if HALTFILE still exists */ chdir(workdir); if (stat(HALTFILE, &st) < 0) { vbprintf("Haltfile gone. Resuming...\n"); command = CMD_OK; } if (event == EV_AOK) { vbprintf("Event over. Resuming...\n"); command = CMD_OK; } } } return; }
DWORD server_dispatch_http_winhttp(Remote* remote, THREAD* dispatchThread) { BOOL running = TRUE; LONG result = ERROR_SUCCESS; Packet* packet = NULL; THREAD* cpt = NULL; DWORD ecount = 0; DWORD delay = 0; HttpTransportContext* ctx = (HttpTransportContext*)remote->transport->ctx; while (running) { if (ctx->comm_timeout != 0 && ctx->comm_last_packet + ctx->comm_timeout < current_unix_timestamp()) { dprintf("[DISPATCH] Shutting down server due to communication timeout"); break; } if (ctx->expiration_time != 0 && ctx->expiration_time < current_unix_timestamp()) { dprintf("[DISPATCH] Shutting down server due to hardcoded expiration time"); dprintf("Timestamp: %u Expiration: %u", current_unix_timestamp(), ctx->expiration_time); break; } if (event_poll(dispatchThread->sigterm, 0)) { dprintf("[DISPATCH] server dispatch thread signaled to terminate..."); break; } dprintf("[DISPATCH] Reading data from the remote side..."); result = packet_receive_via_http(remote, &packet); if (result != ERROR_SUCCESS) { // Update the timestamp for empty replies if (result == ERROR_EMPTY) { ctx->comm_last_packet = current_unix_timestamp(); } else if (result == ERROR_WINHTTP_SECURE_INVALID_CERT) { // This means that the certificate validation failed, and so // we don't trust who we're connecting with. Bail out. break; } if (ecount < 10) { delay = 10 * ecount; } else { delay = 100 * ecount; } ecount++; dprintf("[DISPATCH] no pending packets, sleeping for %dms...", min(10000, delay)); Sleep(min(10000, delay)); continue; } ctx->comm_last_packet = current_unix_timestamp(); // Reset the empty count when we receive a packet ecount = 0; dprintf("[DISPATCH] Returned result: %d", result); running = command_handle(remote, packet); dprintf("[DISPATCH] command_process result: %s", (running ? "continue" : "stop")); } return result; }
int main(int argc,char* argv[]){ //启动方法:./client "ip" "port" if(argc != 3){ printf("args error\n"); return -1; } int ret; int sockfd; sockfd = socket(AF_INET,SOCK_STREAM,0); if(sockfd == -1){ perror("socket"); return -1; } struct sockaddr_in addr; bzero(&addr,sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr(argv[1]); addr.sin_port = htons(atoi(argv[2])); ret = connect(sockfd,(struct sockaddr*)&addr,sizeof(struct sockaddr)); if(ret == -1){ perror("connect"); return -1; } char buf[128] = {0}; int epfd = epoll_create(1); if(epfd == -1){ perror("epoll_create"); return -1; } struct epoll_event event,evs[2]; event.events = EPOLLIN; event.data.fd = 0; ret = epoll_ctl(epfd,EPOLL_CTL_ADD,0,&event); if(ret == -1){ perror("epoll_ctl"); return -1; } event.events = EPOLLIN; event.data.fd = sockfd; ret = epoll_ctl(epfd,EPOLL_CTL_ADD,sockfd,&event); int i; int ret1; int len; while(1){ bzero(evs,sizeof(evs)); ret1 = epoll_wait(epfd,evs,2,-1); for(i = 0;i < ret1;i++){ if(evs[i].events == EPOLLIN && evs[i].data.fd == 0){ bzero(buf,sizeof(buf)); ret = read(0,buf,sizeof(buf)); if(ret == -1){ perror("read"); return -1; } ret = send(sockfd,buf,strlen(buf) - 1,0); if(ret == -1){ perror("send"); return -1; } command_handle(sockfd,buf); } if(evs[i].events == EPOLLIN && evs[i].data.fd == sockfd){ bzero(buf,sizeof(buf)); len=recv_msg(sockfd); if(len) recv_file(sockfd,len); } } } close(sockfd); return 0; }