Windows.Applications.FreeFileSync

This artefact can be used to retrieve and parse some FreeFileSync file in order to:

  • Identify the latest account used to transfer data and the remote ip adresse destination in the case of SFTP protocol with the qeury GlobalInfo
  • Identify the latest transfered files with Latest Data Transfer
  • Identify the presence of others interesting logs about previous or attempt of files transfer

In the case of logs files, only the html version has been parsed

These query were made in the context of the use of legitimate data transfer tools by an attacker. You can read more about it on https://www.synacktiv.com/publications/legitimate-exfiltration-tools-summary-and-detection-for-incident-response-and-threat


name: Windows.Applications.FreeFileSync
author: Nathanaël Ndong, Synacktiv
description: |
   This artefact can be used to retrieve and parse some FreeFileSync file in order to:
   - Identify the latest account used to transfer data and the remote ip adresse destination in the case of SFTP protocol with the qeury GlobalInfo
   - Identify the latest transfered files with Latest Data Transfer
   - Identify the presence of others interesting logs about previous or attempt of files transfer

   In the case of logs files, only the html version has been parsed
   
   These query were made in the context of the use of legitimate data transfer tools by an attacker.
   You can read more about it on https://www.synacktiv.com/publications/legitimate-exfiltration-tools-summary-and-detection-for-incident-response-and-threat

type: CLIENT

parameters:
   - name: FreeFileInfoGlob
     default: \AppData\Roaming\FreeFileSync\
     description: Use to retreive lastest global information including userID and remote destination for SFTP from GlobalSettings.xml file

   - name: userRegex
     default: .
     type: regex 
     
   - name: SearchFreeFileSyncLogs
     default: C:\Users\*\AppData\Roaming\FreeFileSync\Logs\*
     description:  Use a glob to define the files that will be searched

   - name: FreeFileSyncGlob
     default: C:\Users\*\AppData\Roaming\FreeFileSync\Logs\*Last*.html
     description: Use to retreive and parse lastest html log file
    
sources:
    - name: GlobalInfo
      query: |
        
        LET GlobalSettings_xml = SELECT * FROM foreach(
            row={
                SELECT Uid, Name As User,
                    expand (path=Directory) AS HomeDirectory
                FROM Artifact.Windows.Sys.Users()
                WHERE Name=~userRegex
            },
            query={
                SELECT User, OSPath,
                    parse_xml(file=OSPath).FreeFileSync.MainDialog.FilePanel.FolderHistoryRight AS Protocol,
                    parse_xml(file=OSPath).FreeFileSync.LastOnlineCheck AS Online,
                    Mtime
                FROM glob(globs=FreeFileInfoGlob + 'GlobalSettings.xml', root=HomeDirectory)
            })
        
        LET Value = SELECT * FROM foreach(
            row=GlobalSettings_xml,
            query={
                SELECT *, OSPath AS SourceFilePath
                FROM foreach(row=Protocol, query={
                    SELECT * FROM _value
                })
            })
        
        SELECT Item AS Last_Session_GlobalInfo FROM Value

    - name: Latest Data Transfer
      query: |
        LET InputLogPath = SELECT OSPath FROM glob(globs=FreeFileSyncGlob)
        
        LET extract_file(message)= parse_string_with_regex(string=message,
            regex=
                '''<.+?>(?P<Copy>.+?\s.+?)\s''' +
                '''&quot;'''+
                '''<*(?P<Provider>.+?)'''+
                ''':'''+
                '''[/\\]{1,2}'''+'''(?P<Connexion>.+?)[/\\]'''+
                '''(?P<Message>.+?)'''+
                '''&.*?</.+?>'''
        )
        
        LET last_date(message) = parse_string_with_regex(string=message,
            regex=
                '''(?P<Directory>.+?)''' +
                '''(?P<Date>\[.+?).html'''
        )
        
        LET parsed_line = SELECT * FROM foreach(row=InputLogPath,
            query={
                SELECT Line, FullPath FROM parse_lines(filename=InputLogPath.FullPath)
                WHERE Line =~ "Creating"
        })
                
        SELECT extract_file(message=Line).Copy AS Operation,
            extract_file(message=Line).Provider AS Protocol,
            extract_file(message=Line).Connexion AS Identifer, 
            extract_file(message=Line).Message AS File_Destination,
            last_date(message=FullPath).Date AS Last_Session_Date
        FROM parsed_line
        
        
    - name: FileUpload
      query: |
        LET logs_search = SELECT 
            OSPath,
            get(item=Data, field="mft") as Inode,
            Mode.String AS Mode,
            Size,
            Btime AS BTime,
            Mtime AS MTime,
            Ctime AS CTime,
            Atime AS ATime,
            IsDir, Data
        FROM glob(globs=SearchFreeFileSyncLogs)
      
        SELECT OSPath, Size,
            BTime, MTime, ATime,
            upload(file=OSPath) AS Upload
        FROM logs_search

column_types:
  - name: Modified
    type: timestamp
  - name: ATime
    type: timestamp
  - name: MTime
    type: timestamp
  - name: CTime
    type: timestamp
  - name: Upload
    type: preview_upload