September 7, 2026
Breaking Down a Lecturer’s Dummy Pokemon App: A Penetration Testing Learning Journey
conducted a penetration test on a dummy Android application created by my lecturer for educational purposes. The app is named Pokemon…
By Anggitaputri
4 min read
conducted a penetration test on a dummy Android application created by my lecturer for educational purposes. The app is named Pokemon Application (Package: com.haku.taptapme). The objective of this testing was purely academic to understand how attackers exploit client-side security flaws in Android apps, and how developers can defend against them.
From my testing, I discovered 6 critical vulnerabilities that allowed me to:
- Bypass the authentication mechanism entirely
- Gain access as an admin/VIP user
- Extract sensitive data from the application's memory
- Perform Man-in-the-Middle (MitM) attacks
The Initial Challenge: Apple Silicon Architecture
The first problem I encountered: I was unable to log in as a guest or a regular user.
The cause: The dummy APK had built-in detection for the Mac M1 chip architecture (Apple Silicon/ARM). When I ran the app on the Android Studio emulator, the login was automatically blocked with an Error 0x02 message.
My solution: I opened a terminal and used JADX to statically analyze the application's source code.
Findings & Exploitation
1. Vulnerabilities in AndroidManifest.xml
Upon inspecting AndroidManifest.xml, I found two dangerous flags:
A. android:debuggable="true"
<application
android:debuggable="true"
android:allowBackup="true"
android:usesCleartextTraffic="true"
...><application
android:debuggable="true"
android:allowBackup="true"
android:usesCleartextTraffic="true"
...>
Risk:
- This flag should never be enabled in a production build.
- If left as
true, an attacker can attach a debugger (JDWP) to the application process.
Impact on Login:
- Enables runtime inspection
- Allows reading variables in memory (passwords/auth tokens)
- Allows manipulation of login functions
- Allows extraction of data from the local database
B. android:usesCleartextTraffic="true"
Risk:
- The application is permitted to send data over plain HTTP (not HTTPS).
Impact on Login:
- Credentials are sent in plain text
- Makes Man-in-the-Middle (MitM) attacks easy on public networks
- Attackers can steal login data using tools like Burp Suite
2. Bypassing Security in SecurityUtils.smali
After extracting the APK using Apktool, I opened SecurityUtils.smali and discovered three security functions that could be modified:
A. Modifying checkSystemState() – Emulator/Root Detection
Original Code:
smali
.method public static checkSystemState()Z
.locals 9
...
return v4
.end method.method public static checkSystemState()Z
.locals 9
...
return v4
.end method
Modified Code:
smali
.method public static checkSystemState()Z
.locals 1
const/4 v0, 0x0
return v0
.end method.method public static checkSystemState()Z
.locals 1
const/4 v0, 0x0
return v0
.end methodExplanation: I modified this function to always return
False(0x0), so the application no longer detects that I am using an emulator or a rooted device.
B. Modifying performDataValidation() – Data Validation
Original Code:
smali
.method public static native performDataValidation(Landroid/content/Context;)Z
.end method.method public static native performDataValidation(Landroid/content/Context;)Z
.end method
Modified Code:
smali
.method public static performDataValidation(Landroid/content/Context;)Z
.locals 1
const/4 v0, 0x1
return v0
.end method.method public static performDataValidation(Landroid/content/Context;)Z
.locals 1
const/4 v0, 0x1
return v0
.end methodExplanation: By forcing the function to return
true (0x1), I bypassed the APK integrity check. This native function typically verifies whether the APK has been tampered with or if there are suspicious system files.
C. Modifying verifyPrivilegeLevel() – Privilege Escalation
Original Code:
smali
.method public static native verifyPrivilegeLevel(Lcom/haku/taptapme/models/User;)Z
.end method.method public static native verifyPrivilegeLevel(Lcom/haku/taptapme/models/User;)Z
.end methodModified Code:
smali
.method public static verifyPrivilegeLevel(Lcom/haku/taptapme/models/User;)Z
.locals 1
const/4 v0, 0x1
return v0
.end method.method public static verifyPrivilegeLevel(Lcom/haku/taptapme/models/User;)Z
.locals 1
const/4 v0, 0x1
return v0
.end methodExplanation: Privilege Escalation — By forcing
verifyPrivilegeLevelto always returntrue, I manipulated the user's account status. This function is likely used to check whether the user is an admin or has special permissions.
D. Modifying verifyRuntimeEnvironment() – Hacking Tool Detection
Original Code:
smali
.method public static verifyRuntimeEnvironment()Z
.locals 7
...
return v3
.end method.method public static verifyRuntimeEnvironment()Z
.locals 7
...
return v3
.end method
Modified Code:
smali
.method public static verifyRuntimeEnvironment()Z
.locals 1
const/4 v0, 0x0
return v0
.end method.method public static verifyRuntimeEnvironment()Z
.locals 1
const/4 v0, 0x0
return v0
.end methodExplanation: Changing the return value from
truetofalsedisables the hacking tool detection, allowing me to use tools like Burp Suite or Frida without being blocked.
3. Re-signing the APK
After modifying all the smali files, I needed to re-sign the APK for installation:
bash
# Download uber-apk-signer
curl -O -L https://github.com/patrickfav/uber-apk-signer/releases/download/v1.3.0/uber-apk-signer-1.3.0.jar
# Sign the APK
java -jar uber-apk-signer-1.3.0.jar -a taptap_mod.apk# Download uber-apk-signer
curl -O -L https://github.com/patrickfav/uber-apk-signer/releases/download/v1.3.0/uber-apk-signer-1.3.0.jar
# Sign the APK
java -jar uber-apk-signer-1.3.0.jar -a taptap_mod.apkThe new file taptap_mod-aligned-debugSigned.apk was successfully created.
4. Installation & A New Problem
bash
# Install to emulator
adb install taptap_mod-aligned-debugSigned.apk# Install to emulator
adb install taptap_mod-aligned-debugSigned.apkProblem: Still couldn't log in! After further investigation, I found an additional issue.
5. Analyzing ApiHandler.smali
I opened ApiHandler.smali and discovered that the application was sending requests to the following URL:
text
https://00bfc8c729f5d4d529a412b12c58ddd2.solusisiber.comhttps://00bfc8c729f5d4d529a412b12c58ddd2.solusisiber.com
When I opened this URL in Chrome, I got "Method Not Allowed" — meaning the server was still alive, and the issue was with the credentials I was entering.
6. Bypassing Login with a Fake Admin Account
I found the login() method in ApiHandler.smali and modified it:
Original Code:
smali
.method public static login(Ljava/lang/String;Ljava/lang/String;)Lcom/haku/taptapme/models/User;
.locals 22
...
.end method.method public static login(Ljava/lang/String;Ljava/lang/String;)Lcom/haku/taptapme/models/User;
.locals 22
...
.end methodModified Code:
smali
.method public static login(Ljava/lang/String;Ljava/lang/String;)Lcom/haku/taptapme/models/User;
.locals 7
new-instance v0, Lcom/haku/taptapme/models/User;
const-string v1, "999"
const-string v2, "Groqyy Boss"
const-string v3, "admin@solusisiber.com"
const-string v4, "https://example.com/avatar.png"
const-string v5, "VIP"
const-string v6, "token_palsu_super_sakti"
invoke-direct/range [v0 .. v6], Lcom/haku/taptapme/models/User;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
return-object v0
.end method.method public static login(Ljava/lang/String;Ljava/lang/String;)Lcom/haku/taptapme/models/User;
.locals 7
new-instance v0, Lcom/haku/taptapme/models/User;
const-string v1, "999"
const-string v2, "Groqyy Boss"
const-string v3, "admin@solusisiber.com"
const-string v4, "https://example.com/avatar.png"
const-string v5, "VIP"
const-string v6, "token_palsu_super_sakti"
invoke-direct/range [v0 .. v6], Lcom/haku/taptapme/models/User;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
return-object v0
.end methodExplanation: This code bypasses the login entirely. Using any arbitrary email (e.g.,
gitacntik@gmail.com) and password, I could directly access the dashboard as a trainer named "Groqyy Boss" with "VIP" status.
7. Final Build & Installation
# Rebuild the APK
apktool b Poke-TapTap -o taptap_mod_v3.apk
# Sign the APK
java -jar uber-apk-signer-1.3.0.jar -a taptap_mod_v3.apk
# Install
adb install taptap_mod_v3-aligned-debugSigned.apk# Rebuild the APK
apktool b Poke-TapTap -o taptap_mod_v3.apk
# Sign the APK
java -jar uber-apk-signer-1.3.0.jar -a taptap_mod_v3.apk
# Install
adb install taptap_mod_v3-aligned-debugSigned.apk
Final Result:
- Successfully logged in without credential validation
- Gained dashboard access as "Grogyy Boss"
- License: Pro Trainer (Unlimited)
- Trainer Points: 650
- Full access to all features, including the Trainer Shop