Case 02 → Gone Phishing 🪱

Background: The complaints are pouring in, and people are fed up with the sudden increase in phishing calls attempting to steal their identity details.

Mission: Analyze the data and use your detective skills to find any patterns or clues that could lead us to the source of these calls.

For all the marbles: What phone number is used for placing the phishing calls?


To catch a phisherman.

.execute database script <|
.create-merge table PhoneCalls (Timestamp:datetime, EventType:string, CallConnectionId:string, Properties:dynamic)
//clear any previously ingested data if such exists
.clear table PhoneCalls data
.ingest async into table PhoneCalls (@'https://kustodetectiveagency.blob.core.windows.net/kda2c2phonecalls/log_00000.csv.gz')
.ingest async into table PhoneCalls (@'https://kustodetectiveagency.blob.core.windows.net/kda2c2phonecalls/log_00001.csv.gz')
// Last command is running sync, so when it finishes the data is already ingested.
// It can take about 1min to run.
.ingest into table PhoneCalls (@'https://kustodetectiveagency.blob.core.windows.net/kda2c2phonecalls/log_00002.csv.gz')

We need to understand the structure of this data.

PhoneCalls
| where EventType == "Disconnect"
| extend DisconnectedBy = tostring(Properties.DisconnectedBy)
| take 5
PhoneCalls
| where EventType == "Connect"
| extend Origin = tostring(Properties.Origin), Destination = tostring(Properties.Destination), IsHidden = tobool(Properties.IsHidden)
| project-away Properties
| take 5

We join the two events by the callConnectionId to get a better view

PhoneCalls
| where EventType == "Disconnect"
| extend DisconnectedBy = tostring(Properties.DisconnectedBy)
| join kind=inner(PhoneCalls
    | where EventType == "Connect"
    | extend Origin = tostring(Properties.Origin), Destination = tostring(Properties.Destination), IsHidden = tobool(Properties.IsHidden))
    on CallConnectionId
| extend Duration = datetime_diff('minute', Timestamp, Timestamp1)
| project CallConnectionId, Origin, Destination, IsHidden, Duration, DisconnectedBy 
| take 5

For us to proceed, we have to draw out the behavior of a phishing call and analyze using these.

The phishing call would probably:

  • Be hidden

Count by whether IsHidden or not

Count by whether IsHidden or not

  • Disconnected by me

    Count by who disconnected the call

    Count by who disconnected the call

  • Lasts a shorter time

    Count of number of calls by Duration

    Count of number of calls by Duration

To find the phisher, we have to check all these boxes.

PhoneCalls
| where EventType == "Disconnect"
| extend DisconnectedBy = tostring(Properties.DisconnectedBy)
| join kind=inner(PhoneCalls
    | where EventType == "Connect"
    | extend Origin = tostring(Properties.Origin), Destination = tostring(Properties.Destination), IsHidden = tobool(Properties.IsHidden))
    on CallConnectionId
| extend Duration = datetime_diff('minute', Timestamp, Timestamp1)
| project CallConnectionId, Origin, Destination, IsHidden, Duration, DisconnectedBy 
| where IsHidden == true and DisconnectedBy == "Destination"
| summarize count() by Origin
| top 1 by count_

Untitled

Case 01 → Something’s leaking 👃🏾

Case 03 → A Brief History of Time 🚘

comments powered by Disqus