<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Logic Flaw on HitCat</title>
        <link>https://blog.hitc.at/tags/logic-flaw/</link>
        <description>Recent content in Logic Flaw on HitCat</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en-us</language>
        <copyright>HitCat</copyright>
        <lastBuildDate>Sun, 07 May 2023 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.hitc.at/tags/logic-flaw/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>Forging a client-side score to beat an unbeatable game - PwnMe 2023</title>
        <link>https://blog.hitc.at/posts/ctf/pwnme-2023/web/beat-me/</link>
        <pubDate>Sun, 07 May 2023 00:00:00 +0000</pubDate>
        
        <guid>https://blog.hitc.at/posts/ctf/pwnme-2023/web/beat-me/</guid>
        <description>&lt;img src="https://blog.hitc.at/images/pwnme2023/web/beat_me_game.png" alt="Featured image of post Forging a client-side score to beat an unbeatable game - PwnMe 2023" /&gt;&lt;h2 id=&#34;introduction&#34;&gt;Introduction
&lt;/h2&gt;&lt;p&gt;This challenge is a WEB challenge from the PWNME 2023 CTF.&lt;/p&gt;
&lt;h3 id=&#34;context-explanation&#34;&gt;Context explanation
&lt;/h3&gt;&lt;p&gt;A pro player challenges you in a new game. They have spent a lot of time on it and achieved an extremely high score.&lt;/p&gt;
&lt;h3 id=&#34;directive&#34;&gt;Directive
&lt;/h3&gt;&lt;p&gt;Your goal is to beat them by any means necessary.&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution
&lt;/h2&gt;&lt;p&gt;The challenge is a game where you must move a ship to avoid shots and fire at enemies.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.hitc.at/images/pwnme2023/web/beat_me_game.png#center&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Beat me!&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;The player you must beat is Eteck, the challenge creator, who has a score of 1337420.&lt;/p&gt;
&lt;p&gt;Of course, we won&amp;rsquo;t tryhard to beat this score; instead, we&amp;rsquo;ll try to find a flaw in the game.&lt;/p&gt;
&lt;p&gt;When playing, at the end of the game, we can see that two requests are made:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;POST /scores&lt;/strong&gt;: to send the score obtained at the end of the game.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GET /scores&lt;/strong&gt;: to retrieve the scoreboard.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.hitc.at/images/pwnme2023/web/beat_me_game_end.png#center&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Beat me!&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;The payload sent to post the score is the following:&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-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;HitCat&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;score&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;signature&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;-1166920824&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If we try to replay this request by modifying our score, we get an error indicating that the signature is not correct:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.hitc.at/images/pwnme2023/web/beat_me_post_score_error.png#center&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Beat me!&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s analyze the source code of the page to see how the signature is calculated.&lt;/p&gt;
&lt;p&gt;On the home page there is nothing special, except for some imports of JavaScript scripts, including &lt;code&gt;/js/main.0acc8a51228c77e4a908.bundle.js&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This JavaScript file is obfuscated, making it unreadable.&lt;/p&gt;
&lt;p&gt;Before wasting time trying to deobfuscate it, we can try to debug the script in the browser to see where the signature calculation is done.&lt;/p&gt;
&lt;p&gt;Searching for &lt;code&gt;signature&lt;/code&gt; in the code, we come across this function:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.hitc.at/images/pwnme2023/web/beat_me_script.png#center&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;signature&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;We can see here that the signature value is calculated using the &lt;code&gt;_0x3f306f&lt;/code&gt; function with &lt;code&gt;_0x5a84cd&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We can imagine that &lt;code&gt;_0x3f306f&lt;/code&gt; is the hash function, and &lt;code&gt;_0x5a84cd&lt;/code&gt; is the score.&lt;/p&gt;
&lt;p&gt;This is confirmed by playing a bit and analyzing the values during debugging:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.hitc.at/images/pwnme2023/web/beat_me_score_debug.png#center&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;signature&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;We can see in the top left of the screenshot that my score is 12.&lt;/p&gt;
&lt;p&gt;Likewise, we can see that the variable &lt;code&gt;_0x5a84cd&lt;/code&gt; is equal to 12 in the debug section on the right side of the screenshot.&lt;/p&gt;
&lt;p&gt;Since we&amp;rsquo;re debugging, we can modify the value of &lt;code&gt;_0x5a84cd&lt;/code&gt; to see what happens.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.hitc.at/images/pwnme2023/web/beat_me_cheated_score.png#center&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;signature&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Then, if we continue debugging, we can see that the score has been taken into account, and the signature is valid since the flag appears.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.hitc.at/images/pwnme2023/web/beat_me_flag.png#center&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;signature&#34;
	
	
&gt;&lt;/p&gt;
&lt;p&gt;Flag: &lt;code&gt;PWNME{ChE4t_oN_cLI3N7_G4m3_Is_Not_3aS1}&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&#34;tips--tricks&#34;&gt;Tips &amp;amp; Tricks
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Debug the JavaScript code to see how data is processed.&lt;/li&gt;
&lt;li&gt;Use the debugger to modify values.&lt;/li&gt;
&lt;li&gt;Don&amp;rsquo;t overlook obfuscated or minified JavaScript files; often, they contain valuable information.&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        
    </channel>
</rss>
