Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
beefproject
GitHub Repository: beefproject/beef
Path: blob/master/test/integration/tc_webrtc_rest.rb
1154 views
1
#
2
# Copyright (c) 2006-2025 Wade Alcorn - [email protected]
3
# Browser Exploitation Framework (BeEF) - https://beefproject.com
4
# See the file 'doc/COPYING' for copying permission
5
#
6
require 'test/unit'
7
require 'rest-client'
8
require 'json'
9
require '../common/test_constants'
10
require '../common/beef_test'
11
12
class TC_WebRTCRest < Test::Unit::TestCase
13
14
class << self
15
16
# Login to API before performing any tests - and fetch config too
17
def startup
18
json = {:username => BEEF_USER, :password => BEEF_PASSWD}.to_json
19
@@headers = {:content_type => :json, :accept => :json}
20
21
response = RestClient.post("#{RESTAPI_ADMIN}/login",
22
json,
23
@@headers)
24
25
result = JSON.parse(response.body)
26
@@token = result['token']
27
28
$root_dir = '../../'
29
$:.unshift($root_dir)
30
31
require 'core/loader'
32
33
BeEF::Core::Configuration.new(File.join($root_dir, 'config.yaml'))
34
BeEF::Core::Configuration.instance.load_extensions_config
35
36
@@config = BeEF::Core::Configuration.instance
37
38
@@activated = @@config.get('beef.extension.webrtc.enable') || false
39
40
@@victim1 = BeefTest.new_victim
41
@@victim2 = BeefTest.new_victim
42
43
# puts "WebRTC Tests beginning"
44
sleep 8.0
45
46
# Fetch last online browsers' ids
47
rest_response = RestClient.get "#{RESTAPI_HOOKS}", {:params => {
48
:token => @@token}}
49
result = JSON.parse(rest_response.body)
50
browsers = result["hooked-browsers"]["online"]
51
browsers.each_with_index do |elem, index|
52
if index == browsers.length - 1
53
@@victim2id = browsers["#{index}"]["id"].to_s
54
end
55
if index == browsers.length - 2
56
@@victim1id = browsers["#{index}"]["id"].to_s
57
end
58
end
59
60
end
61
62
def shutdown
63
$root_dir = nil
64
@@victim1.driver.browser.close
65
@@victim2.driver.browser.close
66
end
67
68
end
69
70
def test_1_webrtc_check_for_two_hooked_browsers
71
return unless @@activated
72
73
rest_response = nil
74
assert_nothing_raised do
75
rest_response = RestClient.get "#{RESTAPI_HOOKS}", {:params => {
76
:token => @@token}}
77
end
78
check_rest_response(rest_response)
79
result = JSON.parse(rest_response.body)
80
browsers = result["hooked-browsers"]["online"]
81
assert_not_nil browsers
82
assert_operator browsers.length, :>=, 2
83
end
84
85
def test_2_webrtc_establishing_p2p
86
return unless @@activated
87
88
rest_response = nil
89
assert_nothing_raised do
90
rest_response = RestClient.post("#{RESTAPI_WEBRTC}/go?token=#{@@token}",
91
{:from => @@victim1id, :to => @@victim2id, :verbose => "true"}.to_json,
92
@@headers)
93
end
94
check_rest_response(rest_response)
95
result = JSON.parse(rest_response.body)
96
assert_equal true, result["success"]
97
98
sleep 30.0
99
100
rest_response = nil
101
assert_nothing_raised do
102
rest_response = RestClient.get "#{RESTAPI_LOGS}", {:params => {
103
:token => @@token}}
104
end
105
check_rest_response(rest_response)
106
result = JSON.parse(rest_response.body)
107
108
loghitcount = 0
109
result["logs"].reverse.each {|l|
110
# Using free-space matching mode /x below to wrap regex.
111
# therefore need to escape spaces I want to check, hence the \
112
regex = Regexp.new(/Browser:(#{@@victim1id}|#{@@victim2id})\ received\
113
message\ from\ Browser:(#{@@victim1id}|#{@@victim2id})
114
:\ ICE\ Status:\ connected/x)
115
loghitcount += 1 if (not regex.match(l["event"]).nil?) and
116
(l["type"].to_s.eql?("WebRTC"))
117
}
118
assert_equal 2, loghitcount
119
end
120
121
def test_3_webrtc_send_msg # assumes test 2 has run
122
return unless @@activated
123
124
rest_response = nil
125
assert_nothing_raised do
126
rest_response = RestClient.post("#{RESTAPI_WEBRTC}/msg?token=#{@@token}",
127
{:from => @@victim1id, :to => @@victim2id,
128
:message => "RTC test message"}.to_json,
129
@@headers)
130
end
131
check_rest_response(rest_response)
132
result = JSON.parse(rest_response.body)
133
assert_equal true, result["success"]
134
135
sleep 10.0
136
137
rest_response = nil
138
assert_nothing_raised do
139
rest_response = RestClient.get "#{RESTAPI_LOGS}", {:params => {
140
:token => @@token}}
141
end
142
check_rest_response(rest_response)
143
result = JSON.parse(rest_response.body)
144
145
assert_block do
146
result["logs"].reverse.each {|l|
147
# Using free-space matching mode /x below to wrap regex.
148
# therefore need to escape spaces I want to check, hence the \
149
regex = Regexp.new(/Browser:(#{@@victim1id}|#{@@victim2id})\ received\
150
message\ from\ Browser:
151
(#{@@victim1id}|#{@@victim2id})
152
:\ RTC\ test\ message/x)
153
return true if (not regex.match(l["event"]).nil?) and
154
(l["type"].to_s.eql?("WebRTC"))
155
}
156
end
157
end
158
159
def test_4_webrtc_stealthmode # assumes test 2 has run
160
return unless @@activated
161
162
# Test our two browsers are still online
163
rest_response = nil
164
assert_nothing_raised do
165
rest_response = RestClient.get "#{RESTAPI_HOOKS}", {:params => {
166
:token => @@token}}
167
end
168
check_rest_response(rest_response)
169
result = JSON.parse(rest_response.body)
170
online = result["hooked-browsers"]["online"]
171
assert_block do
172
online.each {|hb|
173
return true if hb[1]["id"].eql?(@@victim1id)
174
}
175
end
176
assert_block do
177
online.each {|hb|
178
return true if hb[1]["id"].eql?(@@victim2id)
179
}
180
end
181
182
183
# Command one of the browsers to go stealth
184
rest_response = nil
185
assert_nothing_raised do
186
rest_response = RestClient.post("#{RESTAPI_WEBRTC}/msg?token=#{@@token}",
187
{:from => @@victim1id, :to => @@victim2id,
188
:message => "!gostealth"}.to_json,
189
@@headers)
190
end
191
check_rest_response(rest_response)
192
result = JSON.parse(rest_response.body)
193
assert_equal true, result["success"]
194
195
sleep 40.0 #Wait until that browser is offline.
196
197
# Test that the browser is now offline
198
rest_response = nil
199
assert_nothing_raised do
200
rest_response = RestClient.get "#{RESTAPI_HOOKS}", {:params => {
201
:token => @@token}}
202
end
203
check_rest_response(rest_response)
204
result = JSON.parse(rest_response.body)
205
offline = result["hooked-browsers"]["offline"]
206
assert_block do
207
offline.each {|hb|
208
return true if hb[1]["id"].eql?(@@victim2id)
209
}
210
end
211
212
# Test that we can bring it back online (which implies comms are still ok)
213
rest_response = nil
214
assert_nothing_raised do
215
rest_response = RestClient.post("#{RESTAPI_WEBRTC}/msg?token=#{@@token}",
216
{:from => @@victim1id, :to => @@victim2id,
217
:message => "!endstealth"}.to_json,
218
@@headers)
219
end
220
check_rest_response(rest_response)
221
result = JSON.parse(rest_response.body)
222
assert_equal true, result["success"]
223
224
sleep 10.0 # Wait until browser comes back
225
226
# Test that the browser is now online
227
rest_response = nil
228
assert_nothing_raised do
229
rest_response = RestClient.get "#{RESTAPI_HOOKS}", {:params => {
230
:token => @@token}}
231
end
232
check_rest_response(rest_response)
233
result = JSON.parse(rest_response.body)
234
online = result["hooked-browsers"]["online"]
235
assert_block do
236
online.each {|hb|
237
return true if hb[1]["id"].eql?(@@victim2id)
238
}
239
end
240
241
end
242
243
def test_5_webrtc_execcmd # assumes test 2 has run
244
return unless @@activated
245
246
#
247
248
end
249
250
private
251
252
# Standard assertions for verifying response from RESTful API
253
def check_rest_response(response)
254
assert_not_nil(response.body)
255
assert_equal(200, response.code)
256
end
257
258
end
259
260