<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Experiment on Monish Kumar&#39;s Blog</title>
        <link>https://itsmonish.pages.dev/categories/experiment/</link>
        <description>Recent content in Experiment on Monish Kumar&#39;s Blog</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en-us</language>
        <lastBuildDate>Sun, 08 Mar 2026 16:42:18 +0530</lastBuildDate><atom:link href="https://itsmonish.pages.dev/categories/experiment/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>Barbwire: an eBPF based behavioral correlator</title>
        <link>https://itsmonish.pages.dev/blog/barbwire/</link>
        <pubDate>Sun, 08 Mar 2026 16:42:18 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/barbwire/</guid>
        <description>&lt;h2 id=&#34;introduction&#34;&gt;Introduction
&lt;/h2&gt;&lt;p&gt;After the eBPF learning phase I wrote about in the &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/blog/learning-ebpf&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;last post&lt;/a&gt;, I wanted to build something that looked like a real security tool. Not because I thought I&amp;rsquo;d ship it, but because the programs I tried before where stupid. At some point you need a problem with actual constraints.&lt;/p&gt;
&lt;p&gt;Barbwire is that project. It&amp;rsquo;s a lightweight behavioral correlator for Linux. It watches for processes that open sensitive files and then make network connections within a short time window. This is classic exfil behavior and rough fingerprint for credential harvesting and so on. It&amp;rsquo;s not a production EDR. It&amp;rsquo;s an experiment. It&amp;rsquo;s on my &lt;a class=&#34;link&#34; href=&#34;https://github.com/ItsMonish/barbwire&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Github&lt;/a&gt; if anyone&amp;rsquo;s interested.&lt;/p&gt;
&lt;h2 id=&#34;the-core-design-decision&#34;&gt;The core design decision
&lt;/h2&gt;&lt;p&gt;The first instinct when building something with eBPF is to put logic in the BPF side. It&amp;rsquo;s running in the kernel, it&amp;rsquo;s fast, why not do the correlation there?&lt;/p&gt;
&lt;p&gt;I thought about it and decided against it early. The BPF verifier gets unhappy with complex logic. It&amp;rsquo;s harder to debug, less portable across kernel versions, and for this use case, unnecessary. Userspace is fast enough. The design I landed on: BPF is a dumb data collector, userspace does the thinking.&lt;/p&gt;
&lt;p&gt;The BPF side attaches tracepoints to three syscalls. &lt;code&gt;sys_enter_openat&lt;/code&gt; for file opens, &lt;code&gt;sys_enter_connect&lt;/code&gt; for network connections, and &lt;code&gt;sys_enter_execve&lt;/code&gt; for process execution to track lineage. All three write into a single shared ring buffer with an event type field. Userspace reads and routes.&lt;/p&gt;
&lt;p&gt;I used a ring buffer over a perf event array deliberately. Perf event arrays are per-CPU, so you have to poll multiple buffers and deal with out-of-order events. A ring buffer is a single shared buffer, better throughput, simpler consumer. So obviously I wanted the path of least resistance.&lt;/p&gt;
&lt;h2 id=&#34;how-correlation-and-scoring-works&#34;&gt;How correlation and scoring works
&lt;/h2&gt;&lt;p&gt;On the userspace side, three in-memory maps hold state. Recent file opens per PID, process lineage from exec events, and a deduplication map to avoid alerting on the same PID repeatedly. A cleanup goroutine evicts stale entries every 30 seconds.&lt;/p&gt;
&lt;p&gt;The correlation window is configurable. I have it set to 5 seconds. When a connect event comes in, Barbwire looks back at that PID&amp;rsquo;s recent file opens and checks if any fall within the window. If they do, it scores the pair.&lt;/p&gt;
&lt;p&gt;Scoring is based on file and connect pairs, not individual signals. A process connecting to the network is normal. Opening &lt;code&gt;/etc/passwd&lt;/code&gt; on its own is normal. Both within 5 seconds is suspicious. The score comes from which file category was accessed:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;suspicious_files&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - &lt;span style=&#34;color:#f92672&#34;&gt;category&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;credential access&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;base_score&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;patterns&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/etc/passwd&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/etc/shadow&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/.aws/credentials&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - &lt;span style=&#34;color:#f92672&#34;&gt;category&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ssh key exfiltration&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;base_score&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;patterns&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;.ssh/id_rsa&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;.ssh/id_ed25519&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Process lineage modifies the score up or down. A shell spawning a process that reads credentials and connects out is more suspicious than the same behavior happening under systemd:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;suspicious_parents&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - &lt;span style=&#34;color:#f92672&#34;&gt;comm&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;bash&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;modifier&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - &lt;span style=&#34;color:#f92672&#34;&gt;comm&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;sshd&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;modifier&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;legit_parents&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - &lt;span style=&#34;color:#f92672&#34;&gt;comm&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;systemd&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;modifier&lt;/span&gt;: -&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - &lt;span style=&#34;color:#f92672&#34;&gt;comm&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;dockerd&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;modifier&lt;/span&gt;: -&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Alert threshold and severity thresholds are decoupled. The threshold decides if the alert is an actual alert, severity is a classification of the alert. When a connect event comes in, Barbwire picks the highest scoring file match for that PID and emits one alert. One alert per connect event per process, no duplicates (hopefully).&lt;/p&gt;
&lt;p&gt;A fired alert looks like this:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;┌─ barbwire alert — PID 41890  ─────────────
│  command  : python
│  file     : /etc/passwd
│  connect  : 2404:6800:4007:821::200e:80
│  severity : HIGH
│  reasons  : credential access, suspicious parent: fish
│  parent   : fish (pid 13387)
│  gparent  : tmux: server (pid 9483)
└─────────────────────────────────────────────
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;my-screwups-while-building-it&#34;&gt;My Screwups while building it
&lt;/h2&gt;&lt;p&gt;A few things broke in ways that were actually instructive. The first one was actually two bugs hiding behind each other, which made it genuinely annoying to debug.&lt;/p&gt;
&lt;p&gt;There was a constant mismatch between the C and Go sides. &lt;code&gt;EVENT_EXEC&lt;/code&gt;, the event type for &lt;code&gt;sys_enter_execve&lt;/code&gt; tracepoint, was 2 and &lt;code&gt;EVENT_CONNECT&lt;/code&gt;, the event type for &lt;code&gt;sys_enter_connect&lt;/code&gt;, was 3 in the BPF code, but I had them swapped in Go. At the same time, I had attached the exec tracepoint and called Close() on it immediately without a defer, so it detached right after attaching (Yeah this is embrassing).&lt;/p&gt;
&lt;p&gt;The symptom was simple, in terms of events I had none. Thing was execve events were being routed to the connect handler. Since those events carry no IP address family, they got dropped as invalid. Meanwhile connect events were being routed to the exec handler, which was already closed. Everything was failing quietly in a different place than where I was looking.&lt;/p&gt;
&lt;p&gt;I spent a while staring at the correlation logic before going back to basics and checking whether the tracepoints were even active. Once I caught the missing defer, connect events started showing up, but in the wrong handler. That&amp;rsquo;s when I found the swapped constants. Two separate bugs, one symptom, neither pointing at the other. Really annoying&lt;/p&gt;
&lt;p&gt;The most useful bug involved stale memory in the event struct. &lt;code&gt;bpf_ringbuf_reserve&lt;/code&gt; gives you a pointer to uninitialized memory. If you skip the &lt;code&gt;__builtin_memset&lt;/code&gt; before writing your fields, whatever was in memory from the previous event bleeds into the fields you didn&amp;rsquo;t set. I had filenames with garbage characters appended, leftovers from longer filenames earlier in the buffer. The fix is one line. But you have to know it&amp;rsquo;s needed.&lt;/p&gt;
&lt;h2 id=&#34;limitations-and-takeaways&#34;&gt;Limitations and takeaways
&lt;/h2&gt;&lt;p&gt;The biggest problem with Barbwire is the one that can&amp;rsquo;t be tuned away.&lt;/p&gt;
&lt;p&gt;For example, &lt;code&gt;curl&lt;/code&gt; reads &lt;code&gt;/etc/passwd&lt;/code&gt; on every invocation. Here is it making the call:
&lt;img src=&#34;https://itsmonish.pages.dev/images/barbwire/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;curl opening passwd&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Not because it&amp;rsquo;s malicious, but because that&amp;rsquo;s how it works. I believe, basically any program using libc networking does this. Barbwire flags it every time. No matter how hard I tuned the knobs, I couldn&amp;rsquo;t get rid of such alerts. Then it hit me, single-process correlation without broader context has a ceiling.&lt;/p&gt;
&lt;p&gt;Evidently, production security tools handle this differently. Binary hash whitelisting instead of process name matching, which is spoofable. Process ancestry graphs that track behavioral chains across multiple processes. Behavioral baselines built up over time. A shell that reads &lt;code&gt;/etc/passwd&lt;/code&gt; and then forks a child that connects out would be caught by a graph-based correlator. Barbwire misses it because the file open and the connect are in different PIDs.&lt;/p&gt;
&lt;p&gt;Building this made that limitation concrete in a way I don&amp;rsquo;t think I&amp;rsquo;d have gotten from just reading about EDR design. Honestly, I never even thought of these before. You also understand why process ancestry graphs exist when your tool fails exactly where they&amp;rsquo;d succeed.&lt;/p&gt;
&lt;p&gt;The other thing I took away: the BPF to userspace boundary is unforgiving. Memory layout, pointer semantics, which helper functions apply where, what the verifier accepts. The documentation covers the what, but the why only shows up when things break.&lt;/p&gt;
&lt;p&gt;All things considered, I had fun with all this. That&amp;rsquo;s the whole point if you think about it.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Honeyfused: An intrusion detection script using FUSE filesystem</title>
        <link>https://itsmonish.pages.dev/blog/honeyfused/</link>
        <pubDate>Tue, 26 Aug 2025 18:24:58 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/honeyfused/</guid>
        <description>&lt;h2 id=&#34;introduction&#34;&gt;Introduction
&lt;/h2&gt;&lt;p&gt;First things first, what is Honeyfused? It&amp;rsquo;s a fun little side project that I spent some time on. It is on my &lt;a class=&#34;link&#34; href=&#34;https://github.com/ItsMonish/honeyfused&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;github repo&lt;/a&gt; if anyone&amp;rsquo;s interested.&lt;/p&gt;
&lt;p&gt;Honeyfused is in a sense an intrusion detection application using honey-files. The program emulates filesystem mounted on directories and presents files that are actually not part of the original filesystem. Since the program emulates folders that usually contains secrets and API keys, intruders and infostealers may try to access it and possibly exfil the files. Since we control the filesystem, we can generate alerts whenever the file is accessed or modified. That is the gist of it. In this article you&amp;rsquo;ll find why I did this, how I did this and things like that.&lt;/p&gt;
&lt;h2 id=&#34;how-did-i-get-here&#34;&gt;How did I get here?
&lt;/h2&gt;&lt;p&gt;I very recently learnt that you can implement virtual filesystems, that is, filesystem that are not actually present on the disk, using FUSE bindings. All one had to do is override the operating system filesystem function calls to &lt;strong&gt;mimic&lt;/strong&gt; an actual filesystem and you can literally pull show a filesystem out of nowhere.&lt;/p&gt;
&lt;p&gt;Armed with the knowledge, I thought &amp;ldquo;why can&amp;rsquo;t I just implement a decoy filesystem with decoy files and generate alerts whenever the files are accessed?&amp;rdquo;. But this is basically honey-files with extra steps, that is, the virtual filesystem. Then I thought a honey-file is always the same, always there in the same place, and it is usually something like &amp;ldquo;passwords.txt&amp;rdquo; or &amp;ldquo;keys.csv&amp;rdquo;. So what if I could dynamically generate new file contents in important places, places where applications usually keep their tokens, secrets and keys, places which are more believable and look like legit files to an attacker, places which an infostealer would automatically enumerate. And hence, I got started to find out.&lt;/p&gt;
&lt;h2 id=&#34;the-filesystem-implementation&#34;&gt;The filesystem implementation
&lt;/h2&gt;&lt;p&gt;There are a few libraries that provide libfuse bindings in Python. Namely &lt;a class=&#34;link&#34; href=&#34;https://github.com/fusepy/fusepy&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;fusepy&lt;/a&gt;, &lt;a class=&#34;link&#34; href=&#34;https://github.com/libfuse/python-fuse&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;python-fuse&lt;/a&gt;, &lt;a class=&#34;link&#34; href=&#34;https://github.com/mxmlnkn/mfusepy&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;mfusepy&lt;/a&gt; etc. I choose to work with &lt;code&gt;mfusepy&lt;/code&gt; as it is one of the still maintained one. I couldn&amp;rsquo;t find any documentation about the module. But lucky for me, they maintain a folder of &lt;a class=&#34;link&#34; href=&#34;https://github.com/mxmlnkn/mfusepy/tree/master/examples&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;example implementations&lt;/a&gt;. One of those aligns closely with what I want, a pure &lt;a class=&#34;link&#34; href=&#34;https://github.com/mxmlnkn/mfusepy/blob/master/examples/memory.py&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;in-memory virtual filesystem implementation&lt;/a&gt;. Even though it did not clearly specify what should be actually done, it did give me a gist of how to do it.&lt;/p&gt;
&lt;p&gt;However the example script didn&amp;rsquo;t quite work out-of-the-box for me. So I made some modifications and additions of my own to emulate an actual filesystem. At the end of it, I had a script to create a virtual filesystem that can contain and display files, create new files, delete existing ones, create a directoy and so on.&lt;/p&gt;
&lt;h2 id=&#34;what-to-generate&#34;&gt;What to generate?
&lt;/h2&gt;&lt;p&gt;Now that, I can mount an filesystem whereever I want, I need to generate files. Not just any files, files that appear to be legit, files that should be placed in places where popular applications places them. Then I spent some time researching in popular applications and their configurations. Nah, I&amp;rsquo;m kidding. I used ChatGPT to tell me how popular applications stored their configs and keys. At the end of it, I had a list of applications that seemed to be good candidates for the decoy files. I settled for Kubernetes&amp;rsquo;s kubeconfig, AWS&amp;rsquo;s credential and config file, Azure&amp;rsquo;s credentials.json, GCP&amp;rsquo;s default application config file, Terraform&amp;rsquo;s credential file, Docker&amp;rsquo;s config file and lastly Bitcoin&amp;rsquo;s config and wallet files. Mostly developer centric, I know.&lt;/p&gt;
&lt;p&gt;With an list of candidate application, I then again asked ChatGPT to give me a blueprint of configuration files and what kind of data should I use to fill it with. With that, I used Python&amp;rsquo;s &lt;code&gt;string.template&lt;/code&gt; to craft template of files and wrote generator functions to dynamically populate the templates. It took me some time to cover this aspect of the ground but it was fine.&lt;/p&gt;
&lt;h2 id=&#34;putting-things-together&#34;&gt;Putting things together
&lt;/h2&gt;&lt;p&gt;At this point, I have a script to mount a fake filesystem anywhere I want and generator functions that can give me realistic looking files that popular applications use. Only thing left is to put these things together. I used a YAML file (&lt;code&gt;config.yml&lt;/code&gt;) as the configuration file for user. With that user can specify which applications can the script emulate and present decoys for. Because we don&amp;rsquo;t want to present decoys for already present applications.&lt;/p&gt;
&lt;p&gt;It took going a little back and forth on things, until I finally managed to put it together. So now my script (actually scripts), managed to generate decoy files for applications provided in &lt;code&gt;config.yml&lt;/code&gt; and mount it in place I wanted.&lt;/p&gt;
&lt;h2 id=&#34;the-logging&#34;&gt;The logging
&lt;/h2&gt;&lt;p&gt;I&amp;rsquo;ll admit, I haven&amp;rsquo;t done a lot of logging stuff in Python. Since &lt;code&gt;mfusepy&lt;/code&gt; already provided debug logs for the filesystem, I tried to implement logging that gives debug information for my script. So I read the documentation (yes I actually did that), and implemented it. And then I remembered that I had to log alerts as well, because that is the whole point of the application. But I didn&amp;rsquo;t want to throw all the log at once. So I seperated logs from &lt;code&gt;myfusepy&lt;/code&gt;, debug information from my script and the alerts I want to give out. Turns out it&amp;rsquo;s surprisingly easy than it sounds.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion
&lt;/h2&gt;&lt;p&gt;It took me over an week to put all these together. I mean I didn&amp;rsquo;t spent all my time on this, but okay. So basically I got an Intrusion detection system out that puts fake files on your filesystem and then alerts you when someone accesses it. It is geared more towards developers who keep these kinda files in their storage. But at the end this is just a stupid experiment. So I hope no one uses it as an actual security measure. Still it was pretty fun convincing the system that a filesystem exists when it doesn&amp;rsquo;t and generate configuration files for various applications.&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
