Holiday Hack 2024: Mobile Analysis
Introduction
Eve Snowshoes is to the left side of the front yard:
They are asking for help with a new mobile app:
Eve Snowshoes
Hi there, tech saviour! Eve Snowshoes and Team Alabaster in need of assistance.
I’ve been busy creating and testing a modern solution to Santa’s Naughty-Nice List, and I even built an Android app to streamline things for Alabaster’s team.
But here’s my tiny reindeer-sized problem: I made a debug version and a release version of the app.
I accidentally left out a child’s name on each version, but for the life of me, I can’t remember who!
Could you start with the debug version first, figure out which child’s name isn’t shown in the list within the app, then we can move on to release? I’d be eternally grateful!
Mobile Analysis
Challenge
Data
The two links from Eve provide one file each:
oxdf@hacky$ ls
SantaSwipe.apk SantaSwipeSecure.aab
oxdf@hacky$ file *
SantaSwipe.apk: Zip archive data, at least v0.0 to extract, compression method=deflate
SantaSwipeSecure.aab: Zip archive data, at least v0.0 to extract, compression method=deflate
The “debug” version is an Android Application Package (APK), which is the format for an application that gets installed on an Android device.
The “release” version is an Android Application Bundle (AAB), which is used by the Play store to create optimized APKs on the fly for each user’s device configuration. It’s described in much more details in the Android Developers documentation.
Both files are just Zip archives.
Emulation
It’s not necessary, but I can create a free account at appetize and run the APK app:
I can swipe names left for the naughty list or right for the nice list.
I’ll have to generate an APK from the AAB to emulate it.
jadx-gui
While I could use unzip
or 7z
to extract files from the .apk
, but they will be in a binary format. I’ll use jadx to look at the files by downloading the latest release, unzipping it, and running bin/jadx-gui
:
I’ll open the .apk
file, and after some processing, it provides a file tree:
Silver
Resources
The AndroidManifest.xml
file in Resources
will define how the application starts, specifically this section:
<activity
android:theme="@style/Theme.SantaSwipe"
android:label="@string/app_name"
android:name="com.northpole.santaswipe.MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
The code will be at com/northpole/santaswipe/MainActivity
.
There’s also an HTML file in assets
:
I don’t need to look at this, but it’s the UI for the application. I can re-create it locally and open it in Firefox:
There’s a JavaScript function that handles swipes, and it calls this function which makes called to the Android functions:
function handleSwipe(item, startX, endX) {
const threshold = 100; // Minimum distance for a swipe to be recognized
if (startX - endX > threshold) {
// Swiped left
item.classList.remove('swipe-green');
item.classList.add('swipe-left');
Android.addToNaughtyList(item.textContent); // Call Android interface to add to Naughty List
setTimeout(() => item.remove(), 300); // Remove item after animation
} else if (endX - startX > threshold) {
// Swiped right
item.classList.remove('swipe-red');
item.classList.add('swipe-right');
Android.addToNiceList(item.textContent); // Call Android interface to add to Nice List
setTimeout(() => item.remove(), 300); // Remove item after animation
} else {
// Reset colors if no significant swipe
item.classList.remove('swipe-green');
item.classList.remove('swipe-red');
}
}
I’ll keep an eye out for addToNaughtyList
and addToNiceList
. There’s also functions to get the normal, nice, and naughty lists that interact with the application:
// Functions to request lists from the Android side
function showNormalList() {
Android.getNormalList();
document.getElementById('header').innerHTML = '<h2 class="illumination">Unlisted</h2>';
}
function showNiceList() {
Android.getNiceList();
document.getElementById('header').innerHTML = '<h2 class="illumination">Nice</h2>';
}
function showNaughtyList() {
Android.getNaughtyList();
document.getElementById('header').innerHTML = '<h2 class="illumination">Naughty</h2>';
}
DatabaseHelper
The com.northpole.santaswipe
folder has not only the MainActivity
class, but also a class for interacting with the database:
jadx will make Java-like code, which is pretty readable. The DB path will be nautynicelist.db
:
public static final int $stable = 0;
private static final String DATABASE_NAME = "naughtynicelist.db";
private static final int DATABASE_VERSION = 3;
On creating the DB, it creates tables, and then creates a bunch of users into the normal list:
MainActivity
This code has initialization code, as well as setting up and interacting with the HTML WebAppInterface
. I’ll also find the functions referenced in the JavaScript above. For example, addToNiceList
:
@JavascriptInterface
public final void addToNiceList(String item) {
Intrinsics.checkNotNullParameter(item, "item");
try {
removeFromAllLists(item);
SQLiteDatabase sQLiteDatabase = MainActivity.this.database;
if (sQLiteDatabase == null) {
Intrinsics.throwUninitializedPropertyAccessException("database");
sQLiteDatabase = null;
}
sQLiteDatabase.execSQL("INSERT INTO NiceList (Item) VALUES ('" + item + "');");
} catch (Exception e) {
Log.e("WebAppInterface", "Error adding to NiceList: " + e.getMessage());
}
}
This looks to be very SQL-injectable, but that’s not the goal here!
The getNormalList
function builds a raw SQL query in a similar way, but it makes an interesting exclusion:
@JavascriptInterface
public final void getNormalList() {
final String jsonItems;
try {
SQLiteDatabase sQLiteDatabase = MainActivity.this.database;
if (sQLiteDatabase == null) {
Intrinsics.throwUninitializedPropertyAccessException("database");
sQLiteDatabase = null;
}
Cursor cursor = sQLiteDatabase.rawQuery("SELECT Item FROM NormalList WHERE Item NOT LIKE '%Ellie%'", null);
List items = new ArrayList();
Log.d("WebAppInterface", "Fetching items from NormalList table");
while (cursor.moveToNext()) {
String item = cursor.getString(0);
Intrinsics.checkNotNull(item);
items.add(item);
Log.d("WebAppInterface", "Fetched item: " + item);
}
cursor.close();
if (items.isEmpty()) {
jsonItems = "[]";
} else {
jsonItems = CollectionsKt.joinToString$default(items, "\",\"", "[\"", "\"]", 0, null, null, 56, null);
}
MainActivity mainActivity = MainActivity.this;
final MainActivity mainActivity2 = MainActivity.this;
mainActivity.runOnUiThread(new Runnable() { // from class: com.northpole.santaswipe.MainActivity$WebAppInterface$$ExternalSyntheticLambda1
@Override // java.lang.Runnable
public final void run() {
MainActivity.WebAppInterface.getNormalList$lambda$0(jsonItems, mainActivity2);
}
});
} catch (Exception e) {
Log.e("WebAppInterface", "Error fetching NormalList: " + e.getMessage());
}
}
The query is:
SELECT Item FROM NormalList WHERE Item NOT LIKE '%Ellie%'
“Ellie” is the answer that solves the silver challenge.
Gold
Generate APK
To look at the application, I’ll need to get an APK file from the AAB. I’ll use Google’s official developer tool for this, bundletool. I’ll grab the latest release from GitHub. Running it takes a bundle and an output. I’ll also give it --mode universal
to get a single APK:
oxdf@hacky$ java -jar bundletool-all-1.17.2.jar build-apks --bundle ./SantaSwipeSecure.aab --output SantaSwipeSecure.apks --mode universal
WARNING: The APKs won't be signed and thus not installable unless you also pass a keystore via the flag --ks. See the command help for more information.
The resulting .apks
file is an archive with the APK (without --mode universal
there are 83 APKs):
oxdf@hacky$ unzip -l SantaSwipeSecure.apks
Archive: SantaSwipeSecure.apks
Length Date Time Name
--------- ---------- ----- ----
95 1981-01-01 01:01 toc.pb
7750598 1981-01-01 01:01 universal.apk
--------- -------
7750693 2 files
I’ll open universal.apk
in jadx-gui
.
MainActivity
This time, there’s no shadiness in MainActivity
. The getNormalList
function that was excluding Ellie before is just making a regular query:
But I’ll notice that after it gets the data, it passes it to decryptData
before adding it to the list. I’ll show shortly how data going into the database is encrypted.
DatabaseHelper - Decrypt
The decryptData
function is defined in DatabaseHelper
:
private final String decryptData(String encryptedData) {
try {
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(2, this.secretKeySpec, new GCMParameterSpec(128, this.iv));
byte[] doFinal = cipher.doFinal(Base64.decode(encryptedData, 0));
Intrinsics.checkNotNull(doFinal);
return new String(doFinal, Charsets.UTF_8);
} catch (Exception e) {
Log.e("DatabaseHelper", "Decryption failed: " + e.getMessage());
return null;
}
}
It’s using AES in GCM mode with a specified key and IV to decrypt. The key
and iv
are set in the class’ constructor function:
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, (SQLiteDatabase.CursorFactory) null, 1);
Intrinsics.checkNotNullParameter(context, "context");
String string = context.getString(R.string.ek);
Intrinsics.checkNotNullExpressionValue(string, "getString(...)");
String obj = StringsKt.trim((CharSequence) string).toString();
String string2 = context.getString(R.string.iv);
Intrinsics.checkNotNullExpressionValue(string2, "getString(...)");
String obj2 = StringsKt.trim((CharSequence) string2).toString();
byte[] decode = Base64.decode(obj, 0);
Intrinsics.checkNotNullExpressionValue(decode, "decode(...)");
this.encryptionKey = decode;
byte[] decode2 = Base64.decode(obj2, 0);
Intrinsics.checkNotNullExpressionValue(decode2, "decode(...)");
this.iv = decode2;
this.secretKeySpec = new SecretKeySpec(decode, "AES");
}
It’s calling context.getString
on resources. They strings are located in Resources/resources.arsc/res/values/strings.xml
:
The key was loaded from R.string.ek
and then base64 decoded, and the iv
from R.string.iv
:
Decode Script
With a bit of help from ChatGPT, I’ll write a decode script in Python that takes a base64-encoded encrypted string (which includes the “TAG” value appended to the end) and returns the plaintext:
import sys
from base64 import b64decode
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
key = b64decode("rmDJ1wJ7ZtKy3lkLs6X9bZ2Jvpt6jL6YWiDsXtgjkXw=")
iv = b64decode("Q2hlY2tNYXRlcml4")
ciphertext = b64decode(sys.argv[1])
ciphertext_data = ciphertext[:-16]
tag = ciphertext[-16:]
aesgcm = AESGCM(key)
try:
decrypted_data = aesgcm.decrypt(iv, ciphertext_data + tag, None)
print("Decrypted text:", decrypted_data.decode('utf-8'))
except Exception as e:
print("Decryption failed:", str(e))
Decrypt with CyberChef
It’s also possible to do this with CyberChef. It’s easy enough to enter the key and IV, but the challenge comes in getting the 16 tag bytes from the end of the cipher text. I’ll start by base64-decoding the input, and converting it to hex. I don’t have to convert to hex, but it makes it easier for me to visualize the data I’m working with.
I’ll use a register to save the tag:
This doesn’t change the data coming out, but saves the last 32 hex characters (which is 16 bytes) as $R0
.
Now I’ll use Find / Replace to those last 32 characters:
This gives just the cipher text flowing into the next operation, AES:
The key and IV come from the reversing. The tag is from the register, $R0
. And it works:
The full recipe is here.
DatabaseHelper - Initialize Values
The insertInitialData
function loops over a series of encrypted strings and adds them to the DB:
private final void insertInitialData(SQLiteDatabase db) {
Iterator it = CollectionsKt.listOf((Object[]) new String[]{"L2HD1a45w7EtSN41J7kx/hRgPwR8lDBg9qUicgz1qhRgSg==", "IWna1u1qu/4LUNVrbpd8riZ+w9oZNN1sPRS2ujQpMqAAt114Yw==", "MWfO0+M1t5IvQtN2ad9w3hp81sYQIIaX6veq03bnk6I4H/1n89gW", "LmHJ164506skXdh3K9MZ/BBiw90TRO2mD0Hp9Nuoxu4ghx5/WQ==", "J2XF2645xKciX9RgK9MR+wZ60NIbKIsOTRSHP0jkBJPaF0djlqbc", "LGfJ0q451qslWt14aZd8rjtr1ZMtJItIvrKk8RRQWh2U6bQSEdPga59XDQ==", "LWTBzOt4u/4KXt99aJ18riBgy8cSJcpvtrKnM4IEsMDr9AwtlSJW+S/jdoHvXA==", "I2HM3+w1t4opQ953c5x8rjZvzNITIEFFaMC3bP4bW/FptwSEIzo=", "K3vJ2Od1+79qEeN2apZ8rjx6w98OKXRQNvvj/tYXj2mFoDhaZw==", "O33D06452K0nWtA1J7kx/hRgtZNzI71BDpxorJ6mxImw/A==", "L2na0+M1t58yWdR3dN9wyQdrx9ASZFBP13TAtgvjKYVFW9J6rA==", "KmnGya451bs0Xdh3K9MX6wdjw90OdugnqIwKHDmVzoF7PjkQJQ==", "IWDN1K451bsvW9h3YN9wzR1nzNLx7AaHK857pwQ3GlLQ2i+e", "I2XByK451L8vQ941J7Y39wV6pk1FpbJdc3QZRlpVuVIsjQ==", "JGnc0+94u/4FUMJ4ZZ8x4BZvjpM6LphLvL+vfIsRMj38FLu+GyCyUdPJ2g==", "I2TNwq452bsxEeh2dZh8riBd4zTtytJ89Bxu9NEok+aDWmI=", "J2TN1OM1t5MpQtJ2cN9w3AB90doWBr/HMmnvw088K+A8OYyeqg==", "Ln3L26452rcqUN81J7ok7xl32UJTvrQCKVSd6Z+tiX2Hmg==", "Lm3B1uM1t5wjWMNsc99wwhBsw90YLyjPYh2rLfMJ1C4VX2kQBpE=", "KGfG2/E1t40yXtJyb5w841ku8cQSJY9K1bwgTiInx6cYV5Ui/DM+sA==", "L23BlqJK/78oVtl4bt9wzR1nzNKBr23V1KlRgUeyT5PagT9r", "MWnFz+d1u/4EVMN3K9MD+Rx62NYFLYtKu34IoIzUoRVftPjhSrdCxro=", "LGnM0+M1t5UvVMc1J6Y7/BRnzNY2Zug0wYGSAMBLA1AcU9yx", "NGHLzu1ru/4ERNJxZoE1/QEiguEYLItKtr0WsmwcMfhswLv9Tec+ZRjR", "I2Hb0uM1t5AnWMN2ZZp8rj5rzMoWa/+6xCGsNnHvb00IU4Fr3Q==", "JmnG0+d1u/4JQt12K9Me4Qd5w8o6jn3t2IdQwSuXYx7u//Cv", "I2bBzuM1t5MzXNN4bt9wxxtqy9JRetksUopAr2UrK5xAUHDW", "JmHN3e01t5MjSdh6aNMT5wF3jpM6JJJNvLOoRJgv4sLKLQau2YBLzokQ", "LmHG3uM1t50pQdR3b5I36xsigvcSL4dFrbfU9Cqvl5I/xLcz0XU03pLK", "I2bc1ew1t4gvVN93Zt9wzwB91sEeIIGZ9QAB6FA50LlDQiHup1s=", "MWna264537sqQth3bJp8rjNnzN8WL47gYBHKOnMA/05AZVXhUewu", "KGfa3ec1t5IvXNA1J6M1/ACz8Z0iiXnvwFsEg5jrkLGq", "JXrJ2ec1t5siWN97coE35lku8dAYNYZFsbi05FzIyksNODX0NjFqyvVn", "L2nc3+01t5wzVN92dNMR5wdr0Z9XAJhDurK0PoMIwB3/YInPpneEf/Q3blsrDg==", "J2XB1vs1t5ozU91wad9wxwdrztIZJQMfNE4DYwx1R7bg5c50NDQ=", "Jmne0+Y1t5QpWdB3aZYj7AB8xZ9XEoVRq7TgFosbO6NUOYiKnRWuNaKuxMtDzqVA7Q==", "LGfa26451rM1RdRrY5I9olVAx8cfJJhIvrKkJJm3opYYxGiM9SQhFp8qlek=", "MXzN3ON3u/4EVN1+dZI061ku8dYFI4NF6DAFvK8r77cS9dUOpitQRg==", "KWHFlqJK8rEzXZ05VJwl+h0u6dwFJIuDD8ONR42MoY7KFht/QJfy", "Ln3L0+M1t5wnQ9J8a5w+71ku8cMWKIQC0zxiXHG/YZvw7T+TNIqz", "LWXJyK451rMrUN81J7k//BFvzGO14j2tV1Au4CjIir5oH4s=", "L2na0+c1t44nQ9hqK9MW/BRgwdazin6FJqgBFVKkiYZE/Oku", "NmfFlqJa/7clUNZ2K9MF3TR3qVJdK8qDeVx+ZJ0MHnNU", "Km3E3+x4u/4WQ9B+cpZ8rjZ0x9AfYbhBr6miO4QKWNrxWDpCUMmjm7xYtCdc6A==", "I3rCz+w1t5ojXdlwK9MZ4BFnwzwsgLd0z5uSRxTqIB8aQs4=", "L2nazuM1t4knQ8J4cN9w3hpiw90TTjWQOk7MWqw/XG0TO0AeQA==", "MWHF1ew1t4QzQ9h6b99w3QJn1skSM4ZFsbgRVLExuZmptZSHE6Yrul/e", "I2bJlqJD9rk0VNM1J7Ai4RR6y9JIjLKEIfFIhBPBpLBEqomH", "MGnO2+d1u/4KWMJ7aJ18riVh0McCJotIhSM4dPg694vcV/24WexvGQ==", "LmHG3uM1t4wjSNpzZoU55Vku69ASLYtKu2L+bDaBlZjDIaGNeZhBJqA=", "L2HL0uN1u/4EQ9BtboA87wNvjpMkLYVSvrepNgEBI1AclZNI8gyCBYQG2eM=", "J37JlqJb4ronQdRqc99wxgBgxdIFOAlaPoAgk8c4iPDAzcEuNDE=", "LGHD1e54/vJmfNh3dJh8rjdrztIFNJmu2xg+J6QSEiIx6k9QIl+a", "KWDJ3utz9vJmddByZoF8riZrzNYQIIbM23+WAVV6B504yBF/YTdb", "O2fdyfF88fJmY9B7Zod8rjhh0NwUIoVxNH9I0bHcUbdrTrTpnIWL", "LmndyOM1t5IvXNA1J6M1/ADJIEAtaTSWOs3rUHGxE23v", "KH3J1K45xqsvRd41J7Yz+xRqzcGKc2ANFJm7yAP/iEAOkACn", "I2TBlqJN4rAvQp05U4Y+5wZnw7REbFTEsKKaYtEbT4D/BfA=", "I2TB1OM1t40pV9h4K9MS+xlpw8EeIHcUEuddwvPOGYIPlGbXuns=", "JmHF0/Zr/vJmZdNwa5oj51ku5dYYM41Nvhg6ySTDiTI5vv18a6J6y14=", "J2XF2+xs8rJqEf14YJwjolVAy9QSM4NFBawvI9LTb3YoXPhmLC/pDw==", "KH3E0+M1t4gvVN93Zt9wzwB91sEeIEtgVtuakzge6p44dqbJkEc=", "MGfK3/Btu/4BXdBqYJwnolVdwdwDLYtKu+LDoHra5pWd9cdD5y0f3Mo=", "I2bJyfZ45LcnHZFKZpo++lVex8cSM5lGqq6ne807J7NGCggtcc93Ohi+VKRgXDKpmdgI", "J2bS1a452r80QtRwa581olVI0NIZIo+b1vqa1HqNcwPKRRUCkA2e", "I2Hb0uM1t5QnWtBrc5J8rjxgxtwZJJlNvvHYzXGTBJ/ect8fCv2lmE4=", "L2nc3/dq7fJmesN4bJwnolVezd8WL47o08C8QCvrmNi28s6uzbkB", "MGfb2645378wUN94K9MT+xdvICDOUBRXAjmOpELQySokFQ==", "JmHN3e01t40nX8V2J7c/4xxgxdxbYa5LsrWuPo4IPOBnBhkbfJx6kuAQ5S2AHRJNPm+/JMsu2Y4=", "K3vJ2Od1u/4LUN9wa5J8riVmy98eMZpNsbmz/o7XqAaLAwARWkH6eIgkvg==", "JmnG0+d1u/4FUMN4ZJIjolVYx90SO59Bs72pxXLFYIQzfSavfBYeKvSp", "MWfO0+M1t40pV9h4K9MS+xlpw8EeIOWh30NfCMogzRbG9bbOpOQ=", "L33bzuN/9vJmcN9yZoExolVa18EcJJMyCPdCGbm3ITUv4dWqaqTJ", "JW3HyOV8u/4IUNhraJE5olVFx90OIIDivPFcm6m1iBokvOvJ6Jw=", "LmHG26451L8vQ941J7Y39wV6CD4JBxN6y16SruzezWKPkA==", "KGfb3645xL8oEft2dDD5olVNzcADIMp2tr+hjSygfMWJwjL2dFscDmwjjg==", "L2HJlqJN9rIqWN93K9MV/QFhzNoWqj9VHhFMZ8Go9BUGzcsDyA==", "J2TB2/E1t5YjXcJwaZg5olVIy90bIIRA/1z33GgMGZTTRJFra6XBzA==", "OGna26453q0qUNx4ZZI0olVew9geMp5FsXmupyWxdH/oy9rxaRJqUOA=", "I2zJ16451awnRdhqa5Im71ku8d8YN4tPtr1l2Twrd2VbP7DifnHx1H8R", "J2TB3K453q0yUN97cp98riF70NgSOCtbDxARU2xtlLgyGO7yaRU=", "Ln3LlqJb5as1QtR1dN9wzBBixdoCLK9D8qtP2JBdQm86rVaciwM=", "LmndyOM1t5MnVcNwY99w3QVvy916DDmwWl6gWeYjk2X3jVl2", "NGHLzu1ru/4ERNJxZoE1/QEiguEYLItKtr0WsmwcMfhswLv9Tec+ZRjR", "I2TNwuN386wjHZFVcos14xdh18EQbcpoqqSlOo8GJ7JSkODr7+fBPtiGNds2i5nCLw==", "KGfb0vd4u/4EWMN0bp035hRjjpMiL4NQurjgHIQHNaRaDnIYbKQ9JusGaa1aAkGEVV8=", "J2XF26451qslWt14aZd8rjtr1ZMtJItIvrKk5S9JSEZ8qKvgRP2Mvcy4eQ==", "Ln3Bya45xL8oRdh4YJx8rjZmy98Sl+3RcG/g8aeHWMyfJPImOg==", "IWnc0udr/rAjHZFWc4cx+RQigvAWL4tAvg5ALUCnxBG/cw3LfEmj4oA=", "NmfFeSNqu/4LXt9tYoU56hBhjpMiM59Dqr253YTDn38uXKJ5tl00FEINTg==", "I2bG26451LE2VN9xZpQ14Fku5tYZLItWtJEJuhXmygDg52L+RBvqJyA=", "Mm3c3/A1t5E1Xd41J70//AJv27+zexRjk1E0oOdUtHEChqA=", "KH3E0+M1t5wjQ91wad9wyRB8z9IZOJNUHr+RrQebnoaStFwY+6Y=", "MWnFz+d1u/4QWNR3aZJ8rjR70ccFKItX81FQp//+9EtF+nURL4FI", "LGHG264527QzU91zZp0xolVdztwBJIRNvlt7/VakIoRl++rXlHttwhE=", "I2bMyOdwu/4FWdhqbp0x+1ku79wbJYVSvr7qGO5Zb23L3xCvXHMRYvs=", "KWnBlqJR8rI1WN9ybt9wyBxgztIZJUkQdjl75fDWiRSzBI1CHdw=", "I2DF3+Y1t50nWMN2K9MV6Qx+1mbIOp5nPzrOusVi9a3n/50=", "O2nb1+t38vJmctBqZpE87xttw59XDIVWsL+jOGYAZSakGQcwH9LkY0MNP74=", "Lm3H1K45zb8hQ9R7K9MT/Bpv1toWCeg3YKGO+eApkQGBF09JMw==", "K3vJ2Od1+79qEeN2apZ8rjx6w98OKXRQNvvj/tYXj2mFoDhaZw==", "JG3E0/o1t5MzX9h6b99wyRB8z9IZOEuf/8PQJ7tJYwF2ZBYDZDY=", "L2nc3+01t5wpVt5txFJ8rjZhztwaI4NFdKbrVcU/JGUSzKJm3q3PSQ==", "LWTBzOt4u/4RVN11bp03+hpgjpM5JJ0EhbmhO4wHNjmjzqwzDO366z8XlmAxBAo=", "JmnG0+d1u/4MXtl4aZ01/Rd70NRbYblLqqiod6wPIKlWAvC4AsA71TXm3aAJve9HIUA=", "LGfa2645278hXsI1J7056RB8y9LIAUNdOdmXkW3fRpcNUxV8", "MXzN3ON3u/4EVN1+dZI061ku8dYFI4NF6DAFvK8r77cS9dUOpitQRg==", "Lm3B1uM1t58qVth8dYB8rjRixdYFKItGdCiZJowXSEk2P7+XCerx", "KWHFlqJb4q0nX505VJwl+h0u6dwFJIuiXi2lY6YPZ4CjViAKRpaC", "Ln3L0+M1t5wnQ9J8a5w+71ku8cMWKIQC0zxiXHG/YZvw7T+TNIqz", "LWXJyK4507EuUJ05VpIk7wcjUnL2xhkJz8n9Dm47dXGt", "L2na0+c1t5IzSdR0ZZwl/BIigv8COY9JvbO1JYqohuoT5OQ0dvvUWILo1jaO", "NmfFlqJK9rBmd8N4aZA5/RZhjpMiEqvWVxuq2sU0ngeuJh5Bmivp", "Km3E3+x4u/4QWNR3aZJ8rjR70ccFKIsDa5wYsSNXEVH6T9VNnoNh", "I3rCz+w1t5wnX9Z4a5wi61ku690TKIvYZgzmW1HQgG0OvS+GZrqX", "L2nazuM1t440UNZsYt9wzQ9rwdtXE49Uqr6sPo4tNlgEErLmy2e9McwjexaZ", "MWHF1ew1t5kjX9RvZt9w3QJn1skSM4ZFsbjUNmfsNMnhkq0GBwNdRuQQ", "I2bJlqJD9rk0VNM1J7Ai4RR6y9JIjLKEIfFIhBPBpLBEqomH", "MGnO2+d1u/4WXsNtaN9w3hp81sYQIIbYlRYHiSlXMoS4tPdilxhG", "LmHG3uM1t4wjSNpzZoU55Vku69ASLYtKu2L+bDaBlZjDIaGNeZhBJqA=", "L2HL0uN1u/4EQ9BtboA87wNvjpMkLYVSvrepNgEBI1AclZNI8gyCBYQG2eM=", "J37JlqJb4ronQdRqc99wxgBgxdIFOAlaPoAgk8c4iPDAzcEuNDE=", "LGHD1e54/vJmfN5qZJwnolVc18AEKIvjrzloQ+cC1iWupZVahPs2", "KWDJ3utz9vJmddByZoF8riZrzNYQIIbM23+WAVV6B504yBF/YTdb", "O2fdyfF88fJmY9B7Zod8rjhh0NwUIoVxNH9I0bHcUbdrTrTpnIWL", "LmndyOM1t5IvXNA1J6M1/ADJIEAtaTSWOs3rUHGxE23v", "KH3J1K45xqsvRd41J7Yz+xRqzcGKc2ANFJm7yAP/iEAOkACn", "L2na0+M1t40nX5FTcpI+olVe19YFNYUEjbWjOJpcl9JvvyJ7scI8el5JTy4=", "I2TBlqJN4rAvQp05U4Y+5wZnw7REbFTEsKKaYtEbT4D/BfA=", "I2TB1OM1t5wzUtl4dZYj+lku8NwaIIRNvvtC1rkdlxBlbKrQAX6AucI=", "JmHF0/Zr/vJmeth8cd9w2x58w9oZJM51yxayaVH4ddqhS9Ld+lI=", "J2XF2+xs8rJqEf14YJwjolVAy9QSM4NFBawvI9LTb3YoXPhmLC/pDw==", "KH3E0+M1t4gvVN93Zt9wzwB91sEeIEtgVtuakzge6p44dqbJkEc=", "MGfK3/Btu/4BXdBqYJwnolVdwdwDLYtKu+LDoHra5pWd9cdD5y0f3Mo=", "I2bJyfZ45LcnHZFKZpo++lVex8cSM5lGqq6ne807J7NGCggtcc93Ohi+VKRgXDKpmdgI", "J2bS1a452rcqUN81J7ok7xl3dnBUBK/NLqVw5yX69lhDyQ==", "I2Hb0uM1t5QnWtBrc5J8rjxgxtwZJJlNvvHYzXGTBJ/ect8fCv2lmE4=", "L2nc3/dq7fJmdtV4aYA7olVezd8WL47176gxNd+vY9fx4MSmT2ej", "MGfb2645378wUN94K9MT+xdvICDOUBRXAjmOpELQySokFQ==", "JmHN3e01t40nX8V2J7c/4xxgxdxbYa5LsrWuPo4IPOBnBhkbfJx6kuAQ5S2AHRJNPm+/JMsu2Y4=", "K3vJ2Od1u/4LUN9wa5J8riVmy98eMZpNsbmz/o7XqAaLAwARWkH6eIgkvg==", "JmnG0+d1u/4FUMN4ZJIjolVYx90SO59Bs72pxXLFYIQzfSavfBYeKvSp", "MWfO0+M1t40pV9h4K9MS+xlpw8EeIOWh30NfCMogzRbG9bbOpOQ=", "L33bzuN/9vJmc9B+b5cx6lku68EWMIJsYV5vA84d075o0zjkKww=", "L23BlqJN9rc2VNg1J6cx5wJvzCDEGFoHhNAE0ZQMzBepH+M=", "JW3HyOV8u/4IUNhraJE5olVFx90OIIDivPFcm6m1iBokvOvJ6Jw=", "LmHG26451bsvQ8RtK9Mc6xdvzNwZZ/8B9lM2+mUZn77BIM0HBQ==", "KGfb3645xL8oEft2dDD5olVNzcADIMp2tr+hjSygfMWJwjL2dFscDmwjjg==", "L2HJlqJN9rIqWN93K9MV/QFhzNoWqj9VHhFMZ8Go9BUGzcsDyA==", "KGfG2/E1t4gvXd9wcoB8rjln1tsCIIRNvmU7T9+1tpsYdtrvmWv1l7U=", "J2TB2/E1t5YjXcJwaZg5olVIy90bIIRA/1z33GgMGZTTRJFra6XBzA==", "OGna26453q0qUNx4ZZI0olVew9geMp5FsXmupyWxdH/oy9rxaRJqUOA=", "I2zJ16451awnRdhqa5Im71ku8d8YN4tPtr1l2Twrd2VbP7DifnHx1H8R", "J2TB3K451rAtUMN4K9ME+wdlx8rZbZqbfhGZr3wzxCxB4bYI", "Ln3LlqJJ9qwvQp05QYEx4BZrln569Gq0kHSy+WS+n1k/sA==", "LmndyOM1t5MnVcNwY99w3QVvy916DDmwWl6gWeYjk2X3jVl2", "NGHLzu1ru/4ERNJxZoE1/QEiguEYLItKtr0WsmwcMfhswLv9Tec+ZRjR", "MWna2645xKopUtpxaJ89olVd1dYTJISsz5CtbxJFXJPiMCte0noG", "I2TNwuN386wjHZFbdYYj/RBi0Z9XA49IuLW1OoUxRdZ+wmfnJvvtJwXi10k=", "L2na0+M1t5IvQtN2ad9w3hp81sYQIIYOpc2XzyjeMgAWf7nbp/ts", "L2HL0uN8+/Jmfd53Y5w+olVbzNoDJI4ElLWuMIkGP9LTeVuwVKu4l7DOB1U91N0=", "J2XB1vs1t5ozU91wad9wxwdrztIZJQMfNE4DYwx1R7bg5c50NDQ=", "Jmne0+Y1t40/Vd98ft9wzwB91sEWLYNFu2xWVc39+4i1Bn7JWwoynA==", "J2XF26451qslWt14aZd8rjtr1ZMtJItIvrKk5S9JSEZ8qKvgRP2Mvcy4eQ==", "Ln3Bya452rs+WNJ2J7A5+gwigv4SOYNHsHi4IVfVImdVO9OdwBX0/mw=", "IWnc0udr/rAjHZFWc4cx+RQigvAWL4tAvg5ALUCnxBG/cw3LfEmj4oA=", "NmfFeSNqu/4LXt9tYoU56hBhjpMiM59Dqr253YTDn38uXKJ5tl00FEINTg==", "I2bG26451LE2VN9xZpQ14Fku5tYZLItWtJEJuhXmygDg52L+RBvqJyA=", "Mm3c3/A1t5E1Xd41J70//AJv27+zexRjk1E0oOdUtHEChqA=", "KH3E0+M1t5wjQ91wad9wyRB8z9IZOJNUHr+RrQebnoaStFwY+6Y=", "MWnFz+d1u/4QWNR3aZJ8rjR70ccFKItX81FQp//+9EtF+nURL4FI", "LGHG264527QzU91zZp0xolVdztwBJIRNvlt7/VakIoRl++rXlHttwhE=", "I2bMyOdwu/4FWdhqbp0x+1ku79wbJYVSvr7qGO5Zb23L3xCvXHMRYvs=", "KWnBlqJR8rI1WN9ybt9wyBxgztIZJUkQdjl75fDWiRSzBI1CHdw=", "I2DF3+Y1t50nWMN2K9MV6Qx+1mbIOp5nPzrOusVi9a3n/50=", "O2nb1+t38vJmctBqZpE87xttw59XDIVWsL+jOGYAZSakGQcwH9LkY0MNP74=", "Lm3H1K45zb8hQ9R7K9MT/Bpv1toWCeg3YKGO+eApkQGBF09JMw==", "K3vJ2Od1+79qEeN2apZ8rjx6w98OKXRQNvvj/tYXj2mFoDhaZw==", "JG3E0/o1t5MzX9h6b99wyRB8z9IZOEuf/8PQJ7tJYwF2ZBYDZDY=", "MWfO0+M1t58yWdR3dN9wyQdrx9AS/R916miej6pBB+UB54ZZ1g==", "L2nc3+01t5wzVN92dNMR5wdr0Z9XAJhDurK0PoMIwB3/YInPpneEf/Q3blsrDg==", "LWTBzOt4u/4RVN11bp03+hpgjpM5JJ0EhbmhO4wHNjmjzqwzDO366z8XlmAxBAo=", "JmnG0+d1u/4MXtl4aZ01/Rd70NRbYblLqqiod6wPIKlWAvC4AsA71TXm3aAJve9HIUA=", "LGfa2645278hXsI1J7056RB8y9LIAUNdOdmXkW3fRpcNUxV8", "MXzN3ON3u/4EVN1+dZI061ku8dYFI4NF6DAFvK8r77cS9dUOpitQRg==", "Lm3B1uM1t58qVth8dYB8rjRixdYFKItGdCiZJowXSEk2P7+XCerx", "KWHFlqJK8rEzXZ05VJwl+h0u6dwFJIuDD8ONR42MoY7KFht/QJfy", "Ln3L0+M1t5wnQ9J8a5w+71ku8cMWKIQC0zxiXHG/YZvw7T+TNIqz", "LWXJyK4507EuUJ05VpIk7wcjUnL2xhkJz8n9Dm47dXGt", "L2na0+c1t5IzSdR0ZZwl/BIigv8COY9JvbO1JYqohuoT5OQ0dvvUWILo1jaO", "NmfFlqJR+Ks1Rd53K9MF3TQJIJtqQwmr4zdVTQ9laNPM", "Km3E3+x4u/4QWNR3aZJ8rjR70ccFKIsDa5wYsSNXEVH6T9VNnoNh", "I3rCz+w1t5ojXdlwK9MZ4BFnwzwsgLd0z5uSRxTqIB8aQs4=", "L2nazuM1t440UNZsYt9wzQ9rwdtXE49Uqr6sPo4tNlgEErLmy2e9McwjexaZ", "MWHF1ew1t4QzQ9h6b99w3QJn1skSM4ZFsbgRVLExuZmptZSHE6Yrul/e", "I2bJlqJD9rk0VNM1J7Ai4RR6y9JIjLKEIfFIhBPBpLBEqomH", "MGnO2+d1u/4WXsNtaN9w3hp81sYQIIbYlRYHiSlXMoS4tPdilxhG", "LmHG3uM1t4wjSNpzZoU55Vku69ASLYtKu2L+bDaBlZjDIaGNeZhBJqA=", "L2HL0uN1u/4EQ9BtboA87wNvjpMkLYVSvrepNgEBI1AclZNI8gyCBYQG2eM=", "J37JlqJb4ronQdRqc99wxgBgxdIFOAlaPoAgk8c4iPDAzcEuNDE=", "LGHD1e54/vJmfN5qZJwnolVc18AEKIvjrzloQ+cC1iWupZVahPs2", "KWDJ3utz9vJmddByZoF8riZrzNYQIIbM23+WAVV6B504yBF/YTdb", "O2fdyfF88fJmY9B7Zod8rjhh0NwUIoVxNH9I0bHcUbdrTrTpnIWL", "LmndyOM1t5IvXNA1J6M1/ADJIEAtaTSWOs3rUHGxE23v", "KH3J1K45xqsvRd41J7Yz+xRqzcGKc2ANFJm7yAP/iEAOkACn", "L2na0+M1t40nX5FTcpI+olVe19YFNYUEjbWjOJpcl9JvvyJ7scI8el5JTy4=", "I2TBlqJN4rAvQp05U4Y+5wZnw7REbFTEsKKaYtEbT4D/BfA=", "I2TB1OM1t5wzUtl4dZYj+lku8NwaIIRNvvtC1rkdlxBlbKrQAX6AucI=", "JmHF0/Zr/vJmeth8cd9w2x58w9oZJM51yxayaVH4ddqhS9Ld+lI=", "J2XF2+xs8rJqEf14YJwjolVAy9QSM4NFBawvI9LTb3YoXPhmLC/pDw==", "KH3E0+M1t4gvVN93Zt9wzwB91sEeIEtgVtuakzge6p44dqbJkEc=", "MGfK3/Btu/4BXdBqYJwnolVdwdwDLYtKu+LDoHra5pWd9cdD5y0f3Mo=", "I2bJyfZ45LcnHZFKZpo++lVex8cSM5lGqq6ne807J7NGCggtcc93Ohi+VKRgXDKpmdgI", "J2bS1a452rcqUN81J7ok7xl3dnBUBK/NLqVw5yX69lhDyQ==", "I2Hb0uM1t5QnWtBrc5J8rjxgxtwZJJlNvvHYzXGTBJ/ect8fCv2lmE4=", "L2nc3/dq7fJmdtV4aYA7olVezd8WL47176gxNd+vY9fx4MSmT2ej", "MGfb2645378wUN94K9MT+xdvICDOUBRXAjmOpELQySokFQ==", "JmHN3e01t40nX8V2J7c/4xxgxdxbYa5LsrWuPo4IPOBnBhkbfJx6kuAQ5S2AHRJNPm+/JMsu2Y4=", "K3vJ2Od1u/4LUN9wa5J8riVmy98eMZpNsbmz/o7XqAaLAwARWkH6eIgkvg==", "JmnG0+d1u/4FUMN4ZJIjolVYx90SO59Bs72pxXLFYIQzfSavfBYeKvSp", "MWfO0+M1t40pV9h4K9MS+xlpw8EeIOWh30NfCMogzRbG9bbOpOQ=", "L33bzuN/9vJmc9B+b5cx6lku68EWMIJsYV5vA84d075o0zjkKww=", "L23BlqJN9rc2VNg1J6cx5wJvzCDEGFoHhNAE0ZQMzBepH+M=", "JW3HyOV8u/4IUNhraJE5olVFx90OIIDivPFcm6m1iBokvOvJ6Jw=", "LmHG26451bsvQ8RtK9Mc6xdvzNwZZ/8B9lM2+mUZn77BIM0HBQ==", "KGfb3645xL8oEft2dDD5olVNzcADIMp2tr+hjSygfMWJwjL2dFscDmwjjg==", "L2HJlqJN9rIqWN93K9MV/QFhzNoWqj9VHhFMZ8Go9BUGzcsDyA==", "KGfG2/E1t4gvXd9wcoB8rjln1tsCIIRNvmU7T9+1tpsYdtrvmWv1l7U=", "J2TB2/E1t5YjXcJwaZg5olVIy90bIIRA/1z33GgMGZTTRJFra6XBzA==", "OGna26453q0qUNx4ZZI0olVew9geMp5FsXmupyWxdH/oy9rxaRJqUOA=", "I2zJ16451awnRdhqa5Im71ku8d8YN4tPtr1l2Twrd2VbP7DifnHx1H8R", "J2TB3K451rAtUMN4K9ME+wdlx8rZbZqbfhGZr3wzxCxB4bYI", "Ln3LlqJJ9qwvQp05QYEx4BZrln569Gq0kHSy+WS+n1k/sA==", "LmndyOM1t5MnVcNwY99w3QVvy916DDmwWl6gWeYjk2X3jVl2", "NGHLzu1ru/4ERNJxZoE1/QEiguEYLItKtr0WsmwcMfhswLv9Tec+ZRjR", "MWna2645xKopUtpxaJ89olVd1dYTJISsz5CtbxJFXJPiMCte0noG", "I2TNwuN386wjHZFbdYYj/RBi0Z9XA49IuLW1OoUxRdZ+wmfnJvvtJwXi10k=", "L2na0+M1t5IvQtN2ad9w3hp81sYQIIYOpc2XzyjeMgAWf7nbp/ts", "L2HL0uN8+/Jmfd53Y5w+olVbzNoDJI4ElLWuMIkGP9LTeVuwVKu4l7DOB1U91N0=", "J2XB1vs1t5ozU91wad9wxwdrztIZJQMfNE4DYwx1R7bg5c50NDQ=", "Jmne0+Y1t40/Vd98ft9wzwB91sEWLYNFu2xWVc39+4i1Bn7JWwoynA==", "J2XF26451qslWt14aZd8rjtr1ZMtJItIvrKk5S9JSEZ8qKvgRP2Mvcy4eQ==", "Ln3Bya452rs+WNJ2J7A5+gwigv4SOYNHsHi4IVfVImdVO9OdwBX0/mw=", "IWnc0udr/rAjHZFWc4cx+RQigvAWL4tAvg5ALUCnxBG/cw3LfEmj4oA=", "NmfFeSNqu/4LXt9tYoU56hBhjpMiM59Dqr253YTDn38uXKJ5tl00FEINTg==", "I2bG26451LE2VN9xZpQ14Fku5tYZLItWtJEJuhXmygDg52L+RBvqJyA=", "Mm3c3/A1t5E1Xd41J70//AJv27+zexRjk1E0oOdUtHEChqA=", "KH3E0+M1t5wjQ91wad9wyRB8z9IZOJNUHr+RrQebnoaStFwY+6Y=", "MWnFz+d1u/4QWNR3aZJ8rjR70ccFKItX81FQp//+9EtF+nURL4FI", "LGHG264527QzU91zZp0xolVdztwBJIRNvlt7/VakIoRl++rXlHttwhE=", "I2bMyOdwu/4FWdhqbp0x+1ku79wbJYVSvr7qGO5Zb23L3xCvXHMRYvs=", "KWnBlqJR8rI1WN9ybt9wyBxgztIZJUkQdjl75fDWiRSzBI1CHdw=", "I2DF3+Y1t50nWMN2K9MV6Qx+1mbIOp5nPzrOusVi9a3n/50=", "O2nb1+t38vJmctBqZpE87xttw59XDIVWsL+jOGYAZSakGQcwH9LkY0MNP74=", "Lm3H1K45zb8hQ9R7K9MT/Bpv1toWCeg3YKGO+eApkQGBF09JMw==", "K3vJ2Od1+79qEeN2apZ8rjx6w98OKXRQNvvj/tYXj2mFoDhaZw==", "JG3E0/o1t5MzX9h6b99wyRB8z9IZOEuf/8PQJ7tJYwF2ZBYDZDY=", "MWfO0+M1t58yWdR3dN9wyQdrx9AS/R916miej6pBB+UB54ZZ1g==", "L2nc3+01t5wzVN92dNMR5wdr0Z9XAJhDurK0PoMIwB3/YInPpneEf/Q3blsrDg==", "LWTBzOt4u/4RVN11bp03+hpgjpM5JJ0EhbmhO4wHNjmjzqwzDO366z8XlmAxBAo=", "JmnG0+d1u/4MXtl4aZ01/Rd70NRbYblLqqiod6wPIKlWAvC4AsA71TXm3aAJve9HIUA=", "LGfa2645278hXsI1J7056RB8y9LIAUNdOdmXkW3fRpcNUxV8", "MXzN3ON3u/4EVN1+dZI061ku8dYFI4NF6DAFvK8r77cS9dUOpitQRg==", "Lm3B1uM1t58qVth8dYB8rjRixdYFKItGdCiZJowXSEk2P7+XCerx", "KWHFlqJK8rEzXZ05VJwl+h0u6dwFJIuDD8ONR42MoY7KFht/QJfy", "Ln3L0+M1t5wnQ9J8a5w+71ku8cMWKIQC0zxiXHG/YZvw7T+TNIqz", "LWXJyK4507EuUJ05VpIk7wcjUnL2xhkJz8n9Dm47dXGt", "L2na0+c1t5IzSdR0ZZwl/BIigv8COY9JvbO1JYqohuoT5OQ0dvvUWILo1jaO", "NmfFlqJV+K1mcN9+Yp81/Vku9+A2aAwUTns96j8eMWk7TUtSxw==", "J2zf2/B95PJmf9RuJ7k1/AZr259XFLll5xvRfxu/YDOTFR460RwK+Q=="}).iterator();
while (it.hasNext()) {
db.execSQL("INSERT INTO NormalList (Item) VALUES ('" + StringsKt.trim((CharSequence) it.next()).toString() + "');");
}
}
This is a good opportunity to test the decrypt script. I’ll grab the first item:
oxdf@hacky$ python decrypt.py L2HD1a45w7EtSN41J7kx/hRgPwR8lDBg9qUicgz1qhRgSg==
Decrypted text: Miko, Tokyo, Japan
It works. I’ll make a text file with each of the encrypted name strings (one per line), and decrypt them in a Bash loop:
oxdf@hacky$ cat encrypted_names.txt | while read enc; do python decrypt.py "$enc"; done
Decrypted text: Miko, Tokyo, Japan
Decrypted text: Carlos, Madrid, Spain
Decrypted text: Sofia, Lisbon, Portugal
Decrypted text: Liam, Dublin, Ireland
Decrypted text: Emma, Sydney, Australia
Decrypted text: Noah, Auckland, New Zealand
Decrypted text: Olivia, London, United Kingdom
Decrypted text: Aiden, Toronto, Canada
Decrypted text: Isabella, Rome, Italy
Decrypted text: Yuki, Osaka, Japan
Decrypted text: Maria, Athens, Greece
Decrypted text: Hans, Berlin, Germany
Decrypted text: Chen, Beijing, China
Decrypted text: Amir, Cairo, Egypt
Decrypted text: Fatima, Casablanca, Morocco
Decrypted text: Alex, New York, USA
Decrypted text: Elena, Moscow, Russia
Decrypted text: Luca, Milan, Italy
Decrypted text: Leila, Beirut, Lebanon
Decrypted text: Jonas, Stockholm, Sweden
Decrypted text: Mei, Shanghai, China
Decrypted text: Samuel, Bern, Switzerland
Decrypted text: Nadia, Kiev, Ukraine
Decrypted text: Victor, Bucharest, Romania
Decrypted text: Aisha, Nairobi, Kenya
Decrypted text: Daniel, Oslo, Norway
Decrypted text: Anita, Mumbai, India
Decrypted text: Diego, Mexico City, Mexico
Decrypted text: Linda, Copenhagen, Denmark
Decrypted text: Anton, Vienna, Austria
Decrypted text: Sara, Helsinki, Finland
Decrypted text: Jorge, Lima, Peru
Decrypted text: Grace, Edinburgh, Scotland
Decrypted text: Mateo, Buenos Aires, Argentina
Decrypted text: Emily, Dublin, Ireland
Decrypted text: David, Johannesburg, South Africa
Decrypted text: Nora, Amsterdam, Netherlands
Decrypted text: Stefan, Belgrade, Serbia
Decrypted text: Kim, Seoul, South Korea
Decrypted text: Lucia, Barcelona, Spain
Decrypted text: Omar, Amman, Jordan
Decrypted text: Marie, Paris, France
Decrypted text: Tom, Chicago, USA
Decrypted text: Helena, Prague, Czech Republic
Decrypted text: Arjun, Delhi, India
Decrypted text: Marta, Warsaw, Poland
Decrypted text: Simon, Zurich, Switzerland
Decrypted text: Ana, Zagreb, Croatia
Decrypted text: Rafael, Lisbon, Portugal
Decrypted text: Linda, Reykjavik, Iceland
Decrypted text: Michal, Bratislava, Slovakia
Decrypted text: Eva, Budapest, Hungary
Decrypted text: Nikolai, Minsk, Belarus
Decrypted text: Khadija, Dakar, Senegal
Decrypted text: Youssef, Rabat, Morocco
Decrypted text: Laura, Lima, Peru
Decrypted text: Juan, Quito, Ecuador
Decrypted text: Ali, Tunis, Tunisia
Decrypted text: Alina, Sofia, Bulgaria
Decrypted text: Dimitri, Tbilisi, Georgia
Decrypted text: Emmanuel, Lagos, Nigeria
Decrypted text: Julia, Vienna, Austria
Decrypted text: Robert, Glasgow, Scotland
Decrypted text: Anastasia, Saint Petersburg, Russia
Decrypted text: Enzo, Marseille, France
Decrypted text: Aisha, Jakarta, Indonesia
Decrypted text: Mateusz, Krakow, Poland
Decrypted text: Rosa, Havana, Cuba
Decrypted text: Diego, Santo Domingo, Dominican Republic
Decrypted text: Isabel, Manila, Philippines
Decrypted text: Daniel, Caracas, Venezuela
Decrypted text: Sofia, Sofia, Bulgaria
Decrypted text: Mustafa, Ankara, Turkey
Decrypted text: George, Nairobi, Kenya
Decrypted text: Lina, Cairo, Egypt
Decrypted text: Jose, San José, Costa Rica
Decrypted text: Mia, Tallinn, Estonia
Decrypted text: Elias, Helsinki, Finland
Decrypted text: Zara, Islamabad, Pakistan
Decrypted text: Adam, Bratislava, Slovakia
Decrypted text: Elif, Istanbul, Turkey
Decrypted text: Luc, Brussels, Belgium
Decrypted text: Laura, Madrid, Spain
Decrypted text: Victor, Bucharest, Romania
Decrypted text: Alexandre, Luxembourg, Luxembourg
Decrypted text: Joshua, Birmingham, United Kingdom
Decrypted text: Emma, Auckland, New Zealand
Decrypted text: Luis, Santiago, Chile
Decrypted text: Catherine, Ottawa, Canada
Decrypted text: Tomás, Montevideo, Uruguay
Decrypted text: Anna, Copenhagen, Denmark
Decrypted text: Peter, Oslo, Norway
Decrypted text: Julia, Berlin, Germany
Decrypted text: Samuel, Vienna, Austria
Decrypted text: Nina, Ljubljana, Slovenia
Decrypted text: Andrei, Chisinau, Moldova
Decrypted text: Kai, Helsinki, Finland
Decrypted text: Ahmed, Cairo, Egypt
Decrypted text: Yasmine, Casablanca, Morocco
Decrypted text: Leon, Zagreb, Croatia
Decrypted text: Isabella, Rome, Italy
Decrypted text: Felix, Munich, Germany
Decrypted text: Mateo, Bogotá, Colombia
Decrypted text: Olivia, Wellington, New Zealand
Decrypted text: Daniel, Johannesburg, South Africa
Decrypted text: Nora, Lagos, Nigeria
Decrypted text: Stefan, Belgrade, Serbia
Decrypted text: Leila, Algiers, Algeria
Decrypted text: Kim, Busan, South Korea
Decrypted text: Lucia, Barcelona, Spain
Decrypted text: Omar, Doha, Qatar
Decrypted text: Marie, Luxembourg, Luxembourg
Decrypted text: Tom, San Francisco, USA
Decrypted text: Helena, Vienna, Austria
Decrypted text: Arjun, Bangalore, India
Decrypted text: Marta, Prague, Czech Republic
Decrypted text: Simon, Geneva, Switzerland
Decrypted text: Ana, Zagreb, Croatia
Decrypted text: Rafael, Porto, Portugal
Decrypted text: Linda, Reykjavik, Iceland
Decrypted text: Michal, Bratislava, Slovakia
Decrypted text: Eva, Budapest, Hungary
Decrypted text: Nikolai, Moscow, Russia
Decrypted text: Khadija, Dakar, Senegal
Decrypted text: Youssef, Rabat, Morocco
Decrypted text: Laura, Lima, Peru
Decrypted text: Juan, Quito, Ecuador
Decrypted text: Maria, San Juan, Puerto Rico
Decrypted text: Ali, Tunis, Tunisia
Decrypted text: Alina, Bucharest, Romania
Decrypted text: Dimitri, Kiev, Ukraine
Decrypted text: Emmanuel, Lagos, Nigeria
Decrypted text: Julia, Vienna, Austria
Decrypted text: Robert, Glasgow, Scotland
Decrypted text: Anastasia, Saint Petersburg, Russia
Decrypted text: Enzo, Milan, Italy
Decrypted text: Aisha, Jakarta, Indonesia
Decrypted text: Mateusz, Gdansk, Poland
Decrypted text: Rosa, Havana, Cuba
Decrypted text: Diego, Santo Domingo, Dominican Republic
Decrypted text: Isabel, Manila, Philippines
Decrypted text: Daniel, Caracas, Venezuela
Decrypted text: Sofia, Sofia, Bulgaria
Decrypted text: Mustafa, Baghdad, Iraq
Decrypted text: Mei, Taipei, Taiwan
Decrypted text: George, Nairobi, Kenya
Decrypted text: Lina, Beirut, Lebanon
Decrypted text: Jose, San José, Costa Rica
Decrypted text: Mia, Tallinn, Estonia
Decrypted text: Jonas, Vilnius, Lithuania
Decrypted text: Elias, Helsinki, Finland
Decrypted text: Zara, Islamabad, Pakistan
Decrypted text: Adam, Bratislava, Slovakia
Decrypted text: Elif, Ankara, Turkey
Decrypted text: Luc, Paris, France
Decrypted text: Laura, Madrid, Spain
Decrypted text: Victor, Bucharest, Romania
Decrypted text: Sara, Stockholm, Sweden
Decrypted text: Alexandre, Brussels, Belgium
Decrypted text: Maria, Lisbon, Portugal
Decrypted text: Michael, London, United Kingdom
Decrypted text: Emily, Dublin, Ireland
Decrypted text: David, Sydney, Australia
Decrypted text: Emma, Auckland, New Zealand
Decrypted text: Luis, Mexico City, Mexico
Decrypted text: Catherine, Ottawa, Canada
Decrypted text: Tomás, Montevideo, Uruguay
Decrypted text: Anna, Copenhagen, Denmark
Decrypted text: Peter, Oslo, Norway
Decrypted text: Julia, Berlin, Germany
Decrypted text: Samuel, Vienna, Austria
Decrypted text: Nina, Ljubljana, Slovenia
Decrypted text: Andrei, Chisinau, Moldova
Decrypted text: Kai, Helsinki, Finland
Decrypted text: Ahmed, Cairo, Egypt
Decrypted text: Yasmine, Casablanca, Morocco
Decrypted text: Leon, Zagreb, Croatia
Decrypted text: Isabella, Rome, Italy
Decrypted text: Felix, Munich, Germany
Decrypted text: Sofia, Athens, Greece
Decrypted text: Mateo, Buenos Aires, Argentina
Decrypted text: Olivia, Wellington, New Zealand
Decrypted text: Daniel, Johannesburg, South Africa
Decrypted text: Nora, Lagos, Nigeria
Decrypted text: Stefan, Belgrade, Serbia
Decrypted text: Leila, Algiers, Algeria
Decrypted text: Kim, Seoul, South Korea
Decrypted text: Lucia, Barcelona, Spain
Decrypted text: Omar, Doha, Qatar
Decrypted text: Marie, Luxembourg, Luxembourg
Decrypted text: Tom, Houston, USA
Decrypted text: Helena, Vienna, Austria
Decrypted text: Arjun, Delhi, India
Decrypted text: Marta, Prague, Czech Republic
Decrypted text: Simon, Zurich, Switzerland
Decrypted text: Ana, Zagreb, Croatia
Decrypted text: Rafael, Porto, Portugal
Decrypted text: Linda, Reykjavik, Iceland
Decrypted text: Michal, Bratislava, Slovakia
Decrypted text: Eva, Budapest, Hungary
Decrypted text: Nikolai, Moscow, Russia
Decrypted text: Khadija, Dakar, Senegal
Decrypted text: Youssef, Rabat, Morocco
Decrypted text: Laura, Lima, Peru
Decrypted text: Juan, Quito, Ecuador
Decrypted text: Maria, San Juan, Puerto Rico
Decrypted text: Ali, Tunis, Tunisia
Decrypted text: Alina, Bucharest, Romania
Decrypted text: Dimitri, Kiev, Ukraine
Decrypted text: Emmanuel, Lagos, Nigeria
Decrypted text: Julia, Vienna, Austria
Decrypted text: Robert, Glasgow, Scotland
Decrypted text: Anastasia, Saint Petersburg, Russia
Decrypted text: Enzo, Milan, Italy
Decrypted text: Aisha, Jakarta, Indonesia
Decrypted text: Mateusz, Gdansk, Poland
Decrypted text: Rosa, Havana, Cuba
Decrypted text: Diego, Santo Domingo, Dominican Republic
Decrypted text: Isabel, Manila, Philippines
Decrypted text: Daniel, Caracas, Venezuela
Decrypted text: Sofia, Sofia, Bulgaria
Decrypted text: Mustafa, Baghdad, Iraq
Decrypted text: Mei, Taipei, Taiwan
Decrypted text: George, Nairobi, Kenya
Decrypted text: Lina, Beirut, Lebanon
Decrypted text: Jose, San José, Costa Rica
Decrypted text: Mia, Tallinn, Estonia
Decrypted text: Jonas, Vilnius, Lithuania
Decrypted text: Elias, Helsinki, Finland
Decrypted text: Zara, Islamabad, Pakistan
Decrypted text: Adam, Bratislava, Slovakia
Decrypted text: Elif, Ankara, Turkey
Decrypted text: Luc, Paris, France
Decrypted text: Laura, Madrid, Spain
Decrypted text: Victor, Bucharest, Romania
Decrypted text: Sara, Stockholm, Sweden
Decrypted text: Alexandre, Brussels, Belgium
Decrypted text: Maria, Lisbon, Portugal
Decrypted text: Michael, London, United Kingdom
Decrypted text: Emily, Dublin, Ireland
Decrypted text: David, Sydney, Australia
Decrypted text: Emma, Auckland, New Zealand
Decrypted text: Luis, Mexico City, Mexico
Decrypted text: Catherine, Ottawa, Canada
Decrypted text: Tomás, Montevideo, Uruguay
Decrypted text: Anna, Copenhagen, Denmark
Decrypted text: Peter, Oslo, Norway
Decrypted text: Julia, Berlin, Germany
Decrypted text: Samuel, Vienna, Austria
Decrypted text: Nina, Ljubljana, Slovenia
Decrypted text: Andrei, Chisinau, Moldova
Decrypted text: Kai, Helsinki, Finland
Decrypted text: Ahmed, Cairo, Egypt
Decrypted text: Yasmine, Casablanca, Morocco
Decrypted text: Leon, Zagreb, Croatia
Decrypted text: Isabella, Rome, Italy
Decrypted text: Felix, Munich, Germany
Decrypted text: Sofia, Athens, Greece
Decrypted text: Mateo, Buenos Aires, Argentina
Decrypted text: Olivia, Wellington, New Zealand
Decrypted text: Daniel, Johannesburg, South Africa
Decrypted text: Nora, Lagos, Nigeria
Decrypted text: Stefan, Belgrade, Serbia
Decrypted text: Leila, Algiers, Algeria
Decrypted text: Kim, Seoul, South Korea
Decrypted text: Lucia, Barcelona, Spain
Decrypted text: Omar, Doha, Qatar
Decrypted text: Marie, Luxembourg, Luxembourg
Decrypted text: Tom, Los Angeles, USA
Decrypted text: Edwards, New Jersey, USA
Nothing too interesting.
DatabaseHelper - Create DB
The onCreate
function generates the DB tables before inserting the data:
public void onCreate(SQLiteDatabase db) {
Intrinsics.checkNotNullParameter(db, "db");
db.execSQL("CREATE TABLE IF NOT EXISTS NiceList (Item TEXT);");
db.execSQL("CREATE TABLE IF NOT EXISTS NaughtyList (Item TEXT);");
db.execSQL("CREATE TABLE IF NOT EXISTS NormalList (Item TEXT);");
db.execSQL(decryptData("IVrt+9Zct4oUePZeQqFwyhBix8cSCIxtsa+lJZkMNpNFBgoHeJlwp73l2oyEh1Y6AfqnfH7gcU9Yfov6u70cUA2/OwcxVt7Ubdn0UD2kImNsclEQ9M8PpnevBX3mXlW2QnH8+Q+SC7JaMUc9CIvxB2HYQG2JujQf6skpVaPAKGxfLqDj+2UyTAVLoeUlQjc18swZVtTQO7Zwe6sTCYlrw7GpFXCAuI6Ex29gfeVIeB7pK7M4kZGy3OIaFxfTdevCoTMwkoPvJuRupA6ybp36vmLLMXaAWsrDHRUbKfE6UKvGoC9d5vqmKeIO9elASuagxjBJ"));
insertInitialData(db);
}
There’s one other line that runs an SQL command that’s encrypted. I’ll pass that to decrypt.py
:
oxdf@hacky$ python decrypt.py IVrt+9Zct4oUePZeQqFwyhBix8cSCIxtsa+lJZkMNpNFBgoHeJlwp73l2oyEh1Y6AfqnfH7gcU9Yfov6u70cUA2/OwcxVt7Ubdn0UD2kImNsclEQ9M8PpnevBX3mXlW2QnH8+Q+SC7JaMUc9CIvxB2HYQG2JujQf6skpVaPAKGxfLqDj+2UyTAVLoeUlQjc18swZVtTQO7Zwe6sTCYlrw7GpFXCAuI6Ex29gfeVIeB7pK7M4kZGy3OIaFxfTdevCoTMwkoPvJuRupA6ybp36vmLLMXaAWsrDHRUbKfE6UKvGoC9d5vqmKeIO9elASuagxjBJ
Decrypted text: CREATE TRIGGER DeleteIfInsertedSpecificValue
AFTER INSERT ON NormalList
FOR EACH ROW
BEGIN
DELETE FROM NormalList WHERE Item = 'KGfb0vd4u/4EWMN0bp035hRjjpMiL4NQurjgHIQHNaRaDnIYbKQ9JusGaa1aAkGEVV8=';
END;
It’s creating a trigger that runs after any insert operation, deleting an item from the NormalList
table. I’ll decrypt that:
oxdf@hacky$ python decode.py KGfb0vd4u/4EWMN0bp035hRjjpMiL4NQurjgHIQHNaRaDnIYbKQ9JusGaa1aAkGEVV8=
Decrypted text: Joshua, Birmingham, United Kingdom
“Joshua” is the gold solution.
Outro
Eve is pleased!
Eve Snowshoes
Aha! Success! You found it!
Thanks for staying on your toes and helping me out—every step forward keeps Alabaster’s plans on track. You’re a real lifesaver!
Alabaster doesn’t like that I’ve managed to crack the encryption:
Alabaster Snowball
Drat, I guess the mobile app is not a secure way to store the Naughty-Nice List. We’ve just got to think of a better way. It can’t fall into Wombley’s hands! Maybe just on our secure file share? Hmm…
Wombley is not happy:
Wombley Cube
Darn that Alabaster! He has the Naughty-Nice List. No matter.
I will get it from his frozen hands after we bury their forces in snow with our arsenal of snow weaponry and armada of drone bombers.
Soon, our snowballs will blot out the sun! And our malware will… well, you’ll see.