Expanding Shortened URLs With PowerShell

Shortened URLs are generated by services such as Bitly or TinyURL, and they take a long address, for example https://xkln.net/blog/putting-the-powershell-window-title-to-better-use/, and turn it into something like https://bit.ly/2VhbwKb.

These are legitimate services as some URLs can be truly horrific (I’m looking at you, IBM SSIC), but they are also often abused to disguise malicious addressees, or tracking and affiliate parameters that you may not wish to entertain. Often you simply want to see what site you’re being taken to before clicking on a link.

There are plenty of URL expanders a mere Google search away, but I’ve always got PowerShell open, and I don’t have one of those sites open. It’s also worth considering the (probably minor) risk of providing the URL to public website in case there are parameters in the expanded address you may not want shared. Another consideration is that some of these public expanders actually list ‘recently expanded’ URLs, and if you’re researching a potentially malicious link, you may have inadvertently left a live link on a public website with no warning.

The way these services work is through HTTP redirects, the browser takes you to the shortened URL, the service returns a HTTP 301 (Moved Permanently), and provides the actual URL in the return header which your client then follows. We can get in the middle of this process by telling PowerShell not to follow redirects using the -MaximumRedirection 0 option with Invoke-WebRequest, and then retrieving the real address from the headers.

Let’s give it a shot.

PS C:\> Invoke-WebRequest -MaximumRedirection 0 -Uri https://t.co/j3hPleGxpx


StatusCode        : 301
StatusDescription : Moved Permanently
Content           : {}
RawContent        : HTTP/1.1 301 Moved Permanently
                    strict-transport-security: max-age=0
                    vary: Origin
                    x-connection-hash: 122de14d7ed640e63018f143f52e7c50
                    x-response-time: 168
                    Content-Length: 0
                    Cache-Control: private...
Headers           : {[strict-transport-security, max-age=0], [vary, Origin], [x-connection-hash, 122de14d7ed640e63018f143f52e7c50], [x-response-time, 168]...}
RawContentLength  : 0

Invoke-WebRequest : The maximum redirection count has been exceeded. To increase the number of redirections allowed, supply a higher value to the -MaximumRedirection parameter.
At line:1 char:1
+ Invoke-WebRequest -MaximumRedirection 0 -Uri https://t.co/j3hPleGxpx
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], InvalidOperationException
    + FullyQualifiedErrorId : MaximumRedirectExceeded,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

We can tell PowerShell to ignore errors, and if we check the headers, we can see the full URL present under the Location key.

PS C:\> (Invoke-WebRequest -MaximumRedirection 0 -Uri https://t.co/j3hPleGxpx -ErrorAction SilentlyContinue).Headers

Key                       Value
---                       -----
strict-transport-security max-age=0
vary                      Origin
x-connection-hash         122de14d7ed640e63018f143f52e7c50
x-response-time           170
Content-Length            0
Cache-Control             private,max-age=300
Date                      Fri, 10 Apr 2020 09:40:32 GMT
Expires                   Fri, 10 Apr 2020 09:45:32 GMT
Location                  https://xkln.net/blog/putting-the-powershell-window-title-to-better-use
Server                    tsa_l

Next we can add a short function to our PowerShell profile which makes the whole process that much more convenient.

function ExpandURL([string]$URL) {
    (Invoke-WebRequest -MaximumRedirection 0 -Uri $URL -ErrorAction SilentlyContinue).Headers.Location
}

Let’s see it in action:

PS C:\> expandurl https://tinyurl.com/2fcpre6
https://www.youtube.com/watch?v=dQw4w9WgXcQ

Sometimes you’ll find that a URL has been through multiple shorteners, in this case we would just need to run the expandurl command multiple times until we got the final destination.

PS C:\> expandurl https://bit.ly/3cj5r6X
https://tinyurl.com/2fcpre6

PS C:\> expandurl https://tinyurl.com/2fcpre6
https://www.youtube.com/watch?v=dQw4w9WgXcQ

That’s it.


Share this post on , , , or