Linux.Carving.SSHLogs

Linux systems typically store audit events in syslog. In particular successful ssh logins are especially important for some investigations.

Unfortunately they are sometimes deleted by attackers or rotated out. If you are desperate it might be worth trying to carve for ssh login events.

NOTES

  1. Syslog does not typically store the year in the date - since carving can recover very old records it might be difficult to pinpoint the time.
  2. This artifact will take a long time! You probably will have to increase the timeout.

name: Linux.Carving.SSHLogs
description: |
  Linux systems typically store audit events in syslog. In particular successful 
  ssh logins are especially important for some investigations.
  
  Unfortunately they are sometimes deleted by attackers or rotated out. If you 
  are desperate it might be worth trying to carve for ssh login events.
  
  ### NOTES
  
  1. Syslog does not typically store the year in the date - since carving can 
     recover very old records it might be difficult to pinpoint the time.
  2. This artifact will take a long time! You probably will have to increase 
     the timeout. 
  
parameters:
   - name: Device
     default: /dev/root

sources:
  - query: |
        LET GrokRule = '''%{SYSLOGTIMESTAMP:Timestamp} (?:%{SYSLOGFACILITY} )?%{SYSLOGHOST:logsource} %{SYSLOGPROG}: %{DATA:event} %{DATA:method} for (invalid user )?%{DATA:user} from %{IPORHOST:ip} port %{NUMBER:port} ssh2(: %{GREEDYDATA:system.auth.ssh.signature})?'''
        LET YaraRule = '''
        rule X {
            strings:
              $a = /(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) [0-9]{1,2} [0-9]{2}:[0-9]{2}[^\n]+/s
            condition:
              any of them
        }
        '''
        
        LET Hits = SELECT str(str=String.Data) AS Hit, String.Offset AS Offset
          FROM yara(
             files=Device, accessor="raw_file", end=1024*1024*1024*56,
             rules=YaraRule, number=100000000000)
          WHERE Hit =~ "Accept|Failed"
        
        SELECT * FROM foreach(row={
            SELECT grok(data=Hit, grok=GrokRule) AS Event, Offset
            FROM Hits
            WHERE Event
        }, query={
          SELECT Offset, timestamp(string=Event.Timestamp) AS Time,
                 Event.ip AS IP,
                 Event.logsource AS logsource,
                 Event.event AS Result,
                 Event.method AS Method,
                 Event.user AS AttemptedUser
          FROM scope()
        })