The Sad, Sorry Life of a Crappy Spyware


Introduction

This is a story from 2023, when I unexpectedly gained access to a spyware panel and witnessed the operator’s alarming mistakes.

Let’s rewind and start at the beginning. One rainy evening, I was hunting for adversary infrastructure using Shodan. Specifically, I was searching for interesting text within web pages using the http.html: tag. After many unsuccessful attempts, I stumbled upon four IP addresses running Node.js web servers, all on irregular ports.

Upon visiting the first web server, it became immediately clear what I had stumbled upon—spyware. This particular spyware didn’t have many victims, but there were two, both women located in Iran. victimo.png Clicking on the ‘Device’ name took me to the main section of the control panel, where various commands could be executed. Not all of these functions worked, which suggested the system was still under development. commands.png The victims were identified as being located in Iran based on the information periodically exfiltrated by the spyware, including SMS messages that featured the +98 area code. areacode.png

Digging Deeper

To get a better understanding of what was going on, I opened up DevTools. devtools.png

One of the first things I noticed was the use of WebSockets. Nothing unusual—fairly standard. However, within bot-list.js, I found something interesting: hardcoded credentials for the admin user: hard code.png At first, these credentials didn’t seem particularly useful to me. But if they had hardcoded these values, what else might be hidden in there? ping.png After spending some time analyzing the Network tab and reviewing the data being sent back and forth, I noticed routine data exfiltration happening via FTP—using, you guessed it, hardcoded credentials. But remember when I mentioned the four unique IP addresses running this same spyware controller? Well, each one had its own set of hardcoded credentials. ftp.png Upon logging into the server, I realized I had read and write access to every file and folder. Surprisingly, this server wasn’t just being used to host spyware—it was also hosting several other project websites. ftp-2.png I decided to poke around a bit to find where the victims’ information was being uploaded. Disturbingly, I discovered thousands of photos, messages, and call logs—some dating back years PhotoExfil1.png Unsure if the operator was aware of my login, I cloned the entire server—except for the directories containing victims’ personal photos and call logs. Copying those felt ethically wrong and wouldn’t provide any valuable insight into the spyware’s operations. I stored the cloned data locally for further analysis while also keeping an archive in case anything changed

Wrapping Up

By reviewing the source code and connected domains, I was able to identify the possible owner of the domains—and potentially the server. However, due to privacy concerns and the risk of falsely accusing the wrong individual, I won’t be sharing these findings publicly.

Further port scans on the FTP server led me to a webpage that appeared to be embedding a video feed—suggesting live camera access. unnamed.png

Since I had write access to the www/public_html directory, I was theoretically able to upload my own PHP code. Given this, and the fact that the spyware controller required little to no authentication to access victims’ personal data, I decided to hold off on disclosing my findings and instead opted to monitor the situation.

I was unable to determine the initial infection vector or how the victims were targeted. However, given the small number of victims—all located within Iran—I assumed this was a small, targeted operation.

I needed a reliable way to track infections without constantly logging into the FTP server to download data. Since this C2 used WebSockets, I decided to whip up a simple Go program to monitor activity. I don’t have much experience with programming or working with WebSockets, but the code just about worked.

Code on github

Throughout the period I spent monitoring the C2, I observed no new infections. However, I did notice they took down two of the servers and changed domains.

Gaslighting with Junk Data

With only one spyware controller remaining and the exfiltration server still live—showing evidence of ongoing periodic data theft—there was only one option left.. Pastedimage20250213152051.png While deleting the data, I kept getting disconnected, likely due to the routine data exfiltration logging me out. So, I decided to automate the deletion process using a bash script to handle re-logins. After letting it run, I came back later to check, and voila—we were cooking! Pasted image 20250213124438.png There was only one thing left to do: gaslight the operator into thinking there were errors with his spyware. I decided to upload junk data until I filled up the server. To add to the confusion, I made sure to follow the naming scheme of previously uploaded files Pasted image 20250213152255.png Not long after, my script started throwing errors. Thinking something was wrong, I paused to check… Nope, the storage was full, but the server was still allowing me to upload 0-byte files, which would then be listed in the directory. Pasted image 20250213153744.png Pasted image 20250213153047.png

With nothing else I could do, and still disappointed that I was unable to determine how the victims were being targeted or what they might have executed, I ran my upload script on two servers. Legend has it, it’s still running in a screen session to this day.