SOLVED

External file support in KQL - Azure Sentinel

%3CLINGO-SUB%20id%3D%22lingo-sub-1433790%22%20slang%3D%22en-US%22%3EExternal%20file%20KQL%20in%20azure%20Sentinel%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1433790%22%20slang%3D%22en-US%22%3E%3CDIV%20class%3D%22qna-item-container%20has-replies%22%3E%0A%3CDIV%3E%0A%3CDIV%20class%3D%22qna-item%20is-you%20is-private%20round-top%22%3E%0A%3CDIV%20class%3D%22qna-item-row%22%3E%0A%3CDIV%20class%3D%22qna-item-column-body%22%3E%0A%3CDIV%20class%3D%22qna-item-row%22%3E%0A%3CDIV%20class%3D%22qna-item-header%22%3E%3CSPAN%3EDoes%20KQL%20supports%20external%20file%20(Like%20.csv%20or%20.txt%20etc.)%20as%20an%20input%20to%20process%20a%20query%20%3F%3C%2FSPAN%3E%3C%2FDIV%3E%0A%3C%2FDIV%3E%0A%3C%2FDIV%3E%0A%3C%2FDIV%3E%0A%3C%2FDIV%3E%0A%3C%2FDIV%3E%0A%3C%2FDIV%3E%0A%3CDIV%3E%0A%3CDIV%20class%3D%22qna-item-container%20qna-replies%22%3E%0A%3CDIV%20class%3D%22qna-item-replybox%20is-private%22%3E%0A%3CDIV%20id%3D%22replyAction%22%20class%3D%22qna-item-replybox--button%22%20tabindex%3D%220%22%20role%3D%22button%22%3E%26nbsp%3B%3C%2FDIV%3E%0A%3C%2FDIV%3E%0A%3C%2FDIV%3E%0A%3C%2FDIV%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1433837%22%20slang%3D%22en-US%22%3ERe%3A%20External%20file%20support%20in%20KQL%20-%20Azure%20Sentinel%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1433837%22%20slang%3D%22en-US%22%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F293468%22%20target%3D%22_blank%22%3E%40Sanket26%3C%2FA%3E%26nbsp%3BYes.%20See%20the%20following%20for%20an%20example%3A%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fazure-sentinel%2Fimplementing-lookups-in-azure-sentinel%2Fba-p%2F1091306%22%20target%3D%22_blank%22%3Ehttps%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fazure-sentinel%2Fimplementing-lookups-in-azure-sentinel%2Fba-p%2F1091306%3C%2FA%3E%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1436288%22%20slang%3D%22en-US%22%3ERe%3A%20External%20file%20support%20in%20KQL%20-%20Azure%20Sentinel%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1436288%22%20slang%3D%22en-US%22%3E%3CDIV%3E%3CP%3E%3CSPAN%3EI've%20just%20created%20a%20file%20for%20you%20to%20try%20that%20you%20can%20access%20on-the-fly%20using%20the%20KQL%20query%3A%3C%2FSPAN%3E%3C%2FP%3E%3C%2FDIV%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-applescript%22%3E%3CCODE%3Eexternaldata%20(UserID%3Astring%2C%20DomainName%3Astring)%20%5B%40%22https%3A%2F%2Fraw.githubusercontent.com%2Fjjsantanna%2Ftest_csv%2Fmaster%2Fioc.csv%22%5D%20with%20(format%3D%22csv%22%2CignoreFirstRecord%3Dtrue)%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EThis%20is%20the%20easiest%20way%20to%20access%20external%20data.%20You%20can%20also%20create%20a%20blob%20within%20Azure%20and%20call%20from%20it.%20You%20can%20also%20read%20external%20text%20file%2C%20json%2C%20and%20many%20others.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EDoes%20this%20answer%20your%20question%3F%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1438541%22%20slang%3D%22en-US%22%3ERe%3A%20External%20file%20support%20in%20KQL%20-%20Azure%20Sentinel%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1438541%22%20slang%3D%22en-US%22%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F584375%22%20target%3D%22_blank%22%3E%40jjsantanna%3C%2FA%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EThe%20issue%20which%20I%20am%20facing%20right%20now%20is%20%3A%20The%20html%20page%20where%20the%20csv%20is%20hosted%20isn't%20in%20desired%20format%20(There%20are%20multiple%20lines%20of%20header%20before%20the%20actual%20data).%20Also%20downloading%20the%20file%2C%20modifying%20the%20format%20and%20then%20uploading%20to%20a%20blob%20isn't%20the%20best%20option%20for%20me.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EI%20am%20getting%20this%20error%20%3A%3C%2FP%3E%0A%3CP%3EPartial%20query%20failure%3A%20Wrong%20number%20of%20fields%20(E_WRONG_NUMBER_OF_FIELDS).%20(message%3A%20'Kusto%3A%3ACsv%3A%3AParser%26lt%3B%26gt%3B.PrepareFields%3A%20CSV%20has%20an%20inconsistent%20number%20of%20fields%20per%20line%3A%20'%2C%20details%3A%20'Offending%20record%3A%2010%20(start%20position%20in%20stream%3A%20531)%2C%20fieldsCount%3A%204%2C%20currentRecordFieldCount%3A%204%2C%20record%3A%20%23%20ja3_md5%2CFirstseen%2CLastseen%2CListingreason%3CBR%20%2F%3E%5Bend%20record%5D')%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1438550%22%20slang%3D%22en-US%22%3ERe%3A%20External%20file%20support%20in%20KQL%20-%20Azure%20Sentinel%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1438550%22%20slang%3D%22en-US%22%3EIf%20you%20send%20me%20the%20link%20to%20the%20HTML%20containing%20the%20csv%20I%20can%20try%20to%20help%20you.%3CBR%20%2F%3EDoes%20it%20need%20to%20be%20in%20Log%20Analytics%2FAzure%20Sentinel%20using%20KQL%3F%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1438637%22%20slang%3D%22en-US%22%3ERe%3A%20External%20file%20support%20in%20KQL%20-%20Azure%20Sentinel%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1438637%22%20slang%3D%22en-US%22%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F584375%22%20target%3D%22_blank%22%3E%40jjsantanna%3C%2FA%3E%3C%2FP%3E%0A%3CP%3EPlease%20find%20the%20link%20details%20%3A%26nbsp%3B%3CA%20href%3D%22https%3A%2F%2Fsslbl.abuse.ch%2Fblacklist%2Fja3_fingerprints.csv%22%20target%3D%22_blank%22%20rel%3D%22nofollow%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3Ehttps%3A%2F%2Fsslbl.abuse.ch%2Fblacklist%2Fja3_fingerprints.csv%3C%2FA%3E%3C%2FP%3E%0A%3CP%3EAlso%20yes%20I%20was%20running%20this%20data%20in%20Azure%20sentinel.%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1438658%22%20slang%3D%22en-US%22%3ERe%3A%20External%20file%20support%20in%20KQL%20-%20Azure%20Sentinel%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1438658%22%20slang%3D%22en-US%22%3E%3CP%3EThere%20you%20go%26nbsp%3B%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F293468%22%20target%3D%22_blank%22%3E%40Sanket26%3C%2FA%3E%26nbsp%3B%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-applescript%22%3E%3CCODE%3Eexternaldata%20(Everything%3Astring)%20%5B%40%22https%3A%2F%2Fsslbl.abuse.ch%2Fblacklist%2Fja3_fingerprints.csv%22%5D%20with%20(format%3D%22txt%22%2CignoreFirstRecord%3Dtrue)%20%2F%2F%20reading%20each%20line%20as%20a%20string%0A%7C%20where%20Everything%20!startswith%20%22%23%22%20%2F%2Fremoving%20the%20lines%20that%20started%20with%20'%23'%0A%7C%20project%20Everything%3Dparse_csv(Everything)%20%2F%2F%20parsing%20the%20string%20as%20csv%0A%7C%20project%20ja3_md5%3DEverything%5B0%5D%2CFirstseen%3DEverything%5B1%5D%2CLastseen%3DEverything%5B2%5D%2C%20Listingreason%3DEverything%5B3%5D%20%2F%2Fsplitting%20the%20csv%20into%20columns%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3EI've%20added%20some%20comments%20for%20you%20to%20know%20what%20I%20was%20doing.%3C%2FP%3E%3CP%3ELet%20me%20know%20if%20this%20was%20helpful!%26nbsp%3B%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1438699%22%20slang%3D%22en-US%22%3ERe%3A%20External%20file%20support%20in%20KQL%20-%20Azure%20Sentinel%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1438699%22%20slang%3D%22en-US%22%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F584375%22%20target%3D%22_blank%22%3E%40jjsantanna%3C%2FA%3E%3C%2FP%3E%0A%3CP%3EThank%20a%20lot.%20It%20really%20helped.%20The%20issue%20is%20resolved.%20I%20am%20now%20able%20to%20fetch%20data%20directly%20from%20the%20http%20page.%20The%20part%20I%20was%20missing%20was%20I%20didn't%20perform%20the%20parsing%20on%20the%20csv%20as%20a%20result%20I%20wasn't%20getting%20the%20schema%20as%20expected.%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1438707%22%20slang%3D%22en-US%22%3ERe%3A%20External%20file%20support%20in%20KQL%20-%20Azure%20Sentinel%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1438707%22%20slang%3D%22en-US%22%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F293468%22%20target%3D%22_blank%22%3E%40Sanket26%3C%2FA%3E%26nbsp%3BMaybe%20its%20just%20me...but%20we%20are%20talking%20about%20security%2C%20right%3F%20While%20you%20*can*%20access%20data%20over%20https%2Fhttp%2Fremote_locations%2C%20is%20that%20really%20a%20best%20practice%3F%20The%20link%20I%20provided%20to%20the%20information%20earlier%20was%20to%20ensure%20that%20your%20blacklist%2Fwhitelist%20information%20was%20being%20stored%20within%20your%20own%20tenant%2Fnetwork.%20I%20suspect%2C%20if%20you%20have%20Analytics%20Rules%20enabled%2C%20that%20URL%20you%20shared%20may%20show%20up%20as%20an%20entity%20for%20an%20investiation.%20%3A)%3C%2Fimg%3E%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1438718%22%20slang%3D%22en-US%22%3ERe%3A%20External%20file%20support%20in%20KQL%20-%20Azure%20Sentinel%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1438718%22%20slang%3D%22en-US%22%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F324945%22%20target%3D%22_blank%22%3E%40rodtrent%3C%2FA%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EI%20totally%20agree%20to%20your%20point.%20The%20https%20link%20I%20provided%20is%20just%20a%20sample%20to%20identify%20if%20there%20is%20any%20option%20where%20these%20feeds%20can%20be%20directly%20utilized%20in%20kusto.%20Accessing%20those%20data%26nbsp%3B%3CSPAN%3Eover%20third%20party%20https%2Fhttp%2Fremote_locations%3C%2FSPAN%3E%20is%20definitely%20not%20a%20best%20security%20practice.%20We%20will%20be%20uploading%20these%20to%20our%20internal%20websites%20and%20from%20there%20we%20will%20be%20accessing%20those.%3C%2FP%3E%0A%3CP%3ELet%20me%20know%20if%20this%20clarifies%20your%20concern%3F%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1438725%22%20slang%3D%22en-US%22%3ERe%3A%20External%20file%20support%20in%20KQL%20-%20Azure%20Sentinel%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1438725%22%20slang%3D%22en-US%22%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F293468%22%20target%3D%22_blank%22%3E%40Sanket26%3C%2FA%3E%26nbsp%3BIt%20does.%20I%20also%20appreciate%20it.%20It%20gives%20me%20some%20things%20to%20think%20about%20from%20a%20security%20perspective%20that%20we%20may%20need%20to%20look%20at%20from%20a%20product%20view.%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1438733%22%20slang%3D%22en-US%22%3ERe%3A%20External%20file%20support%20in%20KQL%20-%20Azure%20Sentinel%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1438733%22%20slang%3D%22en-US%22%3EGreat%20discussion.%20My%20point%20on%20answering%20the%20question%20was%20to%20show%20that%20the%20product%20can%20do%20more%20than%20people%20have%20in%20mind.%3C%2FLINGO-BODY%3E
Highlighted
Microsoft
Does KQL supports external file (Like .csv or .txt etc.) as an input to process a query ?
 
  • s
11 Replies
Highlighted
Highlighted

I've just created a file for you to try that you can access on-the-fly using the KQL query:

 

externaldata (UserID:string, DomainName:string) [@"https://raw.githubusercontent.com/jjsantanna/test_csv/master/ioc.csv"] with (format="csv",ignoreFirstRecord=true)

 

This is the easiest way to access external data. You can also create a blob within Azure and call from it. You can also read external text file, json, and many others.

 

Does this answer your question?

Highlighted

@jjsantanna 

The issue which I am facing right now is : The html page where the csv is hosted isn't in desired format (There are multiple lines of header before the actual data). Also downloading the file, modifying the format and then uploading to a blob isn't the best option for me.

 

I am getting this error :

Partial query failure: Wrong number of fields (E_WRONG_NUMBER_OF_FIELDS). (message: 'Kusto::Csv::Parser<>.PrepareFields: CSV has an inconsistent number of fields per line: ', details: 'Offending record: 10 (start position in stream: 531), fieldsCount: 4, currentRecordFieldCount: 4, record: # ja3_md5,Firstseen,Lastseen,Listingreason
[end record]')

 

 

Highlighted
If you send me the link to the HTML containing the csv I can try to help you.
Does it need to be in Log Analytics/Azure Sentinel using KQL?
Highlighted

@jjsantanna

Please find the link details : https://sslbl.abuse.ch/blacklist/ja3_fingerprints.csv

Also yes I was running this data in Azure sentinel.

Highlighted

There you go @Sanket26 

externaldata (Everything:string) [@"https://sslbl.abuse.ch/blacklist/ja3_fingerprints.csv"] with (format="txt",ignoreFirstRecord=true) // reading each line as a string
| where Everything !startswith "#" //removing the lines that started with '#'
| project Everything=parse_csv(Everything) // parsing the string as csv
| project ja3_md5=Everything[0],Firstseen=Everything[1],Lastseen=Everything[2], Listingreason=Everything[3] //splitting the csv into columns

I've added some comments for you to know what I was doing.

Let me know if this was helpful! 

Highlighted

@jjsantanna

Thank a lot. It really helped. The issue is resolved. I am now able to fetch data directly from the http page. The part I was missing was I didn't perform the parsing on the csv as a result I wasn't getting the schema as expected.

Highlighted

@Sanket26 Maybe its just me...but we are talking about security, right? While you *can* access data over https/http/remote_locations, is that really a best practice? The link I provided to the information earlier was to ensure that your blacklist/whitelist information was being stored within your own tenant/network. I suspect, if you have Analytics Rules enabled, that URL you shared may show up as an entity for an investiation. :)

Highlighted

@rodtrent 

I totally agree to your point. The https link I provided is just a sample to identify if there is any option where these feeds can be directly utilized in kusto. Accessing those data over third party https/http/remote_locations is definitely not a best security practice. We will be uploading these to our internal websites and from there we will be accessing those.

Let me know if this clarifies your concern?

Highlighted

@Sanket26 It does. I also appreciate it. It gives me some things to think about from a security perspective that we may need to look at from a product view.

Highlighted
Great discussion. My point on answering the question was to show that the product can do more than people have in mind.