[cs615asa] CtF notes

Jan Schaumann jschauma at stevens.edu
Sat May 16 14:55:48 EDT 2015


Hello,

I've just sent out grade for the CtF.  In the end all of you managed to
capture the flag (or at least gain 'www' privileges), but it is still
useful to review each level:


Level 0:

As explained in class, it is useful to be able to send and receive
encrypted emails.  The online tutorials are simple enough and easy to
follow, and even if fully understanding all aspects of PGP might take
some time and practice, I hope you're all off to a good start and will
begin using it.

By encrypting instructions for all members individually and requiring
you to submit signatures, I wanted to ensure that all members of the
team are at least marginally involved in the process and gain some
practice in decrypting/signing content.

Note: you could have avoided a bottle-neck by sharing your private keys
with each other, thus allowing any one member to decrypt all messages or
to sign for all team members.  I hope you didn't do that, but
especially within the contet of a CtF it's useful to note the weaknesses
of each procedure.


Level 1:

You all were able to identify the checksum as a SHA256 checksum, and
finding the right file was then just a matter of iterating through the
filesystem.  The starting point for your search would have to have been
~jschauma on linux-lab, as local files on any individual system would
not have been available on the others.

This level also required a little bit of guessing, since you can't
browse my home directory.  This is to show that any attack on an unknown
system does require you to at times make educated guesses about what
could be hiding where.


Level 2:

The URL you were given didn't show the right password, but looking at
the source code, it included a hint to search for the sources of the
CGI.  Finding it in ~jschauma/cs_html/cgi-bin/ctf.cgi, you could then
inspect the source code, which included a commented out call to display
the file '/home/jschauma/tmp/level-3'.

That file was readable only by the 'www-data' user, that the web server
serving the site is running as.  You couldn't access this location using
your web browser, since it's outside of the ~/cs_html directory.

But by staging a symlink attack, you could cause it's disclosure:
~jschauma/cs_html/tmp/d was mode 777, meaning any user could remove or
create files in this directory.  By linking 'nope' to the desired file
~jschauma/tmp/level-3 you could the allow the web server to display the
contents of this file.


Level 3:

Now things were getting a little bit more interesting.  The program you
were instructed to run did not display the passphrase you needed.  If
you looked around in the directory the program was in, then you might
have found a file that you were not able to read, as it was mode 0400
and owned by 'www-data'.

Looking around in the directory, many found that there was directory
containing another file, also owned by the 'www-data' user.  Now over
half of you went down a path I hadn't anticipated: you used the same
symlink attack as in level2 to cause that cgi program to display the
contents of that file.

This worked out fine, but since that wasn't what I wanted you to do, I
changed the ctf.cgi to prevent you from displaying that particular file.
(This is a lesson that circumstances are always fluid and things may
change while you're attacking a system.)

Then some of you created their own php script to be executed from their
~/cs_html directory, again with the privileges of the 'www-data' user.
This also worked, and also was not what I had in mind.  Another useful
lesson that for any given weakness there are likely more than just one
way to exploit them.

What I did have in mind, and what several of you did in fact do, was to
actually use the 'level3' program and trick it into displaying the file
in question.

By running strace(1) or strings(1) or perhaps even by guessing, you
could have realized that the program invokes the id(1) command.  Since
the program just ran "id" instead of using an absolute path, all you
needed to do was create a script called "id" that did what you needed it
to do (for example: "cat /home/jschauma/ctf/whateverXXX"), add the
directory of where that script is stored to the beginning of your PATH
variable and run the command again.

This is a comman attack vector, as many programs shell out to execute
commands they expect to be in the user's PATH.  As a programmer, you
should be aware of this pattern and always defensively specify the full
path to an executable, explicitly set the PATH, or avoid shelling out
altogether.


Level 4:

You were given an ssh keypair.  It seems logical that the private key
would grant you access to the target system, but why did you receive the
public key?  In ssh key authentication, the public key is only needed on
the system on which you log in, not on the system from which you
connect.

The public key did contain a little bit of extra information, namely a
"from=" restriction.  As we've hinted at in one of our classes, ssh keys
can have a number of options that define what the connecting user can
do.  In this case, we can define the networks from which this key may be
used.

The networks given there were those of Amazon's EC2 networks as well as
a private RFC1918 network.  That is, the target system allowed ssh
logins using the private key from any of the EC2 networks as well as
from the internal network.

After spinning up an EC2 instance to connect to the target system, you
might also have run into a problem where some OS did not understand the
ssh key cipher, since some ship with an older version of OpenSSH.
Finally, you had to find out which port to connect to, since ssh on the
target system wasn't listening on the default port (22), but on another
port (2233).  A port mapping tool like nmap would have been able to show
this to you.

This was just a reminder that network services can be run on any port --
nothing says that ssh must always be on port 22, or that HTTP must
always be on port 80.  For example, if you had a firewall that only
allowed outgoing traffic to port 80, you could just run your ssh server
on that port to allow yourself to connect from within the firewalled
network.

Level 5:

This level had a number of steps.  You knew you had to take control of
the web server's index page, which you could find under
/usr/pkg/share/httpd/htdocs/index.html.  But that file was owned by the
'www' user.  You might have noticed that the time stamp on the file was
always recent: something was always updating it.

Looking for the 'www' user's crontab in /var/cron/tabs/www, you could
have found the following entry:

* * * * * /bin/reset-site

That is, 'www' was running the script /bin/reset-site every minute.
That script contained a line that, depending on the method used to
display it, may have looked a bit odd.  If you used 'cat -v', you might
have seen:

cp /var/tmp/d/^M/index.html /usr/pkg/share/httpd/htdocs/

The user copied the file from a funky looking directory to the website
root.  The directory name in question was "^M", which is the control
character used for a carriage-return.  (As discussed in an early
lecture, filenames can contain all sorts of characters, including
control characters.)

You can enter the directory by typing Ctrl+V followed by the return key.


Alright, but that doesn't help you a whole lot.  You'd still have to
have 'www' user-level access to change this setup.

As many of you found, there was an odd process running: 'nc6 -6 -l -e
/bin/64sh'.  Or perhaps you found that there was something listening on
port 6666, but only via IPv6.

Looking at the manual page for nc6(1) and at the file /bin/64sh, you
would have found that this was a backdoor for the 'leaky' user that
requires no authentication, and that would execute any command so long
as it was base64 encoded.  That is, you were able to run any command as
'leaky' by, for example, running

echo 'ls -l' | base64 | nc6 ::1 6666

In the 'leaky' user's home directory, you would then find an executable
that was setuid root, only accessible to the 'leaky' user.  Trying to
run it, you'd find that if given a file, it claimed to have leaked it to
http://www.cs.stevens.edu/~jschauma/cgi-bin/leaky.cgi.  But that CGI
itself did not seem to do anything with the file, and there was no
obvious way to exploit the CGI itself.

However, since you are on the system from which the file is sent, and
since conveniently (and oddly) the tcpdump(8) program had been set
setuid, you were able to run tcpdump while running the 'leak' program.
Capturing all the packets, you'd also get all the data the program sent
-- meaning the contents of the file you gave it as an argument.

So now you had a way of seeing the contents of any file on the system.
Poking around the 'www' user's home directory, you should have found a
file called 'password', which did in fact contain the password for the
'www' user.

Leaking that file to the CGI and extracting the data from the tcpdump
provided you with a method to log in as the 'www' user and thus capture
the flag.  From there, it was up to you to try to find ways to prevent
others from capturing the flag.

At the same time, whenever a team took the flag, I also made their SSH
private key available, which could have been leaked in the same way as
the 'www' user's password.  That is, attackers on the 4th level could
have overtaken the account of any team having captured the flag and then
disabled their access.

(You were not able to change the authorized_keys for your team, nor the
password for the 'www' user.  I put these restrictions in place to make
it a bit harder to defend the flag.)

Many of you implemented a similar crontab as was originally in place; at
least one team wrote a (more efficient) program to monitor the flag file
and overwrite it with their contents whenever it changed.  There were a
number of different ways you could try to retain the flag and keep
others out.  At least one team DoS'd the target system, which is a
rather brute way of trying to accomplish your objective.  However, it
may also well have been effective.  All's fair in war and CtFs.


In the end, I'm glad that all teams managed to get to level 5, and that
we were able to run the CtF.  With that, the semester comes to an end.
I will submit your final grades hopefully later today or tomorrow.

As noted, you should get a reminder to fill out the course survey on
https://assess.stevens.edu, and you can also provide direct anonymous
feedback to me at
https://www.cs.stevens.edu/~jschauma/cgi-bin/CS615-S15-final.cgi.

I hope you enjoyed the class and learned a bit about the profession of
System Administration.  Best of luck in your further academic
endeavours, and congratulations to those of you who are graduating.

-Jan


More information about the cs615asa mailing list