<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>arbitrary code execution Archives - George Gerontakis</title>
	<atom:link href="https://blog.gerontakis.eu/tag/arbitrary-code-execution/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.gerontakis.eu/tag/arbitrary-code-execution/</link>
	<description>My personal Blog and more 😎</description>
	<lastBuildDate>Wed, 05 Jul 2023 13:15:18 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	
	<item>
		<title>BSides Athens 2023 &#8211; Web &#8211; Broken Production Challenge Solution</title>
		<link>https://blog.gerontakis.eu/2023/07/05/bsides-athens-2023-web-broken-production-challenge-solution/</link>
					<comments>https://blog.gerontakis.eu/2023/07/05/bsides-athens-2023-web-broken-production-challenge-solution/#respond</comments>
		
		<dc:creator><![CDATA[g.gerontakis]]></dc:creator>
		<pubDate>Wed, 05 Jul 2023 13:12:11 +0000</pubDate>
				<category><![CDATA[Arbitrary Code Execution]]></category>
		<category><![CDATA[CTF]]></category>
		<category><![CDATA[Local File Inclusion]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[arbitrary code execution]]></category>
		<category><![CDATA[BSides]]></category>
		<category><![CDATA[BSides Athens]]></category>
		<category><![CDATA[Challenge]]></category>
		<category><![CDATA[Command Ececution]]></category>
		<category><![CDATA[LFI]]></category>
		<category><![CDATA[RCE]]></category>
		<guid isPermaLink="false">https://blog.gerontakis.eu/?p=103</guid>

					<description><![CDATA[<p>The description is pretty clear about what should we expect in this challenge (Web application Privilege escalation and Command Execution). A zip file is given with the following structure: First of all let&#8217;s examine the Dockerfile in order to get a better understanding of how this works: Nothing &#8220;too important&#8221; here, but we can see [&#8230;]</p>
<p>The post <a href="https://blog.gerontakis.eu/2023/07/05/bsides-athens-2023-web-broken-production-challenge-solution/">BSides Athens 2023 &#8211; Web &#8211; Broken Production Challenge Solution</a> appeared first on <a href="https://blog.gerontakis.eu">George Gerontakis</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="527" height="630" src="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-30.png" alt="" class="wp-image-104" srcset="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-30.png 527w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-30-251x300.png 251w" sizes="(max-width: 527px) 100vw, 527px" /></figure>



<span id="more-103"></span>



<p class="wp-block-paragraph">The description is pretty clear about what should we expect in this challenge (Web application Privilege escalation and Command Execution).</p>



<p class="wp-block-paragraph">A zip file is given with the following structure:</p>



<figure class="wp-block-image size-full"><img decoding="async" width="354" height="829" src="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-32.png" alt="" class="wp-image-106" srcset="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-32.png 354w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-32-128x300.png 128w" sizes="(max-width: 354px) 100vw, 354px" /></figure>



<p class="wp-block-paragraph">First of all let&#8217;s examine the Dockerfile in order to get a better understanding of how this works:</p>



<figure class="wp-block-image size-full"><img decoding="async" width="883" height="641" src="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-33.png" alt="" class="wp-image-108" srcset="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-33.png 883w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-33-300x218.png 300w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-33-768x558.png 768w" sizes="(max-width: 883px) 100vw, 883px" /></figure>



<p class="wp-block-paragraph">Nothing &#8220;too important&#8221; here, but we can see where and how the flag is stored. <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60e.png" alt="😎" class="wp-smiley" style="height: 1em; max-height: 1em;" /> The name of the file that contains the flag is randomly generated.</p>



<p class="wp-block-paragraph">Let&#8217;s start the instance and add the ip to hosts file as <strong>ctfchall1</strong></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="625" src="https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-27-1024x625.png" alt="" class="wp-image-109" srcset="https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-27-1024x625.png 1024w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-27-300x183.png 300w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-27-768x469.png 768w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-27-1536x938.png 1536w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-27.png 1801w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">An account can be created (user: gger / pass: gger):</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="652" src="https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-28-1024x652.png" alt="" class="wp-image-111" srcset="https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-28-1024x652.png 1024w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-28-300x191.png 300w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-28-768x489.png 768w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-28-1536x978.png 1536w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-28.png 1772w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">With the created account we login:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="433" src="https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-29-1024x433.png" alt="" class="wp-image-112" srcset="https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-29-1024x433.png 1024w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-29-300x127.png 300w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-29-768x325.png 768w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-29-1536x649.png 1536w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-29-2048x866.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">By examining the downloaded source code of the challenge, we can identify a part responsible for seting the authenticated user&#8217;s cookie after a succesfull login:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="829" height="889" src="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-35.png" alt="" class="wp-image-114" srcset="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-35.png 829w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-35-280x300.png 280w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-35-768x824.png 768w" sizes="auto, (max-width: 829px) 100vw, 829px" /></figure>



<p class="wp-block-paragraph">It is just a base64 ,json encoded username value, that we can easily create and set ourselves:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="960" height="181" src="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-36.png" alt="" class="wp-image-115" srcset="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-36.png 960w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-36-300x57.png 300w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-36-768x145.png 768w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-36-953x181.png 953w" sizes="auto, (max-width: 960px) 100vw, 960px" /></figure>



<p class="wp-block-paragraph">After that, with the help of the Burp Proxy <strong>Match and replace rules</strong> setting we can add a replace rule that replaces the PHPSESSID value with ours.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="521" height="277" src="https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-30_1.png" alt="" class="wp-image-116" srcset="https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-30_1.png 521w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-30_1-300x160.png 300w" sizes="auto, (max-width: 521px) 100vw, 521px" /></figure>



<p class="wp-block-paragraph">Now, when we refresh index of the web app, we are authenticated as <strong>Admin</strong>!</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="243" src="https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-31-1024x243.png" alt="" class="wp-image-117" srcset="https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-31-1024x243.png 1024w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-31-300x71.png 300w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-31-768x183.png 768w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-31-1536x365.png 1536w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-31-2048x487.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Analyzing the php source code of the project we also find another vulnerability that could lead to Local File Inclusion (LFI):</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="636" height="347" src="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-37.png" alt="" class="wp-image-118" srcset="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-37.png 636w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-37-300x164.png 300w" sizes="auto, (max-width: 636px) 100vw, 636px" /></figure>



<p class="wp-block-paragraph">Abusing the user controlled <strong>util </strong>parameter can lead to local file inclusion, but because the line 7 replaces the chars &#8220;../&#8221; we need to double the chars we add to the Get request <strong>(&#8230;.// instead of ../ so when the are replaced only the needed ../ part will remain</strong>).</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="414" src="https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-33-1024x414.png" alt="" class="wp-image-119" srcset="https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-33-1024x414.png 1024w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-33-300x121.png 300w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-33-768x310.png 768w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/2023-06-23_14-33.png 1388w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">There are several ways that an LFI can lead to Remote Command Execution. One of them is by polluting the access log file which will later be included and processed by php fpm.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="728" height="202" src="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-38.png" alt="" class="wp-image-121" srcset="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-38.png 728w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-38-300x83.png 300w" sizes="auto, (max-width: 728px) 100vw, 728px" /></figure>



<p class="wp-block-paragraph">So we try to pollute the access log file found in <strong>/var/log/nginx/access.log</strong> </p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="239" src="https://blog.gerontakis.eu/wp-content/uploads/2023/07/2023-06-23_14-37-1024x239.png" alt="" class="wp-image-124" srcset="https://blog.gerontakis.eu/wp-content/uploads/2023/07/2023-06-23_14-37-1024x239.png 1024w, https://blog.gerontakis.eu/wp-content/uploads/2023/07/2023-06-23_14-37-300x70.png 300w, https://blog.gerontakis.eu/wp-content/uploads/2023/07/2023-06-23_14-37-768x179.png 768w, https://blog.gerontakis.eu/wp-content/uploads/2023/07/2023-06-23_14-37-1536x358.png 1536w, https://blog.gerontakis.eu/wp-content/uploads/2023/07/2023-06-23_14-37.png 1561w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">If we request again the <strong>access.log</strong> file we can see that the php code we entered via the <strong>User-Agent</strong> header in order to pollute the log file, was executed successfully!</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="343" src="https://blog.gerontakis.eu/wp-content/uploads/2023/07/2023-06-23_14-43-1024x343.png" alt="" class="wp-image-126" srcset="https://blog.gerontakis.eu/wp-content/uploads/2023/07/2023-06-23_14-43-1024x343.png 1024w, https://blog.gerontakis.eu/wp-content/uploads/2023/07/2023-06-23_14-43-300x100.png 300w, https://blog.gerontakis.eu/wp-content/uploads/2023/07/2023-06-23_14-43-768x257.png 768w, https://blog.gerontakis.eu/wp-content/uploads/2023/07/2023-06-23_14-43-1536x514.png 1536w, https://blog.gerontakis.eu/wp-content/uploads/2023/07/2023-06-23_14-43.png 1557w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">We can also see the flag file with the random name <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60e.png" alt="😎" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">Using the same vulnerability we can read the file:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="546" src="https://blog.gerontakis.eu/wp-content/uploads/2023/07/2023-06-23_14-50-1024x546.png" alt="" class="wp-image-127" srcset="https://blog.gerontakis.eu/wp-content/uploads/2023/07/2023-06-23_14-50-1024x546.png 1024w, https://blog.gerontakis.eu/wp-content/uploads/2023/07/2023-06-23_14-50-300x160.png 300w, https://blog.gerontakis.eu/wp-content/uploads/2023/07/2023-06-23_14-50-768x409.png 768w, https://blog.gerontakis.eu/wp-content/uploads/2023/07/2023-06-23_14-50-1536x818.png 1536w, https://blog.gerontakis.eu/wp-content/uploads/2023/07/2023-06-23_14-50.png 1556w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="505" src="https://blog.gerontakis.eu/wp-content/uploads/2023/07/2023-06-23_14-50_1-1024x505.png" alt="" class="wp-image-128" srcset="https://blog.gerontakis.eu/wp-content/uploads/2023/07/2023-06-23_14-50_1-1024x505.png 1024w, https://blog.gerontakis.eu/wp-content/uploads/2023/07/2023-06-23_14-50_1-300x148.png 300w, https://blog.gerontakis.eu/wp-content/uploads/2023/07/2023-06-23_14-50_1-768x379.png 768w, https://blog.gerontakis.eu/wp-content/uploads/2023/07/2023-06-23_14-50_1-1536x757.png 1536w, https://blog.gerontakis.eu/wp-content/uploads/2023/07/2023-06-23_14-50_1.png 1562w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
<p>The post <a href="https://blog.gerontakis.eu/2023/07/05/bsides-athens-2023-web-broken-production-challenge-solution/">BSides Athens 2023 &#8211; Web &#8211; Broken Production Challenge Solution</a> appeared first on <a href="https://blog.gerontakis.eu">George Gerontakis</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.gerontakis.eu/2023/07/05/bsides-athens-2023-web-broken-production-challenge-solution/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>TJCTF 2023 &#8211; Misc &#8211; Gish Challenge Solution</title>
		<link>https://blog.gerontakis.eu/2023/06/05/tjctf-2023-misc-gish-challenge-solution/</link>
					<comments>https://blog.gerontakis.eu/2023/06/05/tjctf-2023-misc-gish-challenge-solution/#respond</comments>
		
		<dc:creator><![CDATA[g.gerontakis]]></dc:creator>
		<pubDate>Mon, 05 Jun 2023 15:19:58 +0000</pubDate>
				<category><![CDATA[Arbitrary Code Execution]]></category>
		<category><![CDATA[CTF]]></category>
		<category><![CDATA[Misc]]></category>
		<category><![CDATA[TJCTF 2023]]></category>
		<category><![CDATA[arbitrary code execution]]></category>
		<category><![CDATA[Command Ececution]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[TJCTF]]></category>
		<category><![CDATA[TJCTF23]]></category>
		<guid isPermaLink="false">https://blog.gerontakis.eu/?p=67</guid>

					<description><![CDATA[<p>A zip file is given that contained the following files: By examining the Docker file to get a basic idea of what is happening we see that xinetd is executed while it&#8217;s conf file is copied to etc directory earlier. So as we see from the configuration file, the run.py is being executed as user [&#8230;]</p>
<p>The post <a href="https://blog.gerontakis.eu/2023/06/05/tjctf-2023-misc-gish-challenge-solution/">TJCTF 2023 &#8211; Misc &#8211; Gish Challenge Solution</a> appeared first on <a href="https://blog.gerontakis.eu">George Gerontakis</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="916" height="259" src="https://blog.gerontakis.eu/wp-content/uploads/2023/06/Screenshot_1.png" alt="" class="wp-image-68" srcset="https://blog.gerontakis.eu/wp-content/uploads/2023/06/Screenshot_1.png 916w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/Screenshot_1-300x85.png 300w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/Screenshot_1-768x217.png 768w" sizes="auto, (max-width: 916px) 100vw, 916px" /></figure>



<span id="more-67"></span>



<p class="wp-block-paragraph">A zip file is given that contained the following files:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="462" height="157" src="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-10.png" alt="" class="wp-image-71" srcset="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-10.png 462w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-10-300x102.png 300w" sizes="auto, (max-width: 462px) 100vw, 462px" /></figure>



<p class="wp-block-paragraph">By examining the Docker file to get a basic idea of what is happening we see that <strong>xinetd</strong> is executed while it&#8217;s conf file is copied to etc directory earlier.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="814" height="482" src="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-11.png" alt="" class="wp-image-72" srcset="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-11.png 814w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-11-300x178.png 300w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-11-768x455.png 768w" sizes="auto, (max-width: 814px) 100vw, 814px" /></figure>



<p class="wp-block-paragraph">So as we see from the configuration file, the <strong>run.py</strong> is being executed as user <strong>nobody</strong>:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="351" height="369" src="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-12.png" alt="" class="wp-image-73" srcset="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-12.png 351w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-12-285x300.png 285w" sizes="auto, (max-width: 351px) 100vw, 351px" /></figure>



<p class="wp-block-paragraph">So, let&#8217;s have a look at <strong>run.py</strong>:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="637" height="619" src="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-14.png" alt="" class="wp-image-78" srcset="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-14.png 637w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-14-300x292.png 300w" sizes="auto, (max-width: 637px) 100vw, 637px" /></figure>



<p class="wp-block-paragraph">Let&#8217;s analyze the above code:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" style="font-size:.875rem;line-height:1.25rem"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Python</span><span role="button" tabindex="0" data-code="#!/usr/bin/python3
#standard shebang line

#necessary imports are made
import sys
import shlex
import subprocess
from os import chdir

#current directory is changed to
chdir('/srv/')

print('please enter your script, terminated by the word &quot;end&quot;')
sys.stdout.flush()

#a list is created to store the lines of the user's script
script_lines = []

#read the input from the user until they enter the word &quot;end&quot;
while True:
  #Each line of input is stripped of leading/trailing whitespace
  next_line = sys.stdin.readline().strip()
  if next_line == 'end':
    break
  #and appended to the script_lines list
  script_lines.append(next_line)
print('script entered')
sys.stdout.flush()

#iterates over each line in script_lines
for line in script_lines:
  try:
    #this function tokenizes the input line, reducing the likelihood of unintentional command execution due to unescaped characters or spaces.
    args = shlex.split(line)
    #the first argument is checked to ensure it is 'git'.
    assert args[0] == 'git'
    #if the command is valid, the script attempts to execute it
    #it passes the list of arguments directly to the subprocess module, avoiding the use of shell interpolation.
    #and the output is stored in the output variable.
    output = subprocess.check_output(args, timeout=10)
    print(output.decode('utf-8'))
  except:
    print('errored, exiting')
  sys.stdout.flush()" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">#!/usr/bin/python3</span></span>
<span class="line"><span style="color: #6A9955">#standard shebang line</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">#necessary imports are made</span></span>
<span class="line"><span style="color: #C586C0">import</span><span style="color: #D4D4D4"> sys</span></span>
<span class="line"><span style="color: #C586C0">import</span><span style="color: #D4D4D4"> shlex</span></span>
<span class="line"><span style="color: #C586C0">import</span><span style="color: #D4D4D4"> subprocess</span></span>
<span class="line"><span style="color: #C586C0">from</span><span style="color: #D4D4D4"> os </span><span style="color: #C586C0">import</span><span style="color: #D4D4D4"> chdir</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">#current directory is changed to</span></span>
<span class="line"><span style="color: #D4D4D4">chdir(</span><span style="color: #CE9178">&#39;/srv/&#39;</span><span style="color: #D4D4D4">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">print</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&#39;please enter your script, terminated by the word &quot;end&quot;&#39;</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">sys.stdout.flush()</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">#a list is created to store the lines of the user&#39;s script</span></span>
<span class="line"><span style="color: #D4D4D4">script_lines = []</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">#read the input from the user until they enter the word &quot;end&quot;</span></span>
<span class="line"><span style="color: #C586C0">while</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">True</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">#Each line of input is stripped of leading/trailing whitespace</span></span>
<span class="line"><span style="color: #D4D4D4">  next_line = sys.stdin.readline().strip()</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> next_line == </span><span style="color: #CE9178">&#39;end&#39;</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">break</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">#and appended to the script_lines list</span></span>
<span class="line"><span style="color: #D4D4D4">  script_lines.append(next_line)</span></span>
<span class="line"><span style="color: #DCDCAA">print</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&#39;script entered&#39;</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">sys.stdout.flush()</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">#iterates over each line in script_lines</span></span>
<span class="line"><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> line </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> script_lines:</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">try</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955">#this function tokenizes the input line, reducing the likelihood of unintentional command execution due to unescaped characters or spaces.</span></span>
<span class="line"><span style="color: #D4D4D4">    args = shlex.split(line)</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955">#the first argument is checked to ensure it is &#39;git&#39;.</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">assert</span><span style="color: #D4D4D4"> args[</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">] == </span><span style="color: #CE9178">&#39;git&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955">#if the command is valid, the script attempts to execute it</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955">#it passes the list of arguments directly to the subprocess module, avoiding the use of shell interpolation.</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955">#and the output is stored in the output variable.</span></span>
<span class="line"><span style="color: #D4D4D4">    output = subprocess.check_output(args, </span><span style="color: #9CDCFE">timeout</span><span style="color: #D4D4D4">=</span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">print</span><span style="color: #D4D4D4">(output.decode(</span><span style="color: #CE9178">&#39;utf-8&#39;</span><span style="color: #D4D4D4">))</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">except</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">print</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&#39;errored, exiting&#39;</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">  sys.stdout.flush()</span></span></code></pre></div>



<p class="wp-block-paragraph">The above code allows a user to enter a series of Git commands and executes them one by one, printing the output of each command if it is successful. If an error occurs while executing a command, it prints an error message and continues to the next command.</p>



<p class="wp-block-paragraph">From the above script we can also understand that command injection possibility is relatively low. So we must find a way to abuse Git in order to execute a command or print the contents of the <strong>flag.txt</strong> file.</p>



<p class="wp-block-paragraph">There is also an extra file called <strong>git-chache-meta.sh</strong>:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="408" src="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-28-1024x408.png" alt="" class="wp-image-96" srcset="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-28-1024x408.png 1024w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-28-300x119.png 300w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-28-768x306.png 768w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-28.png 1379w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph"><code><strong>git cache-meta --store</strong></code> command is used to output the file metadata to a designated file (<code>.git_cache_meta</code> by default). It saves the metadata information for all files tracked by Git. The metadata includes ownership (user and group), permissions, and modification timestamps. The <code>--store</code> option saves the metadata to the file, while the <code>--stdout</code> option outputs the metadata to standard output.<br><br><code><strong>git cache-meta --apply</strong></code> command is used to apply the stored file metadata from the designated file (<code>.git_cache_meta</code>) back to the tracked files. It reads the metadata from the file and applies the ownership, permissions, and modification timestamps to the respective files. Before applying the metadata, it performs a validity check on the metadata file to ensure the format and structure of the stored metadata are correct.</p>



<p class="wp-block-paragraph">Let&#8217;s start the instance:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="490" height="292" src="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-19.png" alt="" class="wp-image-86" srcset="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-19.png 490w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-19-300x179.png 300w" sizes="auto, (max-width: 490px) 100vw, 490px" /></figure>



<p class="wp-block-paragraph">So there are several ways to do this! </p>



<h2 class="wp-block-heading">Solution 1</h2>



<p class="wp-block-paragraph">Use <strong>git config</strong> in order to set up <strong>alias </strong>and associate them with a command, then git alias as we named it and execute the associated command:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="719" height="487" src="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-20.png" alt="" class="wp-image-87" srcset="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-20.png 719w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-20-300x203.png 300w" sizes="auto, (max-width: 719px) 100vw, 719px" /></figure>



<p class="wp-block-paragraph">We find that the location of the flag is at the parent directory (back) and then we just print the flag file content.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="444" height="117" src="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-21.png" alt="" class="wp-image-88" srcset="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-21.png 444w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-21-300x79.png 300w" sizes="auto, (max-width: 444px) 100vw, 444px" /></figure>



<h2 class="wp-block-heading">Solution 2</h2>



<p class="wp-block-paragraph">1) Initialize a new Git repository in the parent directory of the current working directory.<br>2) Stage a file matching the pattern &#8220;../flag*&#8221; for the next commit.<br>3) Create a new commit with the staged changes.<br>4) Display the content and details of file/s matching the pattern &#8220;../flag*&#8221;</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="861" height="453" src="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-24.png" alt="" class="wp-image-91" srcset="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-24.png 861w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-24-300x158.png 300w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-24-768x404.png 768w" sizes="auto, (max-width: 861px) 100vw, 861px" /></figure>



<div class="wp-block-kevinbatdorf-code-block-pro" style="font-size:.875rem;line-height:1.25rem"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">Bash</span><span role="button" tabindex="0" data-code="#set the global Git configuration for the user's email address
git config --global user.email &quot;git@gerontakis.eu&quot;
#set the global Git configuration for the user's name
git config --global user.name &quot;l33tH4x0r :3&quot;
#initialize a new Git repository in the parent directory of the current working directory
git init ..
#stage file matching the pattern &quot;../flag*&quot;
git add ../flag*
#create a new commit with the staged changes
git commit -m \'lololo\'
#show the content and details of file matching the pattern &quot;../flag*&quot;
git show ../flag*" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">#set the global Git configuration for the user&#39;s email address</span></span>
<span class="line"><span style="color: #DCDCAA">git</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">config</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">--global</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">user.email</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;git@gerontakis.eu&quot;</span></span>
<span class="line"><span style="color: #6A9955">#set the global Git configuration for the user&#39;s name</span></span>
<span class="line"><span style="color: #DCDCAA">git</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">config</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">--global</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">user.name</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;l33tH4x0r :3&quot;</span></span>
<span class="line"><span style="color: #6A9955">#initialize a new Git repository in the parent directory of the current working directory</span></span>
<span class="line"><span style="color: #DCDCAA">git</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">init</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">..</span></span>
<span class="line"><span style="color: #6A9955">#stage file matching the pattern &quot;../flag*&quot;</span></span>
<span class="line"><span style="color: #DCDCAA">git</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">add</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">../flag</span><span style="color: #569CD6">*</span></span>
<span class="line"><span style="color: #6A9955">#create a new commit with the staged changes</span></span>
<span class="line"><span style="color: #DCDCAA">git</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">commit</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-m</span><span style="color: #D4D4D4"> </span><span style="color: #D7BA7D">\&#39;</span><span style="color: #CE9178">lololo</span><span style="color: #D7BA7D">\&#39;</span></span>
<span class="line"><span style="color: #6A9955">#show the content and details of file matching the pattern &quot;../flag*&quot;</span></span>
<span class="line"><span style="color: #DCDCAA">git</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">show</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">../flag</span><span style="color: #569CD6">*</span></span></code></pre></div>



<h2 class="wp-block-heading">Solution 3</h2>



<p class="wp-block-paragraph">Include the <code>bash</code> command, within the <code><strong>git --git-dir</strong></code> option when creating a new repo, then commit a change in the repo and open a shell via the <strong>git-chache-meta.sh</strong> commands.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="448" height="188" src="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-26.png" alt="" class="wp-image-93" srcset="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-26.png 448w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-26-300x126.png 300w" sizes="auto, (max-width: 448px) 100vw, 448px" /></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="486" height="397" src="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-27.png" alt="" class="wp-image-94" srcset="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-27.png 486w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-27-300x245.png 300w" sizes="auto, (max-width: 486px) 100vw, 486px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="576" src="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-29-1024x576.png" alt="" class="wp-image-100" srcset="https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-29-1024x576.png 1024w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-29-300x169.png 300w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-29-768x432.png 768w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-29-953x536.png 953w, https://blog.gerontakis.eu/wp-content/uploads/2023/06/image-29.png 1280w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
<p>The post <a href="https://blog.gerontakis.eu/2023/06/05/tjctf-2023-misc-gish-challenge-solution/">TJCTF 2023 &#8211; Misc &#8211; Gish Challenge Solution</a> appeared first on <a href="https://blog.gerontakis.eu">George Gerontakis</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.gerontakis.eu/2023/06/05/tjctf-2023-misc-gish-challenge-solution/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
