<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Android on Qtnes</title><link>http://qtnes.com/tags/android/</link><description>Recent content in Android on Qtnes</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Wed, 22 Apr 2026 00:00:00 +0000</lastBuildDate><atom:link href="http://qtnes.com/tags/android/index.xml" rel="self" type="application/rss+xml"/><item><title>BotConf 2026 Android Workshop: A Practical Android Malware Analysis Playbook</title><link>http://qtnes.com/posts/botconf-2026-android-workshop---a-practical-malware-analysis-playbook/</link><pubDate>Wed, 22 Apr 2026 00:00:00 +0000</pubDate><guid>http://qtnes.com/posts/botconf-2026-android-workshop---a-practical-malware-analysis-playbook/</guid><description>&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;
&lt;p&gt;The BotConf 2026 Android workshop was not a bag of random “look how clever this sample is” tricks. It was a workflow: learn how the APK is put together, figure out where the malware is hiding, watch what it does at runtime, and then automate the boring rabbit chase once the pattern starts repeating.&lt;/p&gt;
&lt;p&gt;That progression matters. A lot of Android reversing goes sideways because the analyst dives straight into strings or decompilation and never gets the bigger picture. This workshop does the opposite and treats the whole stack as layered:&lt;/p&gt;</description></item><item><title>7 - The Mole: Reconstructing an Android Malware Beacon from a PCAP</title><link>http://qtnes.com/posts/7---the-mole---reconstructing-an-android-malware-beacon-from-a-pcap/</link><pubDate>Fri, 17 Apr 2026 00:00:00 +0000</pubDate><guid>http://qtnes.com/posts/7---the-mole---reconstructing-an-android-malware-beacon-from-a-pcap/</guid><description>&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;
&lt;p&gt;The Mole was an Android malware challenge built around a single artifact: a PCAP. From that capture alone, the goal was to reconstruct the infection chain, recover the device token, derive the bot token, and finally reach the flag endpoint.&lt;/p&gt;
&lt;p&gt;What made this one interesting is that the network trace already contained the important pivots. The APK was not provided up front, but the traffic exposed enough structure to rebuild the dropper&amp;rsquo;s behavior and the C2 flow.&lt;/p&gt;</description></item><item><title>8 - Pizzeria: Prompt Injection Against an Android LLM Agent</title><link>http://qtnes.com/posts/8---pizzeria---prompt-injection-against-an-android-llm-agent/</link><pubDate>Fri, 17 Apr 2026 00:00:00 +0000</pubDate><guid>http://qtnes.com/posts/8---pizzeria---prompt-injection-against-an-android-llm-agent/</guid><description>&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;
&lt;p&gt;Pizzeria looked like a simple Android food-ordering app, but the backend was doing something much more interesting: it was running an LLM agent with tool access.&lt;/p&gt;
&lt;p&gt;The challenge was to move from a normal order request to a tool call that would reveal the flag. The path there was a good example of how brittle keyword filtering becomes once an LLM is exposed to attacker-controlled input.&lt;/p&gt;
&lt;h2 id="recon"&gt;Recon&lt;/h2&gt;
&lt;p&gt;Decompiling the APK showed three useful pieces immediately.&lt;/p&gt;</description></item><item><title>5 - MediterraneanPotions: Decrypting a Flutter App's Encrypted Database</title><link>http://qtnes.com/posts/5---mediterraneanpotions---decrypting-a-flutter-apps-encrypted-database/</link><pubDate>Thu, 16 Apr 2026 00:00:00 +0000</pubDate><guid>http://qtnes.com/posts/5---mediterraneanpotions---decrypting-a-flutter-apps-encrypted-database/</guid><description>&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;
&lt;p&gt;MediterraneanPotions was a Flutter challenge built around a single encrypted asset: &lt;code&gt;potions.hive&lt;/code&gt;, a Hive key-value database where every record was AES-CBC encrypted. The AES key was hardcoded in the app&amp;rsquo;s native Dart binary. The Hive frame format embedded a per-record IV.&lt;/p&gt;
&lt;p&gt;The challenge was to find the key, understand the binary format, and decrypt all records.&lt;/p&gt;
&lt;h2 id="first-impressions"&gt;First Impressions&lt;/h2&gt;
&lt;p&gt;The APK was a Flutter application. That changed the decompilation landscape immediately: the main application logic was compiled into &lt;code&gt;libapp.so&lt;/code&gt; as native Dart code, not Java bytecode. JADX produced almost nothing useful beyond the Android framework glue.&lt;/p&gt;</description></item><item><title>6 - DeadDrop: Emulating an MQTT Bot to Recover a Flag</title><link>http://qtnes.com/posts/6---deaddrop---emulating-an-mqtt-bot-to-recover-a-flag/</link><pubDate>Thu, 16 Apr 2026 00:00:00 +0000</pubDate><guid>http://qtnes.com/posts/6---deaddrop---emulating-an-mqtt-bot-to-recover-a-flag/</guid><description>&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;
&lt;p&gt;DeadDrop presented an Android malware sample that used MQTT as its C2 channel, with RC4 encryption on every message. The challenge was to reverse the network protocol, recover the broker credentials and encryption keys from the APK, and then write a bot emulator that could register a fake device and trigger flag delivery.&lt;/p&gt;
&lt;h2 id="decoding-the-config"&gt;Decoding the Config&lt;/h2&gt;
&lt;p&gt;The APK&amp;rsquo;s &lt;code&gt;Cfg.java&lt;/code&gt; class stored all configuration values as Base64-encoded strings. This is a minimal evasion technique — strings won&amp;rsquo;t appear in a naive grep for IP addresses or credentials — but a single Base64 decode reveals everything:&lt;/p&gt;</description></item><item><title>3 - Smoke: Bypassing StringFog and Decoding a Custom String Cipher</title><link>http://qtnes.com/posts/3---smoke---bypassing-stringfog-and-decoding-a-custom-string-cipher/</link><pubDate>Wed, 15 Apr 2026 00:00:00 +0000</pubDate><guid>http://qtnes.com/posts/3---smoke---bypassing-stringfog-and-decoding-a-custom-string-cipher/</guid><description>&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;
&lt;p&gt;Smoke was a StringFog challenge. StringFog is an open-source Android string obfuscation tool that transforms every string literal in the bytecode into an encrypted hex payload, decoded on demand by a runtime method injected into the class. The goal is to make static analysis significantly harder: decompiling the APK produces no human-readable strings, only opaque calls like &lt;code&gt;AbstractC0006a5.o(&amp;quot;e30385842152b38cc3ab85&amp;quot;)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The challenge used a custom variant of StringFog with its own cipher. The goal was to identify the encryption algorithm, port it to Python, and bulk-decrypt all string payloads in the decompiled source tree to find the flag.&lt;/p&gt;</description></item><item><title>4 - Handshake: Breaking AES-CBC via IV Recovery and CBC Malleability</title><link>http://qtnes.com/posts/4---handshake---breaking-aes-cbc-via-iv-recovery-and-cbc-malleability/</link><pubDate>Wed, 15 Apr 2026 00:00:00 +0000</pubDate><guid>http://qtnes.com/posts/4---handshake---breaking-aes-cbc-via-iv-recovery-and-cbc-malleability/</guid><description>&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;
&lt;p&gt;Handshake was a cryptography challenge disguised as a network one. The APK connected to a mutual TLS C2 server, logged in with hardcoded credentials, and received an AES-CBC-encrypted flag. The AES key was in the APK. The IV was not.&lt;/p&gt;
&lt;p&gt;Everything needed to decrypt the flag was recoverable, but it required understanding how CBC block chaining works and exploiting the fact that one of the two ciphertext blocks behaves independently of the IV.&lt;/p&gt;</description></item><item><title>1 - GhostMode: Reversing a Native Android CTF Library</title><link>http://qtnes.com/posts/1---ghostmode---reversing-a-native-android-ctf-library/</link><pubDate>Tue, 14 Apr 2026 00:00:00 +0000</pubDate><guid>http://qtnes.com/posts/1---ghostmode---reversing-a-native-android-ctf-library/</guid><description>&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;
&lt;p&gt;GhostMode was the workshop&amp;rsquo;s first foray into native code. The APK itself was thin — the interesting logic lived entirely in &lt;code&gt;libctflib.so&lt;/code&gt;, a stripped ELF64 shared library loaded at runtime. The challenge name already telegraphed the approach: you were not meant to find the flag through static analysis alone.&lt;/p&gt;
&lt;p&gt;The fake flag was there to remind you of that.&lt;/p&gt;
&lt;h2 id="first-look--the-stub-and-the-taunt"&gt;First Look — The Stub and the Taunt&lt;/h2&gt;
&lt;p&gt;Decompiling the APK with JADX produced a small &lt;code&gt;FlagManager&lt;/code&gt; class with a single JNI method:&lt;/p&gt;</description></item><item><title>2- ThePackage: Unpacking a Runtime-Loaded DEX</title><link>http://qtnes.com/posts/2---thepackage---unpacking-a-runtime-loaded-dex/</link><pubDate>Tue, 14 Apr 2026 00:00:00 +0000</pubDate><guid>http://qtnes.com/posts/2---thepackage---unpacking-a-runtime-loaded-dex/</guid><description>&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;
&lt;p&gt;ThePackage introduced a classic Android evasion technique: DEX-in-DEX packing. The APK delivered to the user contains nothing interesting in its primary &lt;code&gt;classes.dex&lt;/code&gt;. The actual application logic — including the flag — lives in a secondary DEX that is encrypted inside the assets directory and only loaded at runtime.&lt;/p&gt;
&lt;p&gt;The goal was to find the decryption key, extract the hidden DEX, and recover the flag from the decrypted classes.&lt;/p&gt;
&lt;h2 id="the-stub-apk"&gt;The Stub APK&lt;/h2&gt;
&lt;p&gt;Opening &lt;code&gt;ThePackage.apk&lt;/code&gt; with JADX immediately felt wrong. The package structure was sparse, class names were generic, and there were no obvious flag-related strings. The main activity was minimal. This is the hallmark of a packing stub: the visible DEX exists only to bootstrap the real application.&lt;/p&gt;</description></item></channel></rss>