Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add gethost.py #20

Merged
merged 2 commits into from
Jun 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
__pycache__
alerts
db
log
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ $ python3 scanhost.py --help
~~~

~~~
$ python3 ./scanhost.py -c conf/test.conf
$ python3 ./scanhost.py -c conf/example.conf
Test all domains in DB for Internet Presence:
*********************************************
14:30:12 - ERROR - https://socialparadiseweb.cf.socialparadise.cf - Connection error
Expand All @@ -103,6 +103,26 @@ Creating ./alerts/socialmediaforsocialaction.com.json : {'hostname': 'socialmedi
Creating ./alerts/assurances-sociales.com.json : {'hostname': 'assurances-sociales.com', 'http_code': 503, 'cert_serial_number': '1A:0D:45:D9:05:15:DC:17:6C:9F:9E:47:A5:62:03:D9:25:02:F9:3C', 'webpage_title': 'Accueil', 'ip_addr': '164.132.235.17', 'asn': '16276', 'asn_cidr': '164.132.0.0/16', 'asn_country_code': 'FR', 'asn_description': 'OVH, FR', 'asn_abuse_email': 'lir@ovh.net'}
~~~

### gethost.py

~~~
$ python3 scanhost.py --help

-h --help Print this help
-c --config Configuration file to use
--since Since when it displays findings (seconds)
~~~

~~~
$ python3 ./gethost.py -c conf/example.conf --since 36000 # 10 hours
Display all domains in DB for Internet Presence:
************************************************
socialparadiseweb.cf.socialparadise.cf None
rapportannuel-assurancemaladie.paris None
socialmediaforsocialaction.com 2019-06-12T15:54:31
social.socialbride.co.za None
~~~

## Authors
- Thomas Damonneville ([thomas.damonneville@assurance-maladie.fr](mailto:thomas.damonneville@assurance-maladie.fr))
- Christophe Brocas ([christophe.brocas@assurance-maladie.fr](mailto:christophe.brocas@assurance-maladie.fr))
Expand Down
184 changes: 184 additions & 0 deletions gethost.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
#!/usr/bin/env python3
"""
GetHost display the last findings
"""

# Copyright (c) 2018-2019 Caisse nationale d'Assurance Maladie
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.

# Standard library imports
from __future__ import absolute_import
from datetime import datetime
import getopt
import os
from sqlite3 import connect, Error
import sys

# Own library imports
from utils.confparser import ConfParser

# Debug
# from pdb import set_trace as st

def create_connection(db_file):
""" create a database connection to the SQLite database
specified by the db_file

:param db_file: database file
:return: Connection object or None
"""

try:
conn = connect(db_file, isolation_level=None)
# debug SQL
# conn.set_trace_callback(print)
return conn
except Error as err:
print(err)
return False


def args_parse():
"""
Tools options
"""
global CONFFILE
global SINCE
SINCE = 3600 # One hour

if not len(sys.argv[1:]):
usage()
try:
opts, args = getopt.getopt(sys.argv[1:], "hc:", ["help", "conf=", "since="])
except getopt.GetoptError as err:
print(" Option Error. Exiting..."+str(err))
usage()
sys.exit(2)

for o, a in opts:
if o in ("-h", "--help"):
usage()
elif o in ("-c", "--config"):
if os.path.isfile(a):
CONFFILE = a
else:
print(" Can't find configuration file. Exiting...")
sys.exit(1)
elif o in ("--since"):
SINCE = int(a)
else:
assert False, "Unhandled Option"
return


def usage():
"""
CLI usage printing
"""
usage = """
-h --help Print this help
-c --config Configuration file to use
--since Since when it displays findings (seconds)
"""
print(usage)
sys.exit(0)


def ConfAnalysis(ConfFile):
"""
configuration file analysis. Load global variables with parameters found
in configuration file.

:param confFile: the configuration file
"""
global CONF
global DBFile
global TABLEname

try:
CONF = ConfParser(ConfFile)
DBFile = CONF.DBFile
TABLEname = CONF.TABLEname
except Exception as err:
err = sys.exc_info()
print("ConfParser Error: "+str(err))


def parse_and_display_all_hostnames(TABLEname, conn, print_output=False):
"""
Parse and display all hostnames present in DB ""

:param TABLEname: the table name storing certificate informations in database
:param conn: db connection

:return: True if everything went fine, False if something went wrong
"""
try:
# Query rows that have not StillInvestig column already set
# get Domain and Fingerprint column
cur = conn.cursor()
cur.execute("SELECT Domain,Issuer,Fingerprint,FirstSeen,StillInvestig FROM "+TABLEname)
rows = cur.fetchall()
result = dict()

# run scan on each hostname
for row in rows:
domain = row[0]
issuer = row[1]
fingerprint = row[2]
first_seen = row[3]
still_investing = row[4]
first_seen_date = datetime.strptime(first_seen, '%Y-%m-%dT%H:%M:%S')
since = (datetime.utcnow() - first_seen_date).total_seconds()
if since < SINCE:
result.update({domain: {"issuer": issuer, "fingerprint": fingerprint, "still_investing": still_investing}})
if print_output:
print("{domain} {issuer} {fingerprint} {still_investing}".format(
domain=domain,
issuer=issuer,
fingerprint=fingerprint,
still_investing=still_investing))
return result

except KeyboardInterrupt:
if print_output:
print("Interrupt received, stopping ...")
print("start - committing, closing DB")
conn.commit
conn.close
if print_output:
print("ending - committing, closing DB")
return result

except Exception as err:
if print_output:
print(err)
return result


def main():
"""
Main function
"""
ConfAnalysis(CONFFILE)

# create a database connection
conn = create_connection(DBFile)

with conn:
print("Display all domains in DB for Internet Presence:")
print("************************************************")
parse_and_display_all_hostnames(TABLEname, conn, print_output=True)


if __name__ == '__main__':
args_parse()
main()