mirror of https://github.com/MISP/misp-training
added restsearch module dev
parent
3fb00c9182
commit
6a813428a6
|
@ -0,0 +1,426 @@
|
||||||
|
% DO NOT COMPILE THIS FILE DIRECTLY!
|
||||||
|
% This is included by the other .tex files.
|
||||||
|
|
||||||
|
\begin{frame}
|
||||||
|
\titlepage
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}
|
||||||
|
\frametitle{Building a native restSearch export}
|
||||||
|
\begin{itemize}
|
||||||
|
\item Similar in scope to an export module via MISP modules
|
||||||
|
\item Pros:
|
||||||
|
\begin{itemize}
|
||||||
|
\item Can be used for composited data coming from a search
|
||||||
|
\item Fast, native approach
|
||||||
|
\item Can be built to support several scopes (events, attributes, sightings)
|
||||||
|
\end{itemize}
|
||||||
|
\item Cons...
|
||||||
|
\end{itemize}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}
|
||||||
|
\frametitle{Building a native restSearch export}
|
||||||
|
\begin{itemize}
|
||||||
|
\item Similar in scope to an export module via MISP modules
|
||||||
|
\item Pros:
|
||||||
|
\begin{itemize}
|
||||||
|
\item Can be used for composited data coming from a search
|
||||||
|
\item Fast, native approach
|
||||||
|
\item Can be built to support several scopes (events, attributes, sightings)
|
||||||
|
\end{itemize}
|
||||||
|
\item Cons...
|
||||||
|
\end{itemize}
|
||||||
|
\begin{center}
|
||||||
|
\includegraphics[scale=0.5]{lolphp.jpg}
|
||||||
|
\end{center}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}
|
||||||
|
\frametitle{So how does restSearch work?}
|
||||||
|
\begin{itemize}
|
||||||
|
\item Standardised way of collecting parameters
|
||||||
|
\item Using the parameters, a loop is started to chunk and gradually build our export data
|
||||||
|
\item The chunk size depends on memory envelopes
|
||||||
|
\item Each chunk is converted piece by piece...
|
||||||
|
\item ... and subsequently are concatenated into a temporary file
|
||||||
|
\item Once no more elements are left, the file is sent in the response
|
||||||
|
\end{itemize}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}
|
||||||
|
\frametitle{Where does the module system come into play?}
|
||||||
|
\begin{itemize}
|
||||||
|
\item The export modules handle 5 tasks:
|
||||||
|
\begin{itemize}
|
||||||
|
\item Pass meta-information back to restSearch on the export format itself
|
||||||
|
\item Add a start section to the exported data
|
||||||
|
\item Do the actual conversion from MISP's internal format to the desired export format
|
||||||
|
\item Provide a separator for data chunks
|
||||||
|
\item Have a closing segment for the returned data, based on the format\'s conventions
|
||||||
|
\end{itemize}
|
||||||
|
\end{itemize}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}
|
||||||
|
\frametitle{Our little training module: Nibbler, the ever hungry IDS/IPS}
|
||||||
|
\begin{center}
|
||||||
|
\includegraphics[scale=0.5]{nibbler.jpg}
|
||||||
|
\end{center}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}
|
||||||
|
\frametitle{Nibbler}
|
||||||
|
\begin{itemize}
|
||||||
|
\item Simplistic tool with its own proprietary format
|
||||||
|
\item Meant to mimic a typical in-house tool
|
||||||
|
\item Lightweight scope, for simplicity\'s sake
|
||||||
|
\end{itemize}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}
|
||||||
|
\frametitle{Nibbler format}
|
||||||
|
\begin{itemize}
|
||||||
|
\item Format
|
||||||
|
\item Meant to mimic a typical in-house tool
|
||||||
|
\item Lightweight scope, for simplicity\'s sake
|
||||||
|
\item pipe separated values
|
||||||
|
\item VALUE | TYPE | DESCRIPTION | REFERENCE | ACTION
|
||||||
|
\end{itemize}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}
|
||||||
|
\frametitle{Nibbler format - caveats}
|
||||||
|
\begin{itemize}
|
||||||
|
\item Rules can be prepended by comments, each comment line starting with \#
|
||||||
|
\item Some characters have to be escaped in some custom, crazy ways
|
||||||
|
\begin{itemize}
|
||||||
|
\item linebreaks: \#\#LINEBREAK\#\#
|
||||||
|
\item commas: \#\#COMMA\#\#
|
||||||
|
\item pipes: \#\#PIPE\#\#
|
||||||
|
\end{itemize}
|
||||||
|
\end{itemize}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}
|
||||||
|
\frametitle{Nibbler format}
|
||||||
|
\begin{itemize}
|
||||||
|
\item Value: The actual indicator value
|
||||||
|
\item Type: The format of the indicator
|
||||||
|
\item Description: A quick description for analysts investigating the alert, why is this relevant
|
||||||
|
\item Reference: A backreference that the analyst can use to find out more about the alert
|
||||||
|
\item Action: What should Nibbler do if it trips over the value?
|
||||||
|
\end{itemize}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}
|
||||||
|
\frametitle{Supported types}
|
||||||
|
\begin{itemize}
|
||||||
|
\item IP
|
||||||
|
\item Domain
|
||||||
|
\item Hostname
|
||||||
|
\item MD5
|
||||||
|
\item SHA1
|
||||||
|
\item SHA256
|
||||||
|
\item Filename
|
||||||
|
\end{itemize}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}
|
||||||
|
\frametitle{Supported values}
|
||||||
|
\begin{itemize}
|
||||||
|
\item ALERT - default behaviour, create an alert.
|
||||||
|
\item BLOCK - block the action outright. Only set if the tag nibbler:block is present
|
||||||
|
\end{itemize}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}
|
||||||
|
\frametitle{Mapping the types to MISP}
|
||||||
|
\begin{itemize}
|
||||||
|
\item Though we have types to map from MISP, in some cases several types map to a Nibbler type
|
||||||
|
\item We've created a rough mapping (this is probably the most difficult task) in advance
|
||||||
|
\item Some MISP types map to a Nibbler type directly
|
||||||
|
\item Composite MISP types map to 2 Nibbler types each
|
||||||
|
\end{itemize}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}
|
||||||
|
\frametitle{Mapping the types to MISP}
|
||||||
|
\begin{itemize}
|
||||||
|
\item ip-dst :: IP
|
||||||
|
\item ip-src :: IP
|
||||||
|
\item domain :: Domain
|
||||||
|
\item domain|ip :: Domain, IP
|
||||||
|
\item hostname :: Hostname
|
||||||
|
\item md5 :: MD5
|
||||||
|
\item sha1 :: SHA1
|
||||||
|
\item sha256 :: SHA256
|
||||||
|
\item filename|md5 :: Filename, MD5
|
||||||
|
\item malware-sample :: Filename, MD5
|
||||||
|
\item filename|sha1 :: Filename, SHA1
|
||||||
|
\item filename|sha256 :: Filename, SHA256
|
||||||
|
\end{itemize}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
\frametitle{Export module skeleton}
|
||||||
|
\begin{lstlisting}
|
||||||
|
<?php
|
||||||
|
class NibblerExport
|
||||||
|
{
|
||||||
|
public $additional_params = array();
|
||||||
|
public function handler(
|
||||||
|
$data, $options = array()
|
||||||
|
) {}
|
||||||
|
public function header(
|
||||||
|
$options = array()
|
||||||
|
) {}
|
||||||
|
public function footer() {}
|
||||||
|
public function separator() {}
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
\frametitle{Additional parameters}
|
||||||
|
\begin{lstlisting}
|
||||||
|
public $additional_params = array(
|
||||||
|
'flatten' => 1
|
||||||
|
);
|
||||||
|
\end{lstlisting}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
\frametitle{Adding our mapping}
|
||||||
|
\begin{lstlisting}
|
||||||
|
private $__mapping = array(
|
||||||
|
'ip-dst' => 'IP',
|
||||||
|
'ip-src' => 'IP',
|
||||||
|
'domain' => 'Domain',
|
||||||
|
'domain|ip' => ['Domain', 'IP'],
|
||||||
|
'hostname' => 'Hostname',
|
||||||
|
'md5' => 'MD5',
|
||||||
|
'sha1' => 'SHA1',
|
||||||
|
'sha256' => 'SHA256',
|
||||||
|
'filename|md5' => array('Filename', 'MD5'),
|
||||||
|
'malware-sample' => array('Filename', 'MD5'),
|
||||||
|
'filename|sha1' => array('Filename', 'SHA1'),
|
||||||
|
'filename|sha256' => array('Filename', 'SHA256')
|
||||||
|
);
|
||||||
|
\end{lstlisting}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
\frametitle{Writing the start of the output}
|
||||||
|
\begin{lstlisting}
|
||||||
|
public function header($options = array())
|
||||||
|
{
|
||||||
|
return sprintf(
|
||||||
|
"# Nibbler rules generated by MISP at %s\n",
|
||||||
|
date('Y-m-d H:i:s')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
\frametitle{Footer function - how should the output end?}
|
||||||
|
\begin{lstlisting}
|
||||||
|
public function footer()
|
||||||
|
{
|
||||||
|
return "\n";
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
\frametitle{What separates the chunks?}
|
||||||
|
\begin{lstlisting}
|
||||||
|
public function separator()
|
||||||
|
{
|
||||||
|
return "\n";
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
\frametitle{The actual legwork, the handler}
|
||||||
|
\begin{lstlisting}[
|
||||||
|
basicstyle=\tiny
|
||||||
|
]
|
||||||
|
public function handler($data, $options = array())
|
||||||
|
{
|
||||||
|
if ($options['scope'] === 'Attribute') {
|
||||||
|
$data['Attribute']['AttributeTag'] = $data['AttributeTag'];
|
||||||
|
return $this->__convertAttribute($data['Attribute'], $data['Event']);
|
||||||
|
}
|
||||||
|
if ($options['scope'] === 'Event') {
|
||||||
|
$result = array();
|
||||||
|
foreach ($data['Attribute'] as $attribute) {
|
||||||
|
$temp = $this->__convertAttribute($attribute, $data['Event']);
|
||||||
|
if ($temp) $result[] = $temp;
|
||||||
|
}
|
||||||
|
return implode($this->separator(), $result);
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
\frametitle{Building an optional internal converter function}
|
||||||
|
\begin{lstlisting}
|
||||||
|
private function __convertAttribute($attribute, $event)
|
||||||
|
{
|
||||||
|
if (empty($this->__mapping[$attribute['type']])) {
|
||||||
|
// mapping not found - invalid type for nibbler
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
if (is_array($this->__mapping[$attribute['type']])) {
|
||||||
|
// handle mappings for composites - slide
|
||||||
|
} else {
|
||||||
|
// handle simple mappings - slide
|
||||||
|
}
|
||||||
|
// return 1 or 2 lines, separated by separator()
|
||||||
|
return implode($this->separator(), $result);
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
\frametitle{Handling the simple case}
|
||||||
|
\begin{lstlisting}
|
||||||
|
$result[] = sprintf(
|
||||||
|
'%s|%s|%s|%s|%s',
|
||||||
|
$this->__escapeSpecialChars($attribute['value']),
|
||||||
|
$this->__mapping[$attribute['type']],
|
||||||
|
$event['uuid'],
|
||||||
|
$this->__escapeSpecialChars($event['info']),
|
||||||
|
'ALERT'
|
||||||
|
);
|
||||||
|
\end{lstlisting}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
\frametitle{Handling the case for composites}
|
||||||
|
\begin{lstlisting}
|
||||||
|
$attribute['value'] = explode(
|
||||||
|
'|', $attribute['value']
|
||||||
|
);
|
||||||
|
foreach (array(0,1) as $part) {
|
||||||
|
$result[] = sprintf(
|
||||||
|
'%s|%s|%s|%s|%s',
|
||||||
|
$this->__escapeSpecialChars(
|
||||||
|
$attribute['value'][$part]
|
||||||
|
),
|
||||||
|
$this->__mapping[$attribute['type']][$part],
|
||||||
|
$event['uuid'],
|
||||||
|
$this->__escapeSpecialChars($event['info']),
|
||||||
|
'ALERT'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
\frametitle{Putting it together}
|
||||||
|
\begin{lstlisting}[
|
||||||
|
basicstyle=\tiny
|
||||||
|
]
|
||||||
|
private function __convertAttribute($attribute, $event) {
|
||||||
|
if (empty($this->__mapping[$attribute['type']])) return '';
|
||||||
|
$result = array();
|
||||||
|
$attributes = array();
|
||||||
|
if (is_array($this->__mapping[$attribute['type']])) {
|
||||||
|
$attribute['value'] = explode('|', $attribute['value']);
|
||||||
|
foreach (array(0,1) as $part) {
|
||||||
|
$result[] = sprintf(
|
||||||
|
'%s|%s|%s|%s|%s',
|
||||||
|
$this->__escapeSpecialChars($attribute['value'][$part]),
|
||||||
|
$this->__mapping[$attribute['type']][$part],
|
||||||
|
$event['uuid'],
|
||||||
|
$this->__escapeSpecialChars($event['info']),
|
||||||
|
$this->__decideOnAction($attribute['AttributeTag'])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$result[] = sprintf(
|
||||||
|
'%s|%s|%s|%s|%s',
|
||||||
|
$this->__escapeSpecialChars($attribute['value']),
|
||||||
|
$this->__mapping[$attribute['type']],
|
||||||
|
$event['uuid'],
|
||||||
|
$this->__escapeSpecialChars($event['info']),
|
||||||
|
$this->__decideOnAction($attribute['AttributeTag'])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return implode($this->separator(), $result);
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
\frametitle{Adding the function that decides on the action}
|
||||||
|
\begin{lstlisting}
|
||||||
|
private function __decideOnAction($attributeTags)
|
||||||
|
{
|
||||||
|
foreach($attributeTags as $attributeTag) {
|
||||||
|
if (
|
||||||
|
$attributeTag['Tag']['name'] ===
|
||||||
|
'nibbler:block'
|
||||||
|
) {
|
||||||
|
return 'BLOCK';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 'ALERT';
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
\frametitle{Finalising the export module... The escaping function}
|
||||||
|
\begin{lstlisting}
|
||||||
|
private function __escapeSpecialChars($value)
|
||||||
|
{
|
||||||
|
$value = preg_replace(
|
||||||
|
"/\r|\n/", "##LINEBREAK##", $value
|
||||||
|
);
|
||||||
|
$value = preg_replace(
|
||||||
|
"/,/", "##COMMA##", $value
|
||||||
|
);
|
||||||
|
$value = preg_replace(
|
||||||
|
"/\|/", "##PIPE##", $value
|
||||||
|
);
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
\frametitle{Modifying the MISP core to know about the export module}
|
||||||
|
\begin{itemize}
|
||||||
|
\item The models that we are targeting by scope (Event, Attribute) need to be updated
|
||||||
|
\item They are located in /var/www/MISP/app/Model/
|
||||||
|
\item The global variable \$validFormats houses all mappings
|
||||||
|
\item Simply add a new line such as the following:
|
||||||
|
\item 'nibbler' => array('nibbler', 'NibblerExport', 'nibbler')
|
||||||
|
\end{itemize}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
\frametitle{Let us test the module!}
|
||||||
|
\begin{itemize}
|
||||||
|
\item Use the rest client to test it conveniently
|
||||||
|
\item Both the event and attribute level restSearch function should work
|
||||||
|
\item Simply set the returnFormat to nibbler, which should also show up as a valid export format
|
||||||
|
\end{itemize}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}
|
||||||
|
\frametitle{REST client}
|
||||||
|
\begin{center}
|
||||||
|
\includegraphics[scale=0.5]{nibbler_rest_client.png}
|
||||||
|
\end{center}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
|
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 5.6 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
After Width: | Height: | Size: 37 KiB |
|
@ -0,0 +1,27 @@
|
||||||
|
\documentclass{beamer}
|
||||||
|
\usetheme[numbering=progressbar]{focus}
|
||||||
|
\definecolor{main}{RGB}{47, 161, 219}
|
||||||
|
\definecolor{textcolor}{RGB}{128, 128, 128}
|
||||||
|
\definecolor{background}{RGB}{240, 247, 255}
|
||||||
|
|
||||||
|
\usepackage[utf8]{inputenc}
|
||||||
|
\usepackage{tikz}
|
||||||
|
\usepackage{listings}
|
||||||
|
\usepackage{adjustbox}
|
||||||
|
\usetikzlibrary{positioning}
|
||||||
|
\usetikzlibrary{shapes,arrows}
|
||||||
|
%\usepackage[T1]{fontenc}
|
||||||
|
%\usepackage[scaled]{beramono}
|
||||||
|
|
||||||
|
\author{\small{\input{../includes/authors.txt}}}
|
||||||
|
|
||||||
|
\title{MISP core development crash course}
|
||||||
|
\subtitle{How I learned to stop worrying and love the PHP}
|
||||||
|
\institute{\includegraphics[scale=0.5]{misplogo.pdf}}
|
||||||
|
\titlegraphic{\includegraphics[scale=0.85]{misp.pdf}}
|
||||||
|
|
||||||
|
\date{\input{../includes/location.txt}}
|
||||||
|
\begin{document}
|
||||||
|
\include{content}
|
||||||
|
\end{document}
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 39 KiB |
Loading…
Reference in New Issue