{"componentChunkName":"component---src-templates-post-template-js","path":"/ctf-hitcon-ctf-2024-antivirus-en","result":{"data":{"markdownRemark":{"id":"39cd0159-2e8f-59e0-8019-22e0e6a1a85d","html":"<blockquote>\n<p>This page has been machine-translated from the <a href=\"/ctf-hitcon-ctf-2024-antivirus\">original page</a>.</p>\n</blockquote>\n<p>I participated as a solo player in <a href=\"https://ctf2024.hitcon.org/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">HITCON CTF 2024</a> and placed 120th.</p>\n<p>I only solved one problem, so it’s a very short writeup.</p>\n<!-- omit in toc -->\n<h2 id=\"table-of-contents\" style=\"position:relative;\"><a href=\"#table-of-contents\" aria-label=\"table of contents permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Table of Contents</h2>\n<ul>\n<li>\n<p><a href=\"#antivirus-rev\">AntiVirus (Rev)</a></p>\n<ul>\n<li><a href=\"#overview\">Overview</a></li>\n<li><a href=\"#clamav-bytecode-signature\">ClamAV Bytecode Signature</a></li>\n<li><a href=\"#understanding-the-cbc-file-structure\">Understanding the .cbc File Structure</a></li>\n<li><a href=\"#disassembling-with-clambc\">Disassembling with clambc</a></li>\n<li><a href=\"#func0-analysis\">Func0 Analysis</a></li>\n<li><a href=\"#func1-analysis\">Func1 Analysis</a></li>\n<li><a href=\"#brute-force-approach\">Brute-Force Approach</a></li>\n</ul>\n</li>\n<li><a href=\"#wrap-up\">Wrap-up</a></li>\n</ul>\n<h2 id=\"antivirus-rev\" style=\"position:relative;\"><a href=\"#antivirus-rev\" aria-label=\"antivirus rev permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>AntiVirus (Rev)</h2>\n<h3 id=\"overview\" style=\"position:relative;\"><a href=\"#overview\" aria-label=\"overview permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Overview</h3>\n<p>A <code class=\"language-text\">.cbc</code> file (ClamAV bytecode signature file) was provided and we needed to determine what conditions that bytecode checks.</p>\n<h3 id=\"clamav-bytecode-signature\" style=\"position:relative;\"><a href=\"#clamav-bytecode-signature\" aria-label=\"clamav bytecode signature permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>ClamAV Bytecode Signature</h3>\n<p>ClamAV can detect malicious files using three types of signatures:</p>\n<ol>\n<li><strong>Pattern Signatures</strong> — match specific byte sequences in files</li>\n<li><strong>Logical Signatures</strong> — combine multiple pattern signatures with AND/OR/NOT logic</li>\n<li><strong>Bytecode Signatures</strong> — arbitrary programs compiled to ClamAV bytecode, capable of complex analysis</li>\n</ol>\n<p>Bytecode signatures are compiled with <code class=\"language-text\">clambc</code> and distributed as <code class=\"language-text\">.cbc</code> files. When ClamAV scans a file, the bytecode is executed against it.</p>\n<h3 id=\"understanding-the-cbc-file-structure\" style=\"position:relative;\"><a href=\"#understanding-the-cbc-file-structure\" aria-label=\"understanding the cbc file structure permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Understanding the .cbc File Structure</h3>\n<p>Running the file through <code class=\"language-text\">clambc --printbcir</code> disassembles the bytecode into a human-readable IR format.</p>\n<p>The output is very long, but the key structure is:</p>\n<ul>\n<li><strong>Func0</strong> — Entry point; checks file size, reads bytes, drives main logic</li>\n<li><strong>Func1</strong> — Core transformation function; 93 basic blocks of byte operations</li>\n</ul>\n<h3 id=\"disassembling-with-clambc\" style=\"position:relative;\"><a href=\"#disassembling-with-clambc\" aria-label=\"disassembling with clambc permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Disassembling with clambc</h3>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">clambc --printbcir AntiVirus.cbc <span class=\"token operator\">></span> AntiVirus.cbc.ir</code></pre></div>\n<p>The IR uses a virtual-register SSA form. Key instructions:</p>\n<ul>\n<li><code class=\"language-text\">%RXX = load i8 ... from @apiptr[...]</code> — read bytes from the scanned file</li>\n<li><code class=\"language-text\">%RXX = (RXXX RXXX == comparisons)</code> </li>\n<li>Branch instructions route execution based on comparison results</li>\n</ul>\n<h3 id=\"func0-analysis\" style=\"position:relative;\"><a href=\"#func0-analysis\" aria-label=\"func0 analysis permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Func0 Analysis</h3>\n<p>Func0 performs the following checks at a high level:</p>\n<ol>\n<li><strong>File size check</strong>: Verifies the file is exactly <code class=\"language-text\">0x18c</code> bytes long</li>\n<li><strong>Header check</strong>: Checks that the first two bytes are <code class=\"language-text\">MZ</code> (i.e., <code class=\"language-text\">0x4d 0x5a</code>) — a Windows PE header</li>\n<li><strong>Main loop</strong>: For each remaining byte position, calls Func1 to transform the byte, then compares the result against an expected value stored in the bytecode</li>\n</ol>\n<p>If all comparisons pass, the file is flagged as “malicious” — meaning it is actually the correct flag executable.</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">if (filesize != 0x18c) -> return NOT_FOUND\nif (bytes[0] != 0x4d) -> return NOT_FOUND\nif (bytes[1] != 0x5a) -> return NOT_FOUND\nfor i in 2..0x18c:\n    transformed = Func1(input[i], i)\n    if transformed != expected[i]: return NOT_FOUND\nreturn FOUND (i.e., this is the flag)</code></pre></div>\n<h3 id=\"func1-analysis\" style=\"position:relative;\"><a href=\"#func1-analysis\" aria-label=\"func1 analysis permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Func1 Analysis</h3>\n<p>Func1 takes the byte value and its index as inputs and applies a complex transformation across 93 basic blocks. The transformation involves:</p>\n<ul>\n<li>Multiple bitwise operations (AND, OR, XOR, shifts)</li>\n<li>Index-dependent branching</li>\n<li>Comparisons against hardcoded lookup values embedded in the IR</li>\n</ul>\n<p>Fully reversing Func1 is possible but time-consuming due to the 93-block structure.</p>\n<h3 id=\"brute-force-approach\" style=\"position:relative;\"><a href=\"#brute-force-approach\" aria-label=\"brute force approach permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Brute-Force Approach</h3>\n<p>Rather than fully reversing Func1, we can use a side-channel approach:</p>\n<ol>\n<li>Construct a candidate 0x18c-byte MZ file</li>\n<li>Scan it with a <strong>patched libclamav</strong> that emits debug traces of bytecode execution</li>\n<li>Parse the trace output to find which byte-comparison succeeded (the <code class=\"language-text\">1185 = (1136 == 1184)</code> pattern in the trace indicates a match)</li>\n<li>Iterate byte-by-byte from position 2 to 0x18c</li>\n</ol>\n<p>Patching libclamav to enable bytecode debug tracing:</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token comment\"># Build ClamAV with debug output enabled</span>\ncmake <span class=\"token punctuation\">..</span> -DCMAKE_BUILD_TYPE<span class=\"token operator\">=</span>Debug -DENABLE_BYTECODE_TRACE<span class=\"token operator\">=</span>ON\n<span class=\"token function\">make</span> -j<span class=\"token variable\"><span class=\"token variable\">$(</span>nproc<span class=\"token variable\">)</span></span></code></pre></div>\n<p>Brute-force script:</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">import</span> subprocess\n\ntarget <span class=\"token operator\">=</span> <span class=\"token number\">0</span>\n\n<span class=\"token keyword\">def</span> <span class=\"token function\">bruteforce</span><span class=\"token punctuation\">(</span>target<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">for</span> n <span class=\"token keyword\">in</span> <span class=\"token builtin\">range</span><span class=\"token punctuation\">(</span><span class=\"token number\">0x100</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">with</span> <span class=\"token builtin\">open</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"print_flag.exe\"</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"r+b\"</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">as</span> f<span class=\"token punctuation\">:</span>\n            f<span class=\"token punctuation\">.</span>seek<span class=\"token punctuation\">(</span><span class=\"token number\">2</span> <span class=\"token operator\">+</span> target<span class=\"token punctuation\">)</span>\n            f<span class=\"token punctuation\">.</span>write<span class=\"token punctuation\">(</span><span class=\"token builtin\">bytes</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">[</span>n<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n\n        command <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token string\">\"clamscan\"</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"--bytecode-unsigned\"</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"-d\"</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"print_flag.cbc\"</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"print_flag.exe\"</span><span class=\"token punctuation\">]</span>\n        result <span class=\"token operator\">=</span> subprocess<span class=\"token punctuation\">.</span>run<span class=\"token punctuation\">(</span>command<span class=\"token punctuation\">,</span> stdout<span class=\"token operator\">=</span>subprocess<span class=\"token punctuation\">.</span>PIPE<span class=\"token punctuation\">,</span> stderr<span class=\"token operator\">=</span>subprocess<span class=\"token punctuation\">.</span>PIPE<span class=\"token punctuation\">)</span>\n        outputs <span class=\"token operator\">=</span> result<span class=\"token punctuation\">.</span>stdout<span class=\"token punctuation\">.</span>decode<span class=\"token punctuation\">(</span><span class=\"token string\">\"utf-8\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>splitlines<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\n        is_find <span class=\"token operator\">=</span> <span class=\"token boolean\">False</span>\n        counter <span class=\"token operator\">=</span> <span class=\"token number\">0</span>\n        <span class=\"token keyword\">for</span> i<span class=\"token punctuation\">,</span> line <span class=\"token keyword\">in</span> <span class=\"token builtin\">enumerate</span><span class=\"token punctuation\">(</span>outputs<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n            <span class=\"token keyword\">if</span> <span class=\"token string\">\"1185 = (1136 == 1184)\"</span> <span class=\"token keyword\">in</span> line<span class=\"token punctuation\">:</span>\n                r <span class=\"token operator\">=</span> <span class=\"token builtin\">int</span><span class=\"token punctuation\">(</span>outputs<span class=\"token punctuation\">[</span>i<span class=\"token operator\">+</span><span class=\"token number\">3</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n                <span class=\"token keyword\">if</span> r <span class=\"token operator\">==</span> <span class=\"token number\">1</span><span class=\"token punctuation\">:</span>\n                    <span class=\"token keyword\">if</span> counter <span class=\"token operator\">==</span> target<span class=\"token punctuation\">:</span>\n                        is_find <span class=\"token operator\">=</span> <span class=\"token boolean\">True</span>\n                        <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span><span class=\"token builtin\">hex</span><span class=\"token punctuation\">(</span>n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> line<span class=\"token punctuation\">,</span> counter<span class=\"token punctuation\">,</span> target<span class=\"token punctuation\">)</span>\n                        <span class=\"token keyword\">return</span> n\n                    counter <span class=\"token operator\">+=</span> <span class=\"token number\">1</span>\n                <span class=\"token keyword\">else</span><span class=\"token punctuation\">:</span>\n                    <span class=\"token keyword\">break</span>\n    <span class=\"token keyword\">return</span> <span class=\"token operator\">-</span><span class=\"token number\">1</span>\n\n<span class=\"token keyword\">for</span> x <span class=\"token keyword\">in</span> <span class=\"token builtin\">range</span><span class=\"token punctuation\">(</span><span class=\"token number\">0x18c</span> <span class=\"token operator\">-</span> <span class=\"token number\">2</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    r <span class=\"token operator\">=</span> bruteforce<span class=\"token punctuation\">(</span>target<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">if</span> r <span class=\"token operator\">>=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">:</span>\n        target <span class=\"token operator\">+=</span> <span class=\"token number\">1</span>\n    <span class=\"token keyword\">else</span><span class=\"token punctuation\">:</span>\n        exit<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>Running this script takes several hours (worst-case complexity is <code class=\"language-text\">0xFF × 0x18c</code> iterations, each requiring an EXE write and a <code class=\"language-text\">clamscan</code> invocation), but it successfully recovers the correct EXE byte by byte.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 715px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/22e1d05b62c10d88183d7c7b070b15c9/d0c0e/image-20240820205414624.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 81.25%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAAAsTAAALEwEAmpwYAAABvElEQVQ4y3XUZ4rFMAxG0ezi9d57b/D2vy0PR6AQZpgfJo7KpyvZSXU6ncr5fC6et9utXK/X0m63y2AwKLvdrlwul7JYLMpsNos4T7b1eh3+4/FY9vt95He73VKliKD7/R6inU4nBAWzLZfLEOXzfDwetZg8hdh6vV6pGAimsSkoiY/IfD6PZIRsm82mJkvhIEw6gkmbgofDId4RpmCSKsaf4+ILQgkp+nw+y/v9DodqSbjdbst0Oq1nh8hiJ27vOR6PS6VCLkZJvwmzZXstm6uWm4R89aEIYED4er3CgdKMMpmQ2NVqFUWJ8bMlzGg0KlXi52AJE7O0LJiIlpGgFcunZX7ickMQgdMlhM6+2bL3vDZi89rkCcvL0cShMDLkSUHv9/shigCNg5hMJrEnSAwhcoT8YoNQNbMj9Pl8Yk9sOByGAGqJSYaWLdvMU64J/5thXhv25gyddl4ZZGx5yUH8mWHeQwsFYsl5XYigyi+kOc8Q/E3o2fw5CCRm2ZulOK0rRAyhvLiHKuQ3jPD7/YYYUcF8ggmJQZ0/DQV1lP8B44iLrVLeeu8EW61WtJcETtAemZnaE5CT+Yr+AHRc4SotrPPTAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/22e1d05b62c10d88183d7c7b070b15c9/8ac56/image-20240820205414624.webp 240w,\n/static/22e1d05b62c10d88183d7c7b070b15c9/d3be9/image-20240820205414624.webp 480w,\n/static/22e1d05b62c10d88183d7c7b070b15c9/cb533/image-20240820205414624.webp 715w\"\n              sizes=\"(max-width: 715px) 100vw, 715px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/22e1d05b62c10d88183d7c7b070b15c9/8ff5a/image-20240820205414624.png 240w,\n/static/22e1d05b62c10d88183d7c7b070b15c9/e85cb/image-20240820205414624.png 480w,\n/static/22e1d05b62c10d88183d7c7b070b15c9/d0c0e/image-20240820205414624.png 715w\"\n            sizes=\"(max-width: 715px) 100vw, 715px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/22e1d05b62c10d88183d7c7b070b15c9/d0c0e/image-20240820205414624.png\"\n            alt=\"image-20240820205414624\"\n            title=\"image-20240820205414624\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>Once all bytes are recovered and the complete EXE is assembled, executing it yields the flag.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 440px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/0517147fc12e170327be98d502511211/48c0e/image-20240821204345132.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 8.75%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAcElEQVQI1x2OUQ4EIQhD5wJqvMCOiiBoovc/XZfxoyEF8tpHhEHUoDYxp+GcgyECc8/MsDlRywuRcX15f+i9I6WEEMJVjPEq54zH1C6QiO6ca0F1YKii1ApqFc0Be28HkQfZBep3LwXL/9kLfDv2cn91Nzf086EpTAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/0517147fc12e170327be98d502511211/8ac56/image-20240821204345132.webp 240w,\n/static/0517147fc12e170327be98d502511211/23a50/image-20240821204345132.webp 440w\"\n              sizes=\"(max-width: 440px) 100vw, 440px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/0517147fc12e170327be98d502511211/8ff5a/image-20240821204345132.png 240w,\n/static/0517147fc12e170327be98d502511211/48c0e/image-20240821204345132.png 440w\"\n            sizes=\"(max-width: 440px) 100vw, 440px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/0517147fc12e170327be98d502511211/48c0e/image-20240821204345132.png\"\n            alt=\"image-20240821204345132\"\n            title=\"image-20240821204345132\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<h2 id=\"wrap-up\" style=\"position:relative;\"><a href=\"#wrap-up\" aria-label=\"wrap up permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Wrap-up</h2>\n<p>This was a low-solver problem, but after studying ClamAV bytecode signatures and libclamav debug tracing, it was possible to solve it fairly smoothly.</p>\n<p>If you understand the bytecode IR format and can set up the debug trace pipeline, the brute-force approach — though slow — is methodical and reliable.</p>","fields":{"slug":"/ctf-hitcon-ctf-2024-antivirus-en","tagSlugs":["/tag/clam-av-en/","/tag/malware-en/","/tag/ctf-en/","/tag/rev-en/","/tag/english/"]},"frontmatter":{"date":"2024-08-17","description":"HITCON CTF 2024 Writeup — Reverse-engineering a ClamAV bytecode signature file","tags":["ClamAV (en)","Malware (en)","CTF (en)","Rev (en)","English"],"title":"HITCON CTF 2024 Writeup — AntiVirus (Rev)","socialImage":{"publicURL":"/static/dc4d8b7f8795f3c3d3489d9957d155f2/no-image.png"}}}},"pageContext":{"slug":"/ctf-hitcon-ctf-2024-antivirus-en"}},"staticQueryHashes":["251939775","401334301","825871152"]}