Monday, September 22, 2025

Honey the Hackers are Here


On August 10th, 2025 - I set up an SSH honeypot on my home network, daring any and all hackers to try and break in. I did not actually run any special honeypot software - although they exist - I simply set an incredibly strong SSH password (30 characters long) on my little Raspberry Pi 4 Model B, and opened up port 22 on my ISP-provided SOHO router.

This little microcomputer has been sitting on my desk, fearlessly fending off thousands of intrusions across the globe. I thank it for its service.


I set up a local job that runs at midnight every night that emails me a report on all the SSH intrusion attempts from the previous day. A sample report looks like the following:


Data Collection

The way I achieved this was a simple Bash script that I set to run on a cron schedule:

#!/bin/bash

...
echo "SSH Login Attempts for $REPORTDAY" > $TMPFILE
echo "===================================" >> $TMPFILE
cat $AUTHLOG | grep "$REPORTDAY" | grep "Failed password" | grep -v "192.168.1" \
    | awk '{print $(NF-3)}' \
    | sort | uniq -c | sort -nr \
    | while read COUNT IP; do
        COUNTRY=$(geoiplookup "$IP" | awk -F ': ' '{print $2}' | awk -F, '{print $2}')
        if [[ "$COUNTRY" == *"United States"* ]]; then
STATE=$(whois "$IP" | grep StateProv | awk '{print $2}' | head -1)
echo "$COUNT attempts from $IP (${COUNTRY:1} - $STATE)" >> $TMPFILE
elif [[ "$COUNTRY" == "" ]]; then
echo "$COUNT attempts from $IP (Country not found)" >> $TMPFILE
else
        echo "$COUNT attempts from $IP (${COUNTRY:1})" >> $TMPFILE
fi

...

USERS_TRIED=$(cat $AUTHLOG | grep "$REPORTDAY" | grep "$IP" | grep 'Invalid user' | awk '{print $8}' | uniq -c | head -5)
        echo "Users tried:" >> $TMPFILE
        echo "$USERS_TRIED" | while read ucount uname; do
            printf "    %s %s\n" "$ucount" "$uname" >> "$TMPFILE"
        done

echo "---------------" >> $TMPFILE
      done
...


This script (shortened for brevity) pulls all the authentication logs from the previous day, correlates the IP address with a geolocation and checks it against known Snort blacklist addresses and ToR exit nodes.

Visualization


Using two Python scripts, I aggregated all of these honeypot reports from my email into a single JSON payload that fed an HTML dashboard page. Let's dive into each of the dashboard panels below.

Top 20 Attacking IPs


The top five attacking IPs were all from China. The top one (8[.]140[.]229[.]224) had 957 attempts over the past month and a half. Looking at this IP in Shodan gives us this information:



And searching for it on various malicious IP trackers reveals it is indeed malicious:


Attempts By Country

Looking at total attempts by country (across all IPs coming from each country), you can see China takes the lead at 6,312 with the U.S. not far behind at 6,149. Then it drops off dramatically:

China - 6,312 attempts
United States - 6,149 attempts
India - 1,805 attempts
South Korea - 1,098 attempts
Sweden - 1,001 attempts
Netherlands - 997 attempts
Tunisia - 930 attempts
Iran - 713 attempts
Australia - 480 attempts
Canada - 453 attempts



Top 20 Users Tried


While the graph shows top 20, only the top 10 users tried (excluding attempts without a username) were really relevant:
1. user
2. admin
3. ubuntu
4. debian
5. test
6. oracle
7. dev
8. guest
9. usario
10. support

After that you may see only a handful of attempts with other users.



IPs in Snort List


Here is an interesting one. Snort is an open source IPS (Intrusion Prevention System) and they maintain a pretty active IP blocklist that you can download and add to your firewall rules even if you don't use Snort itself. This blocklist includes ~ 1,575 IP addresses at time of writing. I downloaded this blocklist and simply compared intrusion attempt sources to it (I did not use the blocklist to make firewall decisions). I expected a decent number to be on the Snort list, maybe around 50% or so.

However, according to my honeypot on the front lines, only 4 out of 1,578 unique IP addresses were actually on the Snort blocklist - meaning that Snort would have saved me 0.253% of the time.

This tells me that the Snort "Community Ruleset" may not be comprehensive, but perhaps the paid subscription to the ruleset backed by Cisco Talos includes the IP addresses that have been attacking my honeypot for the past two months.



IPs Using TOR

The graph may look a little off here, showing a value of "100%" - but this is actually how many were NOT using TOR (so the data label is "false"). So 100% of attempts did NOT use TOR.

This was surprising to me. If you don't know, the TOR project (standing for "The Onion Router") is an anonymity-first network and browser that lets you surf the web almost undetected. The way it works is through a large network of proxies and servers that carries your traffic around the world. Once connected to the TOR network, a "circuit" will be produced for you that proxies your traffic through three nodes across the globe. The first node (entry node) knows who you are, but not what you are searching. The last node (exit node) knows what you are searching but not who you are. In a perfect world, this would give you 100% anonymity. TOR is infamous as a hacker favorite and is even referenced within the first five minutes of Mr. Robot

So why are none of these real-life threat actors using it? It could be because there are large, well-founded rumors that the U.S. government along with INTERPOL control quite a large number of TOR nodes. If you control the exit node, you can see traffic as it leaves the TOR network, and if you also control the entry node, you can see the de-anonymized traffic as it enters. Supposedly the government allows TOR to operate independently, but you never know.

Additionally, maybe TOR is just the middle man here. I'm only tracking known exit node IP addresses, but if a threat actor used TOR initially and then after leaving the circuit they use another VPN, I would only see the VPN address. However, I don't think this is the case as routing traffic through at least four proxies across the globe is extremely slow and inefficient.



SSH Attack Origins Worldwide


This graph does not give any more information than previous graphs, but it is a quick and helpful visual into where these attacks are originating. Of course, the darker a country appears, the more honeypot intrusion attempts originated from there.

As expected, the largest geopolitical superpowers (that also quite-publicly flame one another) attempt to hack the most. Makes you wonder if the rest of the global Internet is merely a medium for the U.S. and China to attack one another, but I digress.


Conclusions


I would be remiss if I did not discuss conclusions from this honeypot experiment.

1. Change default usernames. As shown above, attackers will try "user", "admin", etc. quite frequently. Changing the username to something non-obvious and ensuring the password is highly secure will knock out 99% of these attacks easily.

2. Employ a defense-in-depth strategy. Don't use the single Snort IP blocklist as your only defense mechanism, even if it is backed by a community of security professionals. If you had, attackers would be able to intrude 99.7% of the time. Similarly, don't ONLY block TOR exit nodes. None of these attacks used TOR, telling me that threat actors may just be staying off of the TOR network altogether or adding in another layer off the network.


Next Steps


I will attempt to set up an automated pipeline to accurately report potentially malicious IP addresses to some open source threat intelligence community so that I can contribute to more comprehensive blocklists. Stay tuned for more as I set up this pipeline and bake in logic to not report false positives or academic sources.

Thursday, September 4, 2025

CVSS 3.1 Scoring Series - Privileges Required

In this part of my CVSS 3.1 Scoring Series, I will explain how the "Base Score - Exploitability - Privileges Required" classifications work.



Classifications

There are three classifications of Privileges Required:

  1. None (PR:N)
  2. Low (PR:L)
  3. High (PR:H)

None (PR:N) classification means that an attacker can be completely unauthorized prior to a successful attack, and does not require any access to settings or files of the vulnerable system to carry it out.

Low (PR:L) classification means that an attacker must have basic user capabilities that would be accessible under normal BAU for a normal user in order to exploit a vulnerability.

High (PR:H) classification means that an attacker must have elevated privileges (such as administrator) over the vulnerable component that would allow access to component-wide settings and files in order to carry out a successful attack.

Example 1: PR:N

An interesting example is CVE-2014-2005, where an attacker with physical access to a machine can bypass authentication when Sophos Disk Encryption doesn't have a login screen. The reason this is interesting is that even though you need physical access to the machine (AV:P if you've been following along in this series), you technically need no rights or privileges. Many factors get combined to produce the one CVSS score, and I find it interesting that a high barrier to entry of AV:P is lessened by the absence of required permissions (PR:N).


Example 2:  PR:L

Typically you might see these associated with XSS attacks or anything that the browser will load as a malicious link. For instance, I may have an account with a social media application giving me basic user entitlements to post comments or articles. Within a comment, I add a <script> tag that loads malicious JavaScript whenever someone views my comment. I required basic privileges to post (cannot post anonymously), but I was able to exploit an XSS vulnerability.


Example 3: PR:H

You will normally see this associated with large configuration-based vulnerabilities such as loading entirely new web applications into a web server. Normally when an attacker already has high privileges to an application like this, they are actually attempting to "break out" of the application and get rights to the underlying system. Another good example is a container escape that requires root permission to run. You've already compromised the whole container since you are root, but you're really leveraging a vulnerability of PR:H inside of it to compromise the layer below you.


Considerations

It is important to remember that the Privileges Required score describes the level of permissions an attacker must have *before*  successfully exploiting the vulnerability in the component. Reading through a vulnerability scoring and quickly glancing over "Privileges ... None" may make you think that an attacker gains no extra permissions after a successful exploit. However, this is actually the worst rating classification because the actor can attack a vulnerable system with no prerequisite privileges required.


Hopefully that explains the CVSS 3.1 Privileges Required scoring! If you have any questions, feel free to reach out to me on LinkedIn or via email (chris@sinclairsecurity.com). See you next time!


References

More information on this scoring can be found in the official specification: FIRST CVSS 3.1 Spec


Tuesday, August 12, 2025

CVSS 3.1 Scoring Series - Attack Complexity

In this part of my CVSS 3.1 Scoring Series, I will explain how the "Base Score - Exploitability - Attack Complexity" classifications work.


Classifications

There are only two classifications of Attack Complexity:

  1. Low (AC:L)
  2. High (AC:H)

Low (AC:L) classification means that a vulnerability can be exploited consistently without any special circumstances outside of the attacker's control.

High (AC:H) classification means that a vulnerability can only be exploited if extenuating circumstances beyond the attacker's control are met. This is kind of vague, but it can apply in numerous situations. For instance:

Example 1: An attacker must know about the environment

An OpenShift API server vulnerability can only be exploited if the attacker knows the exact OAuth client secret for the cluster’s authentication integration with an external identity provider (IdP). The secret isn’t guessable - the attacker would first need to compromise another system (e.g., an admin’s workstation or a Git IaC configuration source code repository) to retrieve it. Without that prior knowledge, the exploit fails entirely.



Example 2: An attacker must prepare the target environment

A kernel privilege escalation bug in a Red Hat Enterprise Linux system only triggers reliably when a specific sequence of memory allocations occurs. The attacker might have to run a crafted workload in a loop for hours to cause memory fragmentation, increasing the chance that the vulnerable memory layout or register state appears. Until that preparation succeeds, the exploit has a very low probability of working.


Example 3: An attacker must inject themselves into the logical network path

A flaw in the TLS certificate validation logic of an internal banking application would let an attacker impersonate a Kubernetes API server — but only if they can intercept the traffic between the application client and the API server. This would require the attacker to first compromise a router in the bank’s WAN or gain access to a jump host in the same network path. Without this man-in-the-middle position, the vulnerability can’t be exploited.


Considerations

One major caveat to the Attack Complexity rating is that "the assessment of this metric excludes any requirements for user interaction in order to exploit the vulnerability". Which is kind of funny, in my opinion. If I require a Secret Service agent of the United States Presidential Office to fly Air Force One across the globe to hand-deliver a malware-loaded USB to my target, as long as that USB does its job every time its plugged in (without relying on kernel memory layouts, network traffic, or unknown secret) - I get a Low Attack Complexity rating! Sweet!



Luckily the CVSS scoring will involve user interaction in later classifications, so its still considered when calculating the score. More on that later.


Remembering the Difference

I'll leave you with a final visual on how to know the difference between an AC:L and a AC:H rating. If Lady Luck is on your side (or if she's required at all), to exploit a vulnerability, then its more than likely an AC:H. If you're able to pull off the exploit consistently no matter what the circumstances call for, then you get an AC:L.


Remember, just because an exploit may require a little luck sometimes, does not mean you and your assets are safe from AC:H vulnerabilities. These extenuating circumstances will arise, whether naturally or forcefully.


Hopefully that explains the CVSS 3.1 Attack Complexity scoring! If you have any questions, feel free to reach out to me on LinkedIn or via email (chris@sinclairsecurity.com). See you next time!


References

More information on this scoring can be found in the official specification: FIRST CVSS 3.1 Spec


Wednesday, August 6, 2025

Crime Doesn't Pay (Except when it Does)

Situation

Imagine you are a nurse in a large regional hospital. Your worn insoles make your feet ache, the crick in your neck doesn't seem to go away no matter how many pills you down, and your fourth cup of coffee keeps you alert enough to guard over dozens of lives. You shuffle over to your "workstation on wheels" (WOW) to input the time you gave a patient his fourth Warfarin. You go to swipe your badge and notice the following on your screen:


Its not just you. Other patient care faculty are looking up from their desks wondering if its some kind of prank on the resident gone awry. Soon, the floor is abuzz with doctors coming out of their offices and hurried footsteps rushing down the hall to see what can be done. Within minutes, the rude IT guy is looking at some computers at the nurses' station and gets a call from his boss's boss. The call does not go well. Panic sets in as patients realize something is amiss. Is the life-saving surgery able to go forward without the doctor being able to access the patients blood type? Is the diagnosis that a family hangs onto with bated breath able to be released today, or will the nightmare continue indefinitely?

Congratulations, you are a victim of Ransomware.

What is Ransomware?

Ransomware is a malicious software or program that infects your computer with no intention of stealing information. Instead, it purposefully removes your access to any data by encrypting the contents of the computer with encryption keys and passphrases that could never be guessed as long as the universe shall live. The way it actually works looks something like this:

This is a clever way to encrypt files and essentially throw away the key until payment is made.

Normally, a scary-looking window will appear stating that everything is encrypted and to pay the hacker to get your data decrypted. There will usually be a nuclear-countdown-style timer showing how much time you have left to pay until the files are wiped, or the hacker will delete the corresponding private key that would've decrypted the used symmetric key. So what do they expect? Payment made through a secret channel to a secret location.

Anonymity

Ransomware is interesting because you actually get to talk with your hacker! Indeed, communication between victim and attacker must be established in order to accomplish steps 7 and 9 above.

Most ransomware proprietors are fans of the "Dark Web", which I cover in other posts and have my own thoughts about. Through layered proxying and obfuscation, browsers such as "The Onion Router" (ToR)  allow individuals to anonymize their internet browsing to require nation-state level of surveillance and tracking to break. Ransomware hackers often urge their victims to set up a gateway into the ToR network in order to submit payment and exchange keys.

Payment

Notoriously, ransomware threat actors demand payment through Bitcoin, with up to 98% of ransomware payments being made through the cryptocurrency. 70% of CISOs also keep a stash of Bitcoin on hand to quickly pay ransoms should they be infected.

Bitcoin (or any cryptocurrency) makes sense as a perfect hacker direct deposit slip with its anonymity and blockchain technology.


On Reputation

If you're paying attention and have a good head on your shoulders, you are obviously thinking:

> Okay, if I do "negotiate with the terrorists" here and send payment, what are the odds they're going to actually give me the decryption key? Would they not just turn tail and run, and now I'm left with no files AND no money?

Great question, and the truth is that *most* ransomware hacker groups out there will actually cooperate with you and send you the decryption key. Why? Reputation. If they took the money and ran, the company would promptly tell every other company out there not to deal with hacker "im2cool69" and their Bitcoin wallet ending in 0047. Then when this particular denizen of society deals with another victim, they would know not to pay.

Now, you may think its extremely easy to go get another hacker nickname and Bitcoin wallet, and constantly rotate through a cycle of never-ending cash-filled accounts. This is true, but these ransomware adversaries have rating systems as well, just like an eBay seller. I'm not sure if they have client testimonials and glowing reviews, but at the same time, you're much less likely to pay a hacker who has zero successful decrypts and data recoveries compared to one who may have done several already. There's no honor among thieves, but even they have to market their (forced) services!


CVSS 3.1 Scoring Series - Attack Vector

In this part of my CVSS 3.1 Scoring Series, I will explain how the "Base Score - Exploitability - Attack Vector" classifications work.


Classifications

There are four different classifications of Attack Vector:

  1. Network (AV:N)
  2. Adjacent (AV:A)
  3. Local (AV:L)
  4. Physical (AV:P)

A Network (AV:N) classification means that a vulnerability can be exploited across a Wide Area Network (WAN). This applies to the public Internet, corporate and remote business sites, or even traffic that must traverse at least one router to reach the target. Therefore, the simplest way to classify this is "can I exploit a vulnerability (directly) across at least one network router?"

An Adjacent (AV:A) classification means that a vulnerability can only be exploited within the same Local Area Network as the target. If I must exploit this inside the same OSI Layer 2 network as the target (same VLAN, same broadcast domain, etc.), then the vulnerable system would get an AV:A scoring.

A Local (AV:L) classification means that a vulnerability can only be exploited with logical local access to the system. For example, you must have a terminal or shell on the local system in order to exploit a vulnerability.

Finally, a Physical (AV:P) classification means you must have direct physical access to the machine or component in order to exploit a vulnerability. Think "pressing a key combo during boot lets you bypass authentication", or a physical USB stick must be plugged into the device to execute malware, etc.


When determining which classification a vulnerable application or system falls into, it is extremely important to note that this is NOT about the physical medium. SSH as a protocol traverses the network, yes, but if SSH is a necessity in order for me to be on the same host as the vulnerable component, it is a *Local* attack vector.


Example

Pop quiz time! So what if to exploit a vulnerability in a company's server from my laptop I had to SSH to a bastion host in a shared co-located server room in a leased datacenter, craft malformed data frames from my server to the company server in the same L2 domain, spawn a reverse shell inside their server, then attack localhost:6336 to exploit a SQL database vulnerability? Which attack vector classification should the database have?


To summarize:
- I move from my laptop on the public Internet to a bastion host (Network)
- I move from the bastion host to a company server in the same LAN (Adjacent)
- I spawn a shell inside the company server and attack the database (Local)

This would result in a CVSS 3.1 Attack Vector classification of Local. Yes, I can do all this in my slippers from the comfort of my home while watching Finding Nemo. Yes, it requires a lateral movement inside the same L2 network. However, I cannot start attacking SQL until I get onto the local server. Since we care about scoring the database specifically (even if the rest of the network seriously needs to be checked for holes), the database would get a vulnerability scoring of AV:L.


Considerations

One major caveat to note here is that if an attack has to originate from within a corporate intranet (and not the public Internet) in order to be successful, it would *still* be of a Network type. Sorry, you don't get points for having a private intranet for this sort of thing.

This kind of makes sense, right? If I can hijack communication from a retail POS system in a remote site to get all the way to customer financial data across the country in a central site, even if that communication travels across a company intranet - you wouldn't call that an Adjacent attack vector. There are many, many hops and L2 networks in between those points, so it still counts as Network.


Hopefully that explains the CVSS 3.1 Attack Vector scoring! If you have any questions, feel free to reach out to me on LinkedIn or via email (chris@sinclairsecurity.com). See you next time!


References

More information on this scoring can be found in the official specification: FIRST CVSS 3.1 Spec


Honey the Hackers are Here

On August 10th, 2025 - I set up an SSH honeypot on my home network, daring any and all hackers to try and break in. I did not actually run ...