Kusto Detective Agency Case 5
El Puente - Big heist
Hello. It's going to happen soon: a big heist. You can stop it if you are quick enough. Find the exact place and time it’s going to happen.
Do it right, and you will be rewarded, do it wrong, and you will miss your chance.
Here are some pieces of the information:
The heist team has 4 members. They are very careful, hide well with minimal interaction with the external world. Yet, they use public chat-server for their syncs. The data below was captured from the chat-server: it doesn't include messages, but still it may be useful. See what you can do to find the IPs the gang uses to communicate.
Once you have their IPs, use my small utility to sneak into their machine’s and find more hints:
https://sneakinto.z13.web.core.windows.net/<ip>
Cheers
El Puente
PS:
Feeling uncomfortable and wondering about an elephant in the room: why would I help you?
Nothing escapes you, ha?
Let’s put it this way: we live in a circus full of competition. I can use some of your help, and nothing breaks if you use mine... You see, everything is about symbiosis.
Anyway, what do you have to lose? Look on an illustrated past, fast forward N days and realize the future is here.
.execute database script <|
.create-merge table ChatLogs (Timestamp:datetime, Message:string)
.ingest into table ChatLogs ('https://kustodetectiveagency.blob.core.windows.net/digitown-chat/log_00000.csv.gz')
.ingest into table ChatLogs ('https://kustodetectiveagency.blob.core.windows.net/digitown-chat/log_00001.csv.gz')
What is the exact place and time?
Date: [] Longitude: [] Latitude: []
Solution 5 - Solution
let Joined = ChatLogs
| where Message has "joined the channel"
| extend User = extract("User \\'(.+)\\' joined", 1, Message), Channel = extract("joined the channel \\'(.+)\\'", 1, Message)
| summarize Count=count() by bin(Timestamp, 1m), Channel
| where Count == 4
| summarize by Channel, Count;
let Left = ChatLogs
| where Message has "left the channel"
| extend User = extract("User \\'(.+)\\' left", 1, Message), Channel = extract("left the channel \\'(.+)\\'", 1, Message)
| summarize Count=count() by bin(Timestamp, 1d), Channel
| where Count == 4
| summarize by Channel, Count;
Joined
| join kind=innerunique Left on Channel
| project Channel;
let Users= ChatLogs
| where Message has "joined the channel"
| extend User = extract("User \\'(.+)\\' joined", 1, Message), Channel = extract("joined the channel \\'(.+)\\'", 1, Message)
| where Channel == "cf053de3c7b"
| summarize by User;
let Ips = ChatLogs
| where Message has "logged in from"
| extend User = extract("User \\'(.+)\\' logged", 1, Message), Ip = extract("logged in from \\'(\\d+\\.\\d+\\.\\d+\\.\\d+)\\'", 1, Message)
| summarize by User, Ip;
Users
| join kind=innerunique Ips on User
| project User, Ip
Now we have 4 user's ips to sneak in
u8819ece9b0 https://sneakinto.z13.web.core.windows.net/119.10.30.154
uab8088061c https://sneakinto.z13.web.core.windows.net/194.243.69.176
uaf9f4fef17 https://sneakinto.z13.web.core.windows.net/236.48.237.42
uf034c98df3 https://sneakinto.z13.web.core.windows.net/146.49.19.37
The image below has date info
https://sneakinto.z13.web.core.windows.net/119.10.30.154/message-project-x.png
The txt below has further hint, the key is case 4's answer
https://sneakinto.z13.web.core.windows.net/194.243.69.176/utils.txt
// Handy utils
// 1) Utility to discover secondary messages.
// Usage: ReadMessage(Message, Key)
let ReadMessage = (Message:string, Key:string)
{
let m = Message; let K = Key; let l = toscalar(print s = split(split(K,':')[1], ',') | mv-expand s | summarize make_list(tolong(s)));
let ma = (i1:long, i2:long) { make_string(repeat(tolong(l[i1])-tolong(l[i2]), 1))};
let ms = (d:dynamic, s:long, e:long) { make_string(array_slice(d, s, e)) };
let mc = m has '...';
print s=split(split(replace_regex(m, @'[\s\?]+', ' '),substring(K,9,3))[1], ' ')
| mv-expand with_itemindex=r s to typeof(string) | serialize
| where r in (l)
| extend s = iif(r-1 == prev(r), replace_string(strcat(prev(s), s),'o','ou'), s)
| where (r+1 != next(r))
| summarize s=strcat_array(make_list(s), iff(mc, '+%2B', ' '))
| extend k = series_subtract(series_add(to_utf8(K), l), repeat(23, 10))
| project result=iif(mc, strcat(ms(k,0,3), ma(8,2), ms(k,4,6), ms(l,8,8), ms(k,7,7), ma(8,0), s), s)
};
ReadMessage(
```
Hi there! How are you?
PS:
This is a nice utility that reveals what hidden messages the text may have.
We may read the message and think: is there anything beyond words?
Can we find it without the utility, or it will become too much of a headache?
```,
h@'dhkl4fva!that:2,9,15,22,31'
)
// 2) Get GEO location from images:
// Use https://tool.geoimgr.com/
ReadMessage(
```
PS:
Feeling uncomfortable and wondering about an elephant in the room: why would I help you?
Nothing escapes you, ha?
Let’s put it this way: we live in a circus full of competition. I can use some of your help, and nothing breaks if you use mine... You see, everything is about symbiosis.
Anyway, what do you have to lose? Look on an illustrated past, fast forward N days and realize the future is here.
```,
h@'wytaPUJM!PS:2,7,17,29,42,49,58,59,63'
)
Search the decoded URL
https://bing.com?q=uncomfortable+%2Belephant+%2Bescapes+%2Bcircus+%2Bbreaks+%2Beverything+%2Btoulouse+%2Billustrated
We get below URL, which has year info "1891"
The last piece is picture project x's taken day and geo location, which can be retrieved from this this picture
https://sneakinto.z13.web.core.windows.net/146.49.19.37/image3.jpg
Final Answer
What is the exact place and time?
Date: [2022-12-17] Longitude: [-3.380104] Latitude: [58.968867]