Skip to content

Commit

Permalink
Merge pull request #24 from Srinivas11789/develop
Browse files Browse the repository at this point in the history
PcapXray 2.0
  • Loading branch information
Srinivas11789 authored Jan 17, 2019
2 parents f386c1b + 3a77ec6 commit cbb1a7c
Show file tree
Hide file tree
Showing 14 changed files with 275 additions and 27 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.pyc
.DS_Store
*.icloud
10 changes: 8 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,19 @@ python:
matrix:
allow_failures:
- python: "3.6"
before_install:
- pip install -U pytest pytest-cov
- pip install codecov
- pip install flake8
install:
- pip install -r requirements.txt
- pip install flake8
before_script:
# stop the build if there are Python syntax errors or undefined names
- flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
- flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
script:
- pytest
- pytest --cov=./

after_success:
- codecov
35 changes: 35 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# PcapXray Project Dockerfile - https://github.com/Srinivas11789/PcapXray

# Latest ubuntu base image
FROM ubuntu:latest

# Maintainer
MAINTAINER Srinivas Piskala Ganesh Babu "spg349@nyu.edu"

# Apt update and install - nginx and git
RUN apt-get update
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get install -y graphviz
RUN apt-get install -y python-tk
RUN apt-get install -y python-pip
RUN apt-get install -y nginx
RUN apt-get install -y git-core
RUN apt-get install -y sudo
RUN apt-get install -y libx11-dev

# Fetching the latest source code from the github repo of devOps
RUN git clone https://github.com/srinivas11789/PcapXray

### Master branch changes - srinivas11789/pcapxray
RUN pip install -r PcapXray/requirements.txt

WORKDIR PcapXray/Source
CMD python main.py

### Develop/Beta branch changes - srinivas11789/pcapxray-beta
#WORKDIR PcapXray
#RUN git checkout develop
#RUN pip install -r requirements.txt
#WORKDIR Source
#CMD python main.py

32 changes: 26 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# PcapXray [![Build Status](https://travis-ci.org/Srinivas11789/PcapXray.svg?branch=master)](https://travis-ci.org/Srinivas11789/PcapXray)
# PcapXray [![Build Status](https://travis-ci.org/Srinivas11789/PcapXray.svg?branch=master)](https://travis-ci.org/Srinivas11789/PcapXray) [![codecov](https://codecov.io/gh/Srinivas11789/PcapXray/branch/master/graph/badge.svg)](https://codecov.io/gh/Srinivas11789/PcapXray)
A Network Forensics Tool - To visualize a Packet Capture offline as a Network Diagram including device identification, highlight important communication and file extraction
![Alt text](/logo.png?width=20px "PcapXray")
## PcapXray Design Specification
Expand All @@ -24,9 +24,9 @@ Tool Highlights:
* Device Details

### Tool Image:
![Alt text](/Samples/screen1.png?raw=true)
![Alt text](/Samples/screen1_2_1.png?raw=true)

![Alt text](/Samples/screen2.png?raw=true)
![Alt text](/Samples/screen2_2_1.png?raw=true)

### Components:
* Network Diagram
Expand All @@ -50,7 +50,7 @@ Tool Highlights:
* Matplotlib – plot graph

### Demo
![Alt text](/Samples/demo.gif?raw=true)
![Alt text](/Samples/demo2_2.gif?raw=true)

### Getting started:
* Clone the repository
Expand Down Expand Up @@ -83,11 +83,31 @@ Tool Highlights:

* Current Fix in rare occasions: If any of the above issue occurs the progress bar keeps running and no output is generated, a restart of the app would be required.

### PcapXray 2.0
* Includes zoom feature
* Improves usability with a Browse files feature
* Report directory fixes for graph images
* Includes some bug fixes

### Docker Containers of PcapXray
* Dockerfile present in the root folder was used to build images
* Already built docker images are found at dockerhub
- srinivas11789/pcapxray-1.0
- srinivas11789/pcapxray-2.2
* Performing the steps in `run.sh` file manually would work to launch the tool via docker (I can help with errors)
* Running `run.sh` scripts is an attempt to automate (would not work 100 percent)
- tested on mac and linux - will be better soon!...

### Immediate Future Tasks:
* Clean up code - beautify code base from being a prototype
* Report generation on unique folders for all assets of a packet capture

### Future:
* Structured and clean code flow
* Structured and clean code flow
* Change the database from JSON to sqlite or prominent database, due to memory hogging
* Change fronend to web based such as Django
* Make the application more stable
* More protocol support
* More protocol support
* Clean up code

[![Analytics](https://ga-beacon.appspot.com/UA-114681129-1/PcapXray/readme)](https://github.com/igrigorik/ga-beacon)
Binary file added Samples/demo2_2.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Samples/options2_0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Samples/screen1_2_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Samples/screen2_2_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Source/Module/assets/logo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
78 changes: 62 additions & 16 deletions Source/Module/userInterface.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from Tkinter import *
import Tkinter, Tkconstants, tkFileDialog
import ttk
import tkMessageBox
import pcapReader
Expand All @@ -9,7 +10,7 @@
import threading
import Queue
from PIL import Image,ImageTk
import os
import os, sys

class pcapXrayGui:
def __init__(self, base):
Expand All @@ -31,22 +32,30 @@ def __init__(self, base):

# Pcap File Entry
self.pcap_file = StringVar()
self.filename = ""
ttk.Label(InitFrame, text="Enter pcap file path: ",style="BW.TLabel").grid(column=0, row=0, sticky="W")
ttk.Entry(InitFrame, width=30, textvariable=self.pcap_file, style="BW.TEntry").grid(column=1, row=0, sticky="W, E")
self.filename_field = ttk.Entry(InitFrame, width=30, textvariable=self.pcap_file, style="BW.TEntry").grid(column=1, row=0, sticky="W, E")
self.progressbar = ttk.Progressbar(InitFrame, orient="horizontal", length=200,value=0, maximum=200, mode="indeterminate")
ttk.Button(InitFrame, text="Analyze!", command=self.pcap_analyse).grid(column=2, row=0, padx=10, pady=10,sticky="E")
self.progressbar.grid(column=3, row=0, padx=10, pady=10, sticky="E")
# Browse button
#self.filename = StringVar()
ttk.Button(InitFrame, text="Browse", command=self.browse_directory).grid(column=2, row=0, padx=10, pady=10,sticky="E")
ttk.Button(InitFrame, text="Analyze!", command=self.pcap_analyse).grid(column=3, row=0, padx=10, pady=10,sticky="E")
self.progressbar.grid(column=4, row=0, padx=10, pady=10, sticky="E")

# Second Frame with Options
SecondFrame = ttk.Frame(base, width=50, padding="10 10 10 10",relief= GROOVE)
SecondFrame.grid(column=10, row=20, sticky=(N, W, E, S))
SecondFrame.columnconfigure(10, weight=1)
SecondFrame.rowconfigure(10, weight=1)
ttk.Label(SecondFrame, text="Options: ", style="BW.TLabel").grid(column=0, row=10, sticky="W")
ttk.Label(SecondFrame, text="Options: ", style="BW.TLabel").grid(row=10,column=0,sticky="W")
self.option = StringVar()
self.options = {'All','HTTP','HTTPS','Tor','Malicious'}
#self.option.set('Tor')
ttk.OptionMenu(SecondFrame,self.option,"Select",*self.options).grid(column=1, row=10,sticky="W, E")
ttk.OptionMenu(SecondFrame,self.option,"Select",*self.options).grid(row=10,column=1,sticky="W")
self.zoom = [900,900]
self.img = ""
ttk.Button(SecondFrame, text="zoomIn", command=self.zoom_in).grid(row=10,column=10,padx=5,sticky="E")
ttk.Button(SecondFrame, text="zoomOut", command=self.zoom_out).grid(row=10,column=11,sticky="E")

# Third Frame with Results and Descriptioms
self.ThirdFrame = ttk.Frame(base, width=100, height=100, padding="10 10 10 10",relief= GROOVE)
Expand All @@ -64,6 +73,18 @@ def __init__(self, base):
self.ThirdFrame.rowconfigure(0, weight=1)
self.name_servers = ""

def browse_directory(self):
# Reference: http://effbot.org/tkinterbook/tkinter-dialog-windows.htm
self.pcap_file.set(tkFileDialog.askopenfilename(initialdir = sys.path[0],title = "Select Packet Capture File!",filetypes = (("pcap files","*.pcap"),("pcapng files","*.pcapng"))))
self.filename = self.pcap_file.get().replace(".pcap","")
if "/" in self.filename:
self.filename = self.filename.split("/")[-1]
#,("all files","*.*")
#self.filename_field.delete(0, END)
#self.filename_field.insert(0, self.pcap_file)
print self.filename
print self.pcap_file

def pcap_analyse(self):
if os.path.exists(self.pcap_file.get()):
self.progressbar.start()
Expand Down Expand Up @@ -99,31 +120,56 @@ def generate_graph(self):
reportThread = threading.Thread(target=reportGen.reportGen().communicationDetailsReport,args=(self.name_servers,))
reportThread.start()

if not os.path.exists("Report/"+self.pcap_file.get().replace(".pcap","")+self.option.get()+".png"):
t1 = threading.Thread(target=plotLanNetwork.plotLan, args=(self.capture_read, self.pcap_file.get().replace(".pcap",""),self.name_servers,self.option.get(),))
if not os.path.exists("Report/"+self.filename+self.option.get()+".png"):
t1 = threading.Thread(target=plotLanNetwork.plotLan, args=(self.capture_read, self.filename, self.name_servers, self.option.get(),))
t1.start()
self.progressbar.start()
while t1.is_alive():
self.progressbar.update()
t1.join()
self.progressbar.stop()
self.label.grid_forget()
self.load_image()
else:
self.label.grid_forget()
self.load_image()

self.label.grid_forget()
canvas = Canvas(self.ThirdFrame, width=700,height=600, bd=0, bg="navy", xscrollcommand=self.xscrollbar.set, yscrollcommand=self.yscrollbar.set)
canvas.grid(row=0, column=0, sticky=N + S + E + W)
self.img = ImageTk.PhotoImage(Image.open("Report/"+self.pcap_file.get().replace(".pcap","")+self.option.get()+".png").resize((900,900),Image.ANTIALIAS).convert('RGB'))
canvas.create_image(0,0, image=self.img)
canvas.config(scrollregion=canvas.bbox(ALL))
self.xscrollbar.config(command=canvas.xview)
self.yscrollbar.config(command=canvas.yview)

def load_image(self):
self.canvas = Canvas(self.ThirdFrame, width=700,height=600, bd=0, bg="navy", xscrollcommand=self.xscrollbar.set, yscrollcommand=self.yscrollbar.set)
self.canvas.grid(row=0, column=0, sticky=N + S + E + W)
self.img = ImageTk.PhotoImage(Image.open("Report/"+self.filename+self.option.get()+".png").resize(tuple(self.zoom),Image.ANTIALIAS).convert('RGB'))
self.canvas.create_image(0,0, image=self.img)
self.canvas.config(scrollregion=self.canvas.bbox(ALL))
self.xscrollbar.config(command=self.canvas.xview)
self.yscrollbar.config(command=self.canvas.yview)

def map_select(self, *args):
print self.option.get()
self.generate_graph()

def zoom_in(self):
print "zoomin"
self.zoom[0] += 100
self.zoom[1] += 100
if self.img:
self.load_image()

def zoom_out(self):
print "zoomout"
if self.zoom[0] > 700 and self.zoom[1] > 700:
self.zoom[0] -= 100
self.zoom[1] -= 100
else:
print "zoomout --> maximum"
if self.img:
self.load_image()


def main():
base = Tk()
pcapXrayGui(base)
base.mainloop()

#main()

10 changes: 8 additions & 2 deletions Source/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
import ttk

# Import Custom Modules - Self created by the author
sys.path.insert(0, 'Module/')
if sys.path[0]:
sys.path.insert(0,sys.path[0]+'/Module/')
else:
sys.path.insert(0, 'Module/')
import userInterface

# Import 3rd party Libraries -- Needed to be installed using pip
Expand All @@ -17,7 +20,10 @@

def main():
base = Tk()
logo_file = os.path.join(os.path.dirname(__file__), 'Module/assets/logo.gif')
icon = PhotoImage(file=logo_file)
base.tk.call('wm','iconphoto',base._w,icon)
userInterface.pcapXrayGui(base)
base.mainloop()

main()
main()
3 changes: 2 additions & 1 deletion Test/test_pcap_reader_module.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Initial Basic Test - Assure proper pcap reading of the example/test.pcap file
# Separate Module Tests - Assure proper pcap reading of the example/test.pcap file
# Pending work....
import sys
print sys.path[0]
if sys.path[0]:
Expand Down
80 changes: 80 additions & 0 deletions Test/test_sanity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Sanity or Smoke Test - Test proper functionality of the module

# Test System Setup
import sys
import os

if sys.path[0]:
sys.path.insert(0, sys.path[0]+'/../Source/Module/')
else:
sys.path.insert(0,'/../Source/Module/')

# All the Module imports

# Report generation module
import reportGen
# 1 - pcapReader Module
import pcapReader
# 2 - communicationDetailsFetch module
import communicationDetailsFetch
# 3 - deviceDetailsFetch module
import deviceDetailsFetch
# 4 - maliciousTrafficIdentifier module
import maliciousTrafficIdentifier
# 5 - plotLanNetwork module
#import plotLanNetwork
# 7 - userInterface module
#import userInterface
# 8 - torTrafficHandle module
import torTrafficHandle

# End to end Workflow Tests - All tests will be applied to example/test.pcap file

def test_pcapreader():
pcapfile = pcapReader.pcapReader(sys.path[0]+'examples/test.pcap')
if pcapfile.packetDB:
assert True

def test_communication_details_fetch():
capture = pcapReader.pcapReader(sys.path[0]+'examples/test.pcap')
details = communicationDetailsFetch.trafficDetailsFetch(capture.packetDB)
if details.communication_details:
assert True

def test_device_details_fetch():
pcapfile = pcapReader.pcapReader(sys.path[0]+'examples/test.pcap')
for ip in pcapfile.packetDB:
macObj = deviceDetailsFetch.fetchDeviceDetails(pcapfile.packetDB[ip])
if macObj.oui_identification():
assert True

def test_malicious_traffic_identifier():
malicious_capture = pcapReader.pcapReader(sys.path[0]+'examples/test.pcap')
dns_details = {}
mal_identify = maliciousTrafficIdentifier.maliciousTrafficIdentifier(malicious_capture.packetDB, dns_details)
if mal_identify.possible_malicious_traffic:
assert True

#def test_plot_lan_network():
# pcapfile = pcapReader.pcapReader(sys.path[0]+'examples/test.pcap')
# details = communicationDetailsFetch.trafficDetailsFetch(pcapfile.packetDB)
# plotLanNetwork.plotLan(pcapfile.packetDB, "network12345", details.communication_details,"HTTPS")
# if os.path.isfile(sys.path[1]+"/../Report/network12345"):
# assert True

def test_report_gen():
pcapfile = pcapReader.pcapReader(sys.path[0]+'examples/test.pcap')
if pcapfile.packetDB:
reportGen.reportGen().packetDetails(pcapfile.packetDB)
if os.path.isfile(sys.path[1]+"/../Report/communicationDetailsReport.txt") and os.path.isfile(sys.path[1]+"/../Report/deviceDetailsReport.txt") and os.path.isfile(sys.path[1]+"/../Report/packetDetailsReport.txt"):
assert True

# 7 - userInterface module
# Manual Test for now - Sikuli type automation to be implemented soon
# * Look at Travis Integrations for GUI Test

def test_tor_traffic_handle():
tor_capture = pcapReader.pcapReader(sys.path[0]+'examples/test.pcap')
tor_identify = torTrafficHandle.torTrafficHandle(tor_capture.packetDB)
if tor_identify:
assert True
Loading

0 comments on commit cbb1a7c

Please sign in to comment.