mirror of https://github.com/n1nj4sec/pupy.git
Add isearch module
This commit is contained in:
parent
8de4ff940a
commit
9593b71df0
|
@ -0,0 +1,103 @@
|
||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
|
||||||
|
from pupylib.PupyModule import config, PupyModule, PupyArgumentParser
|
||||||
|
from pupylib.PupyOutput import Table
|
||||||
|
from argparse import REMAINDER
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
__class_name__='IndexSearchModule'
|
||||||
|
|
||||||
|
# ZOMG Kill me please
|
||||||
|
def escape(x):
|
||||||
|
if "'" in x:
|
||||||
|
x = x.replace("'", "")
|
||||||
|
|
||||||
|
return "'" + x + "'"
|
||||||
|
|
||||||
|
@config(cat='gather', compat='windows')
|
||||||
|
class IndexSearchModule(PupyModule):
|
||||||
|
''' Use Windows Search Index to search for data '''
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
'win32com', 'win32api', 'winerror',
|
||||||
|
'numbers', 'decimal', 'adodbapi', 'isearch'
|
||||||
|
]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def init_argparse(cls):
|
||||||
|
cls.arg_parser = PupyArgumentParser(prog='isearch', description=cls.__doc__)
|
||||||
|
cls.arg_parser.add_argument(
|
||||||
|
'-L', '--limit', type=int, help='Limit records (default 50)',
|
||||||
|
default=50)
|
||||||
|
cls.arg_parser.add_argument('-v', '--verbose', action='store_true',
|
||||||
|
default=False, help='Show SQL query')
|
||||||
|
cls.arg_parser.add_argument('-t', '--text', help='Text to search')
|
||||||
|
cls.arg_parser.add_argument('-p', '--path', help='Path to search')
|
||||||
|
cls.arg_parser.add_argument('-d', '--directory', help='Directory to limit output')
|
||||||
|
cls.arg_parser.add_argument(
|
||||||
|
'-R', '--raw', metavar='SELECT ... FROM SYSTEMINDEX ...',
|
||||||
|
nargs=REMAINDER, help='RAW SQL Query to search '\
|
||||||
|
'(https://docs.microsoft.com/en-us/windows/'\
|
||||||
|
'desktop/search/-search-3x-advancedquerysyntax)')
|
||||||
|
|
||||||
|
def run(self, args):
|
||||||
|
query = self.client.remote('isearch', 'query')
|
||||||
|
|
||||||
|
request = []
|
||||||
|
if args.raw:
|
||||||
|
request = args.raw
|
||||||
|
else:
|
||||||
|
request.append('SELECT TOP {} System.ItemUrl, System.Size, System.DateModified FROM SYSTEMINDEX'.format(args.limit))
|
||||||
|
where = []
|
||||||
|
if args.text:
|
||||||
|
where.append('FREETEXT({})'.format(escape(args.text)))
|
||||||
|
if args.directory:
|
||||||
|
where.append('SCOPE={}'.format(escape('file:'+args.directory)))
|
||||||
|
if args.path:
|
||||||
|
where.append('CONTAINS(System.FileName, {})'.format(escape(args.path)))
|
||||||
|
|
||||||
|
if where:
|
||||||
|
request.append('WHERE')
|
||||||
|
request.append('AND'.join(where))
|
||||||
|
|
||||||
|
request.append('ORDER BY System.DateModified DESC')
|
||||||
|
|
||||||
|
if not request:
|
||||||
|
self.error('You should specify request')
|
||||||
|
return
|
||||||
|
|
||||||
|
text = ' '.join(request)
|
||||||
|
|
||||||
|
if args.verbose:
|
||||||
|
self.info('QUERY: {}'.format(text))
|
||||||
|
|
||||||
|
idx, cidx, data, error = query(text, args.limit)
|
||||||
|
if error:
|
||||||
|
self.error(error)
|
||||||
|
elif not data:
|
||||||
|
self.warning('No data found')
|
||||||
|
else:
|
||||||
|
objects = []
|
||||||
|
header = []
|
||||||
|
legend = True
|
||||||
|
|
||||||
|
if args.raw:
|
||||||
|
legend = False
|
||||||
|
for record in data:
|
||||||
|
objects.append({
|
||||||
|
str(idx):v for idx,v in enumerate(record)
|
||||||
|
})
|
||||||
|
header = [
|
||||||
|
str(x) for x in xrange(cidx+1)
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
header = ['File', 'Size', 'Modified']
|
||||||
|
for record in data:
|
||||||
|
objects.append({
|
||||||
|
'File': record[0][5:] if record[0].startswith('file:') else record[0],
|
||||||
|
'Size': record[1],
|
||||||
|
'Modified': datetime.fromtimestamp(record[2])
|
||||||
|
})
|
||||||
|
|
||||||
|
self.log(Table(objects, header, legend=legend))
|
|
@ -0,0 +1,47 @@
|
||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
|
||||||
|
import adodbapi
|
||||||
|
import sys
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
PROVIDER = 'provider=Search.CollatorDSO.1;EXTENDED?PROPERTIES="Application=Windows"'
|
||||||
|
|
||||||
|
def query(sql, limit):
|
||||||
|
data = []
|
||||||
|
error = None
|
||||||
|
idx = 0
|
||||||
|
cidx = 0
|
||||||
|
|
||||||
|
encoding = sys.getfilesystemencoding()
|
||||||
|
|
||||||
|
conn = adodbapi.connect(PROVIDER)
|
||||||
|
|
||||||
|
try:
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute(sql)
|
||||||
|
for idx, record in enumerate(cursor):
|
||||||
|
|
||||||
|
if idx >= limit:
|
||||||
|
break
|
||||||
|
|
||||||
|
line = []
|
||||||
|
for cidx, column in enumerate(record):
|
||||||
|
if type(column) == str:
|
||||||
|
column = column.decode(encoding)
|
||||||
|
elif type(column) == datetime.datetime:
|
||||||
|
column = int((
|
||||||
|
column - datetime.datetime.fromtimestamp(0)
|
||||||
|
).total_seconds())
|
||||||
|
line.append(column)
|
||||||
|
data.append(tuple(line))
|
||||||
|
|
||||||
|
except adodbapi.apibase.DatabaseError, e:
|
||||||
|
# ZOMG
|
||||||
|
parts = e.message.split('\n')
|
||||||
|
code = eval(parts[0])[1].decode(encoding)
|
||||||
|
error = '\n'.join(parts[1:]) + '\n' + code
|
||||||
|
|
||||||
|
finally:
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
return idx, cidx, data, error
|
Loading…
Reference in New Issue