WolvCTF 2023: Hunting Down a Flag-Stealing Ransomware Group with OSINT
Published on

WolvCTF 2023: Hunting Down a Flag-Stealing Ransomware Group with OSINT



Over the last weekend, I played in WolvSec's second CTF iteration with Project SekaiWolvCTF 2023. We placed first in the open division, and throughout the solving process I became intrigued by a specific series of challenges placed under the OSINT category: WannaFlag. Telling a story of a supposed ransomware group which had been terrorizing the CTF community for the past several months, these series of challenges offered an opportunity for players to track down this group's means of operation. Ultimately, the goal was to find WannaFlag's kingpin through all possible methods.

Project Sekai was the first to blood the entire series. Here was our thought process, notes, and conclusions.

WannaFlag I: An Introduction

author: dree
points: 188
solves: 107
files: image.png
Welcome to WolvCTF's OSINT Category! We have a bunch of great OSINT lined up, assuming nothing goes wrong hahahhahahhahah but why would it?
For this challenge, find where the image was taken, and look at the Google Maps reviews!
Note: Flags can be found in standard format wctf{...} for ALL OSINT challenges

We're first given a little bit of a warmup: find the location of the following object, and to view its Google Reviews:


Simple task! These types of challenges, often called GEOINT (geospacial intelligence), can be trivial if there is a landmark object situated within the image — in this case, we have some public art resembling a black cube. We can use Google Lens to identify it:


Looks like Google's given us a hit: this is "The Cube," a public art installation in the University of Michigan. Let's take a look at the Google Reviews:


This netcat wanna-flag-i dot wolvctf dot io one three three seven can be converted to a command: nc wanna-flag-i.wolvctf.io 1337. Let's connect to this server to see what it has to say:


Well... that was unexpected. Let's first digest what in the world just happened to this netcat:

  • Our flag is cut off midway, and WannaFlag supposedly "pwns" the server
  • We're told to pay 500,000 Goerli to the wallet 0x08f5AF98610aE4B93...
  • This hashtag #YourFlagsBelongToUs is spammed everywhere throughout the message
  • The group tells "John OSINTs" to leave them alone on Twitter

There's a small connection here, but it's not immediately obvious. We can actually search for this hashtag on Twitter, revealing a tweet from none other than @JohnOSINT_ himself:

John OSINT's avatar
John OSINT@JohnOSINT_March 11, 2023
I've been getting reports of a new ransomware group that have been specifically targeting CTFs. They've been posting #YourFlagsBelongToUs to their victims and demanding crypto in exchange for the flags and infra back. This is big.....
John OSINT's avatar
John OSINT@JohnOSINT_March 11, 2023
I've only exfiltrated one flag from them so far: d2N0Znt1aGhoX3doM3IzX2QxZF80bGxfMHVyX2ZsNGdzX2cwP30=

A simple base64 decode of the exfiltrated string gives us our first flag:

WannaFlag I: An Introduction: wctf{uhhh_wh3r3_d1d_4ll_0ur_fl4gs_g0?}

WannaFlag II: Payments

sahuang author: dree
points: 348
solves: 75
Ok well.........................something may have gone wrong WannaFlag's ransom demand is insane, there's no way we are paying that. Can you figure out which address the money is being funneled to?
From the ransom note: send 500,000 Goerli to 0x08f5AF98610aE4B93cD0A856682E6319bF1be8a6

Our next step involves figuring out where this ransom money is being funneled to. We can use Etherscan's Goerli Testnet Explorer for transactions involving the address 0x08f5AF98610aE4B93cD0A856682E6319bF1be8a6:


We can see the transactions this account has made so far, but the only ones that are relevant would be the ones done before the competition started (since those would be part of the challenge creation process). These are the following transactions the account has made within this reasonable scope:

Goerli 2

Looks like there's something that stands out — although there are a lot of IN transactions, there's only one OUT transaction. This is the transaction that we're looking for, and it's a pretty big one being sent to 0xA01FD0.... Let's follow the breadcrumb:

Goerli 3

From here, it seems as if the money is being distributed into several different accounts. Upon checking these transactions, though, these addresses actually just loop back the crypto into the original 0x08f5AF... wallet. Here is an example of one of these "dummy" accounts, 0xc527ad...; the second transaction on this list sends money back in a seeming "loop":

Goerli 4

However, one outlier amongst these OUT transactions exists: the address 0x80710E..., which funnels these payments into three different accounts:

Goerli 5

Once again, two of these accounts are dummies, and will send money back into 0x08f5AF.... However, one of these accounts, 0x64E69A..., will send money to a completely new address, 0x79616B..., where the trail ends:

Goerli 6

There's a suspicious SELF transaction on this address. Hovering over it, we can see that Etherscan believes there is a hidden message in the "Input Data" field:

Goerli 7

If we take a look at the transaction hash and click on the "More Details" button, we find the flag in the "Input Data" section when decoding it into UTF-8:

Goerli 8

If you're lost, I made a visualization of the transactions which took place, highlighting the breadcrumbs which eventually led to the flag:

WannaFlag II: Payments: wctf{g1v3_m3_b4cK_mY_cRypT0!!11!}

WannaFlag III: Infiltration

author: dree
points: 318
solves: 82
We have some solid leads so far. However, we need our flags back. Find a way to locate their communication and infiltrate their private ransom service, and submit the stolen flag we wanted to use for the first OSINT!
From outside intelligence, we know the group sometimes goes by w4nn4_fl4g

We're now given a keyphrase to work with: w4nn4_fl4g. We can search for the specific term on Google by wrapping it in quotes, and our first result is a subreddit, r/w4nn4_fl4g:


Looking through the small amount of posts on this locked subreddit, we can find three users in particular which have access to post permissions (alongside one moderator): u/w4nn4fl4g_admin, u/RemarkableDiamond443, and u/[deleted]. None of the posts and memes were particularly interesting or relevant, but one thing stuck out in particular: the deleted user. We can find the username of the user through querying camas.unddit.com for a specific comment in r/w4nn4_fl4g; let's utilize the comment "sorry" they left under this post:

First Query

We found the original username of the deleted user: u/Chemical_Bread1558! We can now query for posts the user made under the subreddit:

Second Query

We've got a hit on a moderator-deleted post. Let's check it out:

Deleted Post

Well, that doesn't really help. However, we can see the post's original content by using the Unddit tool once again — simply replace the reddit in the URL with unddit to see deleted comments:


The secret website provided leads us to this:


We've managed to recover the flag from the first OSINT challenge, but it's actually meant to be submitted as part of the third:

WannaFlag III: Infiltration: wctf{sp1nnnNn_tH3_cUb333e3E}

WannaFlag IV: Exfiltration

author: dree
points: 491
solves: 19
Now that we've successfully gotten into their website - I say we figure out what other data they have.
Find and crack the master flag list, and submit the flag you see of ours on the list.

First blood! We're now tasked with analyzing the contents of their website. Scouring through the source code, we find two extra pages: /ctfs.html and /prices.html:


We've also got a footer with various social medias (which are all unsurprisingly rickrolls):


However, on the /ctfs.html page, upon further inspection of the source code we find a secret page, /data.html, linked under the Instagram icon:

Secret Page

Accessing the secret page reveals a secret download link:


Downloading the file, we find a flaglist.xlsx, a Microsoft Excel document. There is an issue, however — the spreadsheet is completely encrypted via password protection, and we cannot import it to Google Sheets:


Let's see what we can do about this. Inspecting the source code of /data.html, we actually find that the file is being sourced from a GitHub account, fl4gpwners:

Secret Page

There happens to be an extraordinarily convenient password-repo repository on this GitHub account, which reveals a passwords_stub.lst file:

Password Repo

Unfortunately, none of the passwords in this list were accepted by the spreadsheet. However, it reveals extraordinarily useful information: the password list is a stub (as hinted by part of the filename), and the real password of the spreadsheet was likely part of the original document.

Let's further analyze the passwords which were given to us. We have the name of a U.S. city/town, followed by a number of some kind. Googling the city followed by the number reveals that the number is actually the population of the city which proceeds it; this means that Concord_city has a population of 105186, Baton_Rouge_city has a population of 225128, etc. We can use this information to our advantage to reassemble the password list, assuming it is every U.S. city/town followed by its population.

Upon further research, the population of the city was discovered to be sourced from the U.S. 2020 Census. Census.gov, their official website, has various datasets of "Annual Estimates of the Resident Population for Incorporated Places of 50,000 or More." Importing the data into Google Sheets, we can see that this was the exact dataset which was used to generate the stub:

Note: See how the term “city”, “munincipality”, and “village” were lowercase in password_stub.lst? This is because the census uses these terms to categorize urban areas in the United States, and are not actually part of the area’s name. That is also why there are some entries which have two “cities” in their name (e.g. Oklahoma City city), as city is both part of the official city name and categorization.

Let's create a wordlist from this data. Although we can export it as a .csv and run a Python script to filter out the passwords, we can simply create a spreadsheet formula on another column to create the wordlist:


We can now copy the column into a text file, wordlist.txt, and use it to crack the spreadsheet. We'll be utilizing the john tool to achieve this.

Firstly, we need the hash of the spreadsheet. We can use the office2john.py tool to extract the proper hash:


After we pipe it into a file, hash.txt, we can now finally run john:

Note: For some reason, john when installed with apt-get doesn't have Office support (at least for me). Make sure that you are compiling from source if you want to use this tool (or just use hashcat)!

The password is Great_Falls_city_60506, which we can now use to open the spreadsheet:

WannaFlag IV: Exfiltration: wctf{y0ur_fl4gS_b3l0nG_t0_m3_;)}

WannaFlag V: The Mastermind

Violin author: dree
points: 500
solves: 6
Alright, I don't know about you but I'm kinda sick of this WannaFlag group. I say we take them down once and for all. Maybe there's a way to figure out who is behind the whole operation...
Consider all possible leads and clues so far. This challenge may be the most complex so far.
No games or programs need to be downloaded, or users messaged.

This challenge remained unsolved for a long while until the first hint was released:

Perhaps we can find the Mastermind's email...

This immediately gave us a starting path to work with. We can find the email address of the user from the commit history of fl4gpwners; I found it from the patch of the commit which uploaded flaglist.xlsx to the flaglist repository:


We've found a [email protected] — from here, although various email OSINT strategies yielded no results (e.g. Epieos), a simple keyword search on Google resulted in a GameBanana profile:


Let's take a look at this user. They currently have one submission, a map titled jump_forklift for the game Team Fortress 2:

GameBanana Submission

Check out that screenshot: it has a snippet of a Discord link, discord.gg/aY4Wuy.... It seems cut off, however, so we'll have to try and recover the rest of the invite.

Although we actually attempted to brute force the invite code (simply a two-character combination of A-Z, a-z, 0-9), we ended up completely IP rate-limited by Discord. So, like any logical person would do, I tried to open the map in the game itself.

To download maps into TF2, you need to subscribe to its respective workshop on Steam. Although GameBanana never explicitly provided the Steam account for this user (or so I believe), their Steam account conveniently had the same as their GameBanana, civilianengi3421:


Here is the workshop item associated with jump_forklift:


After subscribing to the item, I booted up TF2 for the first time in a couple of years to check out what was going on.

Note: The challenge explicitly states that you do not need to download any games or programs. I just simply took the easy route and did so, anyways!

We can navigate to the "Create Server" menu and select the map at the bottom:


I entered the map and lo and behold, the Discord invite was fully visible:

Discord Link

Let's join the server... or not, I guess:


Although this hiccup had my team scratching their heads for a while, we eventually stumbled upon a discrepancy in the invite link presented in the screenshot and the one in the map — the screenshot's initial characters are aY4Wuy..., while the map has aYWuyn.... Let's try adding the missing character 4 to the invite link:


We've successfully gained access to the server! Let's take a look around:


Although there's nothing of relevance in any of the channels, we see that the server has two individuals who have interacted with each other: rocketjumper3005 and s0llym41n3006, who had left the server earlier. Let's run a Sherlock search on these two users and see what we can find:

Coil was a false-positive, but that Pastebin account for the second user was a hit. Visiting their account reveals an interesting paste:


The paste reveals that the rocketjumper3005 user had been keeping their schoolwork in the Discord server, and it had been visible using BetterDiscord's ShowHiddenChannels plugin. The following image was attached:


We're given a couple hints to pick at: rocketjumper3005's real name is Corey, and he had been working on his application to "TNISO University." Let's run a Google search for "corey tniso university" on DuckDuckGo:

TNISO Search

We've got him! This "Corey Jacobs" actually has a LinkedIn profile:


Expanding the "About" section reveals... some interesting text:


A base64 decode reveals our final flag:

WannaFlag V: The Mastermind: wctf{y0u_c4n_r0ck3tjUmp_bUt_y0u_c4nt_h1d3}


This was an extraordinarily well-designed challenge. A lot of OSINT nowadays isn't creative at all, and doesn't employ any sort of "out-of-the-box" thinking. The WannaFlag series, however, was my breath of fresh air — it brought in some really wacky and unique stuff, like the TF2 map/Steam (the Excel password cracking bit was more forensics, but that's just part of the nature of OSINT in general). I hope to see more of these types of challenges in the future. Here is a compiled list of tools that I used throughout the challenge — I hope you find them useful: