Skip to content

Commit

Permalink
Merge pull request #16 from Santandersecurityresearch/pcap
Browse files Browse the repository at this point in the history
PCAP Parsing support
  • Loading branch information
danielcuthbert authored Sep 19, 2024
2 parents a956422 + 13f30e4 commit 5f7426c
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 6 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,16 @@ Where `<iface>` should be replaced with the network interface to be monitored (`

If you have installed `cryptomon` as a service, then you do not need to run the first line. To check the monitor is working you can run `db.cryptomon.count({})` from `mongosh` to see if the record count is increasing.

## PCAP Files

To parse a pcap file `test.pcap`, simply run:

```bash
./parse-pcap.sh test.pcap
```

So long as your data environment variables are all set, then this will parse the PCAP data and replay it over the loopback `lo` interface, allowing cryptomon to parse it.

## FastAPI

To access the FastAPI documentation go to `http://0.0.0.0:8000/docs` to find the documentation for the backend API.
Expand Down
30 changes: 28 additions & 2 deletions cryptomon.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,19 @@

__author__ = "Mark Carney"
__copyright__ = "Copyright 2024, Mark Carney"
__credits__ = ["Mark Carney"]
__credits__ = ["Mark Carney", "Daniel Cuthbert"]
__license__ = "GLP 3.0"
__version__ = "1.0.0"
__maintainer__ = "Mark Carney"
__email__ = "mark.carney@gruposantander.com"
__status__ = "Demonstration"
__status__ = "MVP"

import asyncio
import argparse
import psutil
import sys
from fapi.config import settings
from scapy.all import rdpcap, sendp

from cryptomon import CryptoMon

Expand All @@ -34,6 +36,8 @@ def parse_argz():
parser = argparse.ArgumentParser()
parser.add_argument("-i", "--interface",
help="Interface to hook with eBPF module.")
parser.add_argument("--pcap",
help="PCAP file to be replayed on loopback.")
args = parser.parse_args()

if not args.interface:
Expand All @@ -44,15 +48,37 @@ def parse_argz():
choice = int(input("Select an interface by number: ")) - 1
args.interface = interfaces[choice]

if args.pcap:
print("[i] Setting interface to loopback (lo) to parse PCAPs...")
args.interface = "lo"
return args


def rerun_pcap(pcap_file):
packets = rdpcap(pcap_file)
iface = "lo"
print(f"[i] Replaying packets from {str(pcap_file)}...")
ctr = 0
for packet in packets:
if ctr % 10 == 0:
print(f"[{int(100*ctr/len(packets))}%] {ctr} of {len(packets)}", end='\r')
try:
sendp(packet, iface=iface, verbose=False)
except Exception as e:
print(f"Error happened when sending packet...: {str(e)}")
ctr += 1
sys.exit(0)

if __name__ == "__main__":
task_list = []
args = parse_argz()
if args.pcap:
rerun_pcap(args.pcap)
sys.exit(0)
cm = CryptoMon(iface=args.interface,
mongodb=True,
settings=settings,
pcap_file=args.pcap,
data_tag="")
loop = asyncio.get_event_loop()
loop.create_task(cm.run_async())
Expand Down
4 changes: 2 additions & 2 deletions cryptomon/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
class CryptoMon(object):
def __init__(self, iface="enp0s1", fapiapp: FastAPI = "",
mongodb=False, settings="",
bpf_code=bpf_ipv4_txt,
bpf_code=bpf_ipv4_txt, pcap_file="",
data_tag=""):
if not settings:
raise Exception("No settings provided... Aborting.")
Expand Down Expand Up @@ -84,7 +84,7 @@ def handle_data(self, data_object):
data_object['ts'] = dt.datetime.now().timestamp()
if self.fapi_on:
self.fapi_app.mongodb["cryptomon"].insert_one(data_object)
elif self.mongodb:
elif self.mongodb is not None:
self.mongodb["cryptomon"].insert_one(data_object)
else:
self.tinydb.insert(data_object)
Expand Down
2 changes: 1 addition & 1 deletion fapi/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ class DatabaseSettings(BaseSettings):
class Settings(CommonSettings, ServerSettings, DatabaseSettings):
pass

settings = Settings()
settings = Settings()
7 changes: 7 additions & 0 deletions parse-pcap.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#! /bin/bash

trap 'kill $(jobs -p) 2>/dev/null' EXIT

python3 ./cryptomon.py -i lo &
python3 ./cryptomon.py --pcap $1 -i lo
exit
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ pydantic==2.8.2
tinydb==4.8.0
uvicorn==0.30.0
psutil==6.0.0
pydantic_settings=2.4.0
pydantic_settings==2.4.0
scapy==2.5.0

0 comments on commit 5f7426c

Please sign in to comment.