mirror of https://github.com/CIRCL/lookyloo
				
				
				
			
		
			
				
	
	
		
			322 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			HTML
		
	
	
			
		
		
	
	
			322 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			HTML
		
	
	
| {% macro taxonomy_table(tree_uuid, categories_info, add_category) %}
 | |
| <div class="table-responsive">
 | |
|   <table id="table" class="table">
 | |
|     <thead>
 | |
|       <tr>
 | |
|         <th>Name</th>
 | |
|         <th>Description</th>
 | |
|         <th>Machinetag</th>
 | |
|         {% if add_category %}
 | |
|         <th>Click to add category</th>
 | |
|         {% else %}
 | |
|         <th>Click to remove category</th>
 | |
|         {% endif %}
 | |
|       </tr>
 | |
|     </thead>
 | |
|     <tbody>
 | |
|     {% for mt, val in categories_info.items() %}
 | |
|       <tr>
 | |
|         <td><a href="https://www.misp-project.org/taxonomies.html#_{{ val[0].name }}">{{ val[0].name }}</a></td>
 | |
|         <td>
 | |
|             {% if val|length == 3 %}
 | |
|                 {% if val[2].description %}
 | |
|                     {{ val[2].description }}
 | |
|                 {% elif val[2].expanded %}
 | |
|                     {{ val[2].expanded }}
 | |
|                 {%endif%}
 | |
|             {% elif val[1].description %}
 | |
|                 {{ val[1].description }}
 | |
|             {% else %}
 | |
|                 {{ val[1].predicate }}
 | |
|             {%endif%}
 | |
|         </td>
 | |
|         <td>{{ mt }}</td>
 | |
|         <td>
 | |
|           <button type="button" class="btn btn-info {% if add_category %}categorize_capture{% else %}uncategorize_capture{% endif %}" value="{{ mt }}">
 | |
|           {% if add_category %}
 | |
|           Categorize capture.
 | |
|           {% else %}
 | |
|           Uncategorize capture.
 | |
|           {% endif %}
 | |
|           </button>
 | |
|         </td>
 | |
|       </tr>
 | |
|     {% endfor %}
 | |
|     </tbody>
 | |
|   </table>
 | |
| </div>
 | |
| <script>
 | |
|   $('.categorize_capture').on('click',function(e){
 | |
|     var button = $(this);
 | |
|     $.get("{{ url_for('categorize_capture', tree_uuid=tree_uuid) }}" + button.val())
 | |
|     $('.modal-body').load("{{ url_for('categories_capture', tree_uuid=tree_uuid) }}")
 | |
|   });
 | |
|   $('.uncategorize_capture').on('click',function(e){
 | |
|     var button = $(this);
 | |
|     $.get("{{ url_for('uncategorize_capture', tree_uuid=tree_uuid) }}" + button.val())
 | |
|     $('.modal-body').load("{{ url_for('categories_capture', tree_uuid=tree_uuid) }}")
 | |
|   });
 | |
| </script>
 | |
| {% endmacro %}
 | |
| 
 | |
| 
 | |
| {% macro known_content_details(details) %}
 | |
| <div>
 | |
| {% if details is string %}
 | |
|   <b>{{ details }} </b>
 | |
| {% else %}
 | |
|   This file is known as part of <b>{{ details[0] }}</b>
 | |
|   version <b>{{ details[1] }}</b>: <b>{{ details[2] }}</b>.
 | |
|   {% if details[3] > 1%}
 | |
|     It is also present in <b>{{ details[3] -1 }}</b> other libraries.
 | |
|   {%endif%}
 | |
| {%endif%}
 | |
| </div>
 | |
| {% endmacro %}
 | |
| 
 | |
| {% macro context_form(tree_uuid, urlnode_uuid, hostnode_uuid, hash, callback_str) %}
 | |
| <button class="btn btn-info collapsed" type="button" data-toggle="collapse" data-target="#context_response_{{ urlnode_uuid }}" aria-expanded="false" aria-controls="collapseContextForm">
 | |
|   <span class="if-collapsed">Add context</span>
 | |
|   <span class="if-not-collapsed">Hide context form</span>
 | |
| </button>
 | |
| <div class="collapse" id="context_response_{{ urlnode_uuid }}">
 | |
|   <div class="card card-body">
 | |
|       <form role="form" action="{{ url_for('add_context', tree_uuid=tree_uuid, node_uuid=urlnode_uuid) }}" method=post enctype=multipart/form-data>
 | |
|         <div class="form-group">
 | |
|           <div class="form-check">
 | |
|             <input class="form-check-input" type="checkbox" name="legitimate" id="legitimate">
 | |
|             <label for="legitimate" class="form-check-label">Legitimate</label>
 | |
|           </div>
 | |
|         </div>
 | |
|         <div class="form-group">
 | |
|           <label for="legitimate_domain">Domain serving the file when considered legitimate:</label>
 | |
|           <input type="text" class="form-control" name="legitimate_domain" id="legitimate_domain" placeholder="Domain name">
 | |
|         </div>
 | |
|         <div class="form-group">
 | |
|           <label for="legitimate_description">Other context for this content (library name, owner, ...):</label>
 | |
|           <input type="text" class="form-control" name="legitimate_description" id="legitimate_description" placeholder="Description">
 | |
|         </div>
 | |
|         <div class="form-group">
 | |
|           <div class="form-check">
 | |
|             <input class="form-check-input" type="checkbox" name="malicious"></input>
 | |
|             <label for="malicious" class="form-check-label">Malicious</label>
 | |
|           </div>
 | |
|         </div>
 | |
|         <div class="form-group">
 | |
|           <label for="malicious_type">Type of malicious content (phishing, malware, ...):</label>
 | |
|           <input type="text" class="form-control" name="malicious_type" id="malicious_type" placeholder="Type of malicious content">
 | |
|         </div>
 | |
|         <div class="form-group">
 | |
|           <label for="malicious_target">Legitimate target of the malicious content (expecially for phishing):</label>
 | |
|           <input type="text" class="form-control" name="malicious_target" id="malicious_target" placeholder="Target">
 | |
|         </div>
 | |
|         <input type="hidden" id="hash_to_contextualize" name="hash_to_contextualize" value="{{ hash }}">
 | |
|         <input type="hidden" id="hostnode_uuid" name="hostnode_uuid" value="{{ hostnode_uuid }}">
 | |
|         <input type="hidden" id="callback_str" name="callback_str" value="{{ callback_str }}">
 | |
|         <button type="submit" class="btn btn-info" id="btn-looking">Submit context</button>
 | |
|       </form>
 | |
|   </div>
 | |
| </div>
 | |
| {% endmacro %}
 | |
| 
 | |
| {% macro get_ressource_button(capture_uuid, urlnode_uuid, hash, text, can_preview=False) %}
 | |
| <form method="post" action="{{ url_for('get_ressource', tree_uuid=capture_uuid, node_uuid=urlnode_uuid) }}">
 | |
|   <button class="btn btn-info" name="ressource_hash" value="{{ hash }}"
 | |
|     {% if can_preview %}
 | |
|     data-toggle="tooltip" data-placement="bottom" data-html="true"
 | |
|     title='<img class="ressource_preview" src="{{ url_for('get_ressource_preview', tree_uuid=capture_uuid, node_uuid=urlnode_uuid, h_ressource=hash) }}"/>'
 | |
|     {% endif %}
 | |
|   >{{ text }}</button>
 | |
| </form>
 | |
| {% endmacro %}
 | |
| 
 | |
| {% macro ressource_legitimacy_details(details, ressource_size) %}
 | |
| {% if details and details[0] == False %}
 | |
|   <img src="/static/bomb.svg" title="Known malicious content in the response." width="21" height="21"/>
 | |
| {%endif%}
 | |
| <b>Body size</b>: {{ sizeof_fmt(ressource_size) }}
 | |
| {% if details %}
 | |
|   {% if details[0] %}
 | |
|   - This file is known <b>legitimate</b> on the following domains: {{ ', '.join(details[1]) }}.
 | |
|   {% elif details[0] == False %}
 | |
|     </br>
 | |
|     <p>
 | |
|     The response sould be considered as
 | |
|     {% if details[1] is mapping and details[1].get('tag') %}
 | |
|     <b>{{ ', '.join(details[1]['tag']) }}</b>
 | |
|     {% else %}
 | |
|     <b>phishing</b>
 | |
|     {%endif%}
 | |
|     {% if details[1] is mapping and details[1].get('target') %}
 | |
|       and is targeting <b>the following domain(s)</b>: {{ ', '.join(details[1]['target']) }}
 | |
|     {% else %}
 | |
|       unless it is served by <b>the following domain(s)</b>: {{ ', '.join(details[1]) }}
 | |
|     {%endif%}
 | |
|     </p>
 | |
|   {%endif%}
 | |
| {%endif%}
 | |
| {% endmacro %}
 | |
| 
 | |
| {% macro indexed_hash(details, identifier_for_toggle) %}
 | |
| {% set total_captures = details[0] %}
 | |
| {% set other_captures = details[1] %}
 | |
| {# Only show details if the hits are in an other capture #}
 | |
| {% if total_captures > 0  %}
 | |
| <p>
 | |
|   The same file was seen in <b>{{ total_captures }}</b> other captures.
 | |
|   </br>
 | |
|   <button class="btn btn-info collapsed" type="button" data-toggle="collapse" data-target="#captureslist_{{ identifier_for_toggle }}" aria-expanded="false" aria-controls="collapseExample">
 | |
|     <span class="if-collapsed">Show other captures</span>
 | |
|     <span class="if-not-collapsed">Hide other captures</span>
 | |
|   </button>
 | |
| </p>
 | |
| {# Lists of other captures loading the same content... #}
 | |
| <div class="collapse" id="captureslist_{{ identifier_for_toggle }}">
 | |
|   <div class="card card-body">
 | |
|     {% if total_captures > 20 %}
 | |
|       Note that only 20 captures are displayed here.
 | |
|     {% endif %}
 | |
|     {% if other_captures['different_url']|length > 0 %}
 | |
|     {# ... on other URLs #}
 | |
|     <div>
 | |
|       <p>The following captures get the same file from a <b>different URL</b></p>
 | |
|       {{ other_captures_table(other_captures['different_url']) }}
 | |
|     </div>
 | |
|     {% endif %}
 | |
|     </br>
 | |
|     {% if other_captures['same_url']|length > 0 %}
 | |
|     {# ... on the same URL #}
 | |
|     <div>
 | |
|       <p>The following captures get the same file from the <b>same URL</b></p>
 | |
|       {{ other_captures_table(other_captures['same_url']) }}
 | |
|     </div>
 | |
|     {% endif %}
 | |
|   </div>
 | |
| </div>
 | |
| {% endif %}
 | |
| {% endmacro %}
 | |
| 
 | |
| {% macro other_captures_table(entries) %}
 | |
| <div class="table-responsive">
 | |
|   <table id="table_other_captures" class="table">
 | |
|   <thead>
 | |
|     <tr>
 | |
|       <th>Title</th>
 | |
|       <th>Timestamp</th>
 | |
|       <th>Domain</th>
 | |
|     </tr>
 | |
|   </thead>
 | |
|   <tbody>
 | |
|   {% for capture_uuid, urlnode_uuid, title, timestamp, hostname in entries %}
 | |
|   <tr>
 | |
|     <td>
 | |
|       <a href="#/" onclick="openTreeInNewTab('{{ capture_uuid }}', '{{ urlnode_uuid }}')">{{ title }}</a>
 | |
|     </td>
 | |
|     <td>{{ timestamp }}</td>
 | |
|     <td>{{ hostname }}</td>
 | |
|   </tr>
 | |
|   {% endfor %}
 | |
|   </tbody>
 | |
|   </table>
 | |
| </div>
 | |
| {% endmacro %}
 | |
| 
 | |
| {% macro indexed_cookies(header_text, button_text, cookies) %}
 | |
| {% if cookies %}
 | |
| <div>{{ header_text }}</div>
 | |
| <ul>
 | |
| {% for cookie, details in cookies.items() %}
 | |
|   {% set cookie_name_value = cookie.split('=', 1) %}
 | |
|   {% for detail in details %}
 | |
|     {% if detail|length == 1 %}
 | |
|     <li>
 | |
|         {{ detail[0] }}: <a href="{{ url_for('cookies_name_detail', cookie_name=cookie_name_value[0]) }}">
 | |
|             {{ cookie_name_value[0] }}</a>={{ shorten_string(cookie_name_value[1], 200) }}
 | |
|     </li>
 | |
|     {% else %}
 | |
|     <li>
 | |
|         {{ detail[0] }}: <a href="{{ url_for('cookies_name_detail', cookie_name=cookie_name_value[0]) }}">
 | |
|           {{ cookie_name_value[0] }}</a>={{ shorten_string(cookie_name_value[1], 200) }} -
 | |
|         </br>
 | |
|         {{ button_text }}
 | |
|         <button type="button" class="btn btn-info" onclick="whereAmI('{{ detail[1] }}')">Locate</button>
 | |
|     </li>
 | |
|     {% endif %}
 | |
|   {% endfor %}
 | |
| {% endfor %}
 | |
| </ul>
 | |
| {% endif %}
 | |
| {% endmacro %}
 | |
| 
 | |
| {% macro popup_icons(lookup_dict, urlnode, tree_uuid) %}
 | |
| <div>
 | |
| {% for key, icon_info in lookup_dict.items() %}
 | |
|   {% if urlnode[key] %}
 | |
|     {% if key == "request_cookie" %}
 | |
|     <a href="{{ url_for('urlnode_request_cookies', tree_uuid=tree_uuid, node_uuid=urlnode.uuid) }}"
 | |
|        title="Download all the cookies in the request to the server">
 | |
|      <img src="{{ url_for('static', filename=icon_info['icon']) }}" alt="{{ icon_info['tooltip'] }}"
 | |
|           width="21" height="21"/>
 | |
|     </a>
 | |
|     {% elif key == "response_cookie"%}
 | |
|     <a href="{{ url_for('urlnode_response_cookies', tree_uuid=tree_uuid, node_uuid=urlnode.uuid) }}"
 | |
|        title="Download all the cookies in the response from the server">
 | |
|       <img src="{{ url_for('static', filename=icon_info['icon']) }}" alt="{{ icon_info['tooltip'] }}"
 | |
|            width="21" height="21"/>
 | |
|     </a>
 | |
|     {% elif key in ["js", "exe", "css", "font", "html", "json", "image", "video",
 | |
|                     "unknown_mimetype", "text", "unset_mimetype", "octet-stream", "livestream"]
 | |
|                     and not urlnode.empty_response %}
 | |
|       <a href="{{ url_for('get_ressource', tree_uuid=tree_uuid, node_uuid=urlnode.uuid) }}">
 | |
|         <img src="{{ url_for('static', filename=icon_info['icon']) }}" alt="{{ icon_info['tooltip'] }}"
 | |
|              width="21" height="21"
 | |
|         {% if key == "image" %}
 | |
|              data-toggle="tooltip" data-placement="bottom" data-html="true" title='<img class="ressource_preview" src="{{ url_for('get_ressource_preview', tree_uuid=tree_uuid, node_uuid=urlnode.uuid) }}"/> </br>Click to download.'
 | |
|         {% else %}
 | |
|              data-toggle="tooltip" data-placement="bottom" data-html="true" title="{{icon_info['tooltip']}} <br/>Click to download."
 | |
|         {% endif %}
 | |
|         />
 | |
|       </a>
 | |
|     {% elif key != "redirect" %}
 | |
|     <img src="{{ url_for('static', filename=icon_info['icon']) }}"
 | |
|          alt="{{ icon_info['tooltip'] }}" title="{{ icon_info['tooltip'] }}" width="21" height="21"/>
 | |
|     {%endif%}
 | |
|   {%endif%}
 | |
| {% endfor %}
 | |
| </div>
 | |
| 
 | |
| <div>
 | |
| {% if "redirect" in lookup_dict and urlnode["redirect"] %}
 | |
|   {% for child in urlnode.children if child.name == urlnode.redirect_url %}
 | |
|   <div title='{{ urlnode.redirect_url }}'>
 | |
|     <b>Redirect to</b>: {{ shorten_string(urlnode.redirect_url, 50) }}
 | |
|     <a href="#/" role="button" onclick="whereAmI('{{ child.hostnode_uuid }}')" title="See the node the URL redirects to.">
 | |
|       <img src="{{ url_for('static', filename=lookup_dict['redirect']['icon']) }}" alt="{{ lookup_dict['redirect']['tooltip'] }}" width="21" height="21"/>
 | |
|     </a>
 | |
|   </div>
 | |
|   {% else %}
 | |
|   <img src="{{ url_for('static', filename=lookup_dict['redirect']['icon']) }}"
 | |
|        alt="{{ lookup_dict['redirect']['tooltip'] }}" title="{{ lookup_dict['redirect']['tooltip'] }}"
 | |
|        width="21" height="21"/>
 | |
|   {% endfor %}
 | |
| {%endif%}
 | |
| </div>
 | |
| {% endmacro %}
 | |
| 
 | |
| {% macro shorten_string(string, cut_length, with_title=False) %}
 | |
| {% if with_title %}
 | |
| <div title={{string}}>
 | |
| {%endif%}
 | |
| 
 | |
| {% if string|length > cut_length %}
 | |
|   {{ string[:cut_length] }} [...]
 | |
| {% else %}
 | |
|   {{ string }}
 | |
| {%endif%}
 | |
| 
 | |
| {% if with_title %}
 | |
| </div>
 | |
| {%endif%}
 | |
| 
 | |
| {% endmacro %}
 |