mirror of
https://github.com/inAudible-NG/audible-activator.git
synced 2024-11-18 03:18:57 +01:00
4fc191fee9
* Added a command line option to activate two factor auth * Added a question on the command line for the user to input the two factor auth * Because the chrome driver may take some time to launch, the two factor auth step takes place after the web page has been loaded.
144 lines
5.5 KiB
Python
Executable File
144 lines
5.5 KiB
Python
Executable File
#!/usr/bin/env python2
|
|
|
|
from __future__ import print_function
|
|
from getpass import getpass
|
|
from optparse import OptionParser
|
|
import sys
|
|
import time
|
|
from selenium import webdriver
|
|
from urllib import urlencode
|
|
from urlparse import urlparse, parse_qsl
|
|
import hashlib
|
|
import base64
|
|
import requests
|
|
import os
|
|
import common
|
|
import binascii
|
|
|
|
|
|
def fetch_activation_bytes(username, password, options):
|
|
base_url = 'https://www.audible.com/'
|
|
base_url_license = 'https://www.audible.com/'
|
|
lang = options.lang
|
|
|
|
# Step 0
|
|
opts = webdriver.ChromeOptions()
|
|
opts.add_argument("user-agent=Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; AS; rv:11.0) like Gecko")
|
|
|
|
# Step 1
|
|
if '@' in username: # Amazon login using email address
|
|
login_url = "https://www.amazon.com/ap/signin?"
|
|
else: # Audible member login using username (untested!)
|
|
login_url = "https://www.audible.com/sign-in/ref=ap_to_private?forcePrivateSignIn=true&rdPath=https%3A%2F%2Fwww.audible.com%2F%3F"
|
|
if lang != "us": # something more clever might be needed
|
|
login_url = login_url.replace('.com', "." + lang)
|
|
base_url = base_url.replace('.com', "." + lang)
|
|
|
|
player_id = base64.encodestring(hashlib.sha1("").digest()).rstrip() # keep this same to avoid hogging activation slots
|
|
if options.player_id:
|
|
player_id = base64.encodestring(binascii.unhexlify(options.player_id)).rstrip()
|
|
print("[*] Player ID is %s" % player_id)
|
|
|
|
payload = {
|
|
'openid.ns': 'http://specs.openid.net/auth/2.0',
|
|
'openid.identity': 'http://specs.openid.net/auth/2.0/identifier_select',
|
|
'openid.claimed_id': 'http://specs.openid.net/auth/2.0/identifier_select',
|
|
'openid.mode': 'logout',
|
|
'openid.assoc_handle': 'amzn_audible_' + lang,
|
|
'openid.return_to': base_url + 'player-auth-token?playerType=software&playerId=%s=&bp_ua=y&playerModel=Desktop&playerManufacturer=Audible' % (player_id)
|
|
}
|
|
|
|
if sys.platform == 'win32':
|
|
chromedriver_path = "chromedriver.exe"
|
|
else:
|
|
chromedriver_path = "./chromedriver"
|
|
|
|
driver = webdriver.Chrome(chrome_options=opts,
|
|
executable_path=chromedriver_path)
|
|
|
|
query_string = urlencode(payload)
|
|
url = login_url + query_string
|
|
driver.get(base_url + '?ipRedirectOverride=true')
|
|
driver.get(url)
|
|
if os.getenv("DEBUG") or options.debug: # enable if you hit CAPTCHA or 2FA or other "security" screens
|
|
print("[!] Running in DEBUG mode. You will need to login in a semi-automatic way, wait for the login screen to show up ;)")
|
|
time.sleep(32)
|
|
else:
|
|
search_box = driver.find_element_by_id('ap_email')
|
|
search_box.send_keys(username)
|
|
search_box = driver.find_element_by_id('ap_password')
|
|
search_box.send_keys(password)
|
|
search_box.submit()
|
|
if options.two_factor:
|
|
search_box = driver.find_element_by_id('auth-mfa-otpcode')
|
|
search_box.send_keys(raw_input("Enter Two-Step Verification Code: "))
|
|
search_box.submit()
|
|
|
|
# Step 2
|
|
driver.get(base_url + 'player-auth-token?playerType=software&bp_ua=y&playerModel=Desktop&playerId=%s&playerManufacturer=Audible&serial=' % (player_id))
|
|
current_url = driver.current_url
|
|
o = urlparse(current_url)
|
|
data = dict(parse_qsl(o.query))
|
|
|
|
# Step 2.5, switch User-Agent to "Audible Download Manager"
|
|
headers = {
|
|
'User-Agent': "Audible Download Manager",
|
|
}
|
|
cookies = driver.get_cookies()
|
|
s = requests.Session()
|
|
for cookie in cookies:
|
|
s.cookies.set(cookie['name'], cookie['value'])
|
|
|
|
# Step 3, de-register first, in order to stop hogging all activation slots
|
|
# (there are 8 of them!)
|
|
durl = base_url_license + 'license/licenseForCustomerToken?' \
|
|
+ 'customer_token=' + data["playerToken"] + "&action=de-register"
|
|
s.get(durl, headers=headers)
|
|
|
|
# Step 4
|
|
url = base_url_license + 'license/licenseForCustomerToken?' \
|
|
+ 'customer_token=' + data["playerToken"]
|
|
response = s.get(url, headers=headers)
|
|
|
|
with open("activation.blob", "wb") as f:
|
|
f.write(response.content)
|
|
activation_bytes, _ = common.extract_activation_bytes(response.content)
|
|
print(activation_bytes)
|
|
|
|
# Step 5 (de-register again to stop filling activation slots)
|
|
s.get(durl, headers=headers)
|
|
|
|
# driver.get(url)
|
|
time.sleep(8)
|
|
driver.quit()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
parser = OptionParser(usage="Usage: %prog [options]", version="%prog 0.2")
|
|
parser.add_option("-d", "--debug",
|
|
action="store_true",
|
|
dest="debug",
|
|
default=False,
|
|
help="run program in debug mode, enable this for 2FA enabled accounts or for authentication debugging")
|
|
parser.add_option("-l", "--lang",
|
|
action="store",
|
|
dest="lang",
|
|
default="us",
|
|
help="us (default) / de / fr",)
|
|
parser.add_option("-p",
|
|
action="store",
|
|
dest="player_id",
|
|
default=None,
|
|
help="Player ID in hex (for debugging, not for end users)",)
|
|
parser.add_option("-t", "--two-factor",
|
|
action="store_true",
|
|
dest="two_factor",
|
|
default=False,
|
|
help="Use this option to enable two factor authentication",)
|
|
(options, args) = parser.parse_args()
|
|
|
|
username = raw_input("Username: ")
|
|
password = getpass("Password: ")
|
|
|
|
fetch_activation_bytes(username, password, options)
|