- 08 Nov, 2025 *
When I pushed my first ever web application to my first server, it didn’t take long for me to get hacked and all my data deleted.
At first I was actually very scared, and then I realized the only user data was mine, and then I relaxed.
My first ever web app was a tool that allowed you to select any element on a page, and it would notify you if the value of that element ever changed.
I needed this because my teacher at the time refused to notify us about updates and instead made us constantly check his website (which he would sometimes update at night). I refused and wanted to get notified of it, so much so that I started building my own application for it.
In theory the idea was actually great, you could select anything be it an image, price, tagline, etc, and …
- 08 Nov, 2025 *
When I pushed my first ever web application to my first server, it didn’t take long for me to get hacked and all my data deleted.
At first I was actually very scared, and then I realized the only user data was mine, and then I relaxed.
My first ever web app was a tool that allowed you to select any element on a page, and it would notify you if the value of that element ever changed.
I needed this because my teacher at the time refused to notify us about updates and instead made us constantly check his website (which he would sometimes update at night). I refused and wanted to get notified of it, so much so that I started building my own application for it.
In theory the idea was actually great, you could select anything be it an image, price, tagline, etc, and automatically be notified on change (I think I even added a goes up or goes down feature for prices). And my database was mongodb, I didn’t know I needed authentication because I thought it was all local. But the one thing I did not realize was that I never enabled the firewall, so a mass scanning bot was able to just login to my mongo, delete everything and demand ransomepayment. This happened a couple of more times because for some reason even though I changed the configs I could not get mongo to require authentication (At least I thought I did at one point but it was never required).
Anyways, ever since then I am reminded of it when I spin up a new server and somehow right away see the automatic requests coming in hoping that something was misconfigered and they can access an .env file or some sensitive wordpress (Even though I have never run workpress).
That leads us to today, where I want to spin up a server that accepts every kind of request on every port and just logs everything, and see what I get!
This is typically called a honeypot server, just like honey attraks bees, open ports attract web request.
While there are some existing great honeypot projects, I want to build this out myself.
For today I will be focusing on web requests, how can we do that?
Well its simpler than you think., you can use any language for this but I will use Go.
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"sync"
"time"
)
type LogEntry struct {
Timestamp time.Time `json:"timestamp"`
Method string `json:"method"`
Path string `json:"path"`
RemoteAddr string `json:"remote_addr"`
UserAgent string `json:"user_agent"`
Headers map[string][]string `json:"headers"`
}
func main() {
f, err := os.OpenFile("logs.jsonl", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
log.Fatalf("open log file: %v", err)
}
defer f.Close()
var mu sync.Mutex
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
entry := LogEntry{
Timestamp: time.Now().UTC(),
Method: r.Method,
Path: r.URL.Path,
RemoteAddr: r.RemoteAddr,
UserAgent: r.Header.Get("User-Agent"),
Headers: r.Header,
}
fmt.Printf("%s - %s %s - UA=%s\n", entry.Timestamp.Format(time.RFC3339), entry.Method, entry.Path, entry.UserAgent)
b, _ := json.Marshal(entry)
mu.Lock()
_, err := f.Write(append(b, '\n'))
mu.Unlock()
if err != nil {
log.Printf("failed to write log: %v", err)
}
fmt.Fprintf(w, "Hello from the catch-all handler! You requested: %s\n", r.URL.Path)
})
log.Println("Server starting on :8080")
if err := http.ListenAndServe(":8080", mux); err != nil {
log.Fatalf("server error: %v", err)
}
}
The results (Skip to the bottom for a log dump)
Not surprised at all that GET requests took up the majority (76%), however something that was surprising was how may post requests there were (1409 or 21%).
What were these requests?
.....and that was the moment I realized I never logged the POST request body lol. These things happen, lets move on.
An overwhelming majority of the POST requests went to /wp-login.php, once I give this another try and log all the data, maybe we can take a look at what default credentials they are trying to submit.
For now, the top IP that sent almost half of all the requests was 141.98.11.44 which has already been marked as an abusive domain.
.
As a part of this exploration I will make sure to do an IP lookup on every IP that hit my server, but I will save that for part 2 as today I just want to do a preliminary look.
Unsurprisingly the top routes that were hit were WordPress routes, as those tend to be improperly configured, and then different environmental and configuration routes also.
Some notes from this in case you don’t know yet:
- Make sure your .env files are not available via web request, and try to handle directory listing properly so they cannot trick you system like with “../.env” to go back a directory that you did not intend
- Make to do the same with your .git, if they can access that they can replicate your entire code base, and if you have git actions in there, well they can do whatever they can normally do.
I was also hit by some network/internet scanners, like Nmap and masscan. Masscan is a very cool and powerful tool but normally hosting providers will shut you down because it looks like you are performing a DDOS attack (It happened to a friend who goes to another school).
Log Dump
Total Requests: 6662
Top Methods
| Key | Count |
|---|---|
| GET | 5099 |
| POST | 1409 |
| HEAD | 136 |
| OPTIONS | 18 |
Top Routes
| Key | Count |
|---|---|
| /wp-login.php | 1557 |
| /wp-admin/index.php | 518 |
| /wp-admin/profile.php | 518 |
| /wp-admin/edit.php | 518 |
| /wp-admin/plugins.php | 518 |
| / | 506 |
| /.env | 125 |
| /favicon.ico | 77 |
| /robots.txt | 76 |
| /.git/config | 75 |
| /cgi-bin/luci/;stok=/locale | 29 |
| /.well-known/security.txt | 23 |
| /sitemap.xml | 22 |
| /ads.txt | 18 |
| /app-ads.txt | 18 |
| /api/.env | 17 |
| /.well-known/assetlinks.json | 17 |
| /.well-known/apple-app-site-association | 17 |
| /crossdomain.xml | 17 |
| /.well-known/webfinger | 17 |
Top IPs
| Key | Count |
|---|---|
| 141.98.11.44 | 2614 |
| 91.224.92.35 | 1066 |
| 3.25.108.182 | 577 |
| 45.148.10.158 | 287 |
| 13.73.16.137 | 144 |
| 130.33.49.2 | 111 |
| 48.210.15.48 | 81 |
| 78.153.140.224 | 74 |
| 78.153.140.179 | 61 |
| 63.180.236.160 | 44 |
| 194.26.29.16 | 42 |
| 23.180.120.243 | 39 |
| 78.153.140.176 | 38 |
| 188.166.108.93 | 36 |
| 138.68.144.227 | 36 |
| 78.153.140.203 | 36 |
| 78.153.140.50 | 36 |
| 206.189.2.13 | 36 |
| 139.59.136.184 | 36 |
| 204.76.203.30 | 34 |
Top User-Agents
| Key | Count |
|---|---|
| Mozilla/5.0 (Linux i386; X11) AppleWebKit/535.20 (KHTML, like Gecko) Chrome/8.0.1086.27 Safari/535.33 | 577 |
| Mozilla/5.0 | 318 |
| Mozilla/5.0 (Windows NT 11.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 | 300 |
| Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 | 291 |
| Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 | 266 |
| Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 | 256 |
| Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0 | 231 |
| Go-http-client/1.1 | 138 |
| Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.5845.140 Safari/537.36 | 99 |
| Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 | 80 |
Requests by Hour (UTC)
| Key | Count |
|---|---|
| 2025-11-06T15 | 1317 |
| 2025-11-04T22 | 1311 |
| 2025-11-06T13 | 1106 |
| 2025-11-07T10 | 581 |
| 2025-11-05T22 | 287 |
| 2025-11-05T10 | 147 |
| 2025-11-05T20 | 118 |
| 2025-11-05T02 | 89 |
| 2025-11-04T13 | 67 |
| 2025-11-02T19 | 47 |
Suspicious / Scanner User-Agents
| Key | Count |
|---|---|
| Mozilla/5.0 (compatible; Nmap Scripting Engine; https://nmap.org/book/nse.html) | 24 |
| masscan/1.3 (https://github.com/robertdavidgraham/masscan) | 1 |
Nmap Paths
| Key | Count |
|---|---|
| /sdk | 6 |
| /nmaplowercheck1762148408 | 1 |
| /NmapUpperCheck1762148408 | 1 |
| /Nmap/folder/check1762148408 | 1 |
| /nmaplowercheck1762246946 | 1 |
| /NmapUpperCheck1762246946 | 1 |
| /Nmap/folder/check1762246946 | 1 |
| /nmaplowercheck1762345685 | 1 |
| /NmapUpperCheck1762345685 | 1 |
| /Nmap/folder/check1762345685 | 1 |
| /nmaplowercheck1762445384 | 1 |
| /NmapUpperCheck1762445384 | 1 |
| /Nmap/folder/check1762445384 | 1 |
| /nmaplowercheck1762543865 | 1 |
| /NmapUpperCheck1762543865 | 1 |
| /Nmap/folder/check1762543865 | 1 |
| /nmaplowercheck1762642850 | 1 |
| /NmapUpperCheck1762642850 | 1 |
| /Nmap/folder/check1762642850 | 1 |