Find and parse ssh known hosts files.
name: Linux.Ssh.KnownHosts
description: Find and parse ssh known hosts files.
parameters:
- name: sshKnownHostsFiles
default: '.ssh/known_hosts*'
precondition: SELECT OS From info() where OS = 'linux'
sources:
- query: |
// For each user on the system, search for known_hosts files.
LET authorized_keys = SELECT * from foreach(
row={
SELECT Uid, User, Homedir from Artifact.Linux.Sys.Users()
},
query={
SELECT OSPath, Mtime, Ctime, User, Uid
FROM glob(
globs=sshKnownHostsFiles,
root=Homedir)
})
// For each known_hosts file, extract each line on a different row.
SELECT * from foreach(
row=authorized_keys,
query={
SELECT Uid, User, OSPath, Hostname, Type, PublicKey
FROM split_records(
filenames=OSPath, regex=" ", record_regex="\n",
columns=["Hostname", "Type", "PublicKey"])
/* Ignore comment lines. */
WHERE not Hostname =~ "^[^#]+#"
})
- name: HostPublicKeys
query: |
LET Me <= SELECT * FROM info()
SELECT * FROM foreach(row={
SELECT OSPath
FROM glob(globs="/etc/ssh/ssh_host*.pub")
}, query={
SELECT *, Me[0].Fqdn AS Fqdn
FROM split_records(columns=["Type", "PublicKey", "KeyName"],
filenames=OSPath,
regex=" +")
})
notebook:
- type: vql_suggestion
name: "Resolve Known Hosts"
template: |
/*
# Resolve Hostnames
This query resolves the public keys in the known hosts file
with the collected public keys from all hosts.
This works best when this cell applies to a hunt collection
from a wide number of hosts. It helps to resolve the
hostnames from known hosts to real host names (these are
usually hashed within the file).
This artifact helps to establish historical SSH access from
one machine to another machine.
*/
LET lookup <= memoize(
key="PublicKey",
query={
SELECT *
FROM source(artifact="Linux.Ssh.KnownHosts/HostPublicKeys")
})
SELECT *, get(item=lookup, field=PublicKey) AS Hostname
FROM source(artifact="Linux.Ssh.KnownHosts")