/** * Wrap the execution of the binary passed as argument * and inject it by its stdin. */ int main(int argc, char* argv[]) { int pid; pipe(pipe_in2out); pipe(pipe_out2in); pid = fork(); char* cmd = argv[1]; signal(SIGPIPE, handler); signal(SIGCHLD, handler); if(pid == 0) {// child fprintf(stderr, " [+] forked '%s'\n", cmd); close(pipe_in2out[0]); close(pipe_out2in[1]); // connect the stdout check_return_code("dup2", dup2(pipe_in2out[1], STDOUT_FILENO)); check_return_code("dup2", dup2(pipe_out2in[0], STDIN_FILENO)); if(execv(cmd, argv + 1) < 0) perror("execv"); } else if (pid == -1) { perror("fork()"); exit(1); } fprintf(stderr, " [+] just forked pid %d\n", pid); close(pipe_in2out[1]); close(pipe_out2in[0]); // first of all, read the banner from the vulnerable application char buffer[256]; int count = read(pipe_in2out[0], buffer, 24); buffer[count] = '\0'; fprintf(stderr, " [>] %s\n", buffer); fprintf(stderr, " [press RETURN key to continue] if you want to debug the injection attach it from gdb"); getchar(); char* input = prepare_paylod(pid); write_to_process(input, strlen(input)); free(input); count = read(pipe_in2out[0], buffer, 256); if (count <= 0) { perror("wriote()"); } buffer[count] = '\0'; fprintf(stderr, " [>] %s\n", buffer); return 0; }
file_descriptor connect(std::vector<ipv4_endpoint> const &endpoints, bool non_blocking) { log(utils::info) << "connecting to " << to_string(endpoints.front()) << "...\n"; file_descriptor fd{check_return_code(::socket(AF_INET, SOCK_STREAM, 0))}; if (non_blocking) make_non_blocking(fd); sockaddr_in address; address.sin_family = AF_INET; address.sin_addr.s_addr = endpoints.front().get_address().get_raw_address(); address.sin_port = endpoints.front().get_port_n(); int const code = ::connect(fd.get_raw_fd(), reinterpret_cast<sockaddr const *>(&address), sizeof address); if (errno != EINPROGRESS) check_return_code(code); return fd; }
int main(int argc, char **argv) { struct instance gi; global_context gc; int ret = 0; log_stderr_open(LOG_INFO); if (!get_options(argc, argv, &gi)) { print_usage(); exit(1); } if (gi.daemonize) { daemonize(NULL, GOLDY_DAEMON_USER); } if ((ret = global_init(&gi, &gc)) != 0) { printf("global initialization failed\n"); goto exit; } main_loop(&gc); exit: check_return_code(ret, "main - exit"); global_deinit(&gc); return ret == 0 ? 0 : 1; }
ipv4_endpoint get_socket_endpoint(file_descriptor const &fd) { sockaddr_in address; socklen_t tmp = sizeof address; check_return_code( getsockname(fd.get_raw_fd(), reinterpret_cast<sockaddr *>(&address), &tmp)); return make_ipv4_endpoint_n(address.sin_addr.s_addr, address.sin_port); }
client_socket server_socket::accept() { log(utils::info) << "accepting at " << fd_ << "...\n"; int new_fd = ::accept(fd_.get_raw_fd(), nullptr, nullptr); check_return_code(new_fd); client_socket accepted{file_descriptor{new_fd}}; return accepted; }
server_socket::server_socket(ipv4_endpoint endpoint) : server_socket{file_descriptor{check_return_code(::socket(AF_INET, SOCK_STREAM, 0))}} { log(utils::info) << "starting server at " << to_string(endpoint) << "\n"; int enable = 1; setsockopt(fd_.get_raw_fd(), SOL_SOCKET, SO_REUSEPORT, &enable, sizeof enable); struct sockaddr_in address; address.sin_family = AF_INET; address.sin_addr.s_addr = endpoint.get_address().get_raw_address(); address.sin_port = endpoint.get_port_n(); check_return_code( bind(fd_.get_raw_fd(), reinterpret_cast<sockaddr *>(&address), sizeof address)); check_return_code( listen(fd_.get_raw_fd(), SOMAXCONN)); }
void client_socket::assert_availability() { log(utils::info) << "asserting availability of " << fd_ << "\n"; int error = 0; socklen_t err_len = sizeof error; check_return_code( getsockopt(fd_.get_raw_fd(), SOL_SOCKET, SO_ERROR, static_cast<void *>(&error), &err_len)); if (error != 0) throw network_exception(strerror(errno)); }
size_t client_socket::write(utils::string_view const &str) { ssize_t written = ::send(fd_.get_raw_fd(), str.begin(), str.size(), MSG_NOSIGNAL); check_return_code(written); #ifdef CPP_NETWORK_SOCKET_DEBUG log(utils::verbose) << "written " << std::to_string(written) << " bytes to " << fd_ << "\n"; #endif return static_cast<size_t>(written); }
std::string client_socket::read() { std::array<char, BUFFER_SIZE> buf; ssize_t read_n = ::recv(fd_.get_raw_fd(), buf.begin(), buf.size(), MSG_NOSIGNAL); check_return_code(read_n); std::string string{buf.begin(), static_cast<size_t>(read_n)}; #ifdef CPP_NETWORK_SOCKET_DEBUG log(utils::verbose) << "read " << std::to_string(string.size()) << " bytes from " << fd_ << "\n"; #endif return string; }
static int bind_listen_fd(global_context *gc) { int ret; ret = mbedtls_net_bind(&gc->listen_fd, gc->options->listen_host, gc->options->listen_port, MBEDTLS_NET_PROTO_UDP); if (ret != 0) { log_error("Bind failed for host %s on UDP port %s", gc->options->listen_host, gc->options->listen_port); check_return_code(ret, "bind_listen_fd"); return ret; } log_debug("Binded UDP %s:%s", gc->options->listen_host, gc->options->listen_port); mbedtls_net_set_nonblock(&gc->listen_fd); return 0; }
static int session_init(const global_context *gc, session_context *sc, const mbedtls_net_context *client_fd, unsigned char client_ip[16], size_t cliip_len, const unsigned char* first_packet, size_t first_packet_len) { int ret; memset(sc, 0, sizeof(*sc)); memcpy(&sc->client_fd, client_fd, sizeof(sc->client_fd)); if (cliip_len > sizeof(sc->client_ip)) { log_error("session_init - client_ip size mismatch"); return 1; } memcpy(&sc->client_ip, client_ip, cliip_len); sc->cliip_len = cliip_len; mbedtls_ssl_init(&sc->ssl); mbedtls_net_init(&sc->backend_fd); sc->step = GOLDY_SESSION_STEP_HANDSHAKE; sc->options = gc->options; if ((ret = mbedtls_ssl_setup(&sc->ssl, &gc->conf)) != 0) { check_return_code(ret, "session_init - mbedtls_ssl_steup"); return 1; } //mbedtls_ssl_set_hostname(&sc->ssl, "localhost"); mbedtls_ssl_set_timer_cb(&sc->ssl, &sc->timer, mbedtls_timing_set_delay, mbedtls_timing_get_delay); /* We already read the first packet of the SSL session from the network in * the initial recvfrom() call on the listening fd. Here we copy the content * of that packet into the SSL incoming data buffer so it'll be consumed on * the next call to mbedtls_ssl_fetch_input(). */ if (first_packet_len<MBEDTLS_SSL_BUFFER_LEN) { memcpy(sc->ssl.in_hdr, first_packet, first_packet_len); sc->ssl.in_left = first_packet_len; } return 0; }
int main(int argc, char *argv[]) { try { auto p = path(argv[0]); p = p.parent_path() / p.stem(); LoggerSettings ls; ls.log_level = #ifdef NDEBUG "Info" #else "Debug" #endif ; ls.log_file = p.string(); ls.print_trace = true; initLogger(ls); main_thread_id = std::this_thread::get_id(); // parse cmd if (argc > 1) { for (int i = 1; i < argc; i++) { char *arg = argv[i]; if (*arg != '-') continue; if (strcmp(arg, "--copy") == 0) { char *dst = argv[++i]; std::this_thread::sleep_for(std::chrono::seconds(2)); copy_file(argv[0], dst, fs::copy_options::overwrite_existing); LOG_INFO(logger, "Update successful."); return 0; } else if (strcmp(arg, "--version") == 0) { print_version(); return 0; } else { LOG_FATAL(logger, "Unknown option: " << arg); return 1; } } } print_version(); auto data = load_data(String(BOOTSTRAP_JSON_URL)); bootstrap_module_main(argc, argv, data); } catch (std::exception &e) { LOG_ERROR(logger, e.what()); check_return_code(1); } catch (...) { LOG_FATAL(logger, "Unkown exception!"); check_return_code(2); } return 0; }
static int global_init(const struct instance *gi, global_context *gc) { int ret; #ifdef __APPLE__ // MacOS/X requires an additional call int one = 1; #endif const char *pers = "goldy"; memset(gc, 0, sizeof(*gc)); gc->options = gi; mbedtls_ssl_config_init(&gc->conf); mbedtls_ssl_cookie_init(&gc->cookie_ctx); #if defined(MBEDTLS_SSL_CACHE_C) mbedtls_ssl_cache_init(&gc->cache); #endif mbedtls_x509_crt_init(&gc->cacert); mbedtls_entropy_init(&gc->entropy); mbedtls_ctr_drbg_init(&gc->ctr_drbg); log_info("Goldy %s starting up", GOLDY_VERSION); mbedtls_net_init(&gc->listen_fd); ret = bind_listen_fd(gc); if (ret != 0) { goto exit; } #ifdef __APPLE__ // MacOS/X requires an additional call ret = setsockopt(gc->listen_fd.fd, SOL_SOCKET, SO_REUSEPORT, (char*)&one, sizeof(one)); if (ret != 0) { goto exit; } #endif ret = mbedtls_x509_crt_parse_file(&gc->cacert, gi->cert_file); if (ret != 0) { log_error("mbedtls_x509_crt_parse returned %d", ret); goto exit; } log_debug("Loaded server cacert file"); if ((ret = mbedtls_ctr_drbg_seed(&gc->ctr_drbg, mbedtls_entropy_func, &gc->entropy, (const unsigned char *)pers, strlen(pers))) != 0) { printf(" failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret); goto exit; } log_debug("Seeded random number generator"); if ((ret = mbedtls_ssl_config_defaults(&gc->conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_DATAGRAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { log_error("mbedtls_ssl_config_defaults returned %d", ret); goto exit; } mbedtls_ssl_conf_dbg(&gc->conf, log_mbedtls_debug_callback, NULL); mbedtls_debug_set_threshold(MBEDTLS_DEBUG_LOGGING_LEVEL); mbedtls_ssl_conf_rng(&gc->conf, mbedtls_ctr_drbg_random, &gc->ctr_drbg); #if defined(MBEDTLS_SSL_CACHE_C) mbedtls_ssl_conf_session_cache(&gc->conf, &gc->cache, mbedtls_ssl_cache_get, mbedtls_ssl_cache_set); #endif /* Now we can support verify server client, however for performance, * just change to none because openvpn will do the auth again */ mbedtls_ssl_conf_authmode(&gc->conf, MBEDTLS_SSL_VERIFY_NONE); mbedtls_ssl_conf_ca_chain(&gc->conf, &gc->cacert, NULL); mbedtls_ssl_conf_verify(&gc->conf, server_cert_verify, NULL); if ((ret = mbedtls_ssl_cookie_setup(&gc->cookie_ctx, mbedtls_ctr_drbg_random, &gc->ctr_drbg)) != 0) { log_error("mbedtls_ssl_cookie_setup returned %d", ret); goto exit; } mbedtls_ssl_conf_dtls_cookies(&gc->conf, mbedtls_ssl_cookie_write, mbedtls_ssl_cookie_check, &gc->cookie_ctx); log_info("Proxy is ready, listening for connections on UDP %s:%s", gi->listen_host, gi->listen_port); exit: check_return_code(ret, "global_init - exit"); if (ret != 0) { global_deinit(gc); } return ret == 0 ? 0 : 1; }