<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>flask on Stephen Swanson</title>
    
    
    
    <link>https://stephenswanson.xyz/tags/flask/</link>
    <description>Recent content in flask on Stephen Swanson</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <managingEditor>stephen@stephenswanson.xyz (Stephen Swanson)</managingEditor>
    <webMaster>stephen@stephenswanson.xyz (Stephen Swanson)</webMaster>
    <copyright>Stephen Swanson - CC BY 3.0 US.</copyright>
    <lastBuildDate>Wed, 18 May 2022 00:00:00 -0700</lastBuildDate>
    
	<atom:link href="https://stephenswanson.xyz/tags/flask/index.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>Python PIL is Sus - Amidst Us: HTB Cyber Apocalypse 2022</title>
      <link>https://stephenswanson.xyz/articles/htb-cyber-apocalypse-2022-amidst-us/</link>
      <pubDate>Wed, 18 May 2022 00:00:00 -0700</pubDate>
      <author>stephen@stephenswanson.xyz (Stephen Swanson)</author>
      <guid>https://stephenswanson.xyz/articles/htb-cyber-apocalypse-2022-amidst-us/</guid>
      <description>
        
          &lt;img src=&#34;https://stephenswanson.xyz/articles/htb-cyber-apocalypse-2022-amidst-us/4443a8e2360636f3a99d97aec2a8a62a.png&#34;/&gt;
          
        
        
        &lt;blockquote&gt;
&lt;p&gt;The AmidstUs tribe is a notorious group of sleeper agents for hire. We have plausible reasons to believe they are working with Draeger, so we have to take action to uncover their identities. Ulysses and bonnie have infiltrated their HQ and came across this mysterious portal on one of the unlocked computers. Can you hack into it despite the low visibility and get them access?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This was a fun challenge, mainly because the correct path was fairly obvious, although exploitation required a little googling. It was great practice for python exploitation.&lt;/p&gt;
&lt;h2 id=&#34;the-challenge&#34;&gt;The Challenge&lt;/h2&gt;
&lt;p&gt;We&amp;rsquo;re given a web page with amonglings (?) on them, as well as a place to upload a file&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;9c92ee4755c77c68d5593a24abd09dab.png&#34; alt=&#34;9c92ee4755c77c68d5593a24abd09dab.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;We can upload an image, and the page returns the image with the alpha changed to a value that we can specify here:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;2abdcd8225379377f82919f427048239.png&#34; alt=&#34;2abdcd8225379377f82919f427048239.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;re also given the complete source code, which shows that this is a python flask app.&lt;/p&gt;
&lt;h2 id=&#34;the-solution&#34;&gt;The Solution&lt;/h2&gt;
&lt;p&gt;From examining the page, we can see that we have one pathway through the code; via the &lt;code&gt;/api/alphafy&lt;/code&gt; endpoint. In a flask app, you can typically find all the routes in a file named &lt;code&gt;routes.py&lt;/code&gt; or something like that.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@api&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;route&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;/alphafy&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;methods&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;POST&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;alphafy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
	&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is_json&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;image&amp;#39;&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
		&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;abort&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;400&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

	&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;make_alpha&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This route just calls calls a function called &lt;code&gt;make_alpha&lt;/code&gt; , which we can trace back to the &lt;code&gt;utils.py&lt;/code&gt; file.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;make_alpha&lt;/code&gt; function is too long to include in it&amp;rsquo;s entirety, but here are a few snippets that are relevant:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;make_alpha&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;color&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;background&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;dec_img&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;base64&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;b64decode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;image&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;encode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;

        &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BytesIO&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dec_img&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;convert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;RGBA&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;img_bands&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;band&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;convert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;F&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;band&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;split&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()]&lt;/span&gt;

        &lt;span class=&#34;n&#34;&gt;alpha&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ImageMath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;eval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
            &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;float(
&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;				max(
&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;				max(
&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;					max(
&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;					difference1(red_band, &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;),
&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;					&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# just for syntax highlighting&lt;/span&gt;
					&lt;span class=&#34;c1&#34;&gt;# ...&lt;/span&gt;
					&lt;span class=&#34;c1&#34;&gt;# ...&lt;/span&gt;
					&lt;span class=&#34;c1&#34;&gt;# ...&lt;/span&gt;
			        &lt;span class=&#34;n&#34;&gt;new_image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;save&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;format&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;PNG&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
            &lt;span class=&#34;s2&#34;&gt;&amp;#34;image&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;data:image/png;base64,&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;base64&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;b64encode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getvalue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;decode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Examining this function, it looks like the call of &lt;code&gt;ImageMath.eval&lt;/code&gt;  might be interesting. When looking for vulnerabilites, just the word eval in any context is a huge red flag.&lt;/p&gt;
&lt;p&gt;After some Googling, we figure out that something like CVE-2022-22817 might be interesting. Since we have a preliminary thumbs up, we can reach into our standard python bag of tricks and pull out a payload like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;nb&#34;&gt;__import__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;os&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;system&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;cp /flag.txt /app/application/static&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Since it seems like the color parameters are evaluated, we can try exploiting the parameters using Burp.&lt;/p&gt;
&lt;p&gt;First, we&amp;rsquo;ll send the api request to the Burp repeater:
&lt;img src=&#34;1049bd722aa2bee6abedcf7ad885d7fc.png&#34; alt=&#34;1049bd722aa2bee6abedcf7ad885d7fc.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;Then, we&amp;rsquo;ll scroll to the bottom of the request, add our payload, and send it off:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;5472e9a4d14e7389abcb6c631b70c484.png&#34; alt=&#34;5472e9a4d14e7389abcb6c631b70c484.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ll see that we get a 400 response, indicating some kind of server error, but let&amp;rsquo;s check and see if we actually copied the flag to the &lt;code&gt;/static&lt;/code&gt; directory:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;dff9c4da6160cd37fada5fb000bc1f98.png&#34; alt=&#34;dff9c4da6160cd37fada5fb000bc1f98.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;Boom! We have a working PoC. Time to use it on the actual challenge server!&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;697a1366d985e9940b436e02043a4610.png&#34; alt=&#34;697a1366d985e9940b436e02043a4610.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;This time, I&amp;rsquo;m not using the repeater, just the interceptor.&lt;/p&gt;
&lt;p&gt;After adding the exploit, we&amp;rsquo;ll pass it to the challenge server, and check if our exploit worked.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;f570cb5ae23e062bf416c4b3051659ac.png&#34; alt=&#34;f570cb5ae23e062bf416c4b3051659ac.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;And we get the flag, solving the challenge and giving us access to the internal networks of the mysterious amonglings!&lt;/p&gt;
&lt;p&gt;If this was interesting at all, helped you with one of your challenges, or if you have any questions or corrections, please drop me a line!&lt;/p&gt;

        
        </description>
    </item>
    
  </channel>
</rss>