This parses AnyDesk logs to retrieve information about AnyDesk usage. It includes source IP addresses, AnyDesk ID’s, and filetransfers.
Parts of below code was used from Matt Green - @mgreen27
name: Windows.Applications.AnyDesk
description: |
This parses AnyDesk logs to retrieve information about AnyDesk usage. It includes source IP addresses, AnyDesk ID's, and filetransfers.
Parts of below code was used from Matt Green - @mgreen27
author: Jos Clephas - @DfirJos
reference:
- https://attack.mitre.org/techniques/T1219/
type: CLIENT
parameters:
- name: DateAfter
description: "search for events after this date. YYYY-MM-DDTmm:hh:ss Z"
type: timestamp
- name: DateBefore
description: "search for events before this date. YYYY-MM-DDTmm:hh:ss Z"
type: timestamp
- name: SearchVSS
description: "Add VSS into query."
type: bool
- name: MessageRegex
description: "Keyword search using regex, for example: IP address, AnyDesk ID's"
default: .
- name: SearchFilesGlobTable
type: csv
default: |
Glob
C:\Users\*\AppData\Roaming\AnyDesk\ad_*\ad*.trace
C:\Users\*\AppData\Roaming\AnyDesk\ad*.trace
C:\ProgramData\AnyDesk\ad*.trace
- name: OutputAll
type: bool
description: "By default it only shows events concerning IP addresses, AnyDeskID's and source hostnames. By selecting this it outputs all events."
default: FALSE
sources:
- query: |
-- Build time bounds
LET DateAfterTime <= if(condition=DateAfter,
then=DateAfter, else="1600-01-01")
LET DateBeforeTime <= if(condition=DateBefore,
then=DateBefore, else="2200-01-01")
LET fspaths <= SELECT FullPath FROM glob(globs=SearchFilesGlobTable.Glob)
-- function returning list of VSS paths corresponding to path
LET vsspaths(path) = SELECT FullPath
FROM Artifact.Windows.Search.VSS(SearchFilesGlob=path)
LET parse_log(FullPath) = SELECT parse_string_with_regex(
string=Line,
regex="^[\\s\\w]+?" +
"(?P<Timestamp>[\\d]{4}-[\\d]{2}-[\\d]{2}\\s[\\d]{2}:[\\d]{2}:[\\d]{2}.[\\d]{3})" +
"\\s+\\w+\\s+" +
"(?P<PPID>\\d+)\\s+" +
"(?P<PID>\\d+)[\\s\\w]+" +
"(?P<Type>.+)[ ][-][ ]" +
"(?P<Message>" +
"(Incoming session request: (?P<ComputerName>.+)[ ][(](?P<AnyDeskID>\\d+).)?" +
"(Logged in from (?P<LoggedInFromIP>[\\d.]+):(?P<Port>\\d+))?" +
"(?P<SessionStopped>Session stopped)?" +
"(Preparing files in ['](?P<PotentialFileTransfer>.+)['].+)?" +
"(External address: (?P<ExternalAddress>[\\d.]+):)?" +
".+$)"
) as Record,FullPath
FROM parse_lines(filename=FullPath)
-- function returning IOC hits
LET logsearch(PathList) = SELECT * FROM foreach(
row=PathList,
query={
SELECT *,timestamp(epoch=Record.Timestamp,format="2006-01-02 15:04:05") AS Timestamp
FROM parse_log(FullPath=FullPath)
WHERE Timestamp < DateBeforeTime AND
Timestamp > DateAfterTime AND
Record.Message =~ MessageRegex AND
if(condition=OutputAll, then=TRUE, else= Record.ComputerName OR
Record.LoggedInFromIP OR
Record.PotentialFileTransfer OR
Record.SessionStopped OR
Record.AnyDeskID OR
Record.ExternalAddress)
})
-- include VSS in calculation and deduplicate with GROUP BY by file
LET include_vss = SELECT * FROM foreach(row=fspaths,
query={
SELECT *
FROM logsearch(PathList={
SELECT FullPath FROM vsspaths(path=FullPath)
})
GROUP BY Record
})
-- exclude VSS in logsearch`
LET exclude_vss = SELECT * FROM logsearch(PathList={SELECT FullPath FROM fspaths})
-- return rows
SELECT Timestamp,
Record.Message as Message,
Record.ComputerName as ComputerName,
Record.LoggedInFromIP as LoggedInFromIP,
Record.PotentialFileTransfer as PotentialFileTransfer,
Record.AnyDeskID as AnyDeskID,
Record.ExternalAddress as ExternalAddress,
FullPath
FROM if(condition=SearchVSS,
then=include_vss,
else=exclude_vss)