rapid7 / metasploit-framework

Metasploit Framework
https://www.metasploit.com/
Other
33.62k stars 13.85k forks source link

ASM: Interface Dimensions #18620

Open sempervictus opened 8 months ago

sempervictus commented 8 months ago

Summary

Attack surface mapping requires contextualization of "space" which in the red team world is "space across which vectors are defined." Today, we approximate this in L3/4 terms but with the addition of serial console sessions and the growing demands of our ecosystem, we need to move beyond this shim into traversible space comprehension across OSI layers (and even 8 per the QR concept).

Using the OSI approach, we can alter hosts to have namespaces which are assigned interfaces in the data model which have layer 1 addresses (bus address on the host - PCI/USB/or whatever relevant identifier), layer 2 (MAC), and L3 for IPs. Since L2+ is "virtual" the devices can have multiple addresses in practice especially given the IPv6 bit. A bit of shimming in the ruby layer allows us to transparently add scopes to retain original behavior for back-compat/conversion while making the interfaces command (or analog) for sessions incredibly valuable.

image

Basic example

In the simple use-case, this allows things like hosts -n <subnet> to pull show all hosts/services/whatever exposed on that surface. We can get hosts -r to show currently reachable hosts given framework's and sessions' positions on the field; and for more advanced cases it can be used to tell us which pivots need footholds to move into the next space (say found by an SNMP scan showing us whats "beyond" a device). Going back to the serial console example - AWS assets in an isolated VPC aren't reachable, but that layer1 serial interface on one of them is; if we pop that and run a (future console-transport) meterpreter over it, we can get MAC and IP layers over that target...

Motivation

Improving our understanding of target spaces, pivots, and exposure of surfaces.

sempervictus commented 8 months ago

Question for the ActiveRecord aficionados: what is the "Rails appropriate" modality for implementing the interface database tables?

  1. Do we use narrow tables along the lines of id|name|address|public_name and nest their relationships? This approach makes data typing a bit harder as the address on PCI and IPv4/6 doesn't work the same way in postgres but it makes the individual records small and lightweight while allowing direct relationship to the host for an L3 interface
  2. Do we use a wide table looking like id|name|l1_addr|l2_addr|l3_addr|public_name where we generally just have a bunch of empty fields in the row since we wont know the PCI addr till we pop the target and often can't find MACs on things without that as well.
sempervictus commented 8 months ago

Thinking we can do something along the lines of

class InterfacesMigrator
  def run
    Host.all.each do |host|
      [:address, :address6].each do |addr|
        next if host.send(addr).nil?
        interface = Interface.find_or_create_by(host: host)
        interface.l2_addr = host.mac
        interface.l3_addr = host.send(addr)
        interface.public_name = host.name
      end
      host.save
    end
  end
end

and then drop the columns to "move" the data into relationship proxies. Right now we're using string field types for this information, while postgres provides inet and macaddr fields which we can use to offload network-related calculation to the back-end (finding all hosts in a subnet, etc).

sempervictus commented 8 months ago

This is probably the sort of architectural thought process warranting full-out demonic summoning... So, "I call upon the one and only @hdm (presuming you've a couple cycles to ponder this mess)... the OG architect of this domain" for insight into this mortal's thought exercise and why this seems to be the one part in MSF not mimicking the paradigms of our target surfaces whereas Rex emulates actual kernel components at times and the rest is written quite "true to form" where feasible. Also curious about fidelity of data mapping from the clunky and incoherent VAS' of the world to something as refined as RZ which already figured out what MACs, IPs, localities, etc belong together - i'm trying to construct a mechanism generic enough to import from both but structured enough to inform (preferably mechanical) decision-making in our recon and operational workflows.