does osquery support declaring variables that are ...
# general
j
does osquery support declaring variables that are the result of a select statement, and then using that variable in another select statement?
t
like a subquery?
Copy code
SELECT pid, name FROM processes WHERE pid IN (SELECT parent FROM processes WHERE name = 'docker');
j
Not with variables directly, but you can use sub selects. E.g.
Copy code
osquery> select directory, mode from file where path = (select "/etc/passwd");
+-----------+------+
| directory | mode |
+-----------+------+
| /etc      | 0644 |
+-----------+------+
s
j
Yeah, CTEs are commonly used for this too. Good point.
2
j
hmm, looking into it. The use case is parsing /Users/%%/Library/Preferences/MobileMeAccounts.plist which has a funny data structure
f
if you can provide an example query it will make it more likely to get assistance.
j
yup, working on it 🙂
Untitled
blah, that didn't format so great. But the basic problem is /Service/[number]/ is not guaranteed to be the same for every /Service/[number]/name
f
you can leverage something like regex or str replace, without knowing what shape of data you are looking for it is hard to know the right solution
in general as mentioned a few comments above, you most likely want a CTE aka "WITH blah AS (SELECT the things you want AS var name) SELECT var name FROM blah WHERE things are like this"
aliasing variables in a with query allows you to then reference them by name in the actual query
j
so
Copy code
SELECT sub.*
FROM (select subkey,value FROM plist path like "/Users/%%/Library/Preferences/MobileMeAccounts.plist") sub
WHERE subkey like 'Service/1/%'
will actually get me different services on each machine, because apple just numbers them numerically or something
or maybe osquery takes a series of dicts and orders them randomly, something like that
(to my surprise, this query didn't result in MobileDocuments on each machine, just whatever /Services/1/ was)
ok, I will think about this a bit
i think i get the answer 🙂
so basically i am asking "get me the "Service/[number]" where /Service/%/Name = "Mobile_Documents", and then do my search with that subkey value - and i just have to turn that into valid sql
thank you all!
f
in your sub query you are missing "WHERE" between plist and path fwiw
j
yeah, i was copying by hand from work computer to home computer for purposes of posting in slack
👍 1
its on the work computer :)
f
syntactically this should be equivilant
Copy code
WITH blah AS (SELECT subkey,value FROM plist WHERE path LIKE "/Users/%/Library/Preferences/MobileMeAccounts.plist") SELECT * FROM blah WHERE blah.subkey LIKE "/Service/1/%";
j
ok so:
Copy code
WITH service_number AS (SELECT sub.*
FROM (select subkey,value FROM plist WHERE path LIKE "/Users/%/Library/Preferences/MobileMeAccounts.plist" sub
where value="MOBILE_DOCUMENTS" select subkey from service_number;
returns (on my computer):
Copy code
[
   {
     "subkey": "Services/1/Name"
   }
]
in say python, i'd just grab the value from this dict, use variable="/Services/1/" for my where like = f"{variable}/%"
f
what are you trying to actually get here? is it an issue that it looks to be an array? or you only want it to return "Name" ?
im not sure if sqlite supports it but in bigquery for example you just do something like result[SAFE_OFFSET(0)] or whatever the syntax is to select the Nth element
j
I am so sorry, i think i am just missing the glue where the result of that query gets shoved into:
Copy code
SELECT sub.*
FROM (select subkey,value FROM plist where path like "/Users/%/Library/Preferences/MobileMeAccounts.plist") sub
where subkey like "{result of that first search}"
f
if it is the latter issue, you could do something like SPLIT(result, "/",2) or whatever that syntax is
j
(i'll figure out chopping /Name off)
f
where the result gets shoved into is completely unique to your environment so how it is consumed i don't know, in my case, we stream all of our results to a pubsup topic and everything is parsed and plopped into a data lake so can only speak to that
j
in english its "figure out on this computer which service number MOBILE_DOCUMENTS has, then give me all the keys related to the Service number for MOBILE_DOCUMENTS"
yeah, i mean i could just dump that entire table into splunk, and then use splunk to query it, but gross
i try not to ingest more data than i need
f
you still most likely want to use the WITH pattern, this creates a virtual table that you can subsequently work off of. so create your virtual table as above and then build your where constraint accordingly
j
yeah, I think i am just having trouble visualizing this. Thank you so much for helping me so far :)
s
Copy code
SELECT SPLIT(subkey, "/", 1) FROM plist WHERE path LIKE '/Users/%/Library/Preferences/MobileMeAccounts.plist' AND value="MOBILE_DOCUMENTS";
Should return you a table with all the service numbers, you can put that in a CTE
j
yeah, i apologize for being kinda dense here, i think i've figured out a few ways to pull out the thing i need, its shoving it into a new query that I am just derping on
s
Copy code
SELECT * FROM plist WHERE path LIKE '/Users/%/Library/Preferences/MobileMeAccounts.plist' AND subkey LIKE CONCAT('%/', (SELECT SPLIT(subkey, "/", 1) FROM plist WHERE path LIKE '/Users/%/Library/Preferences/MobileMeAccounts.plist' AND value="MOBILE_DOCUMENTS"), '/%');
This is with a subquery
The concat thing could also be prepared by the inner query itself I would imagine (so that the LIKE string is already in the internal table, ready to be extracted and used directly by the constraint)
j
Oh ok, thats basically it, i just threw in parenthesis and OR subkey="AccountID" to grab the icloud account being used
Copy code
SELECT * FROM plist WHERE path LIKE '/Users/%/Library/Preferences/MobileMeAccounts.plist' AND (subkey="AccountID" OR subkey LIKE CONCAT('%/', (SELECT SPLIT(subkey, "/", 1) FROM plist WHERE path LIKE '/Users/%/Library/Preferences/MobileMeAccounts.plist' AND value="MOBILE_DOCUMENTS"), '/%'));
Thank you ALL
s
For that table, and similar EAV style structured data, the usual recommendation is to pivot it. (The kolide blog has a good write up)
j
Yup! I discovered that after I accidentally returned 34523452296251 results