PicoCTF 2018, part 46 through 50
Introduction
This is a continuation of the series on the PicoCTF 2018 challenges I have completed so far. You can find the previous write-up here. You can find a collection of other write-ups in this series on the home page or through the related posts below this post. The challenges are still elaborate and fun.
What Base Is This?200 points
This challenge asks us to interpret data that appears to be translated from numerical ASCII values to any other base.
To be successful on your mission, you must be able read data represented in different ways, such as hexadecimal or binary. Can you get the flag from this program to prove you are ready? Connect with
nc 2018shell.picoctf.com 1225
.
This challenge was not a very difficult one. You could solve it easily by simply having a browser open and search for a 'binary to text', 'hexadecimal to text' or 'octal to text' converter.
The first thing you see when you connect to the provided server is the first question, it asks you to translate a string of binary numbers to its text representation. You have 30 seconds to solve it. On each failed attempt you see WRONG!
and the program exits. On each successful attempt you get the next question. The order: binary, hexadecimal, octal.
I solved it first by using any shape or form of an aforementioned tool, but that wasn't any fun. I wrote a little Python script to automate the process. The script connects to the server using the socket
module and receives until a question is asked, sends back the right answer and keeps track of the answer in stdout (for every question). At the end, when all questions were correct, you receive the flag.
Here's the format how the questions will be asked, determined during the writing of the script:
We are going to start at the very beginning and make sure you understand how data is stored. computer Please give me the binary values as a word. To make things interesting, you have 30 seconds. Input: .... Please give me the hexadecimal value as a word. Input: .... Please give me the octal values as a word. Input:
Which is solved using the next Python script:
from contextlib import contextmanager
import socket
import re
# Receive data until a certain message is found
def recv_until(socket, message):
data = ""
while (data.find(message) == -1):
data += socket.recv(1).decode()
return data
# I like to be able to write with sock(...) as s
@contextmanager
def sock(*args, **kw):
s = socket.socket(*args, **kw)
try:
yield s
finally:
s.close()
# convert a list of data in 'base' to string
def base_to_str(parts, base):
return ''.join(chr(int(value, base)) for value in parts)
# We'll connect directly to the shell and send our exploit data
HOST = "2018shell.picoctf.com"
PORT = 1225
with sock(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
# Get the first question and convert the binary values to a string and send
question = recv_until(s, "To make things interesting, you have 30 seconds.\nInput:\n")
solution = base_to_str(re.findall("([01]{8})", question), 2)
print("found '{:s}' from binary string".format(solution))
s.send((solution + "\n").encode())
# Get the second question and convert the hex values to a string and send
question = recv_until(s, "as a word.\nInput:\n")
solution = base_to_str(re.findall("([0-9a-f]{2})", re.findall("the ([0-9a-f]+)", question)[0]), 16)
print("found '{:s}' from hexadecimal string".format(solution))
s.send((solution + "\n").encode())
# Get the third question and convert the octal values to a string and send
question = recv_until(s, "as a word.\nInput:\n")
solution = base_to_str(re.findall("([0-7]+)", question), 8)
print("found '{:s}' from octal string".format(solution))
s.send((solution + "\n").encode())
# Get the flag
flagline = recv_until(s, "}")
flagtext = re.findall("(picoCTF\{.+\})", flagline)[0]
print(flagtext)
python3 solution.py
# found 'cake' from binary string
# found 'apple' from hexadecimal string
# found 'test' from octal string
# picoCTF{delusions_about_finding_values_451a9a74}
Your output will vary, as the data is randomized.
flag: picoCTF{delusions_about_finding_values_451a9a74}
You Can't See Me200 points
This challenge asks us to retrieve the flag from a provided directory on the remote server.
'...reading transmission... Y.O.U. .C.A.N.'.T. .S.E.E. .M.E. ...transmission ended...' Maybe something lies in /problems/you-can-t-see-me_2_cfb71908d8368e3062423b45959784aa.
I don't quite understand why this challenge is in the 200 points range, as it is extremely easy when you have basic experience with Unix systems.
When you connect to the server and cd
to the specified directory, you can use ls -al
to view the directory entries (I always use -al
first). This will reveal the current directory .
, the parent directory ..
and a file named .
. You might see how this might be problematic if you simply try to cat .
, but when you cat .*
you'll get the flag.
ls -al
total 60
drwxr-xr-x 2 root root 4096 Nov 15 02:40 .
-rw-rw-r-- 1 hacksports hacksports 57 Nov 15 02:40 .
drwxr-x--x 566 root root 53248 Nov 15 04:28 ..
cat .*
cat: .: Is a directory
picoCTF{j0hn_c3na_paparapaaaaaaa_paparapaaaaaa_093d6aff}
cat: ..: Permission denied
I can see how people don't think about using cat .*
or don't even notice the .
file, however I don't think this challenge should give you 200 points for solving it.
flag: picoCTF{j0hn_c3na_paparapaaaaaaa_paparapaaaaaa_093d6aff}
250 points
This challenge wants us to push the buttons on a simple website.
There is a website running at
http://2018shell.picoctf.com:18342
(link). Try to see if you can push their buttons.
Again, in contrast to some other challenges, this one seems a bit too small or too easy. When you visit the page referred to by the link in the problem description, you see a button saying PUSH ME! I am your only hope!
. When you click it, you are redirected to another page (buttons1.php
)
On that second page, you see a line of text suggesting you try the next button. After that comes a link (<a href...></a>
), not a button... Immediately I figured that it should be a button, but I clicked the link anyway. I got rickrolled, but the joke's on them; I love that song.
I went back to buttons1.php
and decided to copy the form from the first page (with the first button) and paste it in this page and changed to form action to what is in the href
attribute of the Button
link (using Developer Tools in Chrome).
<form action="button2.php" method="POST">
<input type="submit" value="PUSH ME! I am your only hope!">
</form>
With that code inserted I click on the button and guess what, we get the flag.
Well done, your flag is: picoCTF{button_button_whose_got_the_button_25a99f84}
Now for a little python script to fetch it for us:
import requests
import re
form_action = "http://2018shell.picoctf.com:18342/button2.php"
form_response = requests.post(form_action)
assert form_response.status_code == 200, "POST request to challenge failed"
print(re.findall("picoCTF{.+}", form_response.text)[0])
python3 solution.py
# picoCTF{button_button_whose_got_the_button_25a99f84}
flag: picoCTF{button_button_whose_got_the_button_25a99f84}
Ext Super Magic250 points
This challenge requests that you repair an extracted file system image, implying the flag is in the corrupted file.
We salvaged a ruined Ext SuperMagic II-class mech recently and pulled the filesystem out of the black box. It looks a bit corrupted, but maybe there's something interesting in there. You can also find it in /problems/ext-super-magic_4_f196e59a80c3fdac37cc2f331692ef13 on the shell server.
This challenge was quite interesting. Knowing that this ext-super-magic.img
is an image of a file system, but corrupted, I first tried file ext-super-magic.img
to see what it is. Well, file
doesn't know. This already implies to me that the recognizable part of the image file is damaged - which often is a signature, magic number or something in a header
that is constant for that format. Here's the output for file
:
# ext-super-magic.img: data
So that's not useful at all. There's another tool, fsck
and with that e2fsck
, which you can use to check the integrity of Linux file systems. e2fsck
specifically checks ext2
, ext3
or ext4
file systems. When I run e2fsck ext-super-magic.img
:
e2fsck ext-super-magic.img
# e2fsck 1.42.13 (17-May-2015)
# ext2fs_open2: Bad magic number in super-block
# e2fsck: Superblock invalid, trying backup blocks...
# e2fsck: Bad magic number in super-block while trying to open ext-super-magic.img
# The superblock could not be read or does not describe a valid ext2/ext3/ext4
# filesystem. If the device is valid and it really contains an ext2/ext3/ext4
# filesystem (and not swap or ufs or something else), then the superblock
# is corrupt, and you might try running e2fsck with an alternate superblock:
# e2fsck -b 8193 <device>
# or
# e2fsck -b 32768 <device>
Interesting, here we can see that the magic number is invalid. A magic number is a value that is often sitting at a fixed offset of a file or data format to indicate the type of data that will follow. This magic number is often checked for when processing files and if it is not what is expected, an application might decide to not proceed with that particular file and display an error (like in the output of e2fsck
).
Based on the problem description I will assume that the file system in the image file is ext2
(Ext SuperMagic II-class) and try to repair the magic number, I can always try again after. Let's make a backup of the file first:
cp ext-super-magic.img ext-super-magic.img.bak
Now let's try to patch that magic number. When you Google for ext2 superblock format
a number of interesting results pop up. The first result for me is The Second Extended File System, however I found the second result titled Ext2 -> Superblock a bit more concrete.
In the latter topic you can read that the super block is located at offset 1024 (0x400)
. You can also read that the magic number is at offset 56 (0x38)
of the super block and consists of a 2 byte integer (0xef53
). At the top of the page we can also read that all values stored are little-endian
, we need to consider that.
Knowing these values writing a Python script to patch the file with the correct magic number should be trivial, so at the time I was hoping that this would be it. I had no other way of verifying that this file was indeed an ext2
image, so this was simply a case of following a hunch. It turned out to be right!
ext2file = "ext-super-magic.img"
with open(ext2file, "r+b") as ext2:
ext2.seek(0x400 + 0x38) # seek to super block + magic number offset
ext2.write(b"\x53\xef") # wite ext2 magic number in little endian (0xef53)
We can then run the script and the file command after, to verify what we've done:
python3 solution.py
file ext-super-magic.img
# ext-super-magic.img: Linux rev 1.0 ext2 filesystem data, UUID=c1c861a4-452c-48fd-a83e-f90791120fde (large files)
Interesting, now we can try to mount it as our write has succeeded. Only if we can mount this file, we know it can be processed as a ext2
file system:
mkdir mounted
sudo mount ext-super-magic.img mounted
Nice, that worked! Skimming through the files that opened in my nemo
file manager I see the obvious flag.jpg
. This image file contains a photo of a war (with robots, is this Star Wars? I don't know) and the flag in text format. It took a bit of double-checking and typing it over but here it is, the flag!
flag: picoCTF{a7DB29eCf7dB9960f0A19Fdde9d00Af0}
Lying Out250 points
This challenge asks you to identify some traffic and use an interactive shell to provide a list of moments where traffic is higher than usual.
Some odd traffic has been detected on the network, can you identify it? More info here. Connect with
nc 2018shell.picoctf.com 27108
to help us answer some questions.
This challenge is actually not at all special. You get a graph of the usual traffic, and via the remote terminal session specified above you identify log entries with more traffic than usual.
You'll need to consult the file `traffic.png` to answer the following questions.
Which of these logs have significantly higher traffic than is usual for their time of day? You can see usual traffic on the attached plot. There may be multiple logs with higher than usual traffic, so answer all of them! Give your answer as a list of `log_ID` values separated by spaces. For example, if you want to answer that logs 2 and 7 are the ones with higher than usual traffic, type 2 7.
log_ID time num_IPs
0 0 01:00:00 10209
1 1 03:30:00 11585
2 2 05:30:00 11616
3 3 08:30:00 13209
4 4 10:45:00 10216
5 5 11:30:00 17024
6 6 12:15:00 12939
7 7 14:00:00 9842
8 8 16:30:00 9918
9 9 18:30:00 15887
10 10 19:15:00 11611
11 11 21:45:00 9788
12 12 23:30:00 10517
13 13 23:30:00 10419
1 2 3 5
Correct!
Great job. You've earned the flag: picoCTF{w4y_0ut_de051415}
That's fine, I love a free flag!
flag: picoCTF{w4y_0ut_de051415}