Filesharing Using TinyURL.com

by mirrorshades  (oj28ae02 @sneakemail.com)

If you already know what TinyURL is, then chances are that you probably have the wrong idea as to what this article is about.  Feel free to skip ahead to the good stuff.

If you don't already know what TinyURL is, then you should check it out.  Very simply, it is a free URL redirection service that lets you enter a long URL, and provides a shorter URL that will automatically redirect to it.

So you can enter something like this:

www.extremetech.com/article2/0,1697,1153284,00.asp

and TinyURL will give you something like this:

tinyurl.com/7up

As you can see, the TinyURL version is much shorter and easier to email (it won't have the line break problem), or even write by hand or give out over the phone.

Entering the "tiny" URL in your browser will give you a 302 redirect to the original URL.  (Actually, there are two redirects to get you there, but that doesn't affect what we will be doing.)

That's it!  That's what it does.  Pretty straightforward, really.

The interesting thing that I found out is that there doesn't seem to be any sort of URL validation on their end.  They assume that whatever you type into the input box will be valid, so they give you a redirect to it.

So if you type in "I will hax0r joo!", then the resulting TinyURL redirect will go to http://I will hax0r joo! (which, obviously, is invalid).

What this means to you and me is that it will take whatever arbitrary string you give it, and give you a nice short link to it.

What You Will Need

In order to share files via TinyURL, you will need a few things.

The technique I describe should be platform-independent, but was tested on a Windows box.  It should work the same way on whatever OS you like, as long as you can assemble the rest of the tools.

First and foremost, you will need a web browser and a text editor.  I assume you are smart enough to handle these without any additional explanation.

Next, you will need the command-line utility GNU Wget.  This should come standard with most *NIX installations, but Windows users will need to grab a copy from the web (see the download link at the end of the article).

Finally, you will need a hex editor.  This is important, as your text editor will not give you the expected results.  I like the Hex Workshop editor for Windows, but use whichever one you prefer - they should all work more or less the same way.

How It Works

What we will be doing is taking advantage of the apparent lack of input checking.

We already know that what you type in doesn't have to be a valid URL, so let's make it something useful.  Let's say you have this file, nekkid_chick.jpg, that you want to send to your friend overseas.  However, since The Man snoops on all your email and IM communication, you need a sneakier way to transfer the file.  This is where TinyURL comes in.

Open nekkid_chick.jpg in your hex editor.  Chances are that you will see a three column layout.

The first column is probably the address column (you can just ignore this for now).

The other two columns should be the actual byte sequence and the ASCII equivalent of the byte sequence in the file; for Hex Workshop the middle column is the bytes and the third column is the ASCII.

For this process, we are only interested in the byte sequence, not in the ASCII values.  This is important, and this is why just using a text editor will not work for this.

Select all the text in the byte sequence and copy it to the clipboard.  You now have a copy of the binary version of the file ready to go somewhere.  Can you guess what we do next?  Right - open your browser and visit tinyurl.com.

In the middle of the page, you will see a text box with the label "Enter a long URL to make tiny."

Go ahead and paste the contents of the clipboard into this box and click the "Make TinyURL!" button.

If all goes well, you will be taken to a page that gives you the "URL" that you entered and the resulting short URL.  This new URL is the one to send to your friend.

Congratulations!  You have just stored your file on TinyURL's servers.

Getting the file back out is more or less the same process in reverse but with one important difference.

Even though tinyurl.com doesn't seem to care whether a URL is valid or not, your web browser does.  If you just enter the TinyURL link into your preferred browser, it won't know what to do with the full link (the way it handles this may differ depending on which browser you use).  This is where GNU Wget enters the picture.

For those not in the know, GNU Wget is a program that acts more or less as a way to download web pages and save them locally.

Typing wget http://www.google.com will get you a complete copy of Google's index.html page, nicely saved on your hard drive.  GNU Wget is pretty smart in that it knows how to handle a web redirect... and this is the key to retrieving the file stored on TinyURL.

To get your file back, get to a command prompt and type in the following:

$ wget -o output-file http://tinyurl.com/your-link-here

What this will do is retrieve the page redirected to by your short URL and store the entire output of the process in a text file (output-file - what you name this file is unimportant).

Open this file in a text editor and you will see the entire output of GNU Wget.

If all went well, you should see a long string of hex characters in the mix - this is the byte sequence for your file.  (This byte sequence is actually repeated a few times inside the log file since GNU Wget assumes it is the target URL.)

Now what you need to do is to copy the complete byte sequence from your output file.

The string Location: http:// will be at the beginning of the first sequence, and will be ended by  [following] (there is a space before the first bracket).

If you're a regular expression kind of geek, this should work for you: /Location: http:\/\/(\w*)/

Otherwise, you may just need to use your text editor's search function.  Either way, grab hold of the entire byte sequence and copy it to your clipboard.

Once you have the complete sequence copied, open up your hex editor and paste it.

Again, be sure that you are pasting into the byte column, not the ASCII column.

Save the file as nekkid_chick_w00t.jpg and exit your hex editor.  You're done!

Thanks to TinyURL, you have now downloaded a shared picture in a manner not likely to be discovered by the casual observer.  (Note that even if The Man is able to locate the byte sequence, he will still need to figure out what type of file it is - this may be easier for some types of files than for others.)

If all this Wget/copy/hexedit/paste/save nonsense is too much for you, fear not!

Because I got tired of doing it that way myself, I wrote two short programs, Implant and Extract, which are designed to automate the process.  Have a look below for the code and additional information.

Outro

For you nerds who are interested in information theory, this method of filesharing uses what is called a "covert channel."

The U.S. Department of Defense defines a covert channel as "Any communication channel that can be exploited by a process to transfer information in a manner that violates the system's security policy" (from the Orange Book).

What this means to the layman is that we are using a method of storing and retrieving information:

  1. Of a different type.
  2. In a different way than the process normally dictates that we use.

(Steganography is another type of covert channel communication that you may be familiar with.  Give it some thought - see where else you can think to hide a string of bytes.)

Please use good judgment with this technique.

I have tested it with a 20k image file and it works as of this writing.  However, if everyone starts uploading 800 meg DVD rips, the TinyURL folks will likely notice and probably put some sort of validation or length check on the initial URL.

I have found, though, that there are quite a few URL redirection providers out there... check the links section for the Open Directory index page on that topic.

I have not tried any others, but my guess is that there are a number of them that will work in the same way.  This is probably best suited for smaller files and is really more proof-of-concept than anything else.

Nevertheless, do with it what you please.  I wash my hands of you.

Thanks to zshzn for help with the regular expression and UziMonkey for help with the Ruby code.

Comments or questions, feel free to email me (address given above).

Related Links

"Implant" and "Extract"

Those of you who are astute enough to use Ruby are in luck, as I have simplified the storage and retrieval process for you.

The Implant program takes a filename as input, then converts it to a binary string and posts it to TinyURL, returning your new redirect link.

The Extract program takes the end portion of your redirect link (it assumes http://tinyurl.com/ at the beginning, so all you need to enter is the part after the final slash) and writes a file to the current directory with that as the name.

You will need to rename it or give it a proper extension on your own to finalize the process.

implant.rb:

require 'net/http'

print "File to upload: "
source = gets.chomp
raise "No source found." if source == ""

bytes = ""
File.open(source, "rb") do |f|
	print "Reading file..."
	f.each_byte do |b|
		#format as hex
		bytes << sprintf("%02X", b)
	end
	puts "done"
end

Net::HTTP.start("tinyurl.com") do |http|
	puts "Sending file..."
	resp = http.post("/create.php", "url=#{bytes}")
	resp.body.scan(%r{value="http://tinyurl.com/(\w*)"})
	puts "File #{source} uploaded to http://tinyurl.com/#{$1}"
end

extract.rb:

require 'net/http'

print "Extract file -- http://tinyurl.com/"
target = gets.chomp
raise "No target found." if target == ""

Net::HTTP.start("forwarding.tinyurl.com") do |http|
	resp = http.get("/redirect.php?num=#{target}")
	if resp.code  == "302" then
		puts "Retrieving data..."
		resp['location'] =~ %r{http://(\w*)}
		bytes = $1.split(/(..)/)
		bytes.compact!
		byte_string = bytes.pack("H*"*bytes.length)
		puts "Creating file #{target}..."
		File.open(target, 'wb') do |f|
			f << byte_string
		end
	else
		raise "HTTP #{resp.code} received. Something is fux0red somewhere..."
	end
	puts "Done!"
end

Code: implant.rb

Code: extract.rb

Return to $2600 Index