Expanding Shortened URLs With PowerShell
Posted on April 10, 2020
- and tagged as
- 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.