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
	
	 iglocska
						iglocska