From 132750867fab3a9129c06ecbddd3de06b804f6e2 Mon Sep 17 00:00:00 2001
From: c0decave
" + html + "
\n" + #jdata = json.dumps(analysis_dict) + + # create html + #html = json2html.convert(json = jdata, table_attributes=attr) + + # write html + fwhtml.write(html_head) + fwhtml.write(html_body) + fwhtml.write(html_out) + fwhtml.write(html_end) + + # close html file + fwhtml.close() + +def create_url_json(url_d, outdir, out_filename): + ''' create a json url file in output directory + ''' + + # create url savefile + jsonurlout = "%s/%s_url.json" % (outdir, out_filename) + + # open up file for writting urls down + fwjson = open(jsonurlout, 'w') + + # convert url dictionary to json + jdata = json.dumps(url_d) + + # write json data to file + fwjson.write(jdata) + + # close filedescriptor + fwjson.close() + + return True + +def create_url_txt(url_d, outdir, out_filename): + ''' create a txt url file in output directory + ''' + # build up txt out path + txtout = "%s/%s_url.txt" % (outdir, out_filename) + + # open up our url txtfile + fwtxt = open(txtout, 'w') + + # iterating through the keys of the url dictionary + for k in url_d.keys(): + + # get the entry + ddata = url_d[k] + + # create meta data for saving + metatxt = '%s:%s\n' % (ddata['url'], ddata['filename']) + + # write metadata to file + fwtxt.write(metatxt) + + # close fd + fwtxt.close() + + return True diff --git a/libs/librequest.py b/libs/librequest.py new file mode 100644 index 0000000..a8df76b --- /dev/null +++ b/libs/librequest.py @@ -0,0 +1,162 @@ +import os +import sys +import json +import socket +import requests + +from libs.liblog import logger +from libs.libhelper import * +from libs.libgoogle import get_random_agent + +def store_file(url, data, outdir): + ''' storing the downloaded data to a file + params: url - is used to create the filename + data - the data of the file + outdir - to store in which directory + returns: dict { "code":, "data":,"error":} - the status code, the savepath, the errorcode
+ '''
+
+ logger.info('Store file {0}'.format(url))
+ name = find_name(url)
+
+ # only allow stored file a name with 50 chars
+ if len(name) > 50:
+ name = name[:49]
+
+ # build up the save path
+ save = "%s/%s" % (outdir, name)
+
+ try:
+ f = open(save, "wb")
+
+ except OSError as e:
+ logger.warning('store_file {0}'.format(e))
+ # return ret_dict
+ return {"code":False,"data":save,"error":e}
+
+ # write the data and return the written bytes
+ ret = f.write(data)
+
+ # check if bytes are zero
+ if ret == 0:
+ logger.warning('Written {0} bytes for file: {1}'.format(ret,save))
+
+ else:
+ # log to info that bytes and file has been written
+ logger.info('Written {0} bytes for file: {1}'.format(ret,save))
+
+ # close file descriptor
+ f.close()
+
+ # return ret_dict
+ return {"code":True,"data":save,"error":False}
+
+
+def download_file(url, args, header_data):
+ ''' downloading the file for later analysis
+ params: url - the url
+ args - argparse args namespace
+ header_data - pre-defined header data
+ returns: ret_dict
+ '''
+
+ # check the remote tls certificate or not?
+ cert_check = args.cert_check
+
+ # run our try catch routine
+ try:
+ # request the url and save the response in req
+ # give header data and set verify as delivered by args.cert_check
+ req = requests.get(url, headers=header_data, verify=cert_check)
+
+ except requests.exceptions.SSLError as e:
+ logger.warning('download file {0}{1}'.format(url,e))
+
+ # return retdict
+ return {"code":False,"data":req,"error":e}
+
+ except requests.exceptions.InvalidSchema as e:
+ logger.warning('download file {0}{1}'.format(url,e))
+
+ # return retdict
+ return {"code":False,"data":False,"error":e}
+
+ except socket.gaierror as e:
+ logger.warning('download file, host not known {0} {1}'.format(url,e))
+ return {"code":False,"data":False,"error":e}
+
+ except:
+ logger.warning('download file, something wrong with remote server? {0}'.format(url))
+ # return retdict
+ if not req in locals():
+ req = False
+
+ return {"code":False,"data":req,"error":True}
+
+ #finally:
+ # lets close the socket
+ #req.close()
+
+ # return retdict
+ return {"code":True,"data":req,"error":False}
+
+def grab_run(url, args, outdir):
+ ''' function keeping all the steps for the user call of grabbing
+ just one and analysing it
+ '''
+ header_data = {'User-Agent': get_random_agent()}
+ rd_download = download_file(url, args, header_data)
+ code_down = rd_download['code']
+
+ # is code True download of file was successfull
+ if code_down:
+ rd_evaluate = evaluate_response(rd_download)
+ code_eval = rd_evaluate['code']
+ # if code is True, evaluation was also successful
+ if code_eval:
+ # get the content from the evaluate dictionary request
+ content = rd_evaluate['data'].content
+
+ # call store file
+ rd_store = store_file(url, content, outdir)
+
+ # get the code
+ code_store = rd_store['code']
+
+ # get the savepath
+ savepath = rd_store['data']
+
+ # if code is True, storing of file was also successfull
+ if code_store:
+ return {"code":True,"data":savepath,"error":False}
+
+ return {"code":False,"data":False,"error":True}
+
+def evalute_content(ret_dict):
+ pass
+
+def evaluate_response(ret_dict):
+ ''' this method comes usually after download_file,
+ it will evaluate what has happened and if we even have some data to process
+ or not
+ params: data - is the req object from the conducted request
+ return: {}
+ returns: dict { "code":, "data":,"error":} - the status code, the savepath, the errorcode
+ '''
+ # extract data from ret_dict
+ req = ret_dict['data']
+
+ # get status code
+ url = req.url
+ status = req.status_code
+ reason = req.reason
+
+ # ahh everything is fine
+ if status == 200:
+ logger.info('download file, {0} {1} {2}'.format(url,reason,status))
+ return {"code":True,"data":req,"error":False}
+
+ # nah something is not like it should be
+ else:
+ logger.warning('download file, {0} {1} {2}'.format(url,reason,status))
+ return {"code":False,"data":req,"error":True}
diff --git a/libs/pdf_png.py b/libs/pdf_png.py
new file mode 100644
index 0000000..9ec8052
--- /dev/null
+++ b/libs/pdf_png.py
@@ -0,0 +1,5 @@
+
+def get_png_base64(filename):
+ fr = open(filename,'r')
+ buf = fr.read()
+ return buf
diff --git a/pdfgrab.py b/pdfgrab.py
index cb5ed69..d620653 100755
--- a/pdfgrab.py
+++ b/pdfgrab.py
@@ -22,12 +22,14 @@ from PyPDF2 import pdf
from libs.liblog import logger
from libs.libhelper import *
from libs.libgoogle import *
+from libs.libreport import *
+from libs.librequest import grab_run
from IPython import embed
# some variables in regard of the tool itself
name = 'pdfgrab'
-version = '0.4.8-Pre'
+version = '0.4.9'
author = 'dash'
date = 'November 2019'
@@ -243,72 +245,6 @@ def check_encryption(filename):
return True
-
-def download_pdf(url, args, header_data):
- ''' downloading the pdfile for later analysis '''
-
- # check the remote tls certificate or not?
- cert_check = args.cert_check
-
- try:
- req = requests.get(url, headers=header_data, verify=cert_check)
- # req = requests.get(url,headers=header_data,verify=False)
- data = req.content
- status_code = req.status_code
-
- except requests.exceptions.SSLError as e:
- logger.warning('download pdf {0}{1}'.format(url,e))
- return -1
-
- except:
- logger.warning('download pdf, something wrong with remote server? {0}'.format(url))
- return -1
-
- if status_code == 403:
- logger.warning('download pdf, 403 Forbidden {0}'.format(url))
- return -1
-
- # print(len(data))
- return data
-
-
-def store_pdf(url, data, outdir):
- ''' storing the downloaded pdf data
- '''
-
- logger.info('Store pdf {0}'.format(url))
- name = find_name(url)
- #logger.warning(url)
- #logger.warning(name)
- #logger.warning(outdir)
-
- # only allow stored file a name with 50 chars
- if len(name) > 50:
- name = name[:49] + '.pdf'
- # print(len(name))
-
- save = "%s/%s" % (outdir, name)
-
- try:
- f = open(save, "wb")
- except OSError as e:
- logger.warning('store_pdf {0}'.format(e))
- return -1
-
- ret = f.write(data)
- logger.info('Written {0} bytes for file: {1}'.format(ret,save))
- f.close()
-
- if ret == 0:
- logger.warning('Written {0} bytes for file: {1}'.format(ret,save))
- return save
- #return -1
-
-
- # return the savepath
- return save
-
-
def _parse_pdf(filename):
''' the real parsing function '''
@@ -320,26 +256,18 @@ def _parse_pdf(filename):
logger.warning('Filesize is 0 bytes at file: {0}'.format(filename))
return False
-
-def grab_url(url, args, outdir):
- ''' function keeping all the steps for the user call of grabbing
- just one pdf and analysing it
- '''
- header_data = {'User-Agent': get_random_agent()}
- data = download_pdf(url, args, header_data)
- if data != -1:
- savepath = store_pdf(url, data, outdir)
- _parse_pdf(savepath)
-
- return
-
-
def seek_and_analyse(search, args, outdir):
''' function for keeping all the steps of searching for pdfs and analysing
them together
'''
+ # check how many hits we got
+ # seems like the method is broken in googlsearch library :(
+ #code, hits = hits_google(search,args)
+ #if code:
+ # print('Got {0} hits'.format(hits))
+
# use the search function of googlesearch to get the results
- code, values=search_pdf(search, args)
+ code, values=search_google(search, args)
if not code:
if values.code == 429:
logger.warning('[-] Too many requests, time to change ip address or use proxychains')
@@ -362,7 +290,11 @@ def seek_and_analyse(search, args, outdir):
item = url_q.get()
# print(item)
url = item['url']
- grab_url(url, args, outdir)
+ rd_grabrun = grab_run(url, args, outdir)
+ code = rd_grabrun['code']
+ savepath = rd_grabrun['data']
+ if code:
+ _parse_pdf(savepath)
return True
@@ -372,6 +304,9 @@ def run(args):
# initialize logger
logger.info('{0} Started'.format(name))
+ # create some variables
+
+
# outfile name
if args.outfile:
out_filename = args.outfile
@@ -381,6 +316,7 @@ def run(args):
# specify output directory
outdir = args.outdir
+
# create output directory
make_directory(outdir)
@@ -417,68 +353,43 @@ def run(args):
fpath = '%s/%s' % (directory, f)
_parse_pdf(fpath)
+ # simply generate html report from json outfile
+ elif args.gen_html_report:
+ fr = open(args.gen_html_report,'r')
+ analysis_dict = json.loads(fr.read())
+ if create_html_report(analysis_dict, outdir,out_filename):
+ logger.info('Successfully created html report')
+ sys.exit(0)
+ else:
+ sys.exit(1)
+
else:
print('[-] Dunno what to do, bro. Use help. {0} -h'.format(sys.argv[0]))
+ sys.exit(1)
- # move analysis dictionary in queue back to dictionary
- analysis_dict = {}
- while ana_q.empty() == False:
- item = ana_q.get()
- # print('item ', item)
- analysis_dict.update(item)
+ # creating the analysis dictionary for reporting
+ analysis_dict = prepare_analysis_dict(ana_q)
- #print('dict:',analysis_dict)
- # ana_q is empty now
+ # lets go through the different reporting types
+ if args.report_txt:
+ if create_txt_report(analysis_dict, outdir,out_filename):
+ logger.info('Successfully created txt report')
- # create txt output
- sep = '-' * 80 + '\n'
- txtout = "%s/%s.txt" % (outdir, out_filename)
- fwtxt = open(txtout, 'w')
- # print(analysis_dict)
- for k in analysis_dict.keys():
- fwtxt.write(sep)
- fname = 'File: %s\n' % (analysis_dict[k]['filename'])
- ddata = analysis_dict[k]['data']
- fwtxt.write(fname)
- for kdata in ddata.keys():
- metatxt = '%s:%s\n' % (kdata, ddata[kdata])
- fwtxt.write(metatxt)
- fwtxt.write(sep)
- fwtxt.close()
+ if args.report_json:
+ if create_json_report(analysis_dict, outdir,out_filename):
+ logger.info('Successfully created json report')
- # create json output
- jsonout = "%s/%s.json" % (outdir, out_filename)
- fwjson = open(jsonout, 'w')
+ if args.report_html:
+ if create_html_report(analysis_dict, outdir,out_filename):
+ logger.info('Successfully created html report')
- # print(analysis_dict)
- jdata = json.dumps(analysis_dict)
- fwjson.write(jdata)
- fwjson.close()
+ if args.report_url_txt:
+ if create_url_txt(url_d, outdir,out_filename):
+ logger.info('Successfully created txt url report')
- # create html from json
- htmlout = "%s/%s.html" % (outdir, out_filename)
- fwhtml = open(htmlout,'w')
- #print(jdata)
- html = json2html.convert(json = jdata)
- fwhtml.write(html)
- fwhtml.close()
-
-
- # create url savefile
- # print('url_d: ', url_d)
- jsonurlout = "%s/%s_url.json" % (outdir, out_filename)
- fwjson = open(jsonurlout, 'w')
- jdata = json.dumps(url_d)
- fwjson.write(jdata)
- fwjson.close()
-
- txtout = "%s/%s_url.txt" % (outdir, out_filename)
- fwtxt = open(txtout, 'w')
- for k in url_d.keys():
- ddata = url_d[k]
- metatxt = '%s:%s\n' % (ddata['url'], ddata['filename'])
- fwtxt.write(metatxt)
- fwtxt.close()
+ if args.report_url_json:
+ if create_url_json(url_d, outdir,out_filename):
+ logger.info('Successfully created json url report')
return 42
@@ -504,8 +415,14 @@ def main():
help="specify domain or tld to scrape for pdf-files", default=None)
parser.add_argument('-sn', '--search-number', action='store', dest='search_stop', required=False,
help="specify how many files are searched", default=10, type=int)
- parser.add_argument('-z', '--disable-cert-check', action='store_false', dest='cert_check', required=False,
- help="if the target domain(s) run with old or bad certificates", default=True)
+ parser.add_argument('-z', '--disable-cert-check', action='store_false', dest='cert_check', required=False,help="if the target domain(s) run with old or bad certificates", default=True)
+
+ parser.add_argument('-ghr', '--gen-html-report', action='store', dest='gen_html_report', required=False,help="If you want to generate the html report after editing the json outfile (parameter: pdfgrab_analysis.json)")
+ parser.add_argument('-rtd', '--report-text-disable', action='store_false', dest='report_txt', required=False,help="Disable txt report",default=True)
+ parser.add_argument('-rjd', '--report-json-disable', action='store_false', dest='report_json', required=False,help="Disable json report",default=True)
+ parser.add_argument('-rhd', '--report-html-disable', action='store_false', dest='report_html', required=False,help="Disable html report",default=True)
+ parser.add_argument('-rutd', '--report-url-text-disable', action='store_false', dest='report_url_txt', required=False,help="Disable url txt report",default=True)
+ parser.add_argument('-rujd', '--report-url-json-disable', action='store_false', dest='report_url_json', required=False,help="Disable url json report",default=True)
if len(sys.argv)<2:
parser.print_help(sys.stderr)
diff --git a/supply/pdf.png b/supply/pdf.png
new file mode 100644
index 0000000000000000000000000000000000000000..769b4078a208ba47caa05b608eb326d61c4aae88
GIT binary patch
literal 24483
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