-
Notifications
You must be signed in to change notification settings - Fork 26
/
part6.html
396 lines (274 loc) · 29.7 KB
/
part6.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
<!-- BEGIN HEADER -->
<!DOCTYPE html>
<html>
<head>
<title>Securing Software</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="/assets/css/mooc-icon/style.css"/>
<link rel="stylesheet" href="/assets/css/csa.css"/>
<link rel="stylesheet" href="/assets/css/csa-mooc.css"/>
</head>
<body>
<!-- BEGIN NAV -->
<header role="navigation">
<h1>
<a href="https://mooc.fi" alt="MOOC" target="_blank">
<span class="icon-mooc"></span>
</a>
<button type="button" data-toggle="collapse" data-target=".bs-navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</h1>
<nav class="collapse bs-navbar-collapse" role="navigation">
<ul>
<li>
<a href="#" class="table-of-contents-trigger">
Table of contents
</a>
</li>
<li>
<a href="index.html">Part I</a>
</li>
<li>
<a href="part2.html">Part II</a>
</li>
<li>
<a href="part3.html">Part III</a>
</li>
<li>
<a href="part4.html">Part IV</a>
</li>
<li>
<a href="part5.html">Part V</a>
</li>
<li>
<a href="part6.html">Part VI</a>
</li>
</ul>
<ul class="pull-right side-nav">
<li>
<a href="#" class="login-trigger">
Log in
</a>
</li>
</ul>
</nav>
</header>
<!-- // END NAV -->
<article>
<!-- END HEADER -->
<!-- BEGIN CONTENT -->
<section class="no-toc weeklimit hidden" data-week-id="0">
<h1>Assignments</h1>
<ul class="nav nav-pills nav-pills-fixed-width nav-pills--no-border" id="assignments-toc"></ul>
</section>
<!-- END CONTENT -->
<section class="weeklimit" data-week-id="3">
<aside class="warning">
<br />
<h1>How to pass the course</h1>
<p>Securing software is a course consisting of six parts (which are released weekly). In order to pass the course you'll need to complete and pass 85% of the quizzes and essays, and 85% of the programming assignments. In order to pass an essay you must also do <i>all</i> the peer reviews we offer for it (usually it is 3 peer reviews).
</p>
<p>
Essays must be within 20% of the proposed length. If they're not within this limit you will not get any points for your answer.
We also may reject your answer if it's flagged too many times as spam or if it doesn't contain deep enough discussion. Also, we may reject your peer reviews if you haven't put genuine effort into them. All essays must be written in english. Other languages are not acceptable.</p>
<p>If you want ECTS credits you will need to register here AFTER completing the course:
<b>To be announced after the course.</b> Join the mailing list for updates!
</p>
<p>The course will be graded after the final deadline for this course and the results will be announced on the mailing list.</p>
</aside>
<header class="hidden">
<h1>Threat Analysis</h1>
</header>
<h1>Threat Analysis</h1>
<p>In the previous sections of the course we have shown how input checking is important and introduced some tools for Fuzzing the input. As a reminder, dumb fuzzing was based mainly on random inputs on a black box and smart fuzzing relied on test harnesses on the target application. What happens inside an application when the input is given to it? If one follows the target application with a debugger one can easily see that data is being copied and modified here and there inside the program. One can even say that data is always moving (most of the time anyway). One should also remember that the data may be code and it may be accidentally interpreted if there's a vulnerability in a parser.</p>
<p>The key to understanding how a complex piece of software works is drawing a picture. You might have heard about a saying that goes "a picture is worth a thousand words". Humans cannot remember many things at a time and most systems have legions of parts and some of them are produced by a third party. It helps if the developers and the security analysts can sit down and draw while discussing about the system and what it is doing. Resolving questions like "<i>how</i>" and "<i>exactly what</i>" are very effective while one draws on whiteboard and others comment.</p>
<aside class="info">
<br/>
<h1>How to draw</h1>
<p>You might be tempted to start using a drawing apps for this task. You get nice pictures out of these but one tends to spend time tweaking with the app rather than drawing. So paper will be enough. However, whiteboard is the best option as you can easily erase and redraw parts of the diagram. If a nice looking image is needed then it is easy to copy it from the whiteboard and then use the drawing apps.</p>
</aside>
<h2>Creating diagrams</h2>
<h3>What to draw and how</h3>
<p>The diagrams presented in this section are more conceptual than technical as there is no need for all the details and the form of it is free. For example, <a href="https://en.wikipedia.org/wiki/Class_diagram">class diagrams</a> are not useful with threat analysis as they do not relate to processes, i.e. run-time encapsulation. Although some information from the classes is useful, such as serialization of data, but it can be expressed easily by writing it to the diagram.</p>
<h3>Data Flow Diagram</h3>
<p>Data Flow Diagrams are graphical representations of the data flow through the system. It is used to get an overview of the system but can be used to visualize the data processing. From the diagram it should be visible what kind of information is going in and out of the system. Below is a very simple one physical machine LAMP website example.</p>
<img src="img/dfd-lamp.png" width="70%"></img>
<aside class="info">
<br/>
<h1>Example of DFD usage</h1>
<p>Danny Dhillon writes about Developer-Driven Threat Modeling in IEEE Security & Privacy issue in Jul-Aug 2011.<a href="http://www.infoq.com/articles/developer-driven-threat-modeling" target="_blank">article</a>. In this article he tells how they use DFDs and how they scale up.</p>
</aside>
<p>The following image is related to the next question.</p>
<img src="img/dfd-simple.png" alt="dfd simple example" width="30%"></img>
<div class="quiznator-plugin" data-quiz-id="5c0f41b0369632ba3cd72049"></div>
<div class="quiznator-plugin" data-quiz-id="5c0f41b0369632ba3cd7204a"></div>
<div class="quiznator-plugin" data-quiz-id="5c0f41b0369632ba3cd72053"></div>
<div class="quiznator-plugin" data-quiz-id="5c0f41b0369632ba3cd7204b"></div>
<div class="quiznator-plugin" data-quiz-id="5c0f41b0369632ba3cd7204c"></div>
<h3>Message Sequence Chart</h3>
<p>What if there are more communicating entities and/or more complex protocols with more messages. The Message Sequence Chart is an interaction diagram which is used to illustrate communication system components and their message interchange flows. In MSC all the entities have their own vertical line and between them the messages are drawn as horizontal arrows between the entities. In MSC time runs from top to bottom. Below is an example of a Axis2 web service SSO messaging with Shibboleth.</p>
<img src="img/msc-example-shibboleth-sso.png" alt="msc example" width="70%"></img>
<!--
<p><b>Question:</b> When to use DFD or MSC? When describing what happens inside one or few boundaries Data Flow Diagram (DFD) is a good option as a diagram type and with multiple entities communicating possibly with a more complex protocol a Message Sequence Chart (MSC) is a good option. </p> -->
<h2>What to include in the diagram</h2>
<p>We just got off from saying that there is no need to be fully formal and there is no need to draw unnecessary details into the diagram. Hmm, so what to draw into the diagram? What kind of information is then needed?</p>
<p>There might be available architectural images of the whole system and they are tempting starting points to use in the analysis but actually they are not. These images might come from design team and possibly they are even for marketing purposes and should not be used. In real-life what the system exactly does is not always clear.</p>
<p>When starting with the architectural threat analysis the people around the table rarely agree on what everything in the system does. Also the fact that the developers use abstractions that are helping them to work efficiently but the abstractions might mask what is really happening in the software or give wrong assumptions on the workings of the system. Sometimes the design plan has been changed and the changes are not translated into the system itself or the system contains undocumented debugging features, etc. The best way is to start from the empty whiteboard, draw the overall architecture, and refine it in steps. These steps include many questions of "how" and "what exactly" and they are repeated multiple times. How many times depends on the situation but the point is to arrive in a place where all around the table agree that the security analysis level is meaningful.</p>
<p>So what to draw then? Keeping in mind that the result should explain the system in sufficient detail. This may differ case by case but at least the following should be found from the diagram.</p>
<p>Let's start from the way how the attacker interacts with the target system. The data needs to flow to and from the attacker to the system. This is called an interface, which is a place in the system that crosses a boundary. A security boundary is a barrier between processing blocks that is enforced externally, for example, OS controls that a process cannot read another processes' memory.</p>
<aside class="info">
<br/>
<h1>Actors</h1>
<p>Sometimes when drawing DFDs the actors are forgotten. However, the data flow sometimes starts and ends at the user and that user could be an attacker and so an important part of the DFD. Also do not forget the administrators and their administration interfaces.</p>
</aside>
<p>The first letter in DFD stands for data, but what do we want to know about it? It is good to know three things about the data: where did it come from, where is it going, and what it is. First, where did the data come from? If the data came from outside it can be attacker controlled. Second, where is the data going to? This helps in figuring out the places in the system that may have potential attacker controllable parts. Some good follow-up questions to this are how is the data transported and where is it going to be stored. It makes a huge difference that the access rights for important files are correct or that the database users are correctly setup. Third, what the data is? Depending on the data it might need more or even more security services. The data may contain information that needs to be kept safe. Information such as social security numbers or other data that needs to be kept private or otherwise sensitive data such as credit card numbers. Normally data is the content in the system but also cryptographic keys, certificates, and configuration files of the system should be considered as data.</p>
<p>The DFDs are full of blocks or sometimes bubbles (also known as bubble charts). These blocks handle the data processing and they have to be reduced to the point in which they contain a single decision on the data. This basically means that you are going as deep as needed until all ambiguity is removed from the block. Important things to draw with the blocks is information such as the implementation language. Also where did the code or block come from might be of interest as applications written today reuse existing code and are based on frameworks. From the diagram it should be easy to understand what framework and what version was used and what are all the static and dynamic libraries. Moreover, plug-ins and extensions should not be forgotten. What not to reduce? When you find a processing block over which you are not developing or have no control over otherwise. For example, the browser can be left undrawn if the system is purely server side application. However, the data flow to the browser has to be drawn.</p>
<p>The underlying technologies are one point of interest in DFDs. Virtual machines, load balancers and such should also be drawn in. Basically anything that handles the data in a way or another.</p>
<div class="quiznator-plugin" data-quiz-id="5c0f41b0369632ba3cd7204d"></div>
<div class="quiznator-plugin" data-quiz-id="5c0f41b0369632ba3cd7204e"></div>
<h2>Boundaries</h2>
<p>The DFDs are full of boxes but what are they and what do they contain? In data flow analysis, the boxes are boundaries that act as barriers between processing blocks. Some of the typical boundaries:</p>
<ul>
<li>Machine boundaries</li>
<li>Containing boundaries</li>
<li>Processes</li>
</ul>
<p>Barriers are usually externally enforced. Security boundaries are nested meaning that the physical machine is the first boundary and for example the virtual machines running on that machine are boundaries and processes running on those virtual machines are boundaries, etc. As mentioned before, in OSs processes cannot read other processes memory (this is a boundary only if the OS or the filesystem really enforces access control). Which would mean that threads do not have their own security boundaries as they share memory with their parents. Somewhat similarly same owner's processes can access the same files in the filesystem (not a boundary if looked from the filesystem point-of-view). Machines and virtual machines are also boundaries as processes do not move between machines or virtual machines.</p>
<div class="quiznator-plugin" data-quiz-id="5c0f41b0369632ba3cd7204f"></div>
<p>Containing boundaries are boundaries that do not come from the system but are usually created on purpose. Containing boundaries are isolated from the hosts execution environment in some way. For example a containing boundary can be a chroot jail, a Mandatory Access Control system (MAC), a sandbox or an operating-system-level virtualization system.</p>
<p><a href="https://help.sap.com/saphelp_nwpi711/helpdata/en/55/c602ccca7441afa6d00e088e4011de/content.htm">Java VM</a> and <a href="https://en.wikipedia.org/wiki/Seccomp">seccomp</a> are examples of sandboxes. A quarantine sandbox looks for malicious files in the confined area and determines if it is something bad. This sandbox is more like a brief period in which the files are scanned and then released. Operating-system-level virtualization can also be thought as a sandbox. For example, <a href="https://www.docker.com/">Docker</a> creates the illusion of containers being their own machines by taking advantage of <a href="https://en.wikipedia.org/wiki/Chroot">chroots</a>, <a href="https://en.wikipedia.org/wiki/Linux_namespaces">resource namespaces</a> and <a href="https://en.wikipedia.org/wiki/Cgroups">resource usage limitations</a>.</p>
<p>AppArmor and SELinux are examples of MAC. With them you can harden the processes running on the same OS and enforce detailed system checks whether the processes have the correct rights to access resources. One might ask why to use this kind of hardening in addition to the built-in OS access control but the reason is quite simple. When operating normally the OS keeps the application (their processes) at bay but if an attacker finds a way to exploit a weakness in the process and tries to access resources it is not meant to read then the MAC will not allow the operation. For example, the access control rules can specify which files, devices, and system calls are allowed and which not.</p>
<p>If an attacker is able to bypass a boundary, it usually is safe to assume that the attacker is in control of all the access rights and what happens inside that boundary. While accomplishing this may not be straightforward, it makes sense to assume the worst has happened. Moreover, this is a good incentive to keep your system up-to-date and hardened. For example if the attacker somehow gains access to a JBOSS Application Server running on the machine the attacker gains control over all the applications running on it or if the attacker gets the control of the kernel of that server the attacker gains control of the whole machine (including the virtual machines on the physical machine).</p>
<h2>Termination</h2>
<p>All the data flows have to end somewhere. Termination is an important concept as always when the data flow is parsed or acted on is a possible place for a attack. These termination points are the places where the target system is exposed to external influence. For this reason it is important to understand where each data flow terminates.</p>
<p>Protocols are one part of interest in the data flow analysis. Typical data flows are using networking protocols such as, IP, UDP, TCP, SSL, TLS, HTTP (Ethernet is not mentioned as it is not end-to-end protocol instead it terminates switch by switch and connects only devices in close proximity). These protocols are stacked on top of each other and all of them have their own task in the networking stack (Please see the <a href="https://en.wikipedia.org/wiki/OSI_model">OSI model</a>). IP is the responsible one to getting the packet routed from the source to the target, Next layer is the transport layer which handles things such as flow control, reliability, multiplexing with either UDP or TCP depending on what kind of traffic characteristics are needed. Protocols such as TLS are used to provide confidentiality and integrity on top of TCP (DTLS on top of UDP). On top of that protocols such as HTTP and CoAP are used to move web page requests and responses. On top of there may still be application level protocols that are using all of the above to transport their protocol messages.</p>
<p>But where do these protocols terminate or do they just pass through? Data passing through if it is passed through without touching it (i.e. no parsing, filtering, etc.). These points are not part of the attack surface. Most of the IP routers and such belong to these devices. Anything that looks into the traffic, be it a proxy or a load balancer terminates the flow of that layer and makes it a possible point of attack. From a black box it is hard to determine if it is passing through the data or is it actively "tampered" with. Sometimes for some boxes the "looking into what it is doing" is impossible and these should be treated as untrustworthy termination and new traffic points.</p>
<div class="quiznator-plugin" data-quiz-id="5c0f41b0369632ba3cd72050"></div>
<h2>Taint Analysis</h2>
<p>Taint analysis is a form of information flow analysis that is used to track untrusted input through the system (the term originates from perl). A flow is an operation or set of operations that operate on value x to derive another value y. If the x here comes from untrustworthy source it is tainted and it is given a tag or a label. This is done to all user data. These tags allow the tracking the influence of the objects through the target application. Tainting also propagates and is transitive as when a tainted object is used to derive yet another value that value is then also tainted.</p>
<p>What can be done with tainting? We can track user data and see if non-trusted data can reach locations that it should not, i.e. which boundaries does the tainted data end up in. For example if non-trusted data reaches privileged location it is possible that it may cause buffer overflows, XSS, etc. Taint analysis is nice as it can detect that something is wrong even with unknown attacks. In taint analysis all statements are checked if there is tainted objects included and if there is the execution is halted.</p>
<p>The taint analysis phase of threat analysis follows all the data flows and all layers of flows and can identify the components that process the data. Taint analysis is one of the easiest ways to understand which components in the system are the ones exposed most to the attacker generated data. The output of the taint analysis is a good list of candidates for fuzz testing (discussed in earlier part). Other analysis can also be performed on the components in the list.</p>
<aside class="info">
<br/>
<h1>The checker framework, type based taint analysis in Java web applications</h1>
<p>The tainting can be as simple as associating a boolean value to a piece of data. Although sometimes more data may be helpful, for example, it may be useful to be able to distinguish the source of the data. Actions that could be taken when for example a tainted piece of data tries to leave the system are for example, logging, stopping the transfer of the data, or even halting the program.</p>
<p><a href="http://types.cs.washington.edu/checker-framework/">Checker framework</a> is one open source tool that enhances Java's type system that it is more expressive. With Checker you can annotate types and source files and detect and prevent errors. They also provide a small <a href="https://types.cs.washington.edu/checker-framework/tutorial/webpages/security-error-eclipse.html">tutorial</a> to get you started with the tainting checker.</p>
</aside>
<div class="quiznator-plugin" data-quiz-id="5c0f41b0369632ba3cd72051"></div>
<h2>Data lifetime</h2>
<p>Data lifetime is very important to think about when implementing software. The lifetime depends on the fact on who allocates the memory for that piece of data and where does it end up. The memory can be allocated from different places, from Kernel, system applications, and from user applications. This means different things for the lifetime of the data and where it ends up. The data may end up in places such as the kernel, any application, system swap, or hibernation storage.</p>
<!--
<p>
<b>Question:</b> In java which one would you use to store sensitive data in an application?
<ul>
<li>String</li>
<li>Char table</li>
</ul>
With an char table one can wipe the data after they are done with the table. One can write anything into the table and be done with it (although, a possibility of runtime copies of the table exists). Strings however are immutable and they leave you no way to clear the data before garbage collection (not exactly true as you can use <a href="https://en.wikipedia.org/wiki/Reflection_%28computer_programming%29">reflection</a>). So char table is better but even that only reduces the window of opportunity for the attacker to dump the memory.
</p>
-->
<p>The problem of minimizing the lifetime of a piece of data is hard. One can follow two different approaches the coarse-grained and fine-grained control for propagation. First, in coarse-grained control one cannot determine when the data is for example swapped out of the memory or have little control in core dump situations (written to a log file). Against the swapping one can try to protect by encrypting the swap with <a href="https://wiki.archlinux.org/index.php/Dm-crypt/Swap_encryption">dm-crypt</a> or similar if possible or by explicitly locking the data to memory which is possible for example in C by using <i>mmap</i> and <i>mlock</i>. If the core dump is setup incorrectly the contents may be readable to unprivileged users and there is a risk that the dump contains sensitive information. Also in situations where the dump is sent to another machine, for example with netdump, care must be taken that the dump is not sent with "NETDUMPKEYEXCHANGE" variable set into <i>none</i>. Second, the fine-grained control relies on programmers. Depending on the language it may not always be possible but, for example in C this would mean removing <i>memsets</i>. More information of this and related things can be found from the <a href="http://www.oracle.com/technetwork/java/seccodeguide-139067.html#2">Secure Coding Guidelines</a> for Java SE.</p>
<div class="quiznator-plugin" data-quiz-id="5c0f41b0369632ba3cd72052"></div>
<div class="quiznator-plugin" data-quiz-id="5c0f41b0369632ba3cd72055"></div>
<div class="quiznator-plugin" data-quiz-id="5c0f41b0369632ba3cd72056"></div>
<div class="quiznator-plugin" data-quiz-id="5c0f41b0369632ba3cd72057"></div>
<div class="quiznator-plugin" data-quiz-id="5c0f41b0369632ba3cd72054"></div>
<p>During this course, we have taken an introductory tour to securing (web) software. In the course project, some of this knowledge is taken into use. Stay tuned.</p>
</section>
</article>
<!-- LOGIN MODAL -->
<div class="modal fade" id="tmc-login-modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">Log in with your MOOC.fi account</h4>
</div>
<div class="modal-body">
<div class="alert alert-info">
Don't have a MOOC.fi account? <a href="https://tmc.mooc.fi/user/new" target="_blank">Sign up</a>.
</div>
<div class="alert alert-danger" id="tmc-login-error" style="display: none">
</div>
<div class="form-group">
<label>Username or email</label>
<input type="text" id="tmc-login-username" class="form-control" placeholder="Username or email"/>
</div>
<div class="form-group">
<label>Password</label>
<input type="password" id="tmc-login-password" class="form-control" placeholder="Password"/>
</div>
<div class="form-group">
<a href="https://tmc.mooc.fi/password_reset_keys/new">I forgot my password</a>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" id="tmc-login-submit">Log in</button>
</div>
</div>
</div>
</div>
<!-- TABLE OF CONTENTS -->
<div class="table-of-contents-layer">
</div>
<div class="table-of-contents">
<h1 class="table-of-contents__heading">
Table of contents
</h1>
<div class="table-of-contents__content">
<ul class="nav" id="material-toc"></ul>
</div>
</div>
<!-- PROGRESS -->
<div class="content-progress">
<div class="content-progress__label">
</div>
<div class="content-progress__bar">
</div>
</div>
<!-- QUIZNATOR DASHBOARD -->
<div class="quiznator-dashboard"></div>
<!-- BROWSER SUPPORT WARNING -->
<div class="browser-support-warning">
Some parts of this page might not work on your current browser. Consider switching to either <a href="https://www.google.com/chrome/browser/desktop/" target="_blank">Chrome</a> or <a href="https://www.mozilla.org/en-US/firefox/new/" target="_blank">Firefox</a>.
<a class="pull-right browser-support-warning__close">Got it!</a>
</div>
<script src="https://quiznator.mooc.fi/javascripts/plugin-loader.min.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"
integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
crossorigin="anonymous"></script>
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script src="/assets/js/tmc-client-js/dist/tmc-client.min.js"></script>
<script src="/assets/js/bowser/bowser.js"></script>
<script src="/assets/js/csa.js"></script>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-86250620-1', 'auto');
ga('set', 'anonymizeIp', true);
ga('require', 'linkid');
ga('send', 'pageview');
var trackOutbound = function(url) {
ga('send', 'event', 'outbound', 'click', url, {
'transport': 'beacon',
'hitCallback': function(){ window.open(url); }
});
}
</script>
<!-- COOKIES -->
<link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.0.1/cookieconsent.min.css" />
<script src="//cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.0.1/cookieconsent.min.js"></script>
<script>window.cookieconsent.initialise({"palette":{"popup":{"background":"#000"},"button":{"background":"#f1d600"}}});</script>
</body>
</html>