Skip to content

Instantly share code, notes, and snippets.

@cs2dsb
Last active May 18, 2017 22:05
Show Gist options
  • Save cs2dsb/ba45aa94384ddd7462323c76325c2de6 to your computer and use it in GitHub Desktop.
Save cs2dsb/ba45aa94384ddd7462323c76325c2de6 to your computer and use it in GitHub Desktop.
Grab bearer token from refresh-token stored by Amazon Cloud Drive desktop app

Extract oauth token from Amazon Drive app

A quick mono app hacked together to extract the refresh-token from the Amazon Drive desktop app and use it to get a valid bearer token.

Will probably break when the app updates as it has a hardcoded initialization vector in the source file. My guess is you don't need to ever run the app again after the initial login but the code is fairly complex and I've only spent an hour investigating this.

No idea what Amazon would think about this use of the app but since it's an oauth token issued to me for uploading to my cloud drive it's probably not that much of an issue. Happy to remove the gist if there are any concerns.

using System;
using System.Security.Cryptography;
using System.Text;
using System.Linq;
using System.IO;
using System.Net;
namespace ACD_Refresh_Token
{
class Program
{
static void Main()
{
var amazon_iv = "d53fda3d1c5934f7eeb88df5ba211c9c";
var refresh_url = "https://api.amazon.co.uk/auth/token";
var method = "POST";
var content_type = "application/json";
var config_path = Environment.ExpandEnvironmentVariables(
"%HOME%/Library/Application Support/Amazon Cloud Drive");
var amazon_serial = File.ReadAllText(config_path + "/serial-number");
var refresh_token = File.ReadAllBytes(config_path + "/refresh-token");
var key_bytes = Encoding.ASCII.GetBytes(amazon_serial);
var iv_bytes = Encoding.UTF8.GetBytes(amazon_iv);
var decrypted_bytes = EncryptedFileTokenProvider_Decrypt(refresh_token, key_bytes, iv_bytes);
var decrypted_refresh_token = Encoding.UTF8.GetString(decrypted_bytes).Trim(new char[1]);
var http = (HttpWebRequest)WebRequest.Create(new Uri(refresh_url));
http.Accept = content_type;
http.ContentType = content_type;
http.Method = method;
var json = String.Format("{{\"app_name\": \"Amazon Drive\", \"app_version\": \"4.0.10.591949c5\", \"requested_token_type\": \"access_token\", \"source_token\": \"{0}\", \"source_token_type\": \"refresh_token\" }}", decrypted_refresh_token);
var body = Encoding.ASCII.GetBytes(json);
var stream = http.GetRequestStream();
stream.Write(body, 0, body.Length);
stream.Close();
var content = new StreamReader(
http.GetResponse()
.GetResponseStream())
.ReadToEnd();
Console.WriteLine("{0}", content);
}
private static byte[] EncryptedFileTokenProvider_Decrypt(byte[] textBytes, byte[] key, byte[] iv)
{
byte[] result;
using (AesCryptoServiceProvider aesCryptoServiceProvider = new AesCryptoServiceProvider())
{
var k = key.Take(aesCryptoServiceProvider.KeySize / 8).ToArray<byte>();
aesCryptoServiceProvider.Key = k;
aesCryptoServiceProvider.IV = iv.Take(aesCryptoServiceProvider.BlockSize / 8).ToArray<byte>();
aesCryptoServiceProvider.Mode = CipherMode.CBC;
aesCryptoServiceProvider.Padding = PaddingMode.PKCS7;
using (MemoryStream memoryStream = new MemoryStream(textBytes))
{
using (ICryptoTransform cryptoTransform = aesCryptoServiceProvider.CreateDecryptor(aesCryptoServiceProvider.Key, aesCryptoServiceProvider.IV))
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Read))
{
byte[] array = new byte[textBytes.Length];
cryptoStream.Read(array, 0, textBytes.Length);
result = array;
}
}
}
}
return result;
}
}
}
#!/bin/bash
set -e
mcs -pkg:dotnet program.cs
mono program.exe
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment