Skip to content
Please update to the latest release 0.77.2 to address Multiple CVEs.
Windows.Applications.FreeFileSync

Windows.Applications.FreeFileSync

This artifact 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 query GlobalInfo
  • Identify the latest transferred 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 artifact 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 query GlobalInfo
   - Identify the latest transferred 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 retrieve latest 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 retrieve and parse latest 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