&1 | grep "response" | grep -c "200 OK"; do echo Sleeping 15 seconds waiting for Jenkins to start... ; sleep 15 ; done
13 |
--------------------------------------------------------------------------------
/webapp/ffate.css:
--------------------------------------------------------------------------------
1 | body {
2 | height: 100%;
3 | font-family: "Trebuchet MS", "Helvetica", "Arial", "Verdana", "sans-serif";
4 | font-size: 62.5%;
5 | }
6 |
7 | iframe[name="frame2"] {
8 | width: 95%;
9 | height: auto !important;
10 | min-height: 600;
11 | //background-color: #666699;
12 | }
13 |
14 | table, td, th {
15 | border: 2px solid green;
16 | padding: 5px;
17 | border-collapse: collapse;
18 | }
19 |
20 | th {
21 | background-color: green;
22 | color: white;
23 | }
24 |
25 | label
26 | {
27 | width: 20em;
28 | float: left;
29 | text-align: right;
30 | margin-right: 0.5em;
31 | }
32 |
33 | .submit input
34 | {
35 | margin-left: 21em;
36 | }
37 |
38 | .ui-dialog-case {
39 | -moz-border-radius: 8px 8px 8px 8px;
40 | -webkit-border-radius: 8px 8px 20px 8px;
41 | border-radius: 8px 8px 8px 8px;
42 | border-width: 8px 8px 8px 8px;
43 | }
44 |
--------------------------------------------------------------------------------
/webapp/ffate.py:
--------------------------------------------------------------------------------
1 | import web, os, hashlib
2 | import requests
3 | import threading
4 | import time
5 | import lxml.objectify
6 |
7 | urls = (
8 | '/', 'index',
9 | '/reverse', 'reverse',
10 | '/ioc','ioc',
11 | '/search', 'search',
12 | '/search_archive', 'search_archive',
13 | '/add','add',
14 | '/process', 'process',
15 | '/config', 'config',
16 | '/dash','dashboard',
17 | '/close','close',
18 | '/reopen','reopen'
19 | )
20 |
21 | db = web.database(dbn='postgres', db='webpy', user='webpy', pw='')
22 |
23 | render = web.template.render('/var/www/templates')
24 |
25 | web.template.Template.globals.update(dict(
26 | render = render,
27 | getsize = os.path.getsize,
28 | ))
29 |
30 |
31 | param_results = db.select('config',what='param_value', where='param_name = \'ELK-IP\'')
32 | for plaso_result in param_results:
33 | plaso_ip = plaso_result.param_value
34 | param_results = db.select('config',what='param_value', where='param_name = \'Plaso-dash\'')
35 | for plaso_result in param_results:
36 | plaso_dash = plaso_result.param_value
37 | plaso_url = "http://" + plaso_ip + ":9292/index.html#/dashboard/file/" + plaso_dash
38 | for572_url = "http://" + plaso_ip + ":9292/index.html#/dashboard/file/for572.json"
39 | xplico_url = "http://" + plaso_ip + ":9876/"
40 |
41 |
42 | class index:
43 | def GET(self):
44 | jenkins_url = web.ctx.homedomain + ":8080/"
45 | return render.tabbed("Forensicator FATE", jenkins_url, plaso_url)
46 |
47 |
48 | class add:
49 | def POST(self):
50 | i = web.input()
51 | n = db.insert('cases', casename=i.casename,memory_image=i.memory_image,disk_image=i.disk_image,disk_name=i.disk_name,timezone=i.timezone,volatility_profile=i.volatility_profile,notes=i.notes,case_keywords=i.case_keywords,status='open')
52 | raise web.seeother('/')
53 |
54 |
55 | class close:
56 | def POST(self):
57 | i = web.input()
58 | n = db.update('cases', where="id = " + i.CASE_ID,status='closed')
59 | raise web.seeother('/')
60 |
61 |
62 | class reopen:
63 | def POST(self):
64 | i = web.input()
65 | n = db.update('cases', where="id = " + i.CASE_ID,status='open')
66 | raise web.seeother('/')
67 |
68 |
69 | class reverse:
70 | def GET(self):
71 | name_hash = []
72 | for (dirname, dirs, files) in os.walk('/reverse'):
73 | for filename in files:
74 | thefile = os.path.join(dirname,filename)
75 | name_hash.append(tuple([thefile, hashlib.md5(open(thefile, 'r').read()).hexdigest()]))
76 |
77 | return render.re_listing(name_hash)
78 |
79 |
80 | class ioc:
81 | def GET(self):
82 | name_hash = []
83 | for (dirname, dirs, files) in os.walk('/ioc'):
84 | for filename in files:
85 | thefile = os.path.join(dirname,filename)
86 |
87 | # next 3 lines idea courtesy of Jeff Bryner http://www.jeffbryner.com/blog/itsec/pythoniocdump.html
88 | ioc_root = lxml.objectify.parse(thefile).getroot()
89 | short_desc = ioc_root.short_description
90 | desc = ioc_root.description
91 |
92 | name_hash.append(tuple([thefile, hashlib.md5(open(thefile, 'r').read()).hexdigest(), short_desc, desc]))
93 |
94 | return render.ioc_listing(name_hash)
95 |
96 |
97 | class search:
98 | def GET(self):
99 | return render.listing(db.select('cases',what='*',where="status is null or status<>'closed'",order='id',limit=10000), 'process')
100 |
101 |
102 | class search_archive:
103 | def GET(self):
104 | return render.archive_listing(db.select('cases',what='*',where="status='closed'",order='id',limit=10000))
105 |
106 |
107 | class config:
108 | def GET(self):
109 | return render.cfg_listing(db.select('config',what='*',limit=10000))
110 |
111 |
112 | class dashboard:
113 | def GET(self):
114 | jenkins_url = web.ctx.homedomain + ":8080/"
115 | return render.dash(plaso_url, jenkins_url, for572_url, xplico_url)
116 |
117 |
118 | class process:
119 | def POST(self):
120 | i = web.input()
121 | jenkins_url = web.ctx.homedomain + ":8080/"
122 | jenkins_job_url = jenkins_url + "job/findWindowsEvidence/buildWithParameters"
123 | jenkins_job_url_with_params = jenkins_job_url + "?CASE_NAME=" + i.CASE_NAME + "&MEMORY_IMAGE_FILE=" + i.MEMORY_IMAGE_FILE + "&DISK_IMAGE_FILE=" + i.DISK_IMAGE_FILE + "&DISK_NAME=" + i.DISK_NAME + "&TIMEZONE=" + i.TIMEZONE + "&VOLATILITY_PROFILE=" + i.VOLATILITY_PROFILE
124 | threading.Thread(target=requests.get, args=(jenkins_job_url_with_params,)).start()
125 | raise web.seeother('/')
126 |
127 |
128 | if __name__ == "__main__":
129 | app.run()
130 |
131 |
132 | app = web.application(urls, globals())
133 | application = app.wsgifunc()
134 |
--------------------------------------------------------------------------------
/webapp/templates/archive_li.html:
--------------------------------------------------------------------------------
1 | $def with (case)
2 |
3 |
4 |
5 | $case.id $case.casename $case.memory_image $case.disk_image $case.disk_name $case.timezone $case.volatility_profile $case.notes $case.case_keywords
6 |
7 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/webapp/templates/archive_listing.html:
--------------------------------------------------------------------------------
1 | $def with (cases)
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | $if cases:
10 |
11 | id casename memory image disk image disk name timezone volatility_profile notes keywords
12 |
13 | $for case in cases:
14 | $:render.archive_li(case)
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/webapp/templates/cfg_li.html:
--------------------------------------------------------------------------------
1 | $def with (config_var)
2 |
3 |
4 |
5 | $config_var.param_name $config_var.param_value
6 |
7 |
--------------------------------------------------------------------------------
/webapp/templates/cfg_listing.html:
--------------------------------------------------------------------------------
1 | $def with (config_vars)
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | $if config_vars:
10 |
11 | Parameter Name Parameter Value
12 |
13 | $for config_var in config_vars:
14 | $:render.cfg_li(config_var)
15 |
16 |
17 |
--------------------------------------------------------------------------------
/webapp/templates/dash.html:
--------------------------------------------------------------------------------
1 | $def with (plaso_url, jenkins_url, for572_url, xplico_url)
2 |
3 | The following dashboards are available (and will open in a new browser tab/window):
4 |
11 |
--------------------------------------------------------------------------------
/webapp/templates/ioc_li.html:
--------------------------------------------------------------------------------
1 | $def with (file, hash, short_desc, desc)
2 |
3 |
4 |
5 | $file $getsize(file) $hash $short_desc
6 |
7 |
8 |
--------------------------------------------------------------------------------
/webapp/templates/ioc_listing.html:
--------------------------------------------------------------------------------
1 | $def with (walk)
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | $if walk:
10 |
11 | IOC Size Hash Description
12 |
13 | $for (file, hash, short_desc, desc) in walk:
14 | $:render.ioc_li(file, hash, short_desc, desc)
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/webapp/templates/li.html:
--------------------------------------------------------------------------------
1 | $def with (case, jenkins_job_url)
2 |
3 |
4 |
5 | $case.id $case.casename $case.memory_image $case.disk_image $case.disk_name $case.timezone $case.volatility_profile $case.notes $case.case_keywords
6 |
7 |
16 |
17 |
18 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/webapp/templates/listing.html:
--------------------------------------------------------------------------------
1 | $def with (cases, jenkins_job_url)
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
113 |
114 |
115 |
116 | $if cases:
117 |
118 | id casename memory image disk image disk name timezone volatility_profile notes keywords
119 |
120 | $for case in cases:
121 | $:render.li(case,jenkins_job_url)
122 |
123 |
124 |
125 |
154 | Create new case
155 |
156 |
157 |
--------------------------------------------------------------------------------
/webapp/templates/re_li.html:
--------------------------------------------------------------------------------
1 | $def with (file, hash)
2 |
3 |
4 |
5 | $file $getsize(file) $hash
6 |
7 |
8 |
--------------------------------------------------------------------------------
/webapp/templates/re_listing.html:
--------------------------------------------------------------------------------
1 | $def with (walk)
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | $if walk:
10 |
11 | Name Size Hash
12 |
13 | $for (file, hash) in walk:
14 | $:render.re_li(file, hash)
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/webapp/templates/tabbed.html:
--------------------------------------------------------------------------------
1 | $def with (title, jenkins_url, plaso_url)
2 |
3 |
4 |
5 |
6 |
7 | $if title: $title
8 |
9 |
10 |
11 |
12 |
13 |
14 |
28 |
29 |
30 |
31 |
32 |
50 |
51 | Plaso dash Tasks Issues
52 |
53 |
54 |
--------------------------------------------------------------------------------