Google CTF 2017 mindreader

This is a write-up for the Google CTF 2017 “mindreader” challenge.

The mindreader webserver presented us with only a single input form:


Pretty much with the second term entered it was clear that any filename specified in the form will be read from the local disk. This sounded like an easy challenge.
Better yet, since also /etc/shadow was displayed, this meant that the process is probably running with root privileges. Jackpot!

The logical next step was to try to fetch the usual files you’d expect to contain anything useful: Service configuration files, shell histories, any log file or pretty much anything we could think of – but nothing useful was returned.

Some files that we expected to exist like /etc/ssh/sshd_config threw a 404 and others (/proc/cpuinfo) a 403.

The HTTPS server responded with a nginx server header but there was no sign of it anywhere either. Nor of any other webserver.

With /etc/issue and /etc/debian_version the system was identified as a Debian 8.8.
Digging into the Debian specific files we grabbed /var/log/apt/history.log:

In that file it showed that those packages were all installed in a single transaction:

git mercurial pkg-config wget python-pip python2.7 python2.7-dev 
python3.4 python3.4-dev build-essential libcurl4-openssl-dev libffi-dev 
libjpeg-dev libmysqlclient-dev libpng12-dev libpq-dev libssl-dev 
libxml2-dev libxslt1-dev swig zlib1g-dev gfortran libatlas-dev 
libblas-dev libfreetype6-dev liblapack-dev libquadmath0 
libmemcached-dev libsasl2-2 libsasl2-dev libsasl2-modules sasl2-bin

Searching for that specific package list leads us to the Google Cloud Platform – Python Runtime Docker Image:
https://github.com/GoogleCloudPlatform/python-runtime/blob/master/runtime-image/resources/apt-packages.txt

This explains the absence of pretty much any other service or configuration: We are attacking a Docker container.

The Dockerfile in that repository configures a work directory of /app. With that knowledge we can get the Python source code by requesting /app/main.py:

The source code revealed two key pieces of information:

  • There is an environment variable called “FLAG” (line 6).
  • Requests containing “proc” will always return a 403 (line 24).

Coincidentally environment variables are of course stored in /proc.

The filter looked solid and pythons open() does not accept wildcards. We cannot request anything containing “proc”.

But if there is a symlink pointing to a folder inside of /proc we wouldn’t need to request a file with “proc” in its name, we could traverse from there.

Quick research in a Vagrant VM showed that /dev/fd is a symlink to /proc/self/fd.
We requested /dev/fd/../environ:


And with that we finally got the flag.

 

CentOS Tor mirror

I’m running a CentOS Tor mirror as a hidden service.
It is available under:

http://vnokiymjbiklyocz.onion/

If you want to use this mirror you must first install Tor.
Follow these instructions to do that:
https://www.torproject.org/docs/rpms.html.en

Once that is complete and the Tor service is running you must install torsocks (from the EPEL repositories):

[root@localhost ~]# yum install epel-release
(...)

Complete!
[root@localhost ~]# yum install torsocks
(...)

Complete!

Afterwards change the YUM repository configuration file (/etc/yum.repos.d/CentOS-Base.repo) to include the hidden service URL.
Create a backup of the file in case you want to use the normal mirrors again.
The adjusted file should look like this (on CentOS 7):

[base]
name=CentOS-$releasever - Base
baseurl=http://vnokiymjbiklyocz.onion/centos/$releasever/os/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

[updates]
name=CentOS-$releasever - Updates
baseurl=http://vnokiymjbiklyocz.onion/centos/$releasever/updates/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

[extras]
name=CentOS-$releasever - Extras
baseurl=http://vnokiymjbiklyocz.onion/centos/$releasever/extras/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

[centosplus]
name=CentOS-$releasever - Plus
baseurl=http://vnokiymjbiklyocz.onion/centos/centos/$releasever/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

If you were manually editing the configuration file please notice that it is now using the baseurl option and not the mirrorlist option as before.

With this in place you can now use the hidden mirror and install packages like this:

[root@localhost ~]# export TORSOCKS_LOG_LEVEL=1 # only required to stop getting spammed with warning messages
[root@localhost ~]# torsocks yum -y install bind-utils
Loaded plugins: fastestmirror
base                                                                                                                                      | 3.6 kB  00:00:00     
epel/x86_64/metalink                                                                                                                      |  26 kB  00:00:00     
epel                                                                                                                                      | 4.3 kB  00:00:00     
extras                                                                                                                                    | 3.4 kB  00:00:00     
tor/x86_64/signature                                                                                                                      |  490 B  00:00:00     
tor/x86_64/signature                                                                                                                      | 2.9 kB  00:00:00 !!! 
tor-source/signature                                                                                                                      |  490 B  00:00:00     
tor-source/signature                                                                                                                      | 2.9 kB  00:00:00 !!! 
updates                                                                                                                                   | 3.4 kB  00:00:00     
(1/9): base/7/x86_64/group_gz                                                                                                             | 155 kB  00:00:00     
(2/9): epel/x86_64/group_gz                                                                                                               | 169 kB  00:00:00     
(3/9): epel/x86_64/updateinfo                                                                                                             | 449 kB  00:00:00     
(4/9): extras/7/x86_64/primary_db                                                                                                         |  90 kB  00:00:00     
(5/9): tor-source/primary_db                                                                                                              | 2.4 kB  00:00:01     
(6/9): tor/x86_64/primary_db                                                                                                              | 4.0 kB  00:00:01     
(7/9): updates/7/x86_64/primary_db                                                                                                        | 953 kB  00:00:01     
(8/9): epel/x86_64/primary_db                                                                                                             | 3.7 MB  00:00:02     
(9/9): base/7/x86_64/primary_db                                                                                                           | 5.3 MB  00:00:05     
Determining fastest mirrors
 * epel: mirror.netcologne.de
Resolving Dependencies
--> Running transaction check
---> Package bind-utils.x86_64 32:9.9.4-29.el7_2.1 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

=================================================================================================================================================================
 Package                               Arch                              Version                                        Repository                          Size
=================================================================================================================================================================
Installing:
 bind-utils                            x86_64                            32:9.9.4-29.el7_2.1                            updates                            200 k

Transaction Summary
=================================================================================================================================================================
Install  1 Package

Total download size: 200 k
Installed size: 434 k
Downloading packages:
bind-utils-9.9.4-29.el7_2.1.x86_64.rpm                                                                                                    | 200 kB  00:00:00     
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : 32:bind-utils-9.9.4-29.el7_2.1.x86_64                                                                                                         1/1 
  Verifying  : 32:bind-utils-9.9.4-29.el7_2.1.x86_64                                                                                                         1/1 

Installed:
  bind-utils.x86_64 32:9.9.4-29.el7_2.1                                                                                                                          

Complete!

Contact me if you need any help or if you have any suggestions.

XSS in ownCloud 2

A few weeks ago ownCloud 4.0.0 was released and it included some cool features like encryption of uploaded files. I decided to take it for a spin again.

I found again some XSS vulnerabilities. As last time, I reported these issues to the ownCloud team which responded quickly and fixed them already (with version 4.0.2). As far as I can tell CVE-2012-4396 was assigned to these issues (and others were merged into it as well).

/?app=media
1) change ID3 title tag of a MP3 file to: “Kalimba<script>alert(1)</script>”
2) upload
3) play it in the integrated player, JS gets executed

Now this is fun! Imagine someone sending you a MP3 which you listen to with ownCloud and in the background your cookies are sent to a remote system. If you run a ownCloud instance with multiple users, you can also share those files. It might be enough to listen to a shared MP3 to get your account compromised, I didn’t verify this though.

/?app=files&getfile=download.php
1) upload picture e.g. trollface.jpg
2) rename picture to “trollf<style onload=alert(1)>ace.jpg”
3) view the picture, JS gets executed

Can’t think of a good scenario for this to be useful. Maybe sharing this file.

/?app=calendar
1) add new appointment, title: “XSS <script>alert(1);</script>”
2) switch calendar view to “list”, JS gets executed

This was a bit surprising as the normal calendar view was not affected, only the list view.

XSS in ownCloud

A few weeks ago there was a bit of a hype about ownCloud when they released version 3.0.1. I decided to give it a spin, here is what I found.

Note: I contacted the development team earlier and these vulnerabilities have been fixed in the meantime with version 3.0.2, although I have not confirmed this myself due to lack of time.

XSS in files/download.php

The attacker can send an URL to the victim and JavaScript will be executed in the victims session. The attacker does not need an account on the ownCloud instance, only knowledge about the URL path:


http://localhost/owncloud/files/download.php?file=/xss.png%3Cscript%3Ealert(1)%3C/script%3E

XSS in files/index.php

If you share your ownCloud instance with multiple users, the attacker can send an URL to the victim and JavaScript will be executed in the victims session. Both the attacker and victim need accounts on the same instance.

Here is how:

1) Create a new folder on http://localhost/owncloud/files/index.php – any name will do, I used “PoC”

2) Share this folder with your victim or the victims group

3) Switch to http://localhost/owncloud/files/index.php?dir=/PoC

4) Create a folder, called:

x"> <body onload=alert(1)><x="

5) Send that link to your victim:


http://localhost/owncloud/files/index.php?dir=/Shared/PoC/x%22%3E%20%3Cbody%20onload%3Dalert%281%29%3E%3Cx%3D%22

6) ???

7) Profit!

It may be possible to create the folder directly in /, however I couldn’t get that folder shared with other users. But since it gets automatically shared if the parent folder is shared, I didn’t invest much time into that.

XSS in apps/contacts/index.php

I found another XSS flaw in the Contacts function, creating a contact and adding this in any field:

foo"><script>alert(1)</script>

will also execute. However, since you cannot share contacts between users (or can you?) I believe this is a minor problem.

XSS in Xymon

Last week I had some time to play with the monitoring tool Xymon. Xymon is a monitoring and alerting software mostly written in C. Its server component provides you with a web-interface to check the health of your systems. I only quickly investigated this web-interface.

After walking through the various kinds of pages I found that almost all parameters are correctly checked or sanitized. But on one page the code was doing something odd (criticalview.c):

fprintf(output, "<a href="\&quot;%s&amp;NKPRIO=%d&amp;NKTTGROUP=%s&amp;NKTTEXTRA=%s\&quot;">",

hostsvcurl(itm->;hostname, colname, 1),

prio,

htmlgroupstr, htmlextrastr);

This is strange, the htmlgroupstr and htmlextrastr variables do not get used anywhere else on criticalview.c. The link it generates points to svcstatus.c (well its wrapper, svcstatus.sh). On that page the NKTTGROUP and NKTTEXTRA parameters simple get displayed on the page, without any further cleanup. With that we can generate links like this:

http://localhost/xymon-cgi/svcstatus.sh?HOST=foo&SERVICE=cpu&NKPRIO=1&NKTTGROUP=admins&NKTTEXTRA=foo%3Cscript%3Ealert(1);%3C/script%3E

This nicely executes our injected JavaScript. Bug was reported at SourceForge.